diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..ab8428c --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,15 @@ +[source.crates-io] +replace-with = "vendored-sources" + +[source."git+https://git.jpace121.net/public/limbo_graph.git?branch=main"] +git = "https://git.jpace121.net/public/limbo_graph.git" +branch = "main" +replace-with = "vendored-sources" + +[source."git+ssh://git@git.jpace121.net:2222/public/j7s_diagnostics.git?branch=main"] +git = "ssh://git@git.jpace121.net:2222/public/j7s_diagnostics.git" +branch = "main" +replace-with = "vendored-sources" + +[source.vendored-sources] +directory = "vendor" diff --git a/Cargo.lock b/Cargo.lock index 36ed34e..d3b4db0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,7 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "j7s_diagnostics" version = "0.1.0" +source = "git+ssh://git@git.jpace121.net:2222/public/j7s_diagnostics.git?branch=main#c8b5db719c0de550a22b87f88c34ac7c0489f78c" dependencies = [ "limbo_graph", "serde", @@ -163,7 +164,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] [[package]] @@ -192,9 +193,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.3" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" dependencies = [ "proc-macro2", "quote", @@ -224,14 +225,14 @@ checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] [[package]] name = "unicode-ident" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +checksum = "ab72a15cf68d77cb0987d3684aa8a45c5ef827e8cb49ee2f30bfd7ba2feb519f" [[package]] name = "zmij" diff --git a/Cargo.toml b/Cargo.toml index 3a3c24a..0202d18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,4 +10,4 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.29.0" -j7s_diagnostics = { path="../j7s_diagnostics/", features=["std"] } +j7s_diagnostics = { branch="main", git="ssh://git@git.jpace121.net:2222/public/j7s_diagnostics.git", features=["std"] } diff --git a/vendor/heck/.cargo-checksum.json b/vendor/heck/.cargo-checksum.json new file mode 100644 index 0000000..21da2a5 --- /dev/null +++ b/vendor/heck/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo_vcs_info.json":"9fe8de8b6d00ac74ff6fd3e25edbed562193b0441d891bb005bcb6e94b983019","CHANGELOG.md":"972078362c7c30856e5ef46aa52c1c0ec3de40f417544566e225204b4cd4982a","Cargo.toml":"db0e63b72de157a2f5194458b73b6542c3f4e17e33ab34a71d0260bfc035467e","Cargo.toml.orig":"f2ce51ef3c464f05e45c5ce01bbc40c90c8fd31885ed7b3b8bf831fd8cf4ad4f","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"c3c627aa49e64826aaf4914e5a3bd0aa2d1b304464c3e99cb6507190d3620a85","src/kebab.rs":"3075cf72c95404e6b5800494a5d8a3c5f6dd5066593ddb249cefcb376e30b450","src/lib.rs":"bffcc5144da472d2f915696d4654f7608e60861d168d3dd07b5dcb8f14211153","src/lower_camel.rs":"3b1e367db1ae22aa8c49b6800abf5e23e6befadf7cc89a252534f7286676e11f","src/shouty_kebab.rs":"8539eeddd4d78c10a8d0df3e19ad171409e95429debcdc6b7dbefd82d37b6928","src/shouty_snake.rs":"e8b6dcb77de87e2355067d5d47037537b68fa51c2601924a6acfae409c6d9920","src/snake.rs":"e13e8a4373e9388044bd91edff496362a1e7f6bd52f5f6be14a043878035245d","src/title.rs":"a12abc5057b48b8d5922d2a11b6029b230e13ae9a04109a40407d19505c2521b","src/train.rs":"0cbe348135852c12e9c56ab93233ca5c044218bc1b8818b620c3e80cd19973c2","src/upper_camel.rs":"9036542a600fd261b046ac4574622f831335abcf1366665aab56f4045fceb0d5"},"package":"2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"} \ No newline at end of file diff --git a/vendor/heck/.cargo_vcs_info.json b/vendor/heck/.cargo_vcs_info.json new file mode 100644 index 0000000..5f5becd --- /dev/null +++ b/vendor/heck/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "070693322aee7c5c7fbee7c9964bf8d7d3a29c96" + }, + "path_in_vcs": "" +} \ No newline at end of file diff --git a/vendor/heck/CHANGELOG.md b/vendor/heck/CHANGELOG.md new file mode 100644 index 0000000..18d752b --- /dev/null +++ b/vendor/heck/CHANGELOG.md @@ -0,0 +1,25 @@ +# unreleased + +# 0.5.0 + +- Add `no_std` support. +- Remove non-additive `unicode` feature. The library now uses `char::is_alphanumeric` + instead of the `unicode-segmentation` library to determine word boundaries in all cases. + +# 0.4.1 + +Improvements: + +- Add Train-Case support + +# 0.4.0 + +Breaking changes: + +* Make unicode support optional (off by default). Enable the `unicode` crate + feature if you need unicode support. +* Rename all traits from `SomeCase` to `ToSomeCase`, matching `std`s convention + of beginning trait names with a verb (`ToOwned`, `AsRef`, …) +* Rename `ToMixedCase` to `ToLowerCamelCase` +* Rename `ToCamelCase` to `ToUpperCamelCase` +* Add `ToPascalCase` as an alias to `ToUpperCamelCase` diff --git a/vendor/heck/Cargo.toml b/vendor/heck/Cargo.toml new file mode 100644 index 0000000..38875e8 --- /dev/null +++ b/vendor/heck/Cargo.toml @@ -0,0 +1,34 @@ +# 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 = "heck" +version = "0.5.0" +include = [ + "src/**/*", + "LICENSE-*", + "README.md", + "CHANGELOG.md", +] +description = "heck is a case conversion library." +readme = "README.md" +keywords = [ + "string", + "case", + "camel", + "snake", + "unicode", +] +categories = ["no-std"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/withoutboats/heck" diff --git a/vendor/heck/Cargo.toml.orig b/vendor/heck/Cargo.toml.orig new file mode 100644 index 0000000..a9fa2c3 --- /dev/null +++ b/vendor/heck/Cargo.toml.orig @@ -0,0 +1,11 @@ +[package] +name = "heck" +version = "0.5.0" +edition = "2021" +rust-version = "1.56" +license = "MIT OR Apache-2.0" +description = "heck is a case conversion library." +repository = "https://github.com/withoutboats/heck" +keywords = ["string", "case", "camel", "snake", "unicode"] +categories = ["no-std"] +include = ["src/**/*", "LICENSE-*", "README.md", "CHANGELOG.md"] diff --git a/vendor/heck/LICENSE-APACHE b/vendor/heck/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/vendor/heck/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/heck/LICENSE-MIT b/vendor/heck/LICENSE-MIT new file mode 100644 index 0000000..e69282e --- /dev/null +++ b/vendor/heck/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2015 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/heck/README.md b/vendor/heck/README.md new file mode 100644 index 0000000..9b9b4e8 --- /dev/null +++ b/vendor/heck/README.md @@ -0,0 +1,53 @@ +# **heck** is a case conversion library + +!["I specifically requested the opposite of this."](./no_step_on_snek.png) + +This library exists to provide case conversion between common cases like +CamelCase and snake_case. It is intended to be unicode aware, internally +consistent, and reasonably well performing. + +## Definition of a word boundary + +Word boundaries are defined by non-alphanumeric characters, as well as +within those words in this manner: + +1. If an uppercase character is followed by lowercase letters, a word +boundary is considered to be just prior to that uppercase character. +2. If multiple uppercase characters are consecutive, they are considered to +be within a single word, except that the last will be part of the next word +if it is followed by lowercase characters (see rule 1). + +That is, "HelloWorld" is segmented `Hello|World` whereas "XMLHttpRequest" is +segmented `XML|Http|Request`. + +Characters not within words (such as spaces, punctuations, and underscores) +are not included in the output string except as they are a part of the case +being converted to. Multiple adjacent word boundaries (such as a series of +underscores) are folded into one. ("hello__world" in snake case is therefore +"hello_world", not the exact same string). Leading or trailing word boundary +indicators are dropped, except insofar as CamelCase capitalizes the first word. + +## Cases contained in this library: + +1. UpperCamelCase +2. lowerCamelCase +3. snake_case +4. kebab-case +5. SHOUTY_SNAKE_CASE +6. Title Case +7. SHOUTY-KEBAB-CASE +8. Train-Case + +## MSRV + +The minimum supported Rust version for this crate is 1.56.0. This may change in +minor or patch releases, but we probably won't ever require a very recent +version. If you would like to have a stronger guarantee than that, please open +an issue. + +## License + +heck is distributed under the terms of both the MIT license and the +Apache License (Version 2.0). + +See LICENSE-APACHE and LICENSE-MIT for details. diff --git a/vendor/heck/src/kebab.rs b/vendor/heck/src/kebab.rs new file mode 100644 index 0000000..b30b0e4 --- /dev/null +++ b/vendor/heck/src/kebab.rs @@ -0,0 +1,75 @@ +use core::fmt; + +use alloc::{borrow::ToOwned, string::ToString}; + +use crate::{lowercase, transform}; + +/// This trait defines a kebab case conversion. +/// +/// In kebab-case, word boundaries are indicated by hyphens. +/// +/// ## Example: +/// +/// ```rust +/// use heck::ToKebabCase; +/// +/// let sentence = "We are going to inherit the earth."; +/// assert_eq!(sentence.to_kebab_case(), "we-are-going-to-inherit-the-earth"); +/// ``` +pub trait ToKebabCase: ToOwned { + /// Convert this type to kebab case. + fn to_kebab_case(&self) -> Self::Owned; +} + +impl ToKebabCase for str { + fn to_kebab_case(&self) -> Self::Owned { + AsKebabCase(self).to_string() + } +} + +/// This wrapper performs a kebab case conversion in [`fmt::Display`]. +/// +/// ## Example: +/// +/// ``` +/// use heck::AsKebabCase; +/// +/// let sentence = "We are going to inherit the earth."; +/// assert_eq!(format!("{}", AsKebabCase(sentence)), "we-are-going-to-inherit-the-earth"); +/// ``` +pub struct AsKebabCase>(pub T); + +impl> fmt::Display for AsKebabCase { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + transform(self.0.as_ref(), lowercase, |f| write!(f, "-"), f) + } +} + +#[cfg(test)] +mod tests { + use super::ToKebabCase; + + macro_rules! t { + ($t:ident : $s1:expr => $s2:expr) => { + #[test] + fn $t() { + assert_eq!($s1.to_kebab_case(), $s2) + } + }; + } + + t!(test1: "CamelCase" => "camel-case"); + t!(test2: "This is Human case." => "this-is-human-case"); + t!(test3: "MixedUP CamelCase, with some Spaces" => "mixed-up-camel-case-with-some-spaces"); + t!(test4: "mixed_up_ snake_case with some _spaces" => "mixed-up-snake-case-with-some-spaces"); + t!(test5: "kebab-case" => "kebab-case"); + t!(test6: "SHOUTY_SNAKE_CASE" => "shouty-snake-case"); + t!(test7: "snake_case" => "snake-case"); + t!(test8: "this-contains_ ALLKinds OfWord_Boundaries" => "this-contains-all-kinds-of-word-boundaries"); + t!(test9: "XΣXΣ baffle" => "xσxς-baffle"); + t!(test10: "XMLHttpRequest" => "xml-http-request"); + t!(test11: "لِنَذْهَبْ إِلَى السِّيْنَمَا" => "لِنَذْهَبْ-إِلَى-السِّيْنَمَا"); + // Japanese and Chinese do not have word separation. + t!(test12: "ファイルを読み込み" => "ファイルを読み込み"); + t!(test13: "祝你一天过得愉快" => "祝你一天过得愉快"); +} diff --git a/vendor/heck/src/lib.rs b/vendor/heck/src/lib.rs new file mode 100644 index 0000000..ab8a015 --- /dev/null +++ b/vendor/heck/src/lib.rs @@ -0,0 +1,192 @@ +//! **heck** is a case conversion library. +//! +//! This library exists to provide case conversion between common cases like +//! CamelCase and snake_case. It is intended to be unicode aware, internally +//! consistent, and reasonably well performing. +//! +//! ## Definition of a word boundary +//! +//! Word boundaries are defined by non-alphanumeric characters, as well as +//! within those words in this manner: +//! +//! 1. If an uppercase character is followed by lowercase letters, a word +//! boundary is considered to be just prior to that uppercase character. +//! 2. If multiple uppercase characters are consecutive, they are considered to +//! be within a single word, except that the last will be part of the next word +//! if it is followed by lowercase characters (see rule 1). +//! +//! That is, "HelloWorld" is segmented `Hello|World` whereas "XMLHttpRequest" is +//! segmented `XML|Http|Request`. +//! +//! Characters not within words (such as spaces, punctuations, and underscores) +//! are not included in the output string except as they are a part of the case +//! being converted to. Multiple adjacent word boundaries (such as a series of +//! underscores) are folded into one. ("hello__world" in snake case is therefore +//! "hello_world", not the exact same string). Leading or trailing word boundary +//! indicators are dropped, except insofar as CamelCase capitalizes the first +//! word. +//! +//! ### Cases contained in this library: +//! +//! 1. UpperCamelCase +//! 2. lowerCamelCase +//! 3. snake_case +//! 4. kebab-case +//! 5. SHOUTY_SNAKE_CASE +//! 6. Title Case +//! 7. SHOUTY-KEBAB-CASE +//! 8. Train-Case +#![deny(missing_docs)] +#![forbid(unsafe_code)] +#![no_std] + +extern crate alloc; + +mod kebab; +mod lower_camel; +mod shouty_kebab; +mod shouty_snake; +mod snake; +mod title; +mod train; +mod upper_camel; + +pub use kebab::{AsKebabCase, ToKebabCase}; +pub use lower_camel::{AsLowerCamelCase, ToLowerCamelCase}; +pub use shouty_kebab::{AsShoutyKebabCase, ToShoutyKebabCase}; +pub use shouty_snake::{ + AsShoutySnakeCase, AsShoutySnakeCase as AsShoutySnekCase, ToShoutySnakeCase, ToShoutySnekCase, +}; +pub use snake::{AsSnakeCase, AsSnakeCase as AsSnekCase, ToSnakeCase, ToSnekCase}; +pub use title::{AsTitleCase, ToTitleCase}; +pub use train::{AsTrainCase, ToTrainCase}; +pub use upper_camel::{ + AsUpperCamelCase, AsUpperCamelCase as AsPascalCase, ToPascalCase, ToUpperCamelCase, +}; + +use core::fmt; + +fn transform( + s: &str, + mut with_word: F, + mut boundary: G, + f: &mut fmt::Formatter, +) -> fmt::Result +where + F: FnMut(&str, &mut fmt::Formatter) -> fmt::Result, + G: FnMut(&mut fmt::Formatter) -> fmt::Result, +{ + /// Tracks the current 'mode' of the transformation algorithm as it scans + /// the input string. + /// + /// The mode is a tri-state which tracks the case of the last cased + /// character of the current word. If there is no cased character + /// (either lowercase or uppercase) since the previous word boundary, + /// than the mode is `Boundary`. If the last cased character is lowercase, + /// then the mode is `Lowercase`. Othertherwise, the mode is + /// `Uppercase`. + #[derive(Clone, Copy, PartialEq)] + enum WordMode { + /// There have been no lowercase or uppercase characters in the current + /// word. + Boundary, + /// The previous cased character in the current word is lowercase. + Lowercase, + /// The previous cased character in the current word is uppercase. + Uppercase, + } + + let mut first_word = true; + + for word in s.split(|c: char| !c.is_alphanumeric()) { + let mut char_indices = word.char_indices().peekable(); + let mut init = 0; + let mut mode = WordMode::Boundary; + + while let Some((i, c)) = char_indices.next() { + if let Some(&(next_i, next)) = char_indices.peek() { + // The mode including the current character, assuming the + // current character does not result in a word boundary. + let next_mode = if c.is_lowercase() { + WordMode::Lowercase + } else if c.is_uppercase() { + WordMode::Uppercase + } else { + mode + }; + + // Word boundary after if current is not uppercase and next + // is uppercase + if next_mode == WordMode::Lowercase && next.is_uppercase() { + if !first_word { + boundary(f)?; + } + with_word(&word[init..next_i], f)?; + first_word = false; + init = next_i; + mode = WordMode::Boundary; + + // Otherwise if current and previous are uppercase and next + // is lowercase, word boundary before + } else if mode == WordMode::Uppercase && c.is_uppercase() && next.is_lowercase() { + if !first_word { + boundary(f)?; + } else { + first_word = false; + } + with_word(&word[init..i], f)?; + init = i; + mode = WordMode::Boundary; + + // Otherwise no word boundary, just update the mode + } else { + mode = next_mode; + } + } else { + // Collect trailing characters as a word + if !first_word { + boundary(f)?; + } else { + first_word = false; + } + with_word(&word[init..], f)?; + break; + } + } + } + + Ok(()) +} + +fn lowercase(s: &str, f: &mut fmt::Formatter) -> fmt::Result { + let mut chars = s.chars().peekable(); + while let Some(c) = chars.next() { + if c == 'Σ' && chars.peek().is_none() { + write!(f, "ς")?; + } else { + write!(f, "{}", c.to_lowercase())?; + } + } + + Ok(()) +} + +fn uppercase(s: &str, f: &mut fmt::Formatter) -> fmt::Result { + for c in s.chars() { + write!(f, "{}", c.to_uppercase())?; + } + + Ok(()) +} + +fn capitalize(s: &str, f: &mut fmt::Formatter) -> fmt::Result { + let mut char_indices = s.char_indices(); + if let Some((_, c)) = char_indices.next() { + write!(f, "{}", c.to_uppercase())?; + if let Some((i, _)) = char_indices.next() { + lowercase(&s[i..], f)?; + } + } + + Ok(()) +} diff --git a/vendor/heck/src/lower_camel.rs b/vendor/heck/src/lower_camel.rs new file mode 100644 index 0000000..a31fc33 --- /dev/null +++ b/vendor/heck/src/lower_camel.rs @@ -0,0 +1,88 @@ +use core::fmt; + +use alloc::{ + borrow::ToOwned, + string::{String, ToString}, +}; + +use crate::{capitalize, lowercase, transform}; + +/// This trait defines a lower camel case conversion. +/// +/// In lowerCamelCase, word boundaries are indicated by capital letters, +/// excepting the first word. +/// +/// ## Example: +/// +/// ```rust +/// use heck::ToLowerCamelCase; +/// +/// let sentence = "It is we who built these palaces and cities."; +/// assert_eq!(sentence.to_lower_camel_case(), "itIsWeWhoBuiltThesePalacesAndCities"); +/// ``` +pub trait ToLowerCamelCase: ToOwned { + /// Convert this type to lower camel case. + fn to_lower_camel_case(&self) -> Self::Owned; +} + +impl ToLowerCamelCase for str { + fn to_lower_camel_case(&self) -> String { + AsLowerCamelCase(self).to_string() + } +} + +/// This wrapper performs a lower camel case conversion in [`fmt::Display`]. +/// +/// ## Example: +/// +/// ``` +/// use heck::AsLowerCamelCase; +/// +/// let sentence = "It is we who built these palaces and cities."; +/// assert_eq!(format!("{}", AsLowerCamelCase(sentence)), "itIsWeWhoBuiltThesePalacesAndCities"); +/// ``` +pub struct AsLowerCamelCase>(pub T); + +impl> fmt::Display for AsLowerCamelCase { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut first = true; + transform( + self.0.as_ref(), + |s, f| { + if first { + first = false; + lowercase(s, f) + } else { + capitalize(s, f) + } + }, + |_| Ok(()), + f, + ) + } +} + +#[cfg(test)] +mod tests { + use super::ToLowerCamelCase; + + macro_rules! t { + ($t:ident : $s1:expr => $s2:expr) => { + #[test] + fn $t() { + assert_eq!($s1.to_lower_camel_case(), $s2) + } + }; + } + + t!(test1: "CamelCase" => "camelCase"); + t!(test2: "This is Human case." => "thisIsHumanCase"); + t!(test3: "MixedUP CamelCase, with some Spaces" => "mixedUpCamelCaseWithSomeSpaces"); + t!(test4: "mixed_up_ snake_case, with some _spaces" => "mixedUpSnakeCaseWithSomeSpaces"); + t!(test5: "kebab-case" => "kebabCase"); + t!(test6: "SHOUTY_SNAKE_CASE" => "shoutySnakeCase"); + t!(test7: "snake_case" => "snakeCase"); + t!(test8: "this-contains_ ALLKinds OfWord_Boundaries" => "thisContainsAllKindsOfWordBoundaries"); + t!(test9: "XΣXΣ baffle" => "xσxςBaffle"); + t!(test10: "XMLHttpRequest" => "xmlHttpRequest"); +} diff --git a/vendor/heck/src/shouty_kebab.rs b/vendor/heck/src/shouty_kebab.rs new file mode 100644 index 0000000..bfa271d --- /dev/null +++ b/vendor/heck/src/shouty_kebab.rs @@ -0,0 +1,73 @@ +use core::fmt; + +use alloc::{borrow::ToOwned, string::ToString}; + +use crate::{transform, uppercase}; + +/// This trait defines a shouty kebab case conversion. +/// +/// In SHOUTY-KEBAB-CASE, word boundaries are indicated by hyphens and all +/// words are in uppercase. +/// +/// ## Example: +/// +/// ```rust +/// use heck::ToShoutyKebabCase; +/// +/// let sentence = "We are going to inherit the earth."; +/// assert_eq!(sentence.to_shouty_kebab_case(), "WE-ARE-GOING-TO-INHERIT-THE-EARTH"); +/// ``` +pub trait ToShoutyKebabCase: ToOwned { + /// Convert this type to shouty kebab case. + fn to_shouty_kebab_case(&self) -> Self::Owned; +} + +impl ToShoutyKebabCase for str { + fn to_shouty_kebab_case(&self) -> Self::Owned { + AsShoutyKebabCase(self).to_string() + } +} + +/// This wrapper performs a kebab case conversion in [`fmt::Display`]. +/// +/// ## Example: +/// +/// ``` +/// use heck::AsShoutyKebabCase; +/// +/// let sentence = "We are going to inherit the earth."; +/// assert_eq!(format!("{}", AsShoutyKebabCase(sentence)), "WE-ARE-GOING-TO-INHERIT-THE-EARTH"); +/// ``` +pub struct AsShoutyKebabCase>(pub T); + +impl> fmt::Display for AsShoutyKebabCase { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + transform(self.0.as_ref(), uppercase, |f| write!(f, "-"), f) + } +} + +#[cfg(test)] +mod tests { + use super::ToShoutyKebabCase; + + macro_rules! t { + ($t:ident : $s1:expr => $s2:expr) => { + #[test] + fn $t() { + assert_eq!($s1.to_shouty_kebab_case(), $s2) + } + }; + } + + t!(test1: "CamelCase" => "CAMEL-CASE"); + t!(test2: "This is Human case." => "THIS-IS-HUMAN-CASE"); + t!(test3: "MixedUP CamelCase, with some Spaces" => "MIXED-UP-CAMEL-CASE-WITH-SOME-SPACES"); + t!(test4: "mixed_up_ snake_case with some _spaces" => "MIXED-UP-SNAKE-CASE-WITH-SOME-SPACES"); + t!(test5: "kebab-case" => "KEBAB-CASE"); + t!(test6: "SHOUTY_SNAKE_CASE" => "SHOUTY-SNAKE-CASE"); + t!(test7: "snake_case" => "SNAKE-CASE"); + t!(test8: "this-contains_ ALLKinds OfWord_Boundaries" => "THIS-CONTAINS-ALL-KINDS-OF-WORD-BOUNDARIES"); + t!(test9: "XΣXΣ baffle" => "XΣXΣ-BAFFLE"); + t!(test10: "XMLHttpRequest" => "XML-HTTP-REQUEST"); + t!(test11: "SHOUTY-KEBAB-CASE" => "SHOUTY-KEBAB-CASE"); +} diff --git a/vendor/heck/src/shouty_snake.rs b/vendor/heck/src/shouty_snake.rs new file mode 100644 index 0000000..54a3556 --- /dev/null +++ b/vendor/heck/src/shouty_snake.rs @@ -0,0 +1,86 @@ +use core::fmt; + +use alloc::{borrow::ToOwned, string::ToString}; + +use crate::{transform, uppercase}; + +/// This trait defines a shouty snake case conversion. +/// +/// In SHOUTY_SNAKE_CASE, word boundaries are indicated by underscores and all +/// words are in uppercase. +/// +/// ## Example: +/// +/// ```rust +/// use heck::ToShoutySnakeCase; +/// +/// let sentence = "That world is growing in this minute."; +/// assert_eq!(sentence.to_shouty_snake_case(), "THAT_WORLD_IS_GROWING_IN_THIS_MINUTE"); +/// ``` +pub trait ToShoutySnakeCase: ToOwned { + /// Convert this type to shouty snake case. + fn to_shouty_snake_case(&self) -> Self::Owned; +} + +/// Oh heck, `ToShoutySnekCase` is an alias for [`ToShoutySnakeCase`]. See +/// ToShoutySnakeCase for more documentation. +pub trait ToShoutySnekCase: ToOwned { + /// CONVERT THIS TYPE TO SNEK CASE. + #[allow(non_snake_case)] + fn TO_SHOUTY_SNEK_CASE(&self) -> Self::Owned; +} + +impl ToShoutySnekCase for T { + fn TO_SHOUTY_SNEK_CASE(&self) -> Self::Owned { + self.to_shouty_snake_case() + } +} + +impl ToShoutySnakeCase for str { + fn to_shouty_snake_case(&self) -> Self::Owned { + AsShoutySnakeCase(self).to_string() + } +} + +/// This wrapper performs a shouty snake case conversion in [`fmt::Display`]. +/// +/// ## Example: +/// +/// ``` +/// use heck::AsShoutySnakeCase; +/// +/// let sentence = "That world is growing in this minute."; +/// assert_eq!(format!("{}", AsShoutySnakeCase(sentence)), "THAT_WORLD_IS_GROWING_IN_THIS_MINUTE"); +/// ``` +pub struct AsShoutySnakeCase>(pub T); + +impl> fmt::Display for AsShoutySnakeCase { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + transform(self.0.as_ref(), uppercase, |f| write!(f, "_"), f) + } +} + +#[cfg(test)] +mod tests { + use super::ToShoutySnakeCase; + + macro_rules! t { + ($t:ident : $s1:expr => $s2:expr) => { + #[test] + fn $t() { + assert_eq!($s1.to_shouty_snake_case(), $s2) + } + }; + } + + t!(test1: "CamelCase" => "CAMEL_CASE"); + t!(test2: "This is Human case." => "THIS_IS_HUMAN_CASE"); + t!(test3: "MixedUP CamelCase, with some Spaces" => "MIXED_UP_CAMEL_CASE_WITH_SOME_SPACES"); + t!(test4: "mixed_up_snake_case with some _spaces" => "MIXED_UP_SNAKE_CASE_WITH_SOME_SPACES"); + t!(test5: "kebab-case" => "KEBAB_CASE"); + t!(test6: "SHOUTY_SNAKE_CASE" => "SHOUTY_SNAKE_CASE"); + t!(test7: "snake_case" => "SNAKE_CASE"); + t!(test8: "this-contains_ ALLKinds OfWord_Boundaries" => "THIS_CONTAINS_ALL_KINDS_OF_WORD_BOUNDARIES"); + t!(test9: "XΣXΣ baffle" => "XΣXΣ_BAFFLE"); + t!(test10: "XMLHttpRequest" => "XML_HTTP_REQUEST"); +} diff --git a/vendor/heck/src/snake.rs b/vendor/heck/src/snake.rs new file mode 100644 index 0000000..c3c8576 --- /dev/null +++ b/vendor/heck/src/snake.rs @@ -0,0 +1,100 @@ +use alloc::{ + borrow::ToOwned, + fmt, + string::{String, ToString}, +}; + +use crate::{lowercase, transform}; + +/// This trait defines a snake case conversion. +/// +/// In snake_case, word boundaries are indicated by underscores. +/// +/// ## Example: +/// +/// ```rust +/// use heck::ToSnakeCase; +/// +/// let sentence = "We carry a new world here, in our hearts."; +/// assert_eq!(sentence.to_snake_case(), "we_carry_a_new_world_here_in_our_hearts"); +/// ``` +pub trait ToSnakeCase: ToOwned { + /// Convert this type to snake case. + fn to_snake_case(&self) -> Self::Owned; +} + +/// Oh heck, `SnekCase` is an alias for [`ToSnakeCase`]. See ToSnakeCase for +/// more documentation. +pub trait ToSnekCase: ToOwned { + /// Convert this type to snek case. + fn to_snek_case(&self) -> Self::Owned; +} + +impl ToSnekCase for T { + fn to_snek_case(&self) -> Self::Owned { + self.to_snake_case() + } +} + +impl ToSnakeCase for str { + fn to_snake_case(&self) -> String { + AsSnakeCase(self).to_string() + } +} + +/// This wrapper performs a snake case conversion in [`fmt::Display`]. +/// +/// ## Example: +/// +/// ``` +/// use heck::AsSnakeCase; +/// +/// let sentence = "We carry a new world here, in our hearts."; +/// assert_eq!(format!("{}", AsSnakeCase(sentence)), "we_carry_a_new_world_here_in_our_hearts"); +/// ``` +pub struct AsSnakeCase>(pub T); + +impl> fmt::Display for AsSnakeCase { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + transform(self.0.as_ref(), lowercase, |f| write!(f, "_"), f) + } +} + +#[cfg(test)] +mod tests { + use super::ToSnakeCase; + + macro_rules! t { + ($t:ident : $s1:expr => $s2:expr) => { + #[test] + fn $t() { + assert_eq!($s1.to_snake_case(), $s2) + } + }; + } + + t!(test1: "CamelCase" => "camel_case"); + t!(test2: "This is Human case." => "this_is_human_case"); + t!(test3: "MixedUP CamelCase, with some Spaces" => "mixed_up_camel_case_with_some_spaces"); + t!(test4: "mixed_up_ snake_case with some _spaces" => "mixed_up_snake_case_with_some_spaces"); + t!(test5: "kebab-case" => "kebab_case"); + t!(test6: "SHOUTY_SNAKE_CASE" => "shouty_snake_case"); + t!(test7: "snake_case" => "snake_case"); + t!(test8: "this-contains_ ALLKinds OfWord_Boundaries" => "this_contains_all_kinds_of_word_boundaries"); + t!(test9: "XΣXΣ baffle" => "xσxς_baffle"); + t!(test10: "XMLHttpRequest" => "xml_http_request"); + t!(test11: "FIELD_NAME11" => "field_name11"); + t!(test12: "99BOTTLES" => "99bottles"); + t!(test13: "FieldNamE11" => "field_nam_e11"); + t!(test14: "abc123def456" => "abc123def456"); + t!(test16: "abc123DEF456" => "abc123_def456"); + t!(test17: "abc123Def456" => "abc123_def456"); + t!(test18: "abc123DEf456" => "abc123_d_ef456"); + t!(test19: "ABC123def456" => "abc123def456"); + t!(test20: "ABC123DEF456" => "abc123def456"); + t!(test21: "ABC123Def456" => "abc123_def456"); + t!(test22: "ABC123DEf456" => "abc123d_ef456"); + t!(test23: "ABC123dEEf456FOO" => "abc123d_e_ef456_foo"); + t!(test24: "abcDEF" => "abc_def"); + t!(test25: "ABcDE" => "a_bc_de"); +} diff --git a/vendor/heck/src/title.rs b/vendor/heck/src/title.rs new file mode 100644 index 0000000..2453430 --- /dev/null +++ b/vendor/heck/src/title.rs @@ -0,0 +1,75 @@ +use core::fmt; + +use alloc::{ + borrow::ToOwned, + string::{String, ToString}, +}; + +use crate::{capitalize, transform}; + +/// This trait defines a title case conversion. +/// +/// In Title Case, word boundaries are indicated by spaces, and every word is +/// capitalized. +/// +/// ## Example: +/// +/// ```rust +/// use heck::ToTitleCase; +/// +/// let sentence = "We have always lived in slums and holes in the wall."; +/// assert_eq!(sentence.to_title_case(), "We Have Always Lived In Slums And Holes In The Wall"); +/// ``` +pub trait ToTitleCase: ToOwned { + /// Convert this type to title case. + fn to_title_case(&self) -> Self::Owned; +} + +impl ToTitleCase for str { + fn to_title_case(&self) -> String { + AsTitleCase(self).to_string() + } +} + +/// This wrapper performs a title case conversion in [`fmt::Display`]. +/// +/// ## Example: +/// +/// ``` +/// use heck::AsTitleCase; +/// +/// let sentence = "We have always lived in slums and holes in the wall."; +/// assert_eq!(format!("{}", AsTitleCase(sentence)), "We Have Always Lived In Slums And Holes In The Wall"); +/// ``` +pub struct AsTitleCase>(pub T); + +impl> fmt::Display for AsTitleCase { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + transform(self.0.as_ref(), capitalize, |f| write!(f, " "), f) + } +} + +#[cfg(test)] +mod tests { + use super::ToTitleCase; + + macro_rules! t { + ($t:ident : $s1:expr => $s2:expr) => { + #[test] + fn $t() { + assert_eq!($s1.to_title_case(), $s2) + } + }; + } + + t!(test1: "CamelCase" => "Camel Case"); + t!(test2: "This is Human case." => "This Is Human Case"); + t!(test3: "MixedUP CamelCase, with some Spaces" => "Mixed Up Camel Case With Some Spaces"); + t!(test4: "mixed_up_ snake_case, with some _spaces" => "Mixed Up Snake Case With Some Spaces"); + t!(test5: "kebab-case" => "Kebab Case"); + t!(test6: "SHOUTY_SNAKE_CASE" => "Shouty Snake Case"); + t!(test7: "snake_case" => "Snake Case"); + t!(test8: "this-contains_ ALLKinds OfWord_Boundaries" => "This Contains All Kinds Of Word Boundaries"); + t!(test9: "XΣXΣ baffle" => "Xσxς Baffle"); + t!(test10: "XMLHttpRequest" => "Xml Http Request"); +} diff --git a/vendor/heck/src/train.rs b/vendor/heck/src/train.rs new file mode 100644 index 0000000..4fcc195 --- /dev/null +++ b/vendor/heck/src/train.rs @@ -0,0 +1,87 @@ +use core::fmt; + +use alloc::{borrow::ToOwned, string::ToString}; + +use crate::{capitalize, transform}; + +/// This trait defines a train case conversion. +/// +/// In Train-Case, word boundaries are indicated by hyphens and words start +/// with Capital Letters. +/// +/// ## Example: +/// +/// ```rust +/// use heck::ToTrainCase; +/// +/// let sentence = "We are going to inherit the earth."; +/// assert_eq!(sentence.to_train_case(), "We-Are-Going-To-Inherit-The-Earth"); +/// ``` +pub trait ToTrainCase: ToOwned { + /// Convert this type to Train-Case. + fn to_train_case(&self) -> Self::Owned; +} + +impl ToTrainCase for str { + fn to_train_case(&self) -> Self::Owned { + AsTrainCase(self).to_string() + } +} + +/// This wrapper performs a train case conversion in [`fmt::Display`]. +/// +/// ## Example: +/// +/// ``` +/// use heck::AsTrainCase; +/// +/// let sentence = "We are going to inherit the earth."; +/// assert_eq!(format!("{}", AsTrainCase(sentence)), "We-Are-Going-To-Inherit-The-Earth"); +/// ``` +pub struct AsTrainCase>(pub T); + +impl> fmt::Display for AsTrainCase { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + transform(self.0.as_ref(), capitalize, |f| write!(f, "-"), f) + } +} + +#[cfg(test)] +mod tests { + use super::ToTrainCase; + + macro_rules! t { + ($t:ident : $s1:expr => $s2:expr) => { + #[test] + fn $t() { + assert_eq!($s1.to_train_case(), $s2) + } + }; + } + + t!(test1: "CamelCase" => "Camel-Case"); + t!(test2: "This is Human case." => "This-Is-Human-Case"); + t!(test3: "MixedUP CamelCase, with some Spaces" => "Mixed-Up-Camel-Case-With-Some-Spaces"); + t!(test4: "mixed_up_ snake_case with some _spaces" => "Mixed-Up-Snake-Case-With-Some-Spaces"); + t!(test5: "kebab-case" => "Kebab-Case"); + t!(test6: "SHOUTY_SNAKE_CASE" => "Shouty-Snake-Case"); + t!(test7: "snake_case" => "Snake-Case"); + t!(test8: "this-contains_ ALLKinds OfWord_Boundaries" => "This-Contains-All-Kinds-Of-Word-Boundaries"); + #[cfg(feature = "unicode")] + t!(test9: "XΣXΣ baffle" => "Xσxς-Baffle"); + t!(test10: "XMLHttpRequest" => "Xml-Http-Request"); + t!(test11: "FIELD_NAME11" => "Field-Name11"); + t!(test12: "99BOTTLES" => "99bottles"); + t!(test13: "FieldNamE11" => "Field-Nam-E11"); + t!(test14: "abc123def456" => "Abc123def456"); + t!(test16: "abc123DEF456" => "Abc123-Def456"); + t!(test17: "abc123Def456" => "Abc123-Def456"); + t!(test18: "abc123DEf456" => "Abc123-D-Ef456"); + t!(test19: "ABC123def456" => "Abc123def456"); + t!(test20: "ABC123DEF456" => "Abc123def456"); + t!(test21: "ABC123Def456" => "Abc123-Def456"); + t!(test22: "ABC123DEf456" => "Abc123d-Ef456"); + t!(test23: "ABC123dEEf456FOO" => "Abc123d-E-Ef456-Foo"); + t!(test24: "abcDEF" => "Abc-Def"); + t!(test25: "ABcDE" => "A-Bc-De"); +} diff --git a/vendor/heck/src/upper_camel.rs b/vendor/heck/src/upper_camel.rs new file mode 100644 index 0000000..c6f29df --- /dev/null +++ b/vendor/heck/src/upper_camel.rs @@ -0,0 +1,88 @@ +use core::fmt; + +use alloc::{ + borrow::ToOwned, + string::{String, ToString}, +}; + +use crate::{capitalize, transform}; + +/// This trait defines an upper camel case conversion. +/// +/// In UpperCamelCase, word boundaries are indicated by capital letters, +/// including the first word. +/// +/// ## Example: +/// +/// ```rust +/// use heck::ToUpperCamelCase; +/// +/// let sentence = "We are not in the least afraid of ruins."; +/// assert_eq!(sentence.to_upper_camel_case(), "WeAreNotInTheLeastAfraidOfRuins"); +/// ``` +pub trait ToUpperCamelCase: ToOwned { + /// Convert this type to upper camel case. + fn to_upper_camel_case(&self) -> Self::Owned; +} + +impl ToUpperCamelCase for str { + fn to_upper_camel_case(&self) -> String { + AsUpperCamelCase(self).to_string() + } +} + +/// `ToPascalCase` is an alias for [`ToUpperCamelCase`]. See ToUpperCamelCase for more +/// documentation. +pub trait ToPascalCase: ToOwned { + /// Convert this type to upper camel case. + fn to_pascal_case(&self) -> Self::Owned; +} + +impl ToPascalCase for T { + fn to_pascal_case(&self) -> Self::Owned { + self.to_upper_camel_case() + } +} + +/// This wrapper performs a upper camel case conversion in [`fmt::Display`]. +/// +/// ## Example: +/// +/// ``` +/// use heck::AsUpperCamelCase; +/// +/// let sentence = "We are not in the least afraid of ruins."; +/// assert_eq!(format!("{}", AsUpperCamelCase(sentence)), "WeAreNotInTheLeastAfraidOfRuins"); +/// ``` +pub struct AsUpperCamelCase>(pub T); + +impl> fmt::Display for AsUpperCamelCase { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + transform(self.0.as_ref(), capitalize, |_| Ok(()), f) + } +} + +#[cfg(test)] +mod tests { + use super::ToUpperCamelCase; + + macro_rules! t { + ($t:ident : $s1:expr => $s2:expr) => { + #[test] + fn $t() { + assert_eq!($s1.to_upper_camel_case(), $s2) + } + }; + } + + t!(test1: "CamelCase" => "CamelCase"); + t!(test2: "This is Human case." => "ThisIsHumanCase"); + t!(test3: "MixedUP_CamelCase, with some Spaces" => "MixedUpCamelCaseWithSomeSpaces"); + t!(test4: "mixed_up_ snake_case, with some _spaces" => "MixedUpSnakeCaseWithSomeSpaces"); + t!(test5: "kebab-case" => "KebabCase"); + t!(test6: "SHOUTY_SNAKE_CASE" => "ShoutySnakeCase"); + t!(test7: "snake_case" => "SnakeCase"); + t!(test8: "this-contains_ ALLKinds OfWord_Boundaries" => "ThisContainsAllKindsOfWordBoundaries"); + t!(test9: "XΣXΣ baffle" => "XσxςBaffle"); + t!(test10: "XMLHttpRequest" => "XmlHttpRequest"); +} diff --git a/vendor/itoa/.cargo-checksum.json b/vendor/itoa/.cargo-checksum.json new file mode 100644 index 0000000..1c33e56 --- /dev/null +++ b/vendor/itoa/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo_vcs_info.json":"e0165305f3b22a9ab4217a121f85379aa56c2675caa7afedc0a7468fc187600b",".github/FUNDING.yml":"b017158736b3c9751a2d21edfce7fe61c8954e2fced8da8dd3013c2f3e295bd9",".github/workflows/ci.yml":"89c4f60223daf03217ea7c1e8879135b11d2554bd1e57dd9eff5c02f1adc7909","Cargo.lock":"1cd64090b8e883963bb08d91e6968cc1e83ffdba4f4b2f47651ce9d351a8a947","Cargo.toml":"894c215e4e7e973b556b0e9627bf9b6a719a043fac9b5af9838660816392a09f","Cargo.toml.orig":"44ca1ae5d9b48743305b57f3367051289512037e7836b8b3693b68d48dec0483","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"1305bd79675db0194915d9bc91bd0b3cf9487bc1126e05bf46b48ab43edce44b","benches/bench.rs":"29a0bdb973848007d681e571c57487e21e1bfb7aed5980c2190dba354498b154","src/lib.rs":"e962338e1886873aa7c3399ec89aa5378ccbfed712b9690f043628079390a34f","src/u128_ext.rs":"498cc94f13805e551248fd82f47cc318f51d953a5002a9f8698858cd12fbae3c","tests/test.rs":"b22f8a8ed89edcbb4140b74f5edd7f2adf3cb0e363990dd6010cd6ebe0dc36b7"},"package":"8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"} \ No newline at end of file diff --git a/vendor/itoa/.cargo_vcs_info.json b/vendor/itoa/.cargo_vcs_info.json new file mode 100644 index 0000000..c084258 --- /dev/null +++ b/vendor/itoa/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "af77385d0daf4d0e949e81f2588be2e44f69f086" + }, + "path_in_vcs": "" +} \ No newline at end of file diff --git a/vendor/itoa/.github/FUNDING.yml b/vendor/itoa/.github/FUNDING.yml new file mode 100644 index 0000000..7507077 --- /dev/null +++ b/vendor/itoa/.github/FUNDING.yml @@ -0,0 +1 @@ +github: dtolnay diff --git a/vendor/itoa/.github/workflows/ci.yml b/vendor/itoa/.github/workflows/ci.yml new file mode 100644 index 0000000..6b7c03d --- /dev/null +++ b/vendor/itoa/.github/workflows/ci.yml @@ -0,0 +1,126 @@ +name: CI + +on: + push: + pull_request: + workflow_dispatch: + schedule: [cron: "40 1 * * *"] + +permissions: + contents: read + +env: + RUSTFLAGS: -Dwarnings + +jobs: + pre_ci: + uses: dtolnay/.github/.github/workflows/pre_ci.yml@master + + test: + name: Rust ${{matrix.rust}} + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rust: [nightly, beta, stable, 1.86.0] + timeout-minutes: 45 + steps: + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{matrix.rust}} + - name: Enable type layout randomization + run: echo RUSTFLAGS=${RUSTFLAGS}\ -Zrandomize-layout >> $GITHUB_ENV + if: matrix.rust == 'nightly' + - run: cargo build + - run: cargo test + - run: cargo test --release + - run: cargo build --no-default-features + - run: cargo test --tests --no-default-features + - run: cargo test --tests --no-default-features --release + - run: cargo build --tests --features no-panic --release + if: matrix.rust == 'nightly' + - run: cargo bench --no-run + if: matrix.rust == 'nightly' + - uses: actions/upload-artifact@v6 + if: matrix.rust == 'nightly' && always() + with: + name: Cargo.lock + path: Cargo.lock + continue-on-error: true + + msrv: + name: Rust 1.68.0 + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@1.68 + - run: cargo build + - run: cargo build --no-default-features + + doc: + name: Documentation + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + env: + RUSTDOCFLAGS: -Dwarnings + steps: + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@nightly + - uses: dtolnay/install@cargo-docs-rs + - run: cargo docs-rs + + miri: + name: Miri + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@miri + - run: cargo miri setup + - run: cargo miri test + env: + MIRIFLAGS: -Zmiri-strict-provenance + + clippy: + name: Clippy + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + timeout-minutes: 45 + steps: + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@clippy + - run: cargo clippy --tests --benches -- -Dclippy::all -Dclippy::pedantic + + fuzz: + name: Fuzz + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@nightly + - uses: dtolnay/install@cargo-fuzz + - run: cargo fuzz check + + outdated: + name: Outdated + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + timeout-minutes: 45 + steps: + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/install@cargo-outdated + - run: cargo outdated --workspace --exit-code 1 + - run: cargo outdated --manifest-path fuzz/Cargo.toml --exit-code 1 diff --git a/vendor/itoa/Cargo.lock b/vendor/itoa/Cargo.lock new file mode 100644 index 0000000..8954517 --- /dev/null +++ b/vendor/itoa/Cargo.lock @@ -0,0 +1,460 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloca" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4" +dependencies = [ + "cc", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cc" +version = "1.2.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "clap" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +dependencies = [ + "anstyle", + "clap_lex", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "criterion" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "950046b2aa2492f9a536f5f4f9a3de7b9e2476e575e05bd6c333371add4d98f3" +dependencies = [ + "alloca", + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "itertools", + "num-traits", + "oorandom", + "page_size", + "regex", + "serde", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8d80a2f4f5b554395e47b5d8305bc3d27813bacb73493eb1001e8f76dae29ea" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "itoa" +version = "1.0.18" +dependencies = [ + "criterion", + "no-panic", +] + +[[package]] +name = "libc" +version = "0.2.183" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "no-panic" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f967505aabc8af5752d098c34146544a43684817cdba8f9725b292530cabbf53" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa 1.0.17", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "zerocopy" +version = "0.8.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/vendor/itoa/Cargo.toml b/vendor/itoa/Cargo.toml new file mode 100644 index 0000000..d60aa96 --- /dev/null +++ b/vendor/itoa/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 = "2021" +rust-version = "1.68" +name = "itoa" +version = "1.0.18" +authors = ["David Tolnay "] +build = false +exclude = ["*.png"] +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +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] +targets = ["x86_64-unknown-linux-gnu"] +rustdoc-args = [ + "--generate-link-to-definition", + "--generate-macro-expansion", + "--extern-html-root-url=core=https://doc.rust-lang.org", + "--extern-html-root-url=alloc=https://doc.rust-lang.org", + "--extern-html-root-url=std=https://doc.rust-lang.org", +] + +[lib] +name = "itoa" +path = "src/lib.rs" + +[[test]] +name = "test" +path = "tests/test.rs" + +[[bench]] +name = "bench" +path = "benches/bench.rs" +harness = false + +[dependencies.no-panic] +version = "0.1" +optional = true + +[target."cfg(not(miri))".dev-dependencies.criterion] +version = "0.8" +default-features = false diff --git a/vendor/itoa/Cargo.toml.orig b/vendor/itoa/Cargo.toml.orig new file mode 100644 index 0000000..d8bd99a --- /dev/null +++ b/vendor/itoa/Cargo.toml.orig @@ -0,0 +1,33 @@ +[package] +name = "itoa" +version = "1.0.18" +authors = ["David Tolnay "] +categories = ["value-formatting", "no-std", "no-std::no-alloc"] +description = "Fast integer primitive to string conversion" +documentation = "https://docs.rs/itoa" +edition = "2021" +exclude = ["*.png"] +keywords = ["integer"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/itoa" +rust-version = "1.68" + +[dependencies] +no-panic = { version = "0.1", optional = true } + +[target.'cfg(not(miri))'.dev-dependencies] +criterion = { version = "0.8", default-features = false } + +[[bench]] +name = "bench" +harness = false + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] +rustdoc-args = [ + "--generate-link-to-definition", + "--generate-macro-expansion", + "--extern-html-root-url=core=https://doc.rust-lang.org", + "--extern-html-root-url=alloc=https://doc.rust-lang.org", + "--extern-html-root-url=std=https://doc.rust-lang.org", +] 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..c539202 --- /dev/null +++ b/vendor/itoa/README.md @@ -0,0 +1,65 @@ +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 [`zmij`] for printing floating point primitives. + +[libcore]: https://github.com/rust-lang/rust/blob/1.92.0/library/core/src/fmt/num.rs#L190-L253 +[`core::fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html +[`zmij`]: https://github.com/dtolnay/zmij + +```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 + +The [itoa-benchmark] compares this library and other Rust integer formatting +implementations across a range of integer sizes. The vertical axis in this chart +shows nanoseconds taken by a single execution of +`itoa::Buffer::new().format(value)` so a lower result indicates a faster +library. + +[itoa-benchmark]: https://github.com/dtolnay/itoa-benchmark + +![performance](https://raw.githubusercontent.com/dtolnay/itoa/master/itoa-benchmark.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..bfd3192 --- /dev/null +++ b/vendor/itoa/benches/bench.rs @@ -0,0 +1,41 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use std::fmt::Display; +use std::hint; +use std::io::Write; + +fn do_bench(c: &mut Criterion, group_name: &str, int: impl itoa::Integer + Display) { + let mut group = c.benchmark_group(group_name); + group.bench_function("itoa", |b| { + let mut buf = itoa::Buffer::new(); + b.iter(move || { + let int = hint::black_box(int); + let formatted = buf.format(int); + hint::black_box(formatted); + }); + }); + group.bench_function("std::fmt", |b| { + let mut buf = Vec::with_capacity(20); + b.iter(|| { + buf.clear(); + let int = hint::black_box(int); + write!(&mut buf, "{int}").unwrap(); + hint::black_box(buf.as_slice()); + }); + }); + group.finish(); +} + +fn bench(c: &mut Criterion) { + do_bench(c, "u64[0]", 0u64); + do_bench(c, "u64[half]", u64::from(u32::MAX)); + do_bench(c, "u64[max]", u64::MAX); + + do_bench(c, "i16[0]", 0i16); + do_bench(c, "i16[min]", i16::MIN); + + do_bench(c, "u128[0]", 0u128); + do_bench(c, "u128[max]", u128::MAX); +} + +criterion_group!(benches, bench); +criterion_main!(benches); diff --git a/vendor/itoa/src/lib.rs b/vendor/itoa/src/lib.rs new file mode 100644 index 0000000..74cd9b4 --- /dev/null +++ b/vendor/itoa/src/lib.rs @@ -0,0 +1,466 @@ +//! [![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 [`zmij`] for printing floating point primitives. +//! +//! [libcore]: https://github.com/rust-lang/rust/blob/1.92.0/library/core/src/fmt/num.rs#L190-L253 +//! [`zmij`]: https://github.com/dtolnay/zmij +//! +//! # Example +//! +//! ``` +//! fn main() { +//! let mut buffer = itoa::Buffer::new(); +//! let printed = buffer.format(128u64); +//! assert_eq!(printed, "128"); +//! } +//! ``` +//! +//! # Performance +//! +//! The [itoa-benchmark] compares this library and other Rust integer formatting +//! implementations across a range of integer sizes. The vertical axis in this +//! chart shows nanoseconds taken by a single execution of +//! `itoa::Buffer::new().format(value)` so a lower result indicates a faster +//! library. +//! +//! [itoa-benchmark]: https://github.com/dtolnay/itoa-benchmark +//! +//! ![performance](https://raw.githubusercontent.com/dtolnay/itoa/master/itoa-benchmark.png) + +#![doc(html_root_url = "https://docs.rs/itoa/1.0.18")] +#![no_std] +#![allow( + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::cast_sign_loss, + clippy::expl_impl_clone_on_copy, + clippy::identity_op, + clippy::items_after_statements, + clippy::must_use_candidate, + clippy::needless_doctest_main, + clippy::unreadable_literal +)] + +mod u128_ext; + +use core::hint; +use core::mem::{self, MaybeUninit}; +use core::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_STR_LEN], +} + +impl Default for Buffer { + #[inline] + fn default() -> Buffer { + Buffer::new() + } +} + +impl Copy for Buffer {} + +#[allow(clippy::non_canonical_clone_impl)] +impl Clone for Buffer { + #[inline] + 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_STR_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 { + let buf_ptr = self.bytes.as_mut_ptr().cast::(); + let string = i.write(unsafe { &mut *buf_ptr }); + if string.len() > I::MAX_STR_LEN { + unsafe { hint::unreachable_unchecked() }; + } + string + } +} + +/// 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 { + /// The maximum length of string that formatting an integer of this type can + /// produce on the current target platform. + const MAX_STR_LEN: usize; +} + +// Seal to prevent downstream implementations of the Integer trait. +mod private { + #[doc(hidden)] + pub trait Sealed: Copy { + #[doc(hidden)] + type Buffer: 'static; + fn write(self, buf: &mut Self::Buffer) -> &str; + } +} + +macro_rules! impl_Integer { + ($Signed:ident, $Unsigned:ident) => { + const _: () = { + assert!($Signed::MIN < 0, "need signed"); + assert!($Unsigned::MIN == 0, "need unsigned"); + assert!($Signed::BITS == $Unsigned::BITS, "need counterparts"); + }; + + impl Integer for $Unsigned { + const MAX_STR_LEN: usize = $Unsigned::MAX.ilog10() as usize + 1; + } + + impl private::Sealed for $Unsigned { + type Buffer = [MaybeUninit; Self::MAX_STR_LEN]; + + #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] + fn write(self, buf: &mut Self::Buffer) -> &str { + let offset = Unsigned::fmt(self, buf); + // SAFETY: Starting from `offset`, all elements of the slice have been set. + unsafe { slice_buffer_to_str(buf, offset) } + } + } + + impl Integer for $Signed { + const MAX_STR_LEN: usize = $Signed::MAX.ilog10() as usize + 2; + } + + impl private::Sealed for $Signed { + type Buffer = [MaybeUninit; Self::MAX_STR_LEN]; + + #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] + fn write(self, buf: &mut Self::Buffer) -> &str { + let mut offset = Self::MAX_STR_LEN - $Unsigned::MAX_STR_LEN; + offset += Unsigned::fmt( + self.unsigned_abs(), + (&mut buf[offset..]).try_into().unwrap(), + ); + if self < 0 { + offset -= 1; + buf[offset].write(b'-'); + } + // SAFETY: Starting from `offset`, all elements of the slice have been set. + unsafe { slice_buffer_to_str(buf, offset) } + } + } + }; +} + +impl_Integer!(i8, u8); +impl_Integer!(i16, u16); +impl_Integer!(i32, u32); +impl_Integer!(i64, u64); +impl_Integer!(i128, u128); + +macro_rules! impl_Integer_size { + ($t:ty as $primitive:ident #[cfg(target_pointer_width = $width:literal)]) => { + #[cfg(target_pointer_width = $width)] + impl Integer for $t { + const MAX_STR_LEN: usize = <$primitive as Integer>::MAX_STR_LEN; + } + + #[cfg(target_pointer_width = $width)] + impl private::Sealed for $t { + type Buffer = <$primitive as private::Sealed>::Buffer; + + #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] + fn write(self, buf: &mut Self::Buffer) -> &str { + (self as $primitive).write(buf) + } + } + }; +} + +impl_Integer_size!(isize as i16 #[cfg(target_pointer_width = "16")]); +impl_Integer_size!(usize as u16 #[cfg(target_pointer_width = "16")]); +impl_Integer_size!(isize as i32 #[cfg(target_pointer_width = "32")]); +impl_Integer_size!(usize as u32 #[cfg(target_pointer_width = "32")]); +impl_Integer_size!(isize as i64 #[cfg(target_pointer_width = "64")]); +impl_Integer_size!(usize as u64 #[cfg(target_pointer_width = "64")]); + +#[repr(C, align(2))] +struct DecimalPairs([u8; 200]); + +// The string of all two-digit numbers in range 00..99 is used as a lookup table. +static DECIMAL_PAIRS: DecimalPairs = DecimalPairs( + *b"0001020304050607080910111213141516171819\ + 2021222324252627282930313233343536373839\ + 4041424344454647484950515253545556575859\ + 6061626364656667686970717273747576777879\ + 8081828384858687888990919293949596979899", +); + +// Returns {value / 100, value % 100} correct for values of up to 4 digits. +fn divmod100(value: u32) -> (u32, u32) { + debug_assert!(value < 10_000); + const EXP: u32 = 19; // 19 is faster or equal to 12 even for 3 digits. + const SIG: u32 = (1 << EXP) / 100 + 1; + let div = (value * SIG) >> EXP; // value / 100 + (div, value - div * 100) +} + +/// This function converts a slice of ascii characters into a `&str` starting +/// from `offset`. +/// +/// # Safety +/// +/// `buf` content starting from `offset` index MUST BE initialized and MUST BE +/// ascii characters. +#[cfg_attr(feature = "no-panic", no_panic)] +unsafe fn slice_buffer_to_str(buf: &[MaybeUninit], offset: usize) -> &str { + // SAFETY: `offset` is always included between 0 and `buf`'s length. + let written = unsafe { buf.get_unchecked(offset..) }; + // SAFETY: (`assume_init_ref`) All buf content since offset is set. + // SAFETY: (`from_utf8_unchecked`) Writes use ASCII from the lookup table exclusively. + unsafe { str::from_utf8_unchecked(&*(written as *const [MaybeUninit] as *const [u8])) } +} + +trait Unsigned: Integer { + fn fmt(self, buf: &mut Self::Buffer) -> usize; +} + +macro_rules! impl_Unsigned { + ($Unsigned:ident) => { + impl Unsigned for $Unsigned { + #[cfg_attr(feature = "no-panic", no_panic)] + fn fmt(self, buf: &mut Self::Buffer) -> usize { + // Count the number of bytes in buf that are not initialized. + let mut offset = buf.len(); + // Consume the least-significant decimals from a working copy. + let mut remain = self; + + // Format per four digits from the lookup table. + // Four digits need a 16-bit $Unsigned or wider. + while mem::size_of::() > 1 + && remain + > 999 + .try_into() + .expect("branch is not hit for types that cannot fit 999 (u8)") + { + offset -= 4; + + // pull two pairs + let scale: Self = 1_00_00 + .try_into() + .expect("branch is not hit for types that cannot fit 1E4 (u8)"); + let quad = remain % scale; + remain /= scale; + let (pair1, pair2) = divmod100(quad as u32); + unsafe { + buf[offset + 0] + .write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 0)); + buf[offset + 1] + .write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 1)); + buf[offset + 2] + .write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 0)); + buf[offset + 3] + .write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 1)); + } + } + + // Format per two digits from the lookup table. + if remain > 9 { + offset -= 2; + + let (last, pair) = divmod100(remain as u32); + remain = last as Self; + unsafe { + buf[offset + 0] + .write(*DECIMAL_PAIRS.0.get_unchecked(pair as usize * 2 + 0)); + buf[offset + 1] + .write(*DECIMAL_PAIRS.0.get_unchecked(pair as usize * 2 + 1)); + } + } + + // Format the last remaining digit, if any. + if remain != 0 || self == 0 { + offset -= 1; + + // Either the compiler sees that remain < 10, or it prevents + // a boundary check up next. + let last = remain as u8 & 15; + buf[offset].write(b'0' + last); + // not used: remain = 0; + } + + offset + } + } + }; +} + +impl_Unsigned!(u8); +impl_Unsigned!(u16); +impl_Unsigned!(u32); +impl_Unsigned!(u64); + +impl Unsigned for u128 { + #[cfg_attr(feature = "no-panic", no_panic)] + fn fmt(self, buf: &mut Self::Buffer) -> usize { + // Optimize common-case zero, which would also need special treatment due to + // its "leading" zero. + if self == 0 { + let offset = buf.len() - 1; + buf[offset].write(b'0'); + return offset; + } + // Take the 16 least-significant decimals. + let (quot_1e16, mod_1e16) = div_rem_1e16(self); + let (mut remain, mut offset) = if quot_1e16 == 0 { + (mod_1e16, u128::MAX_STR_LEN) + } else { + // Write digits at buf[23..39]. + enc_16lsd::<{ u128::MAX_STR_LEN - 16 }>(buf, mod_1e16); + + // Take another 16 decimals. + let (quot2, mod2) = div_rem_1e16(quot_1e16); + if quot2 == 0 { + (mod2, u128::MAX_STR_LEN - 16) + } else { + // Write digits at buf[7..23]. + enc_16lsd::<{ u128::MAX_STR_LEN - 32 }>(buf, mod2); + // Quot2 has at most 7 decimals remaining after two 1e16 divisions. + (quot2 as u64, u128::MAX_STR_LEN - 32) + } + }; + + // Format per four digits from the lookup table. + while remain > 999 { + offset -= 4; + + // pull two pairs + let quad = remain % 1_00_00; + remain /= 1_00_00; + let (pair1, pair2) = divmod100(quad as u32); + unsafe { + buf[offset + 0].write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 0)); + buf[offset + 1].write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 1)); + buf[offset + 2].write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 0)); + buf[offset + 3].write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 1)); + } + } + + // Format per two digits from the lookup table. + if remain > 9 { + offset -= 2; + + let (last, pair) = divmod100(remain as u32); + remain = last as u64; + unsafe { + buf[offset + 0].write(*DECIMAL_PAIRS.0.get_unchecked(pair as usize * 2 + 0)); + buf[offset + 1].write(*DECIMAL_PAIRS.0.get_unchecked(pair as usize * 2 + 1)); + } + } + + // Format the last remaining digit, if any. + if remain != 0 { + offset -= 1; + + // Either the compiler sees that remain < 10, or it prevents + // a boundary check up next. + let last = remain as u8 & 15; + buf[offset].write(b'0' + last); + // not used: remain = 0; + } + offset + } +} + +// Encodes the 16 least-significant decimals of n into `buf[OFFSET..OFFSET + 16]`. +#[cfg_attr(feature = "no-panic", no_panic)] +fn enc_16lsd(buf: &mut [MaybeUninit], n: u64) { + // Consume the least-significant decimals from a working copy. + let mut remain = n; + + // Format per four digits from the lookup table. + for quad_index in (1..4).rev() { + // pull two pairs + let quad = remain % 1_00_00; + remain /= 1_00_00; + let (pair1, pair2) = divmod100(quad as u32); + unsafe { + buf[quad_index * 4 + OFFSET + 0] + .write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 0)); + buf[quad_index * 4 + OFFSET + 1] + .write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 1)); + buf[quad_index * 4 + OFFSET + 2] + .write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 0)); + buf[quad_index * 4 + OFFSET + 3] + .write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 1)); + } + } + + // final two pairs + let (pair1, pair2) = divmod100(remain as u32); + unsafe { + buf[OFFSET + 0].write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 0)); + buf[OFFSET + 1].write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 1)); + buf[OFFSET + 2].write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 0)); + buf[OFFSET + 3].write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 1)); + } +} + +// Euclidean division plus remainder with constant 1E16 basically consumes 16 +// decimals from n. +// +// The 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 +// +#[cfg_attr(feature = "no-panic", no_panic)] +fn div_rem_1e16(n: u128) -> (u128, u64) { + const D: u128 = 1_0000_0000_0000_0000; + // The check inlines well with the caller flow. + if n < D { + return (0, n as u64); + } + + // These constant values are computed with the CHOOSE_MULTIPLIER procedure + // from the Granlund & Montgomery paper, using N=128, prec=128 and d=1E16. + const M_HIGH: u128 = 76624777043294442917917351357515459181; + const SH_POST: u8 = 51; + + // n.widening_mul(M_HIGH).1 >> SH_POST + let quot = u128_ext::mulhi(n, M_HIGH) >> SH_POST; + let rem = n - quot * D; + (quot, rem as u64) +} diff --git a/vendor/itoa/src/u128_ext.rs b/vendor/itoa/src/u128_ext.rs new file mode 100644 index 0000000..866a733 --- /dev/null +++ b/vendor/itoa/src/u128_ext.rs @@ -0,0 +1,22 @@ +#[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)] +pub(crate) fn 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 = (u128::from(x_lo) * u128::from(y_lo)) >> 64; + let m = u128::from(x_lo) * u128::from(y_hi) + carry; + let high1 = m >> 64; + + let m_lo = m as u64; + let high2 = (u128::from(x_hi) * u128::from(y_lo) + u128::from(m_lo)) >> 64; + + u128::from(x_hi) * u128::from(y_hi) + high1 + high2 +} diff --git a/vendor/itoa/tests/test.rs b/vendor/itoa/tests/test.rs new file mode 100644 index 0000000..c4f0617 --- /dev/null +++ b/vendor/itoa/tests/test.rs @@ -0,0 +1,45 @@ +#![allow(non_snake_case)] + +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(u64::from(u32::MAX), "4294967295") + test_u64_max(u64::MAX, "18446744073709551615") + test_i64_min(i64::MIN, "-9223372036854775808") + + test_i16_0(0i16, "0") + test_i16_min(i16::MIN, "-32768") + + test_u128_0(0u128, "0") + test_u128_max(u128::MAX, "340282366920938463463374607431768211455") + test_i128_min(i128::MIN, "-170141183460469231731687303715884105728") + test_i128_max(i128::MAX, "170141183460469231731687303715884105727") +} + +#[test] +fn test_max_str_len() { + use itoa::Integer as _; + + assert_eq!(i8::MAX_STR_LEN, 4); + assert_eq!(u8::MAX_STR_LEN, 3); + assert_eq!(i16::MAX_STR_LEN, 6); + assert_eq!(u16::MAX_STR_LEN, 5); + assert_eq!(i32::MAX_STR_LEN, 11); + assert_eq!(u32::MAX_STR_LEN, 10); + assert_eq!(i64::MAX_STR_LEN, 20); + assert_eq!(u64::MAX_STR_LEN, 20); + assert_eq!(i128::MAX_STR_LEN, 40); + assert_eq!(u128::MAX_STR_LEN, 39); +} diff --git a/vendor/j7s_diagnostics/.cargo-checksum.json b/vendor/j7s_diagnostics/.cargo-checksum.json new file mode 100644 index 0000000..d1fecd5 --- /dev/null +++ b/vendor/j7s_diagnostics/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"cddddd2f5a25156a1afca3460ddabea8e77283ef1870c12aa43a891b44b9f79d","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","src/diagnostic_graph.rs":"c480b370f97805a7ca2bfd9b69b3b26755ed3e9c6d645640faae7c1dfcd9ebb8","src/diagnostic_node.rs":"1d3114a7daf9df4a2516853e6e274824853d40ab453995fa0173770bf4abe6c9","src/diagnostic_status.rs":"2cb49000d8150f9fd60cca61f41cbd59e2036b83d62b22922d85241060720d14","src/error.rs":"e5b06e19b6200ff808f0b2023d408fe12ec59ed8ec9bcc66d397ea5da9974259","src/lib.rs":"b9342371f268ef8e0d3e336d4ba80b74286370ca07ffd7b290d28c3af7e0417b","src/name_parsing.rs":"c9f3c6d9f08eb229d6912e85159304d2ea3568f40d2f220c9eee7d5a86e8644b","src/tree_view.rs":"7a271d782291bbf4df0ac6a536ba4ca015a2a7201e0e7acbdd91d841694653a4"},"package":null} \ No newline at end of file diff --git a/vendor/j7s_diagnostics/Cargo.toml b/vendor/j7s_diagnostics/Cargo.toml new file mode 100644 index 0000000..e1f4569 --- /dev/null +++ b/vendor/j7s_diagnostics/Cargo.toml @@ -0,0 +1,50 @@ +# 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 = "2024" +name = "j7s_diagnostics" +version = "0.1.0" +build = false +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false + +[features] +std = ["serde_json/std"] + +[lib] +name = "j7s_diagnostics" +path = "src/lib.rs" + +[dependencies.limbo_graph] +git = "https://git.jpace121.net/public/limbo_graph.git" +branch = "main" + +[dependencies.serde] +version = "1.0" +features = [ + "derive", + "alloc", +] +default-features = false + +[dependencies.serde_json] +version = "1.0" +features = ["alloc"] +default-features = false + +[dependencies.thiserror] +version = "2.0.18" +default-features = false diff --git a/vendor/j7s_diagnostics/LICENSE b/vendor/j7s_diagnostics/LICENSE new file mode 100644 index 0000000..14e2f77 --- /dev/null +++ b/vendor/j7s_diagnostics/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/vendor/j7s_diagnostics/src/diagnostic_graph.rs b/vendor/j7s_diagnostics/src/diagnostic_graph.rs new file mode 100644 index 0000000..818d0de --- /dev/null +++ b/vendor/j7s_diagnostics/src/diagnostic_graph.rs @@ -0,0 +1,450 @@ +// +// Copyright 2026 James Pace +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +// +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. +// +use alloc::borrow::ToOwned; +use alloc::collections::BTreeMap; +use alloc::collections::VecDeque; +use alloc::string::String; +use alloc::string::ToString; +use alloc::vec::Vec; + +use crate::diagnostic_node::*; +use crate::diagnostic_status::*; +use crate::error::*; +use crate::name_parsing::*; + +/// A graph of diagnostic statuses, following the general idea of +/// ros aggregated diagnostics. +/// +/// Diagnostics are stored in a tree by their namme. +/// Their levels can be reconciled, and the individual +/// statuses queried. +#[derive(Clone)] +pub struct DiagnosticGraph { + graph: limbo_graph::Graph, +} + +impl DiagnosticGraph { + /// Generate a empty graph. + pub fn new() -> Self { + Self { + graph: limbo_graph::Graph::::new(DiagnosticNode::Root), + } + } + + /// Get the root key. + /// Needed to do searches in the graph outside of this crate. + pub fn root(&self) -> limbo_graph::Key { + self.graph.root_key() + } + + /// Get the value of a specific element of the graph. + /// Will error if the key is not in the graph, or if the key + /// is the root, which doesn't have a value. + pub fn value_of(&self, key: &limbo_graph::Key) -> Result { + let graph_value = self.graph.value_of(key)?; + let result = graph_value.value()?; + Ok(result.clone()) + } + + /// Find all the children of key as keys. + /// Will error if key is not in the graph. + pub fn children_of(&self, key: &limbo_graph::Key) -> Result> { + let result = self.graph.children_of(key)?; + Ok(result) + } + + /// Given a key, find the child of that key that has the provided name. + /// The provided name must be basic (have no slashes). + /// Will return None if there are no children with that name. + pub fn child_of_which_has_name( + &self, + parent: &limbo_graph::Key, + desired_child_name: &str, + ) -> Result> { + if !name_is_basic(&desired_child_name.to_owned()) { + return Err(Error::from_msg("desired child name must be basic.")); + } + let all_children = self.children_of(parent)?; + for child in all_children.iter() { + let child_name = self.value_of(&child)?.name(); + if child_name == desired_child_name { + return Ok(Some(child.clone())); + } + } + return Ok(None); + } + + /// Find the key of the item in the graph with the provided full name + /// (i.e. the name has slashes.) + pub fn key_from_full_name(&self, full_name: &String) -> Result> { + let name_as_vec = split_name(&full_name); + + let mut cur_base_key = self.graph.root_key(); + + for cur_name in name_as_vec.iter() { + let key_of_cur_name = self.child_of_which_has_name(&cur_base_key, &cur_name)?; + if key_of_cur_name.is_none() { + return Ok(None); + } + cur_base_key = key_of_cur_name.unwrap(); + } + return Ok(Some(cur_base_key)); + } + + /// Provide the full name for a given key. (i.e. the name will have slashes). + pub fn full_name_from_key(&self, key: &limbo_graph::Key) -> Result { + let path_to_key = self.graph.backtrack_from_key(key)?; + let mut full_name = String::new(); + + for curr_key in path_to_key.iter() { + if *curr_key == self.graph.root_key() { + continue; + } + let status = self.value_of(&curr_key)?; + full_name = full_name + "/" + &status.name(); + } + + Ok(full_name) + } + + /// Provide the value of a status from the full name. + pub fn value_from_name( + &self, + full_name: &String, + ) -> Result> { + let key = self.key_from_full_name(full_name)?; + if key.is_none() { + return Ok(None); + } + let key = key.unwrap(); + let value = self.value_of(&key)?; + + return Ok(Some((value, key))); + } + + /// Add a status to the graph. + /// The name of the status will be used to determine where in the + /// graph the status belongs. + pub fn add_status(&mut self, status: DiagnosticStatus) -> Result<()> { + // If I'm basic I just need to be added as a child of the root. + if status.name_is_basic() { + self.graph.add( + DiagnosticNode::DiagnosticStatus(status), + self.graph.root_key(), + )?; + return Ok(()); + } + // Find this status' child name and parent's names + let parent_names = status.get_parent_names(); + + let mut cur_key = self.graph.root_key(); + + 'parent_loop: for parent_name in parent_names.iter() { + let children = self.graph.children_of(&cur_key)?; + // There are no children of this parent, so we can add + // the parent and go to the next parent. + if children.len() == 0 { + let holder_for_parent = DiagnosticStatus::from_name(parent_name.clone()); + cur_key = self + .graph + .add(DiagnosticNode::DiagnosticStatus(holder_for_parent), cur_key)?; + continue 'parent_loop; + } + // This parent does have children, look at them and + // update loop if appropriate. + for child in children { + let child_node = self.graph.value_of(&child)?; + if child_node.is_root() { + // A child node can't be root. + return Err(Error::from_msg("A child node can't be root!")); + } + if child_node.value()?.name() == *parent_name { + // The child node matched the parent we were looking for. + // Continue to find the next parent, with this key as the + // current key. + cur_key = child; + continue 'parent_loop; + } + } + // Parent wasn't any of the children. Add it and look for next parent. + let holder_for_parent = DiagnosticStatus::from_name(parent_name.clone()); + cur_key = self + .graph + .add(DiagnosticNode::DiagnosticStatus(holder_for_parent), cur_key)?; + } + // We've updated all the parents, so we can add ourselves now. + + // Do we already exist as a child of parent? + let children_of_this_parent = self.graph.children_of(&cur_key)?; + let mut names_of_children_of_this_parent = children_of_this_parent.iter().map(|x| { + self.graph + .value_of(&x) + .expect("Given child not in graph.") + .value() + .expect("Given root node as child?") + .name() + }); + let child_in_children_of_this_parent = + names_of_children_of_this_parent.any(|x| x == status.get_child_name()); + if !child_in_children_of_this_parent { + // If we don't we can be added. + self.graph.add( + DiagnosticNode::DiagnosticStatus(status.copy_with_child_name()), + cur_key, + )?; + } + + Ok(()) + } + + /// Add all the statuses in the provided vector. + /// The name of the statuses will be used to determine where in the + /// graph the statuses belong. + pub fn add_status_vec(&mut self, statuses: &Vec) -> Result<()> { + for status in statuses { + self.add_status(status.clone())?; + } + Ok(()) + } + + /// Update the levels for parent nodes based on the level of their children. + pub fn reconcile_levels(&mut self) -> Result<()> { + let leaf_keys = self.graph.find_leaf_keys()?; + + 'leaf_key_loop: for leaf_key in leaf_keys.iter() { + let mut child_key = leaf_key.clone(); + + while child_key != self.graph.root_key() { + let parent_key_opt = self.graph.parent_of(&child_key)?; + if parent_key_opt == None || parent_key_opt == Some(self.graph.root_key()) { + continue 'leaf_key_loop; + } + let parent_key = parent_key_opt.unwrap(); + // Reconcile the parent values. + let parent_node = self.graph.value_of(&parent_key)?; + let parent_value = parent_node.value()?; + let child_node = self.graph.value_of(&child_key)?; + let child_value = child_node.value()?; + + // if child level is worse than parent key. + // reset parent level. + if child_value.level() > parent_value.level() { + let replacement_parent = DiagnosticNode::from_status( + parent_value.copy_with_new_level(child_value.level()), + ); + self.graph + .replace_value_of(&parent_key, replacement_parent)?; + } + + // Push up the graph. + child_key = parent_key; + } + } + + Ok(()) + } + + pub fn export_graph(&self) -> Result> { + let keys_in_order = self.graph.get_keys_by_depth()?; + + let mut statuses = Vec::::new(); + + for key in keys_in_order.iter() { + if *key == self.root() { + // The root key will always be the first one through this + // loop. + continue; + } + let status_at_key = self.value_of(&key)?; + statuses.push(status_at_key.copy_with_new_name(self.full_name_from_key(&key)?)); + } + + Ok(statuses) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use alloc::vec; + + fn make_a_status_with_name(name: &str) -> DiagnosticStatus { + let level = DiagnosticLevel::OK; + let message = "I'm ok"; + let hardware_id = ""; + let values = BTreeMap::::new(); + + DiagnosticStatus::new( + level, + name.to_owned(), + message.to_owned(), + hardware_id.to_owned(), + values, + ) + } + + fn make_a_status_with_name_and_level(name: &str, level: DiagnosticLevel) -> DiagnosticStatus { + let level = level; + let message = ""; + let hardware_id = ""; + let values = BTreeMap::::new(); + + DiagnosticStatus::new( + level, + name.to_owned(), + message.to_owned(), + hardware_id.to_owned(), + values, + ) + } + + #[test] + fn add_one_to_graph() -> Result<()> { + let mut graph = DiagnosticGraph::new(); + graph.add_status(make_a_status_with_name("/a/b/c"))?; + + let first_child_keys = graph.children_of(&graph.root())?; + assert!(first_child_keys.len() == 1); + let first_child_key = first_child_keys[0]; + let first_child_value = graph.value_of(&first_child_key)?; + assert!(first_child_value.name() == "a"); + + let second_child_keys = graph.children_of(&first_child_key)?; + assert!(second_child_keys.len() == 1); + let second_child_key = second_child_keys[0]; + let second_child_value = graph.value_of(&second_child_key)?; + assert!(second_child_value.name() == "b"); + + let third_child_keys = graph.children_of(&second_child_key)?; + assert!(third_child_keys.len() == 1); + let third_child_key = third_child_keys[0]; + let third_child_value = graph.value_of(&third_child_key)?; + assert!(third_child_value.name() == "c"); + assert!(third_child_value.level() == DiagnosticLevel::OK); + + Ok(()) + } + + #[test] + fn add_multiple_to_graph() -> Result<()> { + let statuses = vec![ + make_a_status_with_name("/a"), + make_a_status_with_name("/a/b"), + make_a_status_with_name("/a/b/c"), + make_a_status_with_name("/a/d/e"), + make_a_status_with_name("/a/d/f"), + make_a_status_with_name("/a/d"), + ]; + + let mut graph = DiagnosticGraph::new(); + graph.add_status_vec(&statuses)?; + + let root_children = graph.children_of(&graph.root())?; + assert!(root_children.len() == 1); + assert!(graph.value_of(&root_children[0])?.name() == "a"); + + let children_of_a = graph.children_of(&root_children[0])?; + let mut children_of_a_names = children_of_a + .iter() + .map(|x| graph.value_of(&x).expect("Value of failed.").name()); + assert!(children_of_a.len() == 2); + assert!(children_of_a_names.any(|x| x == "b")); + assert!(children_of_a_names.any(|x| x == "d")); + + let b_key = graph.child_of_which_has_name(&root_children[0], "b")?; + assert!(b_key.is_some()); + let b_children = graph.children_of(&b_key.unwrap())?; + assert!(b_children.len() == 1); + + let d_key = graph.child_of_which_has_name(&root_children[0], "d")?; + assert!(d_key.is_some()); + let d_children = graph.children_of(&d_key.unwrap())?; + assert!(d_children.len() == 2); + + Ok(()) + } + + #[test] + fn key_name_connections() -> Result<()> { + let statuses = vec![ + make_a_status_with_name("/a"), + make_a_status_with_name("/a/b"), + make_a_status_with_name("/a/d/e"), + make_a_status_with_name("/a/d"), + ]; + + let mut graph = DiagnosticGraph::new(); + graph.add_status_vec(&statuses)?; + + let key_for_a = graph.key_from_full_name(&"/a".to_owned())?; + assert!(key_for_a == Some(1)); + + let key_for_e = graph.key_from_full_name(&"/a/d/e".to_owned())?; + assert!(key_for_e == Some(4)); + + let not_in_graph = graph.key_from_full_name(&"/a/b/c".to_owned())?; + assert!(not_in_graph == None); + + let name_for_e = graph.full_name_from_key(&4)?; + assert!(name_for_e == "/a/d/e".to_owned()); + + Ok(()) + } + + #[test] + fn reconcile_graph() -> Result<()> { + let statuses = vec![ + make_a_status_with_name_and_level("/a", DiagnosticLevel::UNSET), + make_a_status_with_name_and_level("/a/b", DiagnosticLevel::UNSET), + make_a_status_with_name_and_level("/a/b/c", DiagnosticLevel::OK), + make_a_status_with_name_and_level("/a/d/e", DiagnosticLevel::WARN), + make_a_status_with_name_and_level("/a/d", DiagnosticLevel::WARN), + make_a_status_with_name_and_level("/a/d/f", DiagnosticLevel::OK), + ]; + let mut graph = DiagnosticGraph::new(); + graph.add_status_vec(&statuses)?; + + graph.reconcile_levels()?; + + let (a_status, _) = graph.value_from_name(&"/a".to_owned())?.unwrap(); + assert!(a_status.level() == DiagnosticLevel::WARN); + + let (d_status, _) = graph.value_from_name(&"/a/d".to_owned())?.unwrap(); + assert!(d_status.level() == DiagnosticLevel::WARN); + + Ok(()) + } + + #[test] + fn export_graph() -> Result<()> { + let statuses = vec![ + make_a_status_with_name_and_level("/a", DiagnosticLevel::UNSET), + make_a_status_with_name_and_level("/a/b/c", DiagnosticLevel::OK), + make_a_status_with_name_and_level("/a/b", DiagnosticLevel::UNSET), + make_a_status_with_name_and_level("/a/d", DiagnosticLevel::UNSET), + ]; + let mut graph = DiagnosticGraph::new(); + graph.add_status_vec(&statuses)?; + + let exported = graph.export_graph()?; + + assert!(exported.len() == 4); + // Searching doen the b tree first would also be + // technically correct, but this is the order the implementation + // is currently going with. + assert!(exported[0].name() == "/a"); + assert!(exported[1].name() == "/a/d"); + assert!(exported[2].name() == "/a/b"); + assert!(exported[3].name() == "/a/b/c"); + + Ok(()) + } +} diff --git a/vendor/j7s_diagnostics/src/diagnostic_node.rs b/vendor/j7s_diagnostics/src/diagnostic_node.rs new file mode 100644 index 0000000..e08ee52 --- /dev/null +++ b/vendor/j7s_diagnostics/src/diagnostic_node.rs @@ -0,0 +1,39 @@ +// +// Copyright 2026 James Pace +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +// +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. +// +use crate::DiagnosticStatus; +use crate::error::{Error, Result}; + +#[derive(Clone)] +pub enum DiagnosticNode { + Root, + DiagnosticStatus(DiagnosticStatus), +} +impl limbo_graph::NodeValue for DiagnosticNode {} + +impl DiagnosticNode { + pub fn from_status(status: DiagnosticStatus) -> Self { + Self::DiagnosticStatus(status) + } + + pub fn is_root(&self) -> bool { + match self { + Self::Root => true, + _ => false, + } + } + + pub fn value(&self) -> Result<&DiagnosticStatus> { + match self { + Self::DiagnosticStatus(value) => Ok(value), + _ => Err(Error::from_msg("Can't get value of root key.")), + } + } +} diff --git a/vendor/j7s_diagnostics/src/diagnostic_status.rs b/vendor/j7s_diagnostics/src/diagnostic_status.rs new file mode 100644 index 0000000..6e5c2e4 --- /dev/null +++ b/vendor/j7s_diagnostics/src/diagnostic_status.rs @@ -0,0 +1,212 @@ +// +// Copyright 2026 James Pace +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +// +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. +// +use alloc::borrow::ToOwned; +use alloc::collections::BTreeMap; +use alloc::string::String; +use alloc::vec::Vec; +use core::default::Default; + +use serde::{Deserialize, Serialize}; + +use crate::name_parsing::{get_child_name, get_parent_names, name_is_basic}; + +#[derive(Clone, PartialOrd, PartialEq, Default, Serialize, Deserialize)] +pub enum DiagnosticLevel { + #[default] + UNSET, + OK, + WARN, + ERROR, + STALE, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct DiagnosticStatus { + level: DiagnosticLevel, + name: String, + message: String, + hardware_id: String, + values: BTreeMap, +} + +impl DiagnosticStatus { + pub fn new( + level: DiagnosticLevel, + name: String, + message: String, + hardware_id: String, + values: BTreeMap, + ) -> Self { + let cleaned_name = Self::clean_name(&name); + + Self { + level: level, + name: cleaned_name, + message: message, + hardware_id: hardware_id, + values: values, + } + } + + pub fn from_name(name: String) -> Self { + let level = DiagnosticLevel::UNSET; + let message = ""; + let hardware_id = ""; + let values = BTreeMap::::new(); + + Self::new( + level, + name, + message.to_owned(), + hardware_id.to_owned(), + values, + ) + } + + pub fn level(&self) -> DiagnosticLevel { + self.level.clone() + } + + pub fn name(&self) -> String { + self.name.clone() + } + + pub fn message(&self) -> String { + self.message.clone() + } + + pub fn hardware_id(&self) -> String { + self.hardware_id.clone() + } + + pub fn values(&self) -> BTreeMap { + self.values.clone() + } + + pub fn keys(&self) -> Vec { + self.values.keys().cloned().collect() + } + + pub fn value(&self, key: &str) -> Option { + let value = self.values.get(key); + if value.is_none() { + return None; + } + return Some(value.unwrap().clone()); + } + + pub fn name_is_basic(&self) -> bool { + name_is_basic(&self.name) + } + + pub fn get_parent_names(&self) -> Vec { + get_parent_names(&self.name) + } + + pub fn get_child_name(&self) -> String { + get_child_name(&self.name) + } + + pub fn copy_with_child_name(&self) -> Self { + let mut to_return: Self = self.clone(); + to_return.name = self.get_child_name(); + return to_return; + } + + pub fn copy_with_new_level(&self, level: DiagnosticLevel) -> Self { + let mut to_return: Self = self.clone(); + to_return.level = level; + return to_return; + } + + pub fn copy_with_new_name(&self, name: String) -> Self { + let mut to_return = self.clone(); + to_return.name = name; + return to_return; + } + + fn clean_name(name: &str) -> String { + // Remove prefix "/" + let without_prefix = name.strip_prefix("/").unwrap_or(name); + // and suffix + let without_suffix = name.strip_suffix("/").unwrap_or(without_prefix); + + return without_suffix.to_owned(); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn basic_diagnostic_creation() { + let level = DiagnosticLevel::OK; + let name = "/a/b/c"; + let message = "I'm ok"; + let hardware_id = ""; + let values = BTreeMap::::new(); + + let diag_status = DiagnosticStatus::new( + level, + name.to_owned(), + message.to_owned(), + hardware_id.to_owned(), + values, + ); + assert!(diag_status.level() == DiagnosticLevel::OK); + } + + #[test] + fn diagnostic_name_parsing() { + let level = DiagnosticLevel::OK; + let name = "/a/b/c"; + let message = "I'm ok"; + let hardware_id = ""; + let values = BTreeMap::::new(); + + let diag_status = DiagnosticStatus::new( + level, + name.to_owned(), + message.to_owned(), + hardware_id.to_owned(), + values, + ); + + assert!(!diag_status.name_is_basic()); + + let parent_names = diag_status.get_parent_names(); + let child_name = diag_status.get_child_name(); + assert!(parent_names[0] == "a"); + assert!(parent_names[1] == "b"); + assert!(child_name == "c"); + } + + #[test] + fn diagnostic_name_cleaning() { + let level = DiagnosticLevel::OK; + let name = "/a"; + let message = "I'm ok"; + let hardware_id = ""; + let values = BTreeMap::::new(); + + let diag_status = DiagnosticStatus::new( + level, + name.to_owned(), + message.to_owned(), + hardware_id.to_owned(), + values, + ); + + assert!(diag_status.name_is_basic()); + assert!(diag_status.name() == "a"); + } +} diff --git a/vendor/j7s_diagnostics/src/error.rs b/vendor/j7s_diagnostics/src/error.rs new file mode 100644 index 0000000..05089bf --- /dev/null +++ b/vendor/j7s_diagnostics/src/error.rs @@ -0,0 +1,30 @@ +// +// Copyright 2026 James Pace +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +// +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. +// + +use alloc::string::{String, ToString}; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("GraphError: {0}")] + GraphError(#[from] limbo_graph::Error), + #[error("serde_json Error: {0}")] + JsonError(#[from] serde_json::Error), + #[error("Error from j7s_diagnostics: {0}")] + Msg(String), +} + +impl Error { + pub fn from_msg(msg: &str) -> Self { + Error::Msg(msg.to_string()) + } +} + +pub type Result = core::result::Result; diff --git a/vendor/j7s_diagnostics/src/lib.rs b/vendor/j7s_diagnostics/src/lib.rs new file mode 100644 index 0000000..acb9f76 --- /dev/null +++ b/vendor/j7s_diagnostics/src/lib.rs @@ -0,0 +1,30 @@ +// +// Copyright 2026 James Pace +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +// +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. +// + +#![allow(unused_imports)] +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; + +mod diagnostic_graph; +mod diagnostic_node; +mod diagnostic_status; +mod error; +mod name_parsing; + +pub use crate::diagnostic_graph::*; +pub use crate::diagnostic_status::*; +pub use crate::error::*; + +#[cfg(feature = "std")] +mod tree_view; +#[cfg(feature = "std")] +pub use crate::tree_view::*; diff --git a/vendor/j7s_diagnostics/src/name_parsing.rs b/vendor/j7s_diagnostics/src/name_parsing.rs new file mode 100644 index 0000000..ba7762f --- /dev/null +++ b/vendor/j7s_diagnostics/src/name_parsing.rs @@ -0,0 +1,82 @@ +// +// Copyright 2026 James Pace +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +// +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. +// +use alloc::borrow::ToOwned; +use alloc::string::String; +use alloc::vec::Vec; + +pub fn name_is_basic(name: &String) -> bool { + // A basic name is one that doesn't have slashes in it other than the + // first character. + let is_not_basic = name.strip_prefix("/").unwrap_or(name).contains("/"); + return !is_not_basic; +} + +pub fn get_parent_names(name: &String) -> Vec { + if name_is_basic(&name) { + return Vec::::new(); + } + + let split: Vec = name + .split("/") + .map(|x| x.to_owned()) + .filter(|x| !x.is_empty()) + .collect(); + + return split + .iter() + .take(split.len() - 1) + .map(|x| x.to_owned()) + .collect(); +} + +pub fn get_child_name(name: &String) -> String { + if name_is_basic(&name) { + return name.clone(); + } + let split: Vec = name.split("/").map(|x| x.to_owned()).collect(); + return split.last().unwrap().clone(); +} + +pub fn split_name(name: &String) -> Vec { + name.split("/") + .map(|x| x.to_owned()) + .filter(|x| !x.is_empty()) + .collect() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_is_basic() { + assert!(name_is_basic(&"a".to_owned())); + assert!(name_is_basic(&"/a".to_owned())); + assert!(!name_is_basic(&"/a/b".to_owned())); + } + + #[test] + fn test_get_names() { + let name = "/a/b/c"; + + let parent_names = get_parent_names(&name.to_owned()); + assert!(parent_names[0] == "a"); + assert!(parent_names[1] == "b"); + + let child_name = get_child_name(&name.to_owned()); + assert!(child_name == "c"); + + let split = split_name(&name.to_owned()); + assert!(split[0] == "a"); + assert!(split[1] == "b"); + assert!(split[2] == "c"); + } +} diff --git a/vendor/j7s_diagnostics/src/tree_view.rs b/vendor/j7s_diagnostics/src/tree_view.rs new file mode 100644 index 0000000..bd5b907 --- /dev/null +++ b/vendor/j7s_diagnostics/src/tree_view.rs @@ -0,0 +1,118 @@ +// +// Copyright 2026 James Pace +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +// +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. +// +use crate::diagnostic_graph::DiagnosticGraph; +use crate::diagnostic_status::DiagnosticStatus; +use crate::error::Result; +use alloc::string::String; +use alloc::vec::Vec; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Serialize, Deserialize)] +pub struct TreeView { + children: Vec, +} + +#[derive(Clone, Serialize, Deserialize)] +struct TreeViewNode { + id: String, + status: DiagnosticStatus, + children: Vec, +} + +impl TreeView { + fn get_nodes(key: &limbo_graph::Key, graph: &DiagnosticGraph) -> Result> { + let children = graph.children_of(&key)?; + if children.len() == 0 { + return Ok(Vec::::new()); + } + + let mut to_ret = Vec::::new(); + + for child in children { + let status = graph.value_of(&child)?; + let node = TreeViewNode { + id: graph.full_name_from_key(&child)?, + status: status, + children: Self::get_nodes(&child, &graph)?, + }; + + to_ret.push(node); + } + + // Make the order of same id'd (named) entries consistent. + to_ret.sort_by(|a, b| a.id.cmp(&b.id)); + + return Ok(to_ret); + } + + pub fn from_graph(graph: &DiagnosticGraph) -> Result { + let view = TreeView { + children: Self::get_nodes(&graph.root(), &graph)?, + }; + + Ok(view) + } + + pub fn to_json(&self) -> Result { + Ok(serde_json::to_string(self)?) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::*; + use alloc::collections::BTreeMap; + + fn make_a_status_with_name(name: &str) -> DiagnosticStatus { + let level = DiagnosticLevel::OK; + let message = "I'm ok"; + let hardware_id = ""; + let values = BTreeMap::::new(); + + DiagnosticStatus::new( + level, + name.to_owned(), + message.to_owned(), + hardware_id.to_owned(), + values, + ) + } + + #[test] + fn make_view() -> Result<()> { + let statuses = vec![ + make_a_status_with_name("/a"), + make_a_status_with_name("/a/b"), + make_a_status_with_name("/a/b/c"), + make_a_status_with_name("/a/d/e"), + make_a_status_with_name("/a/d"), + ]; + + let mut graph = DiagnosticGraph::new(); + graph.add_status_vec(&statuses)?; + + let view = TreeView::from_graph(&graph)?; + + // First level is just a + assert!(view.children.len() == 1); + // a has children b and d. + assert!(view.children[0].children.len() == 2); + // regardless is this is b or d, it has one child. + // TODO: This isn't the best test. + assert!(view.children[0].children[0].children.len() == 1); + + // Just to confirm it doesn't panic. + let _js = view.to_json()?; + + Ok(()) + } +} diff --git a/vendor/libc/.cargo-checksum.json b/vendor/libc/.cargo-checksum.json new file mode 100644 index 0000000..375982e --- /dev/null +++ b/vendor/libc/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo_vcs_info.json":"3ae25e402263c1d372a9c6a0b09d4f63d6744a1f8d7912108191c3b6276ceb4f",".editorconfig":"e57fecd6b82cd69640ca1bc4e44f0c7acfe5fc12f641f14af9536e323b4159db",".git-blame-ignore-revs":"761aa385c661241fa77c15b502c361398cf500bbb9f8c3a4579b412c4c6249d7",".release-plz.toml":"fcf2d382c4a2abd96caf9cc391b63e0c94d5832f5c48e9ab9eb4b2c847c0887c",".rustfmt.toml":"c88d9ba0e884291a2904d43cc7b940fafcb1ab443cdb7bcfca7117809c4f2816","CHANGELOG.md":"1629ffb688b6f2ea0c1720ba1f768904ef9f27da4e9e7f32b76d6d52cd1940d1","CONTRIBUTING.md":"ed7177a16e331da75244df3232c4e34f70bf58d2b31cffffd9b769a4745de567","Cargo.lock":"7b23220c994971e1ef93c3a13c78476fb35043e701a2e9c3f80567af3d94a9c3","Cargo.toml":"95159789ef9c9aaee8230b13be5c89594833a7bf2db299e61eb23b512cb67144","Cargo.toml.orig":"cba73b06128539455a57f7432e466ba583358ecb83ef8eda60731751b8a9f5cc","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"123a331b5dbf04c30097fa43b8f858bc85df671fe776de498d01f3d6b7c1f69e","README.md":"5af805465cb8cfa4186cb75df07f4aebd35a3d88f497ed71d189b74ecf8cbcdc","build.rs":"e47f4a6762799b6e69cefc7acdb3291df828010e4de20609f7378f9c94ea29e6","etc/libc-util.py":"a99fdefe6354c28c52eeac9c1e851041b69dad25b8a3b521d4f57b761517c798","src/fuchsia/aarch64.rs":"34105478e20e9ce40b9e484eea6494e2408fead17c13500da90a2d44d996ce63","src/fuchsia/mod.rs":"3b17821b3ceaf3430b6503965f5337b033817077e289e3cce29c80bf3960770f","src/fuchsia/riscv64.rs":"a91ae8276df139f6181591be7209f9a68e9f3de5eec881c2e1c9768c53c4e292","src/fuchsia/x86_64.rs":"543ea567b29d646afc026956ee5e652c10e87256789058e7e39f91bf2fe8bf14","src/hermit.rs":"ebfe4d68e8f0323dc97d7e3165f7b315e4058ee9f5ced3e76f181f0a492e75e1","src/lib.rs":"0701ce9606a01448c3229517fab308d49d160cccfca02ed6ebd8edfd8bb37d66","src/macros.rs":"6d534c7b511cd19217ba205a4a30e289f7243ba3706645d6ec5cb417b7bdac7c","src/new/aix/mod.rs":"df0de5d8e452a8abb27727b8451b2ceff3bb856f7e5d9e9306df5177e4c6326f","src/new/aix/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/apple/libc/signal.rs":"a960b6153775d791055b278534f79e21f8ff76c2c0c2891271e7abdf26e193d3","src/new/apple/libc/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/apple/libpthread/mod.rs":"1e99efe513b0ee1fa6e53daf5950fc027380b1d71d793eca9e5b22af7b331b5b","src/new/apple/libpthread/pthread_/introspection.rs":"3c797ded6d1a55670f9537a997407cf2267e6c7e7dbfa360d32474e2432979af","src/new/apple/libpthread/pthread_/pthread.rs":"c2b680120ec8db839e702c4340bc39748ac34c806b5fc08acea0a4593131a015","src/new/apple/libpthread/pthread_/pthread_impl.rs":"57a9925a75b79d092c65288b8a8eb21bfb6c7de4c70d37a49018b4eb8b32a646","src/new/apple/libpthread/pthread_/pthread_spis.rs":"1ba51c251249822fae222db6a19e17278ffffc424fc6eea30282a6171491edbe","src/new/apple/libpthread/pthread_/qos.rs":"40f816fb6cebd19ead21197671e5425b454144515ee4b966d00db32ba6b0dfe5","src/new/apple/libpthread/pthread_/sched.rs":"7b22a3204e72d5013ebac7b830235d50883aefca86d720f1f38b93d54e309477","src/new/apple/libpthread/pthread_/spawn.rs":"daef8af8ed0b3d16922c2f5a511a67f57f69b5f80dfe37362bd0b410213f95ca","src/new/apple/libpthread/pthread_/stack_np.rs":"d1b6e2eab1850c303f8eec4059b3e8ec57d69eb47c216243f6b4b7523761fc29","src/new/apple/libpthread/sys/_pthread/_pthread_types.rs":"a7a4307d7c3f91a6b03f76599fac5f40de556e5652123c6bc3b95df2bfa685de","src/new/apple/libpthread/sys/mod.rs":"337265fe49d77a7dcc879cd23e4f5baedcffab4808433dfb6ab9deb4ab490380","src/new/apple/libpthread/sys/qos.rs":"a6297cbab4089b330416bfcbe13b6d7aa8e75352299295046429b2e9d3bada42","src/new/apple/mod.rs":"96e4f2300247b8b587f312aeb8de991c65afd6a1693bbe0dc25610b9574d66db","src/new/apple/xnu/arm/_mcontext.rs":"63f1c62b47e7d7181c2b85f3cd3833c69a29eb0cad37a5754bfa6b5954ae7f6f","src/new/apple/xnu/i386/_mcontext.rs":"50543eaa5cf1d87f900b0c3e531dbfefd7586e1be2be3406223b2319edfcb7f2","src/new/apple/xnu/mach/arm/_structs.rs":"8e4af554170cef61c9143f92a283fd7eef66ad78824f194bbc89b098c6049a43","src/new/apple/xnu/mach/i386/_structs.rs":"d7316b7d3fa5e55a5818cfd8a1977921bb14e07133648cffa8f4d9da2e31a604","src/new/apple/xnu/mach/machine/_structs.rs":"82f5a7f751897c882ed4c378d6282976ff21cf0c9cdf7f3be3cecd369a63b6f8","src/new/apple/xnu/mach/mod.rs":"46aad5c7197df2cc57c4392d9019034236233f0240bc7975f9e22ac33c9d40ed","src/new/apple/xnu/machine/_mcontext.rs":"166b0a450b730e2a943ca08a0c70061effb77ff9eff6f41c7b0c51b2d4215db9","src/new/apple/xnu/mod.rs":"9359b08f58f8cd88ade250166850202daa6e3278d387c072ac51e8f0c0cced19","src/new/apple/xnu/net/bpf.rs":"0b6477e4ff541fbabe66ac2729524fc38c1e4be52a2f9e34c4155be732643318","src/new/apple/xnu/net/mod.rs":"7868b2b0065e01776ec4badaf166cac4ccb68ed98bf9bc284dbaffbf33e367b5","src/new/apple/xnu/netinet6/in6_var.rs":"61d6fc1ed1bbff8b0aa7de219b181aa68cc870ef290a6c39f5f3703eab955608","src/new/apple/xnu/netinet6/mod.rs":"dd1b80a3a57ffe7b48c60639a003d6e293646eb7a2cf209bf3673b043edbe611","src/new/apple/xnu/sys/_types/_ucontext.rs":"1651132d39042f0fc8cca7a23c890da0031b74359472189f851fb3458f2fde3e","src/new/apple/xnu/sys/ioccom.rs":"dab00d14e36566c21be6cc7063ce4542c5c7fe9d9d3d27b1069a4c523e5125cd","src/new/apple/xnu/sys/mod.rs":"9f1013ae8b269add421f0d4a52b0baba841e1909dee5076fd1e76639a024e379","src/new/apple/xnu/sys/signal.rs":"a03cb64ec19326657c87ff8a5a31c2e6bc1deb55f9a7343ab1b2420819ed72bf","src/new/apple/xnu/sys/sockio.rs":"1f298340a2d7b17b23aeacb87d1af829a142f6c8bb82d2237d7e0bee3b4c053e","src/new/apple/xnu/sys/ttycom.rs":"da3bc0f95f4e7ded2e399fe977a39751b248c8a807cd37b3c6fdf41d15478d18","src/new/bionic_libc/kernel_uapi/linux/mod.rs":"b33dff424c9841a9037e31dddb90d7bd74de451e8509d7abc7dda636ec2646e7","src/new/bionic_libc/kernel_uapi/linux/types.rs":"10860921059eb04c5f0f159becfc415021f501ae33dc374872861b9a339af25b","src/new/bionic_libc/kernel_uapi/mod.rs":"d7808294eeb095d0298e8a9837d597f80f7c2629aa5e3281547f7ae00392f17b","src/new/bionic_libc/mod.rs":"23fdadb2e6d9823b8d37436abf5ba01629006fd5310977d2035802e5ca9a0c1c","src/new/bionic_libc/pthread.rs":"d40b7f8421cf78d61f23224c3bda17407e40a1c85dd8122ca4f290624b21d8a1","src/new/bionic_libc/sys/mod.rs":"570e7c97f7c1efb14e167a3f0688547fbc907ed9dca93ad6d90dc719289cb6f1","src/new/bionic_libc/sys/socket.rs":"19877b1de0e235a01734f9aebf20fc1ff1a01fd17302ed1a7d7b520a9fa68edb","src/new/bionic_libc/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/common/bsd.rs":"8282cc2b87ca3afc6b01216fe3c3fe1818a3d57e95aa8d1e1a36cc5af1660609","src/new/common/freebsd_like.rs":"156dce9baa6b0ac57d483ffb582a913b9e4944cf10bbb5711a64da5f496a55c2","src/new/common/linux_like/mod.rs":"d42e65b3d6fccd5ba85a8397abb28267a96bfb76b6b47754000fbe9332c03fe4","src/new/common/linux_like/pthread.rs":"a1a33b1e27cd159ab1035c73e72fa8b0c266dd5a28f1079ad74d3c370857f097","src/new/common/mod.rs":"5bcbce2960ff0840ab67a1ba5011009fa1f0f7697cff745d1461bf2b1460ddc6","src/new/common/netbsd_like.rs":"4327dd28d929f2c7b316f9241c44da6f6069d3db4381fb82700ec6d70d749041","src/new/common/posix/mod.rs":"f64b9d7f78e924529c62f2cd78199075eb334e0db9479cb59787f2740bd82d51","src/new/common/posix/pthread.rs":"912f3d6bfc4b1e3ec90754d021ead243a5cdc96666b053bec5718edf5fbe6b92","src/new/common/posix/unistd.rs":"3f633a8c6776d1442f014717785fea3f068d1d3edbfad545d445f8076cb58447","src/new/common/solarish.rs":"ac208e1ad95d07b7528419fd9c573612d58af3d50766816b81667570ccb8b3b3","src/new/cygwin/mod.rs":"9de4cba157252e7731256d60192468f5a759ebd33ab2b509819ffc7557adced5","src/new/cygwin/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/dragonfly/mod.rs":"7b96df7e566874a736d0c33ffc9e75a5f80e674da990cb664556728769ff25f9","src/new/dragonfly/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/emscripten/mod.rs":"d0ec81b919d9d078bb7d66d9429c08b609e2b0fab512be30aa22cc00fa620660","src/new/emscripten/pthread.rs":"f14720341515da443cad49d61bf27a3d156b9fe7d7ccdf51651f1fdf4cb15c7f","src/new/emscripten/sched.rs":"6f0a5b3cefb42bb01feabf34ad92d4bdbe5743263d4cd7b754baf921da81a127","src/new/emscripten/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/espidf/mod.rs":"c89c7d3b96583d84888aae0c463dc49b5af61b34a97e9cde52fb9b62d301a023","src/new/freebsd/mod.rs":"d686733e28252ecb6e3100265c2f8c9d7b8ef1c0683504483f097882f195df12","src/new/freebsd/net/dlt.rs":"bf5e1dc8da836253b2a00e14e590d95611d73ac9136fe96af8ac42541905ff9d","src/new/freebsd/net/mod.rs":"68225681a4f1a024f91185088a430a4324dfed6a290ba26cca9c4dd93d0b32c9","src/new/freebsd/netinet6/in6_var.rs":"858763ada9b7d549d0ad95478f40c380e46c2f9ca8af1a35ec86f3ca0545ee74","src/new/freebsd/netinet6/mod.rs":"f6fcf32012b48840525df6e684c83cdbcafe69b8148f540bbc9dfe9f36ce0356","src/new/freebsd/sys/file.rs":"4dffceca36eaa53c3ace434e4fed1309009448c67ea6684a067a2cf362235e02","src/new/freebsd/sys/ioccom.rs":"7b842ee1a6688a6d38ededc8aa69dd991b9d2e31d796fd0b8f9ce982ec8d1867","src/new/freebsd/sys/mod.rs":"3f2a2b60db73753dc32a06cf50914767eb567338ce21d8b18ddf53473688f9c5","src/new/freebsd/sys/socket.rs":"fc0b459bc6f0ae2c5d359b0bcb28d0d5f68ac492e4b7ba06654932e9b72fbe03","src/new/freebsd/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/fuchsia/mod.rs":"c15b2da96c52281e86d4f114522999e6e713723f4950d62c2d544be641b28722","src/new/fuchsia/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/glibc/mod.rs":"fdec8f6272dbb2e084f6f4a87ebf30d479c0f66e7b0677796db8ae5b6c9df3e7","src/new/glibc/posix/unistd.rs":"b8528999ecab0a4883c0d89b1cb3c585a666255ab4a4bf5bfc705f7613edd8f4","src/new/glibc/sysdeps/mips/mod.rs":"4ee7bbd51acb0822e15b0b2e367aeb9c17b8514ec0e30c48f49664d6fda58030","src/new/glibc/sysdeps/mips/nptl/bits/mod.rs":"04b4ad0d30f3909c758eb5f20856289063d40af62a219e458dfe5b395ce46f7d","src/new/glibc/sysdeps/mips/nptl/bits/struct_mutex.rs":"dea882605b6d2bb7ece9f464350a5e08fe60b2269da1e743500862000fff0aa0","src/new/glibc/sysdeps/nptl/bits/struct_mutex.rs":"3eb21d2dca785c486c42cf27f1826d703b93dd68b162b60f27496b759244b55c","src/new/glibc/sysdeps/nptl/mod.rs":"80241727cf97fd683fd142516c8785ff65d5610af46c4d328f7b189968822055","src/new/glibc/sysdeps/nptl/pthread.rs":"2a70703f299597f77969f3c221a8588036f668415fe3c8d7b4cadbb0613b9b84","src/new/glibc/sysdeps/powerpc/mod.rs":"a4ace6198d60e936cf9f9c6c91142de0504deea7e75d956fd87d8616ee9d8ca5","src/new/glibc/sysdeps/powerpc/nptl/bits/mod.rs":"22902d28b252dc2bc895039f35f73b9bd0820901f279c52ea68886dfa3e01bb4","src/new/glibc/sysdeps/powerpc/nptl/bits/struct_mutex.rs":"cabb41afb4bd7a8530381f333cdf5ac10b1e5efa3d8a0b0e5eabb4992fa2dd59","src/new/glibc/sysdeps/s390/mod.rs":"14b77d79c4d6a9c6317de05fcd7abde4ce96d3205d51f122155d97469a3ee3d6","src/new/glibc/sysdeps/s390/nptl/bits/mod.rs":"9917ffcb24f1b3176ef8893b63d62db6e0a1739d127791d57ab747f632d96575","src/new/glibc/sysdeps/s390/nptl/bits/struct_mutex.rs":"d03e09f593df8db6e3c4ea38a0500adef7a55835f8eec094e16d38a65bd65af9","src/new/glibc/sysdeps/unix/linux/mod.rs":"9a7c4d5c62c37166b35d2daa69a3dc8f5b4548ef49955463ae41393e260a4cb5","src/new/glibc/sysdeps/unix/linux/net/route.rs":"d8ec70bbaa919692430fdd608b70db11dbfe86b202760727dfd474a4b25b35c2","src/new/glibc/sysdeps/unix/mod.rs":"aa6d2fb4c32f5e1139cae14bcf7cee5935657aeff97df9c064ae9acd67620d04","src/new/glibc/sysdeps/x86/mod.rs":"3b10a1317ab9a91b525b14072c7a18bd19d03dbfbd7d9c21a67e88677485815d","src/new/glibc/sysdeps/x86/nptl/bits/mod.rs":"ffe722e02d262533f5f1ecdfa972492465ddc8585dd1c586c8ec00c68e59c50e","src/new/glibc/sysdeps/x86/nptl/bits/struct_mutex.rs":"ed725f7e076ebe1ef7ce856d819434f918911f99a9f1541cd1da3d6f8075770c","src/new/haiku/mod.rs":"b3863768692c6da24fc28fdcf0c29a9dd9e3a84f301d4bee6ccc4f802befc4f8","src/new/haiku/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/hermit_abi/mod.rs":"25e5d698f292b95057f18dfe203fa96316326e0ca103da532190bb17c29cfdcf","src/new/horizon/mod.rs":"44b47e15d429026d369adfc16a4e9783cdda1be3d0a04f17c283da06573df886","src/new/hurd/mod.rs":"190a149192c237634df3e49c4834d05299aee91a3d399f356d97c36d35571a59","src/new/illumos/mod.rs":"eb5dd158844f63375a6fbb881d63279b12865342d1bb0da221216b7aa9c474b5","src/new/illumos/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/l4re/mod.rs":"5fe9a1660accdaa5df8c1837b04001cea818620eca4d46d3a9cde81682cc59cb","src/new/l4re/packet.rs":"7f3ddbd9121e2029cdebede7890cf812e16da43bd7f9a0fb3b6cf224fdd318ce","src/new/linux_uapi/linux/can.rs":"b30565ca3a98f76f98a6410fdd0649336270aa1ae4c677d1ce0d67a9be8803ee","src/new/linux_uapi/linux/can/bcm.rs":"1718a1c3aae686d18ec83dff1560439d61de244bfaf332256cc2b42b85fe5249","src/new/linux_uapi/linux/can/error.rs":"5c5ef6d7c2b9432ebbf6147f96cd260e10686f449f879e64db4757670a6ec638","src/new/linux_uapi/linux/can/j1939.rs":"8976b51496d3f4aeb8eeec68558cb0298ad1fa4a879a9b4fda56ce2572f61d18","src/new/linux_uapi/linux/can/netlink.rs":"2d90a0cb5dc9a15365c99c5101db1698f2da2df66704cfefdafd06252bcabe3e","src/new/linux_uapi/linux/can/raw.rs":"669f39f228820f8c76db846322dd4aa7599fcdf90a2f2f17d841294924bc094c","src/new/linux_uapi/linux/futex.rs":"5168f5be61449a3a6d81bc52bbc28f1c006c3c1ee2ae4005800d89d6ff2e1296","src/new/linux_uapi/linux/if_addr.rs":"997e2be333fced6a65698ed07cd0c894c38ccf82ee15e85f46aba3b1956a3e49","src/new/linux_uapi/linux/if_link.rs":"11d7773f787f6eab32e66795d315cc96f72c7fc38bc6a32bcfab3d8465d90ed2","src/new/linux_uapi/linux/if_packet.rs":"27b1f41f897c0ab33809dbcdc53b55e29cf3ba0c542da855f8c871f1c4527b44","src/new/linux_uapi/linux/keyctl.rs":"c25ee20a54a14d56de2c886c32f718b7a403b18152cc81bd7726f974cdf5b3a3","src/new/linux_uapi/linux/membarrier.rs":"5d6b55b1f7410aeb24ce6bcdbac0d33144b14dc048641ebccb5adc697ea7de2f","src/new/linux_uapi/linux/mod.rs":"1ac1404725b699c36f4981f39f0b33f71659fd1d41d2a98527fcff668c72f854","src/new/linux_uapi/linux/mount.rs":"be5bdf14fcab637b86feab3888d4faf4cfbb0b48078af1f5c64a4cc0192bb112","src/new/linux_uapi/linux/netlink.rs":"f662fc63c460e4927874c8143fcc826f9f97da6a878c86db3653b7004a3285fd","src/new/linux_uapi/linux/pidfd.rs":"6500c63d1ccaf4b7e14a36f225fd309bce9de80a50b81bca14bc6bded6ebd04e","src/new/linux_uapi/linux/sctp.rs":"065a53c3d4b6ece8976424eefeb1e1d1a6f0ac842999c58b905631dffdd2a6cc","src/new/linux_uapi/linux/tls.rs":"de59d2e2dd5b9939594874fad5453603ce4d59587d1affad6931616c9e9884bc","src/new/linux_uapi/linux/types.rs":"834f7e361d08bf1dec5c4761011b8df780e14feb69b6e2a6717fc0d3c6a6a12e","src/new/linux_uapi/mod.rs":"76cc081d46d008fe05fbb3d7f007fb62374d4efd9464916bbeb9b20c288c6416","src/new/mod.rs":"7b2d0abc1797d27b8d5d18eba44e722e032cef54e1c9a0110db40422784bd3e5","src/new/musl/arch/generic/mod.rs":"106383ed35cb7526bbbb0e16ce3521ddb2a9e61fb533687922fc9b43cd654af7","src/new/musl/arch/mips/bits/socket.rs":"eb4dff2ab581eb893e0e6547ae7a7d86453caa069b61272a818256280a23ca71","src/new/musl/arch/mips/mod.rs":"cc6c0a24ef77b7c404887fb5b7a7fd15c2a79e2a3396531ea0058636cacb3018","src/new/musl/arch/mips64/bits/socket.rs":"eb4dff2ab581eb893e0e6547ae7a7d86453caa069b61272a818256280a23ca71","src/new/musl/arch/mips64/mod.rs":"40242447a56ed21249f0417f87a7ccd074a366f19eb1353d94e904f370e0f20f","src/new/musl/arch/mod.rs":"31a73fedfd8606e04352425fb4917181f2d7376f445cb61a5460bd682ce29ed4","src/new/musl/mod.rs":"6b2e092bdc907d2d236a5f6ad977d931e13e99425a3738a62769220697cc13de","src/new/musl/pthread.rs":"e76e8f71cba55b45e4aa954970f939142595b828fd7e83586fc9145299a3b1cb","src/new/musl/sched.rs":"6f0a5b3cefb42bb01feabf34ad92d4bdbe5743263d4cd7b754baf921da81a127","src/new/musl/sys/socket.rs":"ed9de77a5937115aada325ce3d68b31e24e7ac21691dc2cb52c4e4695aa1e1dd","src/new/musl/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/netbsd/mod.rs":"d7bddddf98b09188a6fe541feaaaecdee85eb55fee2aa3cf670f7e6afa4ac342","src/new/netbsd/net/if_.rs":"5083d0f9d84de47c8b6fae60c9bb74d7c0586a80ccb8d625e5e2b4876e7f9444","src/new/netbsd/sys/file.rs":"a30095d85a4f8af49494f9b38114415f5c30e1d96a8c882eb7efd83a1cb6816a","src/new/netbsd/sys/ipc.rs":"91af85c26b3dca2a0661c820871d176baf29c00d53540f4807b9b28f9f3dfae4","src/new/netbsd/sys/mod.rs":"2dfbbf18e7585b64acfeb2f39d0495b50c142caec680db64bb4655e182347262","src/new/netbsd/sys/socket.rs":"a926087991d4cd7ebe31a3f626b5a196047c20955e9e3c99f5abe50b899b1ef3","src/new/netbsd/sys/statvfs.rs":"875c73a2c18ef78c7363b2196282579b88beca2d42ed24bda4fe8e7800db9bd4","src/new/netbsd/sys/time.rs":"7d420d5384e13ca361aaf9a7fc9faafe29a55b216988c8252a891d2232407a0c","src/new/netbsd/sys/timex.rs":"1b476328c16ce06e316485bd9dc751f31e51f63d0c07e438bf3227e66da07768","src/new/netbsd/sys/types.rs":"a0ec3ac038f0026c285ebfd869a8ae062117b1ff29855cbcf570f7f55860c854","src/new/netbsd/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/netbsd/utmp_.rs":"cbd35108f4ad7fd3c4fc65b888ba7813a29e3ed4af7920604df8085345f81973","src/new/netbsd/utmpx_.rs":"27171f826d6d2bf962a1d973a3427477ae960ad5dccc947c481d45f17ae645f0","src/new/newlib/mod.rs":"046372b698393e20436c85b28dac6f02b5cc7d599d134637bbdaa89f2530d1a6","src/new/newlib/unistd.rs":"15e74fb2c22e2343faa06a7a61baca198d7867cd70f8a4ead6cdc1f4fae24905","src/new/nto/mod.rs":"2e80a71385d3344a5f0b95b8d509148b52ea1a253d87e8f27345956d119f7e58","src/new/nto/net/bpf.rs":"3634f8f5f31f9ad86bf9fe6b4438782806bffc75700c6045673e5512b4cb14bc","src/new/nto/net/if_.rs":"cdea96569bb155c7372da481dbf00630aadfadb68ef07bfe94d258a6c600b82b","src/new/nto/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/nuttx/mod.rs":"7dbbf039987cb5ca17d2a1a562dc967de1c31b970568f728339cd5b9c8e05e25","src/new/nuttx/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/openbsd/mod.rs":"7d86ff099ddfdc8c383f49a1f6fa9c1169810cbe0c1c57d0e86dc14cb1d87320","src/new/openbsd/sys/ipc.rs":"dd37c821138dbf723d637319ad0849e9ed0b2fce1d498e7e38627a8b0a8bf142","src/new/openbsd/sys/mod.rs":"a8fd8f1cb50bffb34db04d1040048e7c23043fea834c1915453b5d539034a845","src/new/openbsd/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/qurt/dlfcn.rs":"8bfec94f78786e2eee9d4306efbf9ad977cf2b3f0d930f8cc65186e922371a9a","src/new/qurt/errno.rs":"2456f7f7557e4716f8b65b1ef67281f795c70ad1d5515d6b001d26c07b943af3","src/new/qurt/fcntl.rs":"0784ab7c55521df2ae80d37749fd22587bf5fe27568758e7d1b7e121a26db457","src/new/qurt/limits.rs":"91c8b32b54cddbef81c9d1225f0c15d27b8d697e04225a808f28737960390727","src/new/qurt/mod.rs":"8047001f3aa1704683ea57343015248b1ba1c860a671763fb7087da1c497fd36","src/new/qurt/mqueue.rs":"f7d9175c4170f9c7fac147aacece30a08319c1a01ceac242819dacc31b1abb28","src/new/qurt/pthread.rs":"8d6ad30ecf52a10062e0ffc891719643dbe1282d779934180a1e858f8c1b1e5b","src/new/qurt/semaphore.rs":"eb995a92cdead52ee61c3f498c7e408430b8430cd6cb6be74b47e6728c6773ae","src/new/qurt/signal.rs":"82ec220c868d6bff14556abdb8e12fdb9498f991d5b525d5cd13151f57b5f309","src/new/qurt/stdio.rs":"280e1faa29c7e2749469a9f9c4b0fa4ba8e0cee42a6e53d9376be6b8e3b8c2ff","src/new/qurt/stdlib.rs":"7d2aad4837a4be08083be8153ecf3e95d8c70469598fbad25793c4cfed1939d8","src/new/qurt/sys/mman.rs":"c0b862bf262564507796b1cdda967c601d265e6a1f1abfe1a5b6d45aa0742df6","src/new/qurt/sys/mod.rs":"e8585c4d447d02d1f4b72183e3d8b8c0d57301ca7099534ce2086a7a3d384b7d","src/new/qurt/sys/sched.rs":"5ae31ad3bf9199e570b9aa0f164eb337a322498aa8d7fb88e9cd73bc19ded597","src/new/qurt/sys/stat.rs":"bbd98cd523dfc7e34c163bc2d397be8ed08401fe24d85d617b581d31e5bdb708","src/new/qurt/sys/types.rs":"c23c7f02eaa198f04991f0dede9e55279effd49ec4a341fb13064f68c19f24ca","src/new/qurt/time.rs":"2745f5ad92955c192023cb57922c7d028d29a5a36a4cd531f9c2ad2a6f3fabc2","src/new/qurt/unistd.rs":"377331ec77889334611103320c54838592dc1b92f38b52bdf5b324b67657af81","src/new/redox/mod.rs":"aaeaa40c0bffde42973cd1809c1c845075f92fac95a074fe3d01d4fb02dc0992","src/new/relibc/mod.rs":"5c6955e052d8b7ead97179e356c369ffcc435e09fcca4def3e100568845e7296","src/new/relibc/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/rtems/mod.rs":"8ad621434ced0a9d1c0ed5d68514f59b0c8bd4c77fdad81eb09e671e7a42cf1d","src/new/sgx/mod.rs":"c500dc72eff5cbf99c9d7e0e3f1faa3c680bfd7f6ac0166fa1a35fd0d7e69f41","src/new/sgx/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/solaris/mod.rs":"ce8a152ebacb9e8e0d87829d166e3ead64222ead397371bd557e18eefdcafe3d","src/new/solaris/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/solid/mod.rs":"dc5c3c8a627972865ef0a968125e74b2f87636dc89dd2df0f7cea9a40d7c6beb","src/new/teeos/mod.rs":"1d69f212e2a848a32292eef9ad16a44a8d5cf80c7d43db5f445dbd1a49400e3b","src/new/trusty/mod.rs":"3f009fef70cbe062126c82f1f9274cba60b12d3766b825d66326666a1f240fc2","src/new/uclibc/mod.rs":"c3f988f3eb289ba6bc3b2535b82163a7ff160288b7494c156f0fba62143cf2d5","src/new/uclibc/pthread.rs":"ab235319003806c5f20aef5f851af472480e88ff13d2a5f730870efb95e7982e","src/new/uclibc/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/ucrt/mod.rs":"4fd3a973de4c4c6349e76320e09b13701ac284e7ae03c671054b1eeebb86215d","src/new/vita/mod.rs":"196d6ca5c9b1ccc602a6270c3cf0b0bdbd39246066d1a8385df03ba45b31d368","src/new/vxworks/mod.rs":"cf19388e70e80a6712bd770cd650bb4e6b5e95504b3d1d026b37a6bb0ed31e07","src/new/vxworks/unistd.rs":"bcbb65f70759cd84c81fc24ea36aac423edb8f9d7148f65b545ee63954411fd1","src/new/wasi/mod.rs":"2a74140697bc528193214aad11edc632923bd0cf8350d24f6d600f849dd19e19","src/new/xous/mod.rs":"69016c5c153d9a14003b15558cab96b4691a927586c20ca493fc8d3bb65594eb","src/primitives.rs":"af323402fee13278461bcaec6a06a15dfca24a02d48b0570c88e2746288d7078","src/psp.rs":"5c4d5fa3a24dad41aba8e05e5592fbc0bc5a5171785d75dab8f5df4f3727d40a","src/qurt/mod.rs":"5af8edfb34f5431586b7ae00b341daa4312737c1e39c16348b1fff1d1cb8c642","src/sgx.rs":"964d6af358f5c85f948275090e5a7854e0169c43b5c338070b6a4cd156ebc9e6","src/solid/aarch64.rs":"4d4236500f98858fc249f3b6858af5009851c8c582031926b8195b2646f7da5e","src/solid/arm.rs":"4d4236500f98858fc249f3b6858af5009851c8c582031926b8195b2646f7da5e","src/solid/mod.rs":"600ae7749abc6d75d6c6922138505440e73a6959e6dd9a2dee0599fcc8a6b8f2","src/switch.rs":"5db5be2d9c235c00f74b25cceabdf2ce5ec9e1936f991815513e4edf5dec0d56","src/teeos/mod.rs":"5811b33c2a80d152a16462a6620e66b1b5093f7be2fc70de63afda5a196e02a1","src/trusty.rs":"cc90bf6b35a515021a3155aa3cc5fcab33457b8fbb2ac7259f0b694d33625fd8","src/types.rs":"f5d55bd81c50b83575435562c65abf49cedbfe7635d4ba443e33a6d2f24a2294","src/unix/aix/mod.rs":"f8b8e22bc7d82f2b3c7d3a920a4df6d3de95523af9097c02010687f618d9aed9","src/unix/aix/powerpc64.rs":"814b5f3ccef00968c907f2ea126ad8598fc13fe11d186541342ed39d50ff7fa9","src/unix/bsd/apple/b32/mod.rs":"c57d89459e22c7644df826ad694bcfe77e28d4fbfcd8d5fcd51645ec764df901","src/unix/bsd/apple/b64/aarch64/mod.rs":"bf2e39a80c8d768c2969197b80fafa50608ac0186b4f4aea53e7fa8bf40d2214","src/unix/bsd/apple/b64/mod.rs":"c0a38b3174c3a8513e4e27faf75b5e506c6495b98d16ae36cc841b847d7aa404","src/unix/bsd/apple/b64/x86_64/mod.rs":"ff16a360cb478a4c2e912b9779a806d0e3439e4c5110e0325c82af5ee8429591","src/unix/bsd/apple/mod.rs":"30b07c6607e27c676ef00fcd0b8d23001fe6222360a5406f26db06111dd047de","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"ffbd3b6aecfb9154f109e015deb30af91e3470f5502ef6b44691095591cf6ecd","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"f13a68b825a58596b5d3339378b0812b778481a291aeacb41de74cb65ad66d3f","src/unix/bsd/freebsdlike/freebsd/arm.rs":"d627ed0bf17932ec0e3226944a4f9714805b27a953778b309d914545cf21b82a","src/unix/bsd/freebsdlike/freebsd/freebsd11/b32.rs":"316e70938d2b050fd67e5aaf0bcdd0a70d55f195b26ce4ad6055cdf05cea2e61","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"811c3f1aeb70dfd051abc9d3357e8eca9564c08b85d3ea6f81caacfa559e3060","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"76d8b8fa17ebac22cc0423eec6502c51910a03f4e7330d29d88d8908ac30b1a4","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"9f2acdbe2569d1b8890b86019d09d356c43500415a90b2335dd59c8432f557ff","src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs":"cccd7a563ad4e91518fad7c1d1c7630a5348e5d2dd935e36a40f60f254828c9c","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"0ecd3d7abf2c2eeecc343fa7b2f3ae2872535a0ec69a61544f2cf133bcd27897","src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs":"cccd7a563ad4e91518fad7c1d1c7630a5348e5d2dd935e36a40f60f254828c9c","src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs":"b0df06bd48f06eee77446e689c942fa2b33dc73f9653d5e4d49f58479cdcacff","src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs":"838dee28bffe6f5d6bf0004d823cd8d17e642acb1d30c27a99f96faa32f0cdb8","src/unix/bsd/freebsdlike/freebsd/freebsd15/mod.rs":"d85e17e4c18f3cccf4ac563eba35ad5b77a3621244bdd208d78b10c29c9b5f68","src/unix/bsd/freebsdlike/freebsd/freebsd15/x86_64.rs":"838dee28bffe6f5d6bf0004d823cd8d17e642acb1d30c27a99f96faa32f0cdb8","src/unix/bsd/freebsdlike/freebsd/mod.rs":"f1862cec4db3f2c72906c50b9ebeb2fc24007ab6feb8d457852949da6c5015df","src/unix/bsd/freebsdlike/freebsd/powerpc.rs":"af7a43826e3ca9e5e7c3d7c1b50defa482074fd9909de3ee2e52cd0109c1a950","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"f7be922bddd7a4b7da863d6aba057aab2d27f500c7101596bbaaccf075133451","src/unix/bsd/freebsdlike/freebsd/riscv64.rs":"69242a001ab21b6e06b7442c37a89dbc5a67660c7c3cade1d46b65adf32a5669","src/unix/bsd/freebsdlike/freebsd/x86.rs":"5165242f0c82040898dbf711294ba45c5ab2635d39d0bbf9cc899b816415e2a4","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"84044f397dbf13a1c517885c7b234efa2900d116324a4cca626d2f8df398d655","src/unix/bsd/freebsdlike/mod.rs":"514068e20eb263560abaf4bc0f629e4f619d4648e0d25fa765041edb399ed4ec","src/unix/bsd/mod.rs":"f3c1d43560fc184895036a88f65f489b1ed3d31bc38ce30f2bfdc033b9d102cd","src/unix/bsd/netbsdlike/mod.rs":"e935dd0c5fd490e9328b2ac8afcdbe967340692594a7116cc8854fbe5045fae4","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"ba2425edbf025f13ab3c3534d1671d310392df3a7d237539817d9cfa675971c8","src/unix/bsd/netbsdlike/netbsd/arm.rs":"8dd57613695dec1b2104ec35839f0b9b6d234c6cc80365e9fef9ca977c1865a0","src/unix/bsd/netbsdlike/netbsd/mips.rs":"20cdd8d1427c986ecc3fcf7960d337917a13cfd8386dd2d54f8693a23d60892f","src/unix/bsd/netbsdlike/netbsd/mod.rs":"31a6505b5a16b6cbe5b6463359f76a4ad8f896b3beb75a84b71dce2b8188dafa","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"c19c4edbc73b5a97b51e3e2ad39b9fee02ad15e80c70ceb3a1abfe977e5c0ead","src/unix/bsd/netbsdlike/netbsd/riscv64.rs":"f446c996f00e4d15fd25461a30c767c05d083df9e047b0da497ce7c545acfa96","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"d50816e830225779ac9e9a55a7e3e097882153d72987061d76a96ee736c8af9c","src/unix/bsd/netbsdlike/netbsd/x86.rs":"3006b6a086c0241f5383ca101e7b9357368d713f9c38400633491656d110798e","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"13dd36a0db740930155b5f28fedfac606c7291c0276bbf2c2b3fe03a4dbd2a51","src/unix/bsd/netbsdlike/openbsd/aarch64.rs":"13c91b304dfb5c3c26777863827c7b3707fe245fcf50da32caab641aff998c63","src/unix/bsd/netbsdlike/openbsd/arm.rs":"f064d935f416ca9f7e5e767b9b46da2250c997d667c0c7f4b4c7dfe02d0258c3","src/unix/bsd/netbsdlike/openbsd/mips64.rs":"bee7664d88f8451ae22552fc0721b6b6a6dee2493cc42bcb9829c1e47e4b05f5","src/unix/bsd/netbsdlike/openbsd/mod.rs":"b5bf21aef874477bf26664c0ddfdb370ffeb73b287d7447f8bdd9c61e2546bb2","src/unix/bsd/netbsdlike/openbsd/powerpc.rs":"f064d935f416ca9f7e5e767b9b46da2250c997d667c0c7f4b4c7dfe02d0258c3","src/unix/bsd/netbsdlike/openbsd/powerpc64.rs":"1f62a42e2970c42de9e3492fbf3cd5b45410889f033743579266342d1a9e2a00","src/unix/bsd/netbsdlike/openbsd/riscv64.rs":"b2cf3778bfb51d1c0277f0e92963a04f734be3e29879c6c09a25bad2d9b5ab6a","src/unix/bsd/netbsdlike/openbsd/sparc64.rs":"8d4c5a4cae63e09e1c156164ddc82e0fc77926841d4d4e419dd2e7a7b7145f58","src/unix/bsd/netbsdlike/openbsd/x86.rs":"e6da2fdff7706fd3eac147d3aaf16afdd8542f231f502660d1d89c79b5eca21b","src/unix/bsd/netbsdlike/openbsd/x86_64.rs":"bc7ed75ce66059aafa7a86986aefff267b2c951e47558453fe13ce1bdb48dc0b","src/unix/cygwin/mod.rs":"6aad2e8077d97d293889145ea37ecc379cbe5cb78d2b198750639e822f0917d5","src/unix/haiku/b32.rs":"c3f8678ceee65a3094d8133b0d1a94470860e0b1867977f0569c52c5a20e039f","src/unix/haiku/b64.rs":"f97ce9225f4710893dab03ab3e13bc62152cc84f90c597ec88f6dc1f4c27d242","src/unix/haiku/bsd.rs":"4d9af31fdac2561ee5f942dca97dd2f48139ca74660d40b854b307fa5679d1c8","src/unix/haiku/mod.rs":"102560660857c1a7c6113b2a6b12bd816d9b70dd62cca17a77c543f798301681","src/unix/haiku/native.rs":"93993d4cd065550b772c9700b1da64455f1b495ac8ce7fd71d9c043d4bae1ff0","src/unix/haiku/x86_64.rs":"def40c16609b5d62c3cdbba6a38340720a96b326ad98d53838554e4b6878d2ee","src/unix/hurd/b32.rs":"501f426f7aeb60acf4119064100dd94bbdfebff2cec785428708059d853dc123","src/unix/hurd/b64.rs":"b9b2082e721a5ec89ba55fd5a16bbffcc8a05ca7cef6dbfbd78aff0806cb931f","src/unix/hurd/mod.rs":"47c18259062e834f1937aa8e5902f27f431053f112d22f2af64c4826bbaabd6a","src/unix/linux_like/android/b32/arm.rs":"9c19aeacb713b2886e0293c0abb4b64ddba5935a876a239c8c392b8ae68d02ab","src/unix/linux_like/android/b32/mod.rs":"013d0c2f1b53ae7999ed789a6b92fd4938268a6df0e8dda50f6f16a21567bc6f","src/unix/linux_like/android/b32/x86/mod.rs":"3cc9a98c2dd052029901f2c507c72795018a0ccfb64f97297b5680307da362a9","src/unix/linux_like/android/b64/aarch64/mod.rs":"57e8a37d0cf47c07444832c8684d29be2383547a21c388715b2f597573f77412","src/unix/linux_like/android/b64/mod.rs":"0ac090c7920232aecb9efbb7aef6074a1fc09a4f76c195886c1592a23d847374","src/unix/linux_like/android/b64/riscv64/mod.rs":"394125fc6cbf568271c18cba4673dbb136b560c484d38e01670cab825ca55a0d","src/unix/linux_like/android/b64/x86_64/mod.rs":"0ea316ab5e84781758ff14db88c90721400b4a4d2fb73f61c802bf2784774f94","src/unix/linux_like/android/mod.rs":"5b79b3cb98010896af67fdc4a3c8105ce104fecfa8c21373ee2306e2958fd446","src/unix/linux_like/emscripten/lfs64.rs":"5921989146110ae9b898334dc6c1de8fc2334149711f2aeb26dc654857ee82ac","src/unix/linux_like/emscripten/mod.rs":"515dbc5565556e0b21f7453fe9d529a1cba73ae69ca6c0d3386d6eddb4df9bd2","src/unix/linux_like/l4re/mod.rs":"47c07dc3c5e368ec9a64b33af9a314f51e5ed6c7fc6456bfba919d661a812275","src/unix/linux_like/l4re/uclibc/aarch64/mod.rs":"c22979fe55e9fd752114a43d97cc42211fc5b2244a6c601042c1c6d6b263ba53","src/unix/linux_like/l4re/uclibc/mod.rs":"47b8ca0231d56146c4435c9f5cded520ac67d5c5581d6a1277050942991ef4ef","src/unix/linux_like/l4re/uclibc/x86_64/mod.rs":"438e289c3ad818dd8be5391a4b44e294daf8759424bbe54ae6cf06be14d81498","src/unix/linux_like/linux/arch/generic/mod.rs":"39f70281f38aa591d18e23a465ad8b654acfd66203b53e44a9e27cd174fcea70","src/unix/linux_like/linux/arch/mips/mod.rs":"00014d704cc5c578be2300c7c2057358c64c4700d33da5dcf2a01fd1a50c42fa","src/unix/linux_like/linux/arch/mod.rs":"8bc5898b03760a95dd4f124ac76ad92e5ae36b2d0644203d752ef2b37e487c3a","src/unix/linux_like/linux/arch/powerpc/mod.rs":"03b1a1271891909372a3817f208943d8ed273ee66a8342a02426e0dd7b1137cf","src/unix/linux_like/linux/arch/sparc/mod.rs":"5bb8a0680447d5e061fa2f2370681233487f2e099619536ab2392bbafa31cc0b","src/unix/linux_like/linux/gnu/b32/arm/mod.rs":"60d5c7667d81db0ad9faf65edc79420b2100cab27699e03de4d415de931e9f58","src/unix/linux_like/linux/gnu/b32/csky/mod.rs":"627e61997c33fc12fca9e337d248d8531ef0751f21f70110b65631a0e481b66d","src/unix/linux_like/linux/gnu/b32/m68k/mod.rs":"2ea8f649fc9f01829de439ffe0fdbf9566602ed6ec0088128167af1080c3a1b2","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"8b3254b47401cde6118f9eea7e98319af8174d99feac451949e673a28ed4ff6e","src/unix/linux_like/linux/gnu/b32/mod.rs":"c7a1d5a3033fea02322b4d1f17b9576e11761a56f418e4ed5e72993f61fad160","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"585983c6617a590ee0ac5217280d03642efcf721bd80fdabd6b9477031574fee","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"a5e6c931ca8da568626233f2aa5ee0dd0b8e4e1e8905d52ab9dd0ea618376c2f","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"d3f846bfcec990fbc009fe705edc39b64c011464b8ec1dd5373424ab9511e919","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"e370a80bfdec000347c384f080b30c6f537dc51e17e715c2dd8a360e6a1407f3","src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs":"cbf545c6fe4e5998792c036d9456408ae415cfe3d68ae2ad6981b8b8ac47a395","src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs":"0e41329debd9e8924bfe784d082c40efaeb8a585a7b5bc1faf9be8b53f0769e1","src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs":"368b40031515d5c4d9834a899136e0d046fdb06f751df84c143ca257d73d3fd9","src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs":"080980118660502ff312a31e108aa9fee51a671fecd80b1871959586b2bdee02","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"cde2c6f63ef0efb12cb423e313a20572d76d2e3a24deceec2675fbb07ee422f2","src/unix/linux_like/linux/gnu/b64/mod.rs":"4b6ba534576035f3dd89d6d89c520d4c0a98f3a3e24ece70dff5970d2047d446","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"9cd129a0658213e1e13d7a06c88c54035f4e012f0fa73456605808902e4607f5","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"f229eb10a427a4d206bafa433f4f015cccbd4077d04d340bfae163bbb305435f","src/unix/linux_like/linux/gnu/b64/s390x.rs":"f55c3bca64e3d01691125352e1dda98c93db7361761b817378db0b5f62b1df9d","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"0a71dfee9d66d55e20323b82bb1817070a88606dc88e9008c1c11b32a45478f6","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"5e23cc1b0fc69f2c50f6fc83e0dc8d25afef2d2e74dccd4240ae873c5d6bb72d","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"414d14164e09f0d66609180cda5ff919fda0440b29df43bd0f0f55fd2ddcee4b","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"3cab97c6a03adecccd4e10e90196b2555e3c9de77e210ac9caf3f186fbcd3f01","src/unix/linux_like/linux/gnu/mod.rs":"df5cb173336a5381f3a668af12c89495fd161bcaa5ff3a46b0f9e7222a3bda2e","src/unix/linux_like/linux/mod.rs":"caff5b733b297569edca489ab9b0d049c4fe70ca953de635d983ef483e10a197","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"7dc4b9a4d723d6868a84e81dbd5953b234c4540db3edd5a4a7ea0e154b101d91","src/unix/linux_like/linux/musl/b32/hexagon.rs":"e0e53f5575871faa1870f43bf85b0033c1feac149f766ad73fa2149be2447324","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"64f6b834d3d98db1c2d95d40371c644f71170d7710fcdd933f1ff51c3fbe2c70","src/unix/linux_like/linux/musl/b32/mod.rs":"b136185b20a863d5e2bbec9e3bcb7e0c56329e196165ca70f2aed5777e39aeab","src/unix/linux_like/linux/musl/b32/powerpc.rs":"a946612120ed9700ff1e4e729b0f8107a40f9ed7f5b320357552d5475441042d","src/unix/linux_like/linux/musl/b32/riscv32/mod.rs":"7b5efe1ebf7d5d5439fb929032b48dcde98ba274fb22deb0f45137df21eb87b6","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"83e340712e8acd89cefcb5eef0e826da79f47a7a42784699df90604c4e9a8712","src/unix/linux_like/linux/musl/b64/aarch64/mod.rs":"889ba0c0d20a8531dd05024ec9825a7bc57562c2bda4d063e5c632e76a143fc4","src/unix/linux_like/linux/musl/b64/loongarch64/mod.rs":"a7a136f43e8a6f2c680faf477055a12459fa307587111c0c7c147ac7df8722db","src/unix/linux_like/linux/musl/b64/mips64.rs":"a855f49b0685e50b9fd118c8d8f9d5596440092e37b7696db87cc3d3db3894f9","src/unix/linux_like/linux/musl/b64/mod.rs":"1ce1eee49b1c7c5c02fe04b1539a0316becf0295763e3e18b1088895ed937373","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"e18d27dc96bfd7a352b065498847b4f97d00d33dc27f1fd49ead11d97a923211","src/unix/linux_like/linux/musl/b64/riscv64/mod.rs":"7dd2c67186d0f6e0d585c4eabd686f476edf83f2bd4ca0f6a3a55bcd71c11fd6","src/unix/linux_like/linux/musl/b64/s390x.rs":"042a2be23f0b7437e7b5b007ed7ebddaf6b51e32cfac803f7e9d4fd6941d1d39","src/unix/linux_like/linux/musl/b64/wasm32/mod.rs":"2ae98dba37841279be44f68330c301f823ec2e251ea8258dd7d40f491fd26f76","src/unix/linux_like/linux/musl/b64/wasm32/wali.rs":"006149b7af0145dc40123fc7991d853c7f2c5c77bbc9c8a44c276be0d99a1343","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"6a2d9adaf90aa39b56b383d6987091616227f4b6c167934cda2e825e6c806c02","src/unix/linux_like/linux/musl/lfs64.rs":"3c15fd2820d400b0650cca950cd41dc77c017c5f06841db1942cd59118a252e3","src/unix/linux_like/linux/musl/mod.rs":"490ef1317a0173e283c139df5a83e37f54c3ba48eba66a485b2659907220389e","src/unix/linux_like/linux/uclibc/arm/mod.rs":"27a2bab2ff33d0b159eb49ba5a302bcf2ecbc24431ffd0f494ab274a6e43f016","src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs":"39057a283532e0430dc664d9c4ace6a2fba6e9b252c1404a6835ed382a1f2e27","src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs":"7458bd4483a6c16db943d8d69de3e02ca952ec67c608604e174a26e99e453d71","src/unix/linux_like/linux/uclibc/mips/mod.rs":"e552f579a8dc9e690891113aa6360607ad962bd84cbb60c370b5c5f7c7d1d8c0","src/unix/linux_like/linux/uclibc/mod.rs":"aad428f795b39aa987653919175bb2fab633ceedbd01bcbf358c550dc7bdf936","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"68ec631cd8d8da3d5b12161936e367a68fca982dacf45424789840335c1f39c0","src/unix/linux_like/linux_l4re_shared.rs":"ee47eb40a299f4897e0cc1f8d5a6d554e4fb6302f11b752d921cfcfb09c0afab","src/unix/linux_like/mod.rs":"298ca2a15df5313c893184334caef990df5dbe6f71afcf332d4322dde80e1c3d","src/unix/mod.rs":"999588f6f4ac24156c1bf9260d639a64247a83d7b6db187f4f94f7305c5cde47","src/unix/newlib/aarch64/mod.rs":"d72d067a433bf24ee6b6255c4d04ea7c966518b8d064560c593f1ab23c025962","src/unix/newlib/arm/mod.rs":"95b6e4b3cd1eeb0386d4867e9e4c3438305aa3e8ae75697e06720aa06540a666","src/unix/newlib/espidf/mod.rs":"cbaf10ccdb429719003cac3f3cd4aa0aa63a12a383afc5bd88a4ab3abaef9e2e","src/unix/newlib/generic.rs":"c435a955d72878a71ea0719a75a4579818da6a2e01635f9fe1073d9a0d67352f","src/unix/newlib/horizon/mod.rs":"329f41f1703f318ea8999c2a9f48b953381e9a4fc388670ce69444ad7a32b122","src/unix/newlib/mod.rs":"6bbe0874c5d6f53ea2d9f2a7cb1b27bdb27b9b02704160e6133ea6e559ad66cd","src/unix/newlib/powerpc/mod.rs":"4d6dca09ea5dc000cbd39fb939a9b1a743d819931dfca3c896659e919a07a7da","src/unix/newlib/rtems/mod.rs":"efcb2c5f96ae5877fb4cefa59e4a38ae40c4eba22afa9c9a9ecdc61121d3b9d2","src/unix/newlib/vita/mod.rs":"2f9bf66b40c2aa611033faf3ade5510dc9789af7302571fade40a1715398f06c","src/unix/nto/arch/aarch64.rs":"e7fc7ada9e273c6cffe556f977db71a96c9e4a27f496a8223bc23e3fd876c05e","src/unix/nto/arch/i686.rs":"6ebb8acc594e9dbfa80c363dcf56aca0125afdab4fb3a1fc2806ed8ffe9dc252","src/unix/nto/arch/mod.rs":"4ff319773cd756d9dcace1348a3ac4569cf89a031436bdb57e66c9557a9eb948","src/unix/nto/arch/x86_64.rs":"71e97cb09b938b2c6f01ba71e268221f8a51500ca309c71d6c8de61ee2c0e9c8","src/unix/nto/io_pkt/mod.rs":"1fc160ff187fb6b49744859e3da481a3e7264b248bbe289efff22fd1e6d699e9","src/unix/nto/io_sock/mod.rs":"941bfd903a0cd329ed92f36222a2f13c7e798cd403fee7d7859214a794a65534","src/unix/nto/mod.rs":"41b6926daedda07a5dfbca7e23516ba39161f1de9b9cc89d9b6e512bd877f595","src/unix/nto/neutrino.rs":"59e3b22aa27c2aba3e96b39c0f624897747650c7e916832629586259d18579ce","src/unix/nuttx/mod.rs":"b231559c8b5e0af7fa32f869dce8236b32d0057603a5cea115c776b2ceaf14a0","src/unix/redox/mod.rs":"45613acbd48fb5469a9d4e597e4e492a98138af3135887043c6d5b3f64e18ccb","src/unix/solarish/compat.rs":"3d120a056208c03215cfbe3eef1584105160d133c0aa4557bb38018c177640b0","src/unix/solarish/illumos.rs":"597c04a05dd586eec164624d1819d5bd0db3c26711131fdd896e2af09406340a","src/unix/solarish/mod.rs":"9f94cb59612b898d8da26e69e291730cf374376f6d40940faed92c193c51f359","src/unix/solarish/solaris.rs":"5ea6cc86389f7e3b8dca2de17fbd4fcdbb5b0a6638b95efeb7ae15c8bbb9e79b","src/unix/solarish/x86.rs":"44261c1f1b300dac9fa0dab93ec85d0c3b3c48b15bc4515b9820c9421cff7427","src/unix/solarish/x86_64.rs":"eec1602998dbd3b3aeb2d9a5bd66fc53a6fbbcd7967ed0bb2dd61a8c176023e4","src/unix/solarish/x86_common.rs":"4ae02d88622f7f080f5e8cd328f13187edbc5e124fb3e05e4cf212597f6cce48","src/vxworks/aarch64.rs":"4d4236500f98858fc249f3b6858af5009851c8c582031926b8195b2646f7da5e","src/vxworks/arm.rs":"4d4236500f98858fc249f3b6858af5009851c8c582031926b8195b2646f7da5e","src/vxworks/mod.rs":"e5efaf8a584862fca87a3e367042de056a688a8a105d0bed149f09e516e4cc05","src/vxworks/powerpc.rs":"4d4236500f98858fc249f3b6858af5009851c8c582031926b8195b2646f7da5e","src/vxworks/powerpc64.rs":"4d4236500f98858fc249f3b6858af5009851c8c582031926b8195b2646f7da5e","src/vxworks/riscv32.rs":"b1f933205800f0da00f975d53b18fe0035e075cc4613acf110a09a277dc3302a","src/vxworks/riscv64.rs":"b1f933205800f0da00f975d53b18fe0035e075cc4613acf110a09a277dc3302a","src/vxworks/x86.rs":"b1f933205800f0da00f975d53b18fe0035e075cc4613acf110a09a277dc3302a","src/vxworks/x86_64.rs":"b1f933205800f0da00f975d53b18fe0035e075cc4613acf110a09a277dc3302a","src/wasi/mod.rs":"f4bd5f0481da1922dd31195a2825bf9a1a852c82f56e536f82639eff961c0f9a","src/wasi/p2.rs":"feecc0485eabd2c32bc5d800df6ad1b9b4d282741342fb08792f2635204e1e08","src/windows/gnu/mod.rs":"6422acc5c5a82122c11efb84882778e30888c0693c0993fbf7f3baa59e4cbbb5","src/windows/mod.rs":"8ec2bd46a05aed28f8bdfa17d99909300b59eb36cdc694545e29f8aa902e9e53","src/windows/msvc/mod.rs":"40410b26b606d1b59b0742b2632f3cd0a28a5429f784f9693fae0a78c15b3889","src/xous.rs":"1a83621c40248ad4d0c08e1fd4c1107d5efcbc2f4f0169538b7b4a885abedbfa","tests/const_fn.rs":"8ac3171d7bced3576a4e93f48570b3e00c553d7510ab85a7473ae3b716a812dc"},"package":"3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"} \ No newline at end of file diff --git a/vendor/libc/.cargo_vcs_info.json b/vendor/libc/.cargo_vcs_info.json new file mode 100644 index 0000000..62453f2 --- /dev/null +++ b/vendor/libc/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "ef0906e20828777175f65caa7e681a0ce33c559a" + }, + "path_in_vcs": "" +} \ No newline at end of file diff --git a/vendor/libc/.editorconfig b/vendor/libc/.editorconfig new file mode 100644 index 0000000..155c990 --- /dev/null +++ b/vendor/libc/.editorconfig @@ -0,0 +1,7 @@ +[*.sh] +# See https://github.com/mvdan/sh/blob/master/cmd/shfmt/shfmt.1.scd#examples +indent_style = space +indent_size = 4 + +switch_case_indent = true +space_redirects = true diff --git a/vendor/libc/.git-blame-ignore-revs b/vendor/libc/.git-blame-ignore-revs new file mode 100644 index 0000000..d358a2c --- /dev/null +++ b/vendor/libc/.git-blame-ignore-revs @@ -0,0 +1,6 @@ +# Format macro bodies +50f26e08e146b7e9c7d1af9614486eba327d1e31 + +# Automated changes related to the 2021 edition upgrade +643182f7da26cedb09349b8bb3735c2e58ba24e6 +108310db03e7db35ef48a902d9ce9a88ab8f9b77 diff --git a/vendor/libc/.release-plz.toml b/vendor/libc/.release-plz.toml new file mode 100644 index 0000000..6442af5 --- /dev/null +++ b/vendor/libc/.release-plz.toml @@ -0,0 +1,49 @@ +[workspace] +git_release_name = "{{ version }}" +git_tag_name = "{{ version }}" + +[changelog] +body = """ +## [{{ version | trim_start_matches(pat="v") }}]\ + {%- if release_link -%}\ + ({{ release_link }})\ + {% endif %} \ + - {{ timestamp | date(format="%Y-%m-%d") }} +{% for group, commits in commits | group_by(attribute="group") %} +### {{ group | upper_first }} + {% for commit in commits %} + - {% if commit.scope -%}{{ commit.scope | upper_first }}: {% endif %} + {%- if commit.breaking %}[**breaking**] {% endif %} + {{- commit.message }} + {%- if commit.links %} ([{{ commit.links.1.text }}]({{ commit.links.1.href }})){% endif -%} + {% endfor %} +{% endfor %} +{%- if github -%} +{% if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %} + ## New Contributors ❤️ +{% endif %}\ +{% for contributor in github.contributors | filter(attribute="is_first_time", value=true) %} + * @{{ contributor.username }} made their first contribution + {%- if contributor.pr_number %} in \ + [#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \ + {%- endif %} +{%- endfor -%} +{%- endif %} +""" + +commit_parsers = [ + { message = '(?i)^(\w+: )?feat', group = "added" }, + { message = '(?i)^(\w+: )?add', group = "added" }, + { message = '(?i)^(\w+: )?change', group = "changed" }, + { message = '(?i)^(\w+: )?cleanup', group = "cleanup" }, + { message = '(?i)^(\w+: )?deprecate', group = "deprecated" }, + { message = '(?i)^(\w+: )?remove', group = "removed" }, + { message = '(?i)^(\w+: )?fix', group = "fixed" }, + { message = '(?i)^(\w+: )?fix', group = "fixed" }, + { message = '^.*', group = "other" }, +] + +link_parsers = [ + # Extract backport patterns + { pattern = '\(backport <.*/(\d+)>\)', text = "#$1", href = "https://github.com/rust-lang/libc/pull/$1"} +] diff --git a/vendor/libc/.rustfmt.toml b/vendor/libc/.rustfmt.toml new file mode 100644 index 0000000..42e6cff --- /dev/null +++ b/vendor/libc/.rustfmt.toml @@ -0,0 +1,6 @@ +edition = "2021" +error_on_line_overflow = true +group_imports = "StdExternalCrate" +imports_granularity = "Module" +# This crate gets large lists of reexports. Use vertical to reduce conflicts. +imports_layout = "Vertical" diff --git a/vendor/libc/CHANGELOG.md b/vendor/libc/CHANGELOG.md new file mode 100644 index 0000000..079d43c --- /dev/null +++ b/vendor/libc/CHANGELOG.md @@ -0,0 +1,1212 @@ +# Changelog + +## [0.2.189](https://github.com/rust-lang/libc/compare/0.2.188...0.2.189) - 2026-07-21 + +### Added + +- Emscripten: Add `pthread_sigmask`, `sigwait`, `sigwaitinfo`, `sigtimedwait`, `faccessat`, and `pthread_kill` ([#5270](https://github.com/rust-lang/libc/pull/5270)) +- Linux SPARC: Enable the `clone3` syscall ([#4980](https://github.com/rust-lang/libc/pull/4980)) +- Solarish: Add `CLOCK_PROCESS_CPUTIME_ID` and `CLOCK_THREAD_CPUTIME_ID` ([#5274](https://github.com/rust-lang/libc/pull/5274)) + +### Deprecated + +- Deprecate `CLONE_INTO_CGROUP` and `CLONE_CLEAR_SIGHAND`. These overflow their types and will be changed to a larger size in the future. ([8c6e6710458d](https://github.com/rust-lang/libc/commit/8c6e6710458db4d6aa0766f6f84bbf13f640237e)) + +### Fixed + +- Musl riscv32: Rename padding fields to avoid a conflict and fix the build ([2499ff0ad993](https://github.com/rust-lang/libc/commit/2499ff0ad9936a036e78a4e0991445efee383564)) +- NuttX: Fix `wchar_t` definition under Arm ([#5245](https://github.com/rust-lang/libc/pull/5245)) +- Windows: Add back link names for `time`-related symbols ([#5300](https://github.com/rust-lang/libc/pull/5300)) + + +## [0.2.188](https://github.com/rust-lang/libc/compare/0.2.187...0.2.188) - 2026-07-21 + +### Changed + +- Restore `Send` and `Sync` for `DIR` ([35b062263401](https://github.com/rust-lang/libc/commit/35b062263401733cd89065c6a553640f2ba51ff1)) + +These were removed in 0.2.187 because `libc` does not actually make `Send` and `Sync` +guarantees about `DIR` (or other extern types), but this caused some crates to break. +The traits are added back for now to allow time to migrate, but will be removed again +in the future; please make sure your crates are not relying on `libc::DIR: Send` or +`libc::DIR: Sync`. + + +## [0.2.187](https://github.com/rust-lang/libc/compare/0.2.186...0.2.187) - 2026-07-20 + +This release contains a number of improvements related to 64-bit `time_t` configuration. +Of note the existing `RUST_LIBC_UNSTABLE_*` environment variables have been replaced +with configuration options. The new way to use these is: + +```sh +RUSTFLAGS='--cfg=libc_unstable_musl_v1_2_3' cargo ... +RUSTFLAGS='--cfg=libc_unstable_gnu_time_bits="64"' cargo ... +``` + +Being able to set this via `RUSTFLAGS` makes it easier to only apply configuration to +specific targets (and notably, not the host if build scripts are used). + +There are two other notable changes: + +* The 32-bit `windows-gnu` targets now respect `libc_unstable_gnu_time_bits` +* uClibc now supports a similar configuration option: + + ```sh + RUSTFLAGS='--cfg=libc_unstable_uclibc_time64' + ``` + +As a reminder, these options are under active development and may change in the future +(hence the "unstable" in the name). It likely that we will harmonize everything under a +single configuration option before considering them stable. + +### Support + +- Add support for `aarch64-unknown-linux-pauthtest` ([#5065](https://github.com/rust-lang/libc/pull/5065)) +- Add support for new QNX targets ([#5241](https://github.com/rust-lang/libc/pull/5241)) +- Better document breaking change policy and recommended usage ([#5179](https://github.com/rust-lang/libc/pull/5179)) + +### Added + +- Android: Add `POSIX_SPAWN_*` constants ([#5104](https://github.com/rust-lang/libc/pull/5104)) +- Android: Add `getpwent`, `setpwent`, and `endpwent` ([#5160](https://github.com/rust-lang/libc/pull/5160)) +- Android: Add `preadv2` and `pwritev2` ([#5157](https://github.com/rust-lang/libc/pull/5157)) +- Android: Add `seccomp_notif*` structures ([#5224](https://github.com/rust-lang/libc/pull/5224)) +- Android: Add `timer_[create, delete, getoverrun, gettime, settime]` ([#5108](https://github.com/rust-lang/libc/pull/5108)) +- Apple: Add `PROC_PIDT_SHORTBSDINFO` and `proc_bsdshortinfo` ([#5110](https://github.com/rust-lang/libc/pull/5110)) +- Apple: Add `SIOC*` constants from `sockio.h` ([#5263](https://github.com/rust-lang/libc/pull/5263)) +- Apple: Add `_IOR`, `_IOW`, `_IOWR` ([#5264](https://github.com/rust-lang/libc/pull/5264)) +- Apple: Add `bpf_program` and `bpf_insn` ([#5235](https://github.com/rust-lang/libc/pull/5235)) +- Apple: Add additional `kqueue` constants ([#5077](https://github.com/rust-lang/libc/pull/5077)) +- Apple: Update `vm_statistics64` with recently added fields ([#5253](https://github.com/rust-lang/libc/pull/5253)) +- Apple: add `IN6_IFF_*` and `SIOCGIFAFLAG_IN6` ([#5239](https://github.com/rust-lang/libc/pull/5239)) +- Dragonfly: Add `O_*`, `POSIX_FADV_*`, `NI*`, and a few other missing constants ([#5116](https://github.com/rust-lang/libc/pull/5116)) +- Dragonfly: add `fdatasync`, `dlvsym`, `reallocarray`, `qsort_r`, `pthread_*affinity_np`, `ftok`, `extattr_*`, and `dup3` ([#5116](https://github.com/rust-lang/libc/pull/5116)) +- Emscripten: Add `in6_pktinfo` ([#5256](https://github.com/rust-lang/libc/pull/5256)) +- FreeBSD: Add SOL_LOCAL ([#5185](https://github.com/rust-lang/libc/pull/5185)) +- FreeBSD: Add `DLT_*` constants ([#5235](https://github.com/rust-lang/libc/pull/5235)) +- FreeBSD: Add `PROC_LOGSIGEXIT_*` and `PPROT_*` ([#4657](https://github.com/rust-lang/libc/pull/4657)) +- FreeBSD: Add `SO_RERROR` ([#5260](https://github.com/rust-lang/libc/pull/5260)) +- FreeBSD: add `IN6_IFF_*`, `in6_ifreq`, and `SIOCGIFAFLAG_IN6` ([#5239](https://github.com/rust-lang/libc/pull/5239)) +- FreeBSD: add `_IO*` helpers from `sys/ioccom.h` ([#5239](https://github.com/rust-lang/libc/pull/5239)) +- Glibc: Add `PTHREAD_*_MUTEX_INITIALIZER_NP` for riscv64 ([#5094](https://github.com/rust-lang/libc/pull/5094)) +- Glibc: Add new fields to `struct tcp_info` ([#5215](https://github.com/rust-lang/libc/pull/5215)) +- Linux: Add `OPEN_TREE_NAMESPACE` ([#5145](https://github.com/rust-lang/libc/pull/5145)) +- Linux: Add `SECCOMP_IOCTL_*` constants ([#5224](https://github.com/rust-lang/libc/pull/5224)) +- Linux: Add `SO_DETACH_REUSEPORT_BPF` ([#5081](https://github.com/rust-lang/libc/pull/5081)) +- Linux: Add `futex_waitv` ([#5125](https://github.com/rust-lang/libc/pull/5125)) +- Linux: Add constants for `fsopen`, `fsconfig`, `fsmount`, and `fspick` ([#5145](https://github.com/rust-lang/libc/pull/5145)) +- Linux: Add fields to `statx` present since 6.16 ([#4621](https://github.com/rust-lang/libc/pull/4621)) +- Linux: Add network entry API ([#5049](https://github.com/rust-lang/libc/pull/5049)) +- Linux: add `ifaddrmsg` and `rtattr` ([#5234](https://github.com/rust-lang/libc/pull/5234)) +- Linux: add `sockaddr_iucv` ([#5041](https://github.com/rust-lang/libc/pull/5041)) +- MacOS: Add `ENOTCAPABLE` ([#4925](https://github.com/rust-lang/libc/pull/4925)) +- Musl: Add `renameat2` ([#5113](https://github.com/rust-lang/libc/pull/5113)) +- NuttX: Add `F_SETFD` ([#5258](https://github.com/rust-lang/libc/pull/5258)) +- NuttX: Add `POLLRD*` and `POLLWR*` constants ([#5258](https://github.com/rust-lang/libc/pull/5258)) +- NuttX: Add `SO_KEEPALIVE` and TCP keepalive constants ([#5111](https://github.com/rust-lang/libc/pull/5111)) +- NuttX: Add `TCP_MAXSEG` ([#5258](https://github.com/rust-lang/libc/pull/5258)) +- NuttX: Add `eventfd` and `EFD_*` constants ([#5258](https://github.com/rust-lang/libc/pull/5258)) +- NuttX: Add `pipe2` ([#5258](https://github.com/rust-lang/libc/pull/5258)) +- NuttX: Add `strerror_r` ([#5258](https://github.com/rust-lang/libc/pull/5258)) +- NuttX: Add `netinet` structs and constants ([#5258](https://github.com/rust-lang/libc/pull/5258)) +- NuttX: Add socket structs, functions and constants ([#5258](https://github.com/rust-lang/libc/pull/5258)) +- QuRT: Add POSIX timer functions ([#5091](https://github.com/rust-lang/libc/pull/5091)) +- QuRT: Add missing pthread functions from QuRT SDK headers ([#5091](https://github.com/rust-lang/libc/pull/5091)) +- QuRT: Add missing unistd process and file functions ([#5091](https://github.com/rust-lang/libc/pull/5091)) +- QuRT: Add mqueue subsystem (message queues, select/pselect) ([#5091](https://github.com/rust-lang/libc/pull/5091)) +- Redox: Add `*at` and `dirent` functions ([#5117](https://github.com/rust-lang/libc/pull/5117)) +- Solarish: Add IP TTL and IPv6 Hop Limit consts ([#5089](https://github.com/rust-lang/libc/pull/5089)) +- Solarish: Add `port_alert` and `PORT_ALERT*` constants ([#5203](https://github.com/rust-lang/libc/pull/5203)) +- Solarish: add AI_CANONNAME ([#5085](https://github.com/rust-lang/libc/pull/5085)) +- aarch64: Add SYS_sendfile and SYS_fadvise64 constants ([#5133](https://github.com/rust-lang/libc/pull/5133)) + +### Deprecated + +- Dragonfly: Deprecate compatibility aliases `CPUCTL_RSMSR` and `UTX_DB_LASTLOG` ([#5116](https://github.com/rust-lang/libc/pull/5116)) + +### Fixed + +- **breaking** NetBSD: Correct `ts` from `*const timespec` to `*mut timespec` in _lwp_park` ([#5169](https://github.com/rust-lang/libc/pull/5169)) +- **breaking** Linux GNU: Change overflowing `PTRACE_*ET_SYSCALL_USER_DISPATCH_CONFIG` constants from `u8` to `c_uint` ([#4936](https://github.com/rust-lang/libc/pull/4936)) +- Fix the soundness bug in the representation of extern types ([#5021](https://github.com/rust-lang/libc/pull/5021)) +- Cygwin: fix `cpuset_t` typo in `CPU_ZERO` ([#5098](https://github.com/rust-lang/libc/pull/5098)) +- Dragonfly: ABI fixes including regex offsets, `ifaddrs`, pthread barriers, process sizing fields, and `mcontext` alignment ([#5116](https://github.com/rust-lang/libc/pull/5116)) +- Dragonfly: Correct values of `CPUCTL_CPUID*`, `EV_HUP`, and `EV_SYSFLAGS` ([#5116](https://github.com/rust-lang/libc/pull/5116)) +- Emscripten: fix pthread type sizes for wasm64 (MEMORY64) ([#5156](https://github.com/rust-lang/libc/pull/5156)) +- Horizon: Fix the value of `POLLOUT` ([#5090](https://github.com/rust-lang/libc/pull/5090)) +- Linux: Correct the value of `EPIOC[GS]PARAMS` with nonstandard _IOC ([#5188](https://github.com/rust-lang/libc/pull/5188)) +- Make VxWorks shims `unsafe` ([#3727](https://github.com/rust-lang/libc/pull/3727)) +- NetBSD: Correct getmntinfo to link `__getmntinfo13` ([#5251](https://github.com/rust-lang/libc/pull/5251)) +- QNX: Fix the value of `PTHREAD_MUTEX_INITIALIZER` ([#5241](https://github.com/rust-lang/libc/pull/5241)) +- QuRT: fix type and definition inaccuracies against SDK headers ([#5091](https://github.com/rust-lang/libc/pull/5091)) +- Windows: Correctly link to 32-bit time routines on 32-bit platforms ([#5059](https://github.com/rust-lang/libc/pull/5059)) +- uClibc: Fix constants accidentally removed ([#5141](https://github.com/rust-lang/libc/pull/5141)) +- uclibc: Fix build issues ([#5046](https://github.com/rust-lang/libc/pull/5046)) +- uclibc: Fix type of PRIO_PROCESS and friends ([#5046](https://github.com/rust-lang/libc/pull/5046)) + +### Changed + +- AIX, TeeOS: Drop unneeded `-> c_void` ([#5240](https://github.com/rust-lang/libc/pull/5240)) +- Apple: Change `AIO_LISTIO_MAX` to account for changes in macOS 27 ([#5253](https://github.com/rust-lang/libc/pull/5253)) +- Glibc: Update the value of `MS_NOUSER` ([#5215](https://github.com/rust-lang/libc/pull/5215)) +- L4Re: Update definitions and test infra ([#5275](https://github.com/rust-lang/libc/pull/5275)) +- Linux: Update the value of `SW_MAX` and `SW_CNT` ([#5215](https://github.com/rust-lang/libc/pull/5215)) +- MacOS: Add `swapped_count` to `vm_statistics64` ([#4926](https://github.com/rust-lang/libc/pull/4926)) +- Windows: Windows-GNU now respects `libc_unstable_gnu_time_bits` for 64-bit `time_t` config ([#5062](https://github.com/rust-lang/libc/pull/5062)) + +### Removed + +- Dragonfly: Remove FreeBSD-only `Elf32_Lword`, `ip_mreq_source`, and `IP_` constants ([#5116](https://github.com/rust-lang/libc/pull/5116)) +- Dragonfly: Remove private VM type bindings ([#5116](https://github.com/rust-lang/libc/pull/5116)) +- Linux: Remove `KERN_REALROOTDEV` and `VM_LAPTOP_MODE` ([#5177](https://github.com/rust-lang/libc/pull/5177)) +- VxWorks: Remove non-user-facing (kernel) API ([#5129](https://github.com/rust-lang/libc/pull/5129)) + +### Other + +- Print config information if `LIBC_BUILD_VERBOSE` is set ([#5272](https://github.com/rust-lang/libc/pull/5272)) +- Annotate `*LAST` constants as potentially changing ([#5120](https://github.com/rust-lang/libc/pull/5120)) +- Annotate `*MAX` constants as potentially changing ([#5122](https://github.com/rust-lang/libc/pull/5122)) +- BSD: Annotate `ELAST` constants as potentially changing ([#5118](https://github.com/rust-lang/libc/pull/5118)) +- FreeBSD: Annotate `RAND_MAX` as potentially changing ([#5119](https://github.com/rust-lang/libc/pull/5119)) +- Linux, L4re: Annotate `*NUM` constants as potentially changing ([#5123](https://github.com/rust-lang/libc/pull/5123)) +- QNX: Restructure to support new platforms ([#4984](https://github.com/rust-lang/libc/pull/4984)) +- Unix: Annotate `*COUNT` constants as potentially changing ([#5121](https://github.com/rust-lang/libc/pull/5121)) +- uClibc: Add unstable support of 64-bit `time_t` ([#5046](https://github.com/rust-lang/libc/pull/5046)) +- (internal) FreeBSD: Replace unstable env to set version with an unstable cfg ([#5201](https://github.com/rust-lang/libc/pull/5201)) +- (internal) Glibc: Remove public configuration for file offset bits ([#5268](https://github.com/rust-lang/libc/pull/5268)) +- (internal) Linux: Delete config via `RUST_LIBC_UNSTABLE_LINUX_TIME_BITS64` ([#5197](https://github.com/rust-lang/libc/pull/5197)) +- (internal) Replace `RUST_LIBC_UNSTABLE` env with `libc_unstable*` cfg ([#4977](https://github.com/rust-lang/libc/pull/4977)) + + +## [0.2.186](https://github.com/rust-lang/libc/compare/0.2.185...0.2.186) - 2026-04-24 + +### Added + +- Apple: Add `KEVENT_FLAG_*` constants ([#5070](https://github.com/rust-lang/libc/pull/5070)) +- Linux: Add `PR_SET_MEMORY_MERGE` and `PR_GET_MEMORY_MERGE` ([#5060](https://github.com/rust-lang/libc/pull/5060)) + +### Changed + +- CI: Migrate FreeBSD CI from Cirrus CI to GitHub Actions ([#5058](https://github.com/rust-lang/libc/pull/5058)) + +## [0.2.185](https://github.com/rust-lang/libc/compare/0.2.184...0.2.185) - 2026-04-13 + +### Added + +- EspIDF: Add `espidf_picolibc` cfg for picolibc `O_*` flag values ([#5035](https://github.com/rust-lang/libc/pull/5035)) +- Hexagon: add missing constants and fix types for linux-musl ([#5042](https://github.com/rust-lang/libc/pull/5042)) +- Redox: Add semaphore functions ([#5051](https://github.com/rust-lang/libc/pull/5051)) +- Windows: Add `sprintf`, `snprintf`, and the `scanf` family ([#5024](https://github.com/rust-lang/libc/pull/5024)) + +### Fixed + +- Hexagon: Decouple `time64` types from musl symbol redirects ([#5040](https://github.com/rust-lang/libc/pull/5040)) +- Horizon: Change `POLL` constants from `c_short` to `c_int` ([#5045](https://github.com/rust-lang/libc/pull/5045)) + + +## [0.2.184](https://github.com/rust-lang/libc/compare/0.2.183...0.2.184) - 2026-04-01 + +### MSRV + +This release increases the MSRV of `libc` to 1.65. With this update, you can now always use the +`core::ffi::c_*` types with `libc` definitions, since `libc` has been changed to reexport from +`core` rather than redefining them. (This _usually_ worked before but had edge cases.) +([#4972](https://github.com/rust-lang/libc/pull/4972)) + +### Added + +- BSD: Add `IP_MINTTL` to bsd ([#5026](https://github.com/rust-lang/libc/pull/5026)) +- Cygwin: Add `TIOCM_DSR` ([#5031](https://github.com/rust-lang/libc/pull/5031)) +- FreeBSD: Added `xfile` structe and file descriptor types ([#5002](https://github.com/rust-lang/libc/pull/5002)) +- Linux: Add CAN netlink bindings ([#5011](https://github.com/rust-lang/libc/pull/5011)) +- Linux: Add `struct ethhdr` ([#4239](https://github.com/rust-lang/libc/pull/4239)) +- Linux: Add `struct ifinfomsg` ([#5012](https://github.com/rust-lang/libc/pull/5012)) +- Linux: Define `max_align_t` for riscv64 ([#5029](https://github.com/rust-lang/libc/pull/5029)) +- NetBSD: Add missing `CLOCK_` constants ([#5020](https://github.com/rust-lang/libc/pull/5020)) +- NuttX: Add `_SC_HOST_NAME_MAX` ([#5004](https://github.com/rust-lang/libc/pull/5004)) +- VxWorks: Add `flock` and `F_*LCK` constants ([#4043](https://github.com/rust-lang/libc/pull/4043)) +- WASI: Add all `_SC_*` sysconf constants ([#5023](https://github.com/rust-lang/libc/pull/5023)) + +### Deprecated + +The remaining fixed-width integer aliases, `__uint128_t`, `__uint128`, `__int128_t`, and `__int128`, +have been deprecated. Use `i128` and `u128` instead. ([#4343](https://github.com/rust-lang/libc/pull/4343)) + +### Fixed + +- **breaking** Redox: Fix signal action constant types ([#5009](https://github.com/rust-lang/libc/pull/5009)) +- EspIDF: Correct the value of `DT_*` constants ([#5034](https://github.com/rust-lang/libc/pull/5034)) +- Redox: Fix locale values and add `RTLD_NOLOAD`, some TCP constants ([#5025](https://github.com/rust-lang/libc/pull/5025)) +- Various: Use `Padding::new()` rather than `Padding::uninit()` ([#5036](https://github.com/rust-lang/libc/pull/5036)) + +### Changed + +- **potentially breaking** Linux: Add new fields to `struct ptrace_syscall_info` ([#4966](https://github.com/rust-lang/libc/pull/4966)) +- Re-export `core::ffi` integer types rather than redefining ([#5015](https://github.com/rust-lang/libc/pull/5015)) +- Redox: Update `F_DUPFD`, `IP`, and `TCP` constants to match relibc ([#4990](https://github.com/rust-lang/libc/pull/4990)) + + + +## [0.2.183](https://github.com/rust-lang/libc/compare/0.2.182...0.2.183) - 2026-03-08 + +### Added + +- ESP-IDF: Add `SOMAXCONN` ([#4993](https://github.com/rust-lang/libc/pull/4993)) +- Linux: Add `name_to_handle_at` and `open_by_handle_at` ([#4988](https://github.com/rust-lang/libc/pull/4988)) +- NetBSD: Add `kinfo_file`, `kinfo_pcb`, and related constants ([#4985](https://github.com/rust-lang/libc/pull/4985)) +- OpenBSD: Add `kinfo_file` and related constants ([#4991](https://github.com/rust-lang/libc/pull/4991)) +- VxWorks: Add additional structs and defines ([#5003](https://github.com/rust-lang/libc/pull/5003)) +- Various: Implement `Default` for `timeval` and `timespec` ([#4976](https://github.com/rust-lang/libc/pull/4976)) + +### Fixed + +- Hexagon musl: Enable unstable 64-bit `time_t` support and `musl_v1_2_3` ([#4992](https://github.com/rust-lang/libc/pull/4992)) +- Nintendo Switch: Fix target support ([#4982](https://github.com/rust-lang/libc/pull/4982)) +- OpenBSD: Wrap an unused field in `Padding` ([#4997](https://github.com/rust-lang/libc/pull/4997)) +- Redox: Change `sigaction.sa_flags` to `c_int` ([#4986](https://github.com/rust-lang/libc/pull/4986)) +- Redox: Fix `blkcnt_t` type ([#4994](https://github.com/rust-lang/libc/pull/4994)) + +## [0.2.182](https://github.com/rust-lang/libc/compare/0.2.181...0.2.182) - 2026-02-13 + +### Added + +- Android, Linux: Add `tgkill` ([#4970](https://github.com/rust-lang/libc/pull/4970)) +- Redox: Add `RENAME_NOREPLACE` ([#4968](https://github.com/rust-lang/libc/pull/4968)) +- Redox: Add `renameat2` ([#4968](https://github.com/rust-lang/libc/pull/4968)) + + +## [0.2.181](https://github.com/rust-lang/libc/compare/0.2.180...0.2.181) - 2026-02-09 + +### Added + +- Apple: Add `MADV_ZERO` ([#4924](https://github.com/rust-lang/libc/pull/4924)) +- Redox: Add `makedev`, `major`, and `minor` ([#4928](https://github.com/rust-lang/libc/pull/4928)) +- GLibc: Add `PTRACE_SET_SYSCALL_INFO` ([#4933](https://github.com/rust-lang/libc/pull/4933)) +- OpenBSD: Add more kqueue related constants for ([#4945](https://github.com/rust-lang/libc/pull/4945)) +- Linux: add CAN error types ([#4944](https://github.com/rust-lang/libc/pull/4944)) +- OpenBSD: Add siginfo_t::si_status ([#4946](https://github.com/rust-lang/libc/pull/4946)) +- QNX NTO: Add `max_align_t` ([#4927](https://github.com/rust-lang/libc/pull/4927)) +- Illumos: Add `_CS_PATH` ([#4956](https://github.com/rust-lang/libc/pull/4956)) +- OpenBSD: add `ppoll` ([#4957](https://github.com/rust-lang/libc/pull/4957)) + +### Fixed + +- **breaking**: Redox: Fix the type of dev_t ([#4928](https://github.com/rust-lang/libc/pull/4928)) +- AIX: Change 'tv_nsec' of 'struct timespec' to type 'c_long' ([#4931](https://github.com/rust-lang/libc/pull/4931)) +- AIX: Use 'struct st_timespec' in 'struct stat{,64}' ([#4931](https://github.com/rust-lang/libc/pull/4931)) +- Glibc: Link old version of `tc{g,s}etattr` ([#4938](https://github.com/rust-lang/libc/pull/4938)) +- Glibc: Link the correct version of `cf{g,s}et{i,o}speed` on mips{32,64}r6 ([#4938](https://github.com/rust-lang/libc/pull/4938)) +- OpenBSD: Fix constness of tm.tm_zone ([#4948](https://github.com/rust-lang/libc/pull/4948)) +- OpenBSD: Fix the definition of `ptrace_thread_state` ([#4947](https://github.com/rust-lang/libc/pull/4947)) +- QuRT: Fix type visibility and defs ([#4932](https://github.com/rust-lang/libc/pull/4932)) +- Redox: Fix values for `PTHREAD_MUTEX_{NORMAL, RECURSIVE}` ([#4943](https://github.com/rust-lang/libc/pull/4943)) +- Various: Mark additional fields as private padding ([#4922](https://github.com/rust-lang/libc/pull/4922)) + +### Changed + +- Fuchsia: Update `SO_*` constants ([#4937](https://github.com/rust-lang/libc/pull/4937)) +- Revert "musl: convert inline timespecs to timespec" (resolves build issues on targets only supported by Musl 1.2.3+ ) ([#4958](https://github.com/rust-lang/libc/pull/4958)) + + +## [0.2.180](https://github.com/rust-lang/libc/compare/0.2.179...0.2.180) - 2026-01-08 + +### Added + +- QNX: Add missing BPF and ifreq structures ([#4769](https://github.com/rust-lang/libc/pull/4769)) + +### Fixed + +- Linux, L4Re: address soundness issues of `CMSG_NXTHDR` ([#4903](https://github.com/rust-lang/libc/pull/4903)) +- Linux-like: Handle zero-sized payload differences in `CMSG_NXTHDR` ([#4903](https://github.com/rust-lang/libc/pull/4903)) +- Musl: Fix incorrect definitions of struct stat on some 32-bit architectures ([#4914](https://github.com/rust-lang/libc/pull/4914)) +- NetBSD: RISC-V 64: Correct `mcontext` type definitions ([#4886](https://github.com/rust-lang/libc/pull/4886)) +- uClibc: Re-enable `__SIZEOF_PTHREAD_COND_T` on non-L4Re uclibc ([#4915](https://github.com/rust-lang/libc/pull/4915)) +- uClibc: Restructure Linux `netlink` module to resolve build errors ([#4915](https://github.com/rust-lang/libc/pull/4915)) + + +## [0.2.179](https://github.com/rust-lang/libc/compare/0.2.178...0.2.179) - 2025-01-03 + +With this release, we now have _unstable_ support for 64-bit `time_t` on 32-bit +platforms with both Musl and Glibc. Testing is appreciated! + +For now, these can be enabled by setting environment variables during build: + +```text +RUST_LIBC_UNSTABLE_MUSL_V1_2_3=1 +RUST_LIBC_UNSTABLE_GNU_TIME_BITS=64 +``` + +Note that the exact configuration will change in the future. Setting the +`MUSL_V1_2_3` variable also enables some newer API unrelated to `time_t`. + +### Added + +- L4Re: Add uclibc aarch64 support ([#4479](https://github.com/rust-lang/libc/pull/4479)) +- Linux, Android: Add a generic definition for `XCASE` ([#4847](https://github.com/rust-lang/libc/pull/4847)) +- Linux-like: Add `NAME_MAX` ([#4888](https://github.com/rust-lang/libc/pull/4888)) +- Linux: Add `AT_EXECVE_CHECK` ([#4422](https://github.com/rust-lang/libc/pull/4422)) +- Linux: Add the `SUN_LEN` macro ([#4269](https://github.com/rust-lang/libc/pull/4269)) +- Linux: add `getitimer` and `setitimer` ([#4890](https://github.com/rust-lang/libc/pull/4890)) +- Linux: add `pthread_tryjoin_n` and `pthread_timedjoin_np` ([#4887](https://github.com/rust-lang/libc/pull/4887)) +- Musl: Add unstable support for 64-bit `time_t` on 32-bit platforms ([#4463](https://github.com/rust-lang/libc/pull/4463)) +- NetBSD, OpenBSD: Add interface `LINK_STATE_*` definitions from `sys/net/if.h` ([#4751](https://github.com/rust-lang/libc/pull/4751)) +- QuRT: Add support for Qualcomm QuRT ([#4845](https://github.com/rust-lang/libc/pull/4845)) +- Types: Add Padding::uninit() ([#4862](https://github.com/rust-lang/libc/pull/4862)) + +### Fixed + +- Glibc: Link old version of `cf{g,s}et{i,o}speed` ([#4882](https://github.com/rust-lang/libc/pull/4882)) +- L4Re: Fixes for `pthread` ([#4479](https://github.com/rust-lang/libc/pull/4479)) +- L4re: Fix a wide variety of incorrect definitions ([#4479](https://github.com/rust-lang/libc/pull/4479)) +- Musl: Fix the value of `CPU_SETSIZE` on musl 1.2+ ([#4865](https://github.com/rust-lang/libc/pull/4865)) +- Musl: RISC-V: fix public padding fields in `stat/stat64` ([#4463](https://github.com/rust-lang/libc/pull/4463)) +- Musl: s390x: Fix definition of `SIGSTKSZ`/`MINSIGSTKSZ` ([#4884](https://github.com/rust-lang/libc/pull/4884)) +- NetBSD: Arm: Fix `PT_{GET,SET}FPREGS`, `_REG_TIPDR`, and `_REG_{LR,SP}` ([#4899](https://github.com/rust-lang/libc/pull/4899)) +- NetBSD: Fix `if_msghdr` alignment ([#4902](https://github.com/rust-lang/libc/pull/4902)) +- NetBSD: Fix `siginfo_t` layout on 32-bit platforms ([#4904](https://github.com/rust-lang/libc/pull/4904)) +- NetBSD: change definition of `pthread_spin_t` to allow arch redefinition. ([#4899](https://github.com/rust-lang/libc/pull/4899)) +- Newlib: Fix ambiguous glob exports and other warnings for Vita and 3DS ([#4875](https://github.com/rust-lang/libc/pull/4875)) +- QNX: Fix build error ([#4879](https://github.com/rust-lang/libc/pull/4879)) + +### Changed + +- CI: Update CI images to FreeBSD 15.0-release ([#4857](https://github.com/rust-lang/libc/pull/4857)) +- L4Re: Make `pthread` struct fields private ([#4876](https://github.com/rust-lang/libc/pull/4876)) +- Linux, Fuchsia: Mark mq_attr padding area as such ([#4858](https://github.com/rust-lang/libc/pull/4858)) +- Types: Wrap a number of private fields in the `Padding` type ([#4862](https://github.com/rust-lang/libc/pull/4862)) + +### Removed + +- Build: Remove `RUST_LIBC_UNSTABLE_LINUX_TIME_BITS64` ([#4865](https://github.com/rust-lang/libc/pull/4865)) +- WASI: Remove nonexistent clocks ([#4880](https://github.com/rust-lang/libc/pull/4880)) + + +## [0.2.178](https://github.com/rust-lang/libc/compare/0.2.177...0.2.178) - 2025-12-01 + +### Added + +- BSD: Add `issetugid` ([#4744](https://github.com/rust-lang/libc/pull/4744)) +- Cygwin: Add missing utmp/x.h, grp.h, and stdio.h interfaces ([#4827](https://github.com/rust-lang/libc/pull/4827)) +- Linux s390x musl: Add `__psw_t`/`fprefset_t`/`*context_t` ([#4726](https://github.com/rust-lang/libc/pull/4726)) +- Linux, Android: Add definition for IUCLC ([#4846](https://github.com/rust-lang/libc/pull/4846)) +- Linux, FreeBSD: Add `AT_HWCAP{3,4}` ([#4734](https://github.com/rust-lang/libc/pull/4734)) +- Linux: Add definitions from linux/can/bcm.h ([#4683](https://github.com/rust-lang/libc/pull/4683)) +- Linux: Add syscalls 451-469 for m68k ([#4850](https://github.com/rust-lang/libc/pull/4850)) +- Linux: PowerPC: Add 'ucontext.h' definitions ([#4696](https://github.com/rust-lang/libc/pull/4696)) +- NetBSD: Define `eventfd` ([#4830](https://github.com/rust-lang/libc/pull/4830)) +- Newlib: Add missing constants from `unistd.h` ([#4811](https://github.com/rust-lang/libc/pull/4811)) +- QNX NTO: Add `cfmakeraw` ([#4704](https://github.com/rust-lang/libc/pull/4704)) +- QNX NTO: Add `cfsetspeed` ([#4704](https://github.com/rust-lang/libc/pull/4704)) +- Redox: Add `getresgid` and `getresuid` ([#4752](https://github.com/rust-lang/libc/pull/4752)) +- Redox: Add `setresgid` and `setresuid` ([#4752](https://github.com/rust-lang/libc/pull/4752)) +- VxWorks: Add definitions from `select.h`, `stat.h`, `poll.h`, `ttycom.h`, `utsname.h`, `resource.h`, `mman.h`, `udp.h`, `in.h`, `in6.h`, `if.h`, `fnmatch.h`, and `sioLibCommon.h` ([#4781](https://github.com/rust-lang/libc/pull/4781)) +- VxWorks: Add missing defines/functions needed by rust stdlib ([#4779](https://github.com/rust-lang/libc/pull/4779)) +- WASI: Add more definitions for libstd ([#4747](https://github.com/rust-lang/libc/pull/4747)) + +### Deprecated + +- Apple: Deprecate `TIOCREMOTE` ([#4764](https://github.com/rust-lang/libc/pull/4764)) + +### Fixed + +Note that there were a large number of fixes on NetBSD for this `libc` release, some of which include minor breakage. + +- AIX: Change errno `EWOULDBLOCK` to make it an alias of `EAGAIN` ([#4790](https://github.com/rust-lang/libc/pull/4790)) +- AIX: Resolve function comparison and `unnecessary_transmutes` warnings ([#4780](https://github.com/rust-lang/libc/pull/4780)) +- Apple: Correct the value of `SF_SETTABLE` ([#4764](https://github.com/rust-lang/libc/pull/4764)) +- DragonflyBSD: Fix the type of `mcontext_t.mc_fpregs` ([#]()) +- EspIDF: Fix the duplicate definition of `gethostname` ([#4773](https://github.com/rust-lang/libc/pull/4773)) +- L4Re: Update available pthread API ([#4836](https://github.com/rust-lang/libc/pull/4836)) +- Linux: Correct the value of `NFT_MSG_MAX` ([#4761](https://github.com/rust-lang/libc/pull/4761)) +- Linux: Remove incorrect `repr(align(8))` for `canxl_frame` ([#4760](https://github.com/rust-lang/libc/pull/4760)) +- Make `eventfd` argument names match OS docs/headers ([#4830](https://github.com/rust-lang/libc/pull/4830)) +- NetBSD: Account for upstream changes to ptrace with LWP ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Correct `ipc_perm`, split from OpenBSD as `ipc.rs` ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Correct a number of symbol link names ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Correct the type of `kinfo_vmentry.kve_path` ([#]()) +- NetBSD: Fix `uucred.cr_ngroups` from `int` to `short` ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Fix the type of `kevent.udata` ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Fix the type of `mcontext_t.__fpregs` ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Fix the value of `PT_SUSPEND` ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Fix the values of FNM_* constants ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Increase the size of `sockaddr_dl.sdl_data` from 12 to 24 ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Introduce `if_.rs`, fix the definition of `ifreq` ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Introduce `time.rs`, fix the values of `CLOCK_*_CPUTIME_ID` ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Introduce `timex.rs` ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Introduce `types.rs`, correct the definition of `lwpid_t` ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Introduce `utmp_.rs`, correct the definition of `lastlog` ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Introduce `utmpx_.rs`, correct utmpx definitions ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Make `_cpuset` an extern type ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: RISC-V 64: Fix the `mcontext` types ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- Nuttx: Resolve warnings ([#4773](https://github.com/rust-lang/libc/pull/4773)) +- OHOS: Don't emit duplicate lfs64 definitions ([#4804](https://github.com/rust-lang/libc/pull/4804)) +- Redox: Fix the type of `pid_t` ([#4825](https://github.com/rust-lang/libc/pull/4825)) +- WASI: Gate `__wasilibc_register_preopened_fd` ([#4837](https://github.com/rust-lang/libc/pull/4837)) +- Wali: Fix unknown config ([#4773](https://github.com/rust-lang/libc/pull/4773)) + +### Changed + +- AIX: Declare field 'tv_nsec' of structure 'timespec' as 'i32' in both 32-bit and 64-bit modes ([#4750](https://github.com/rust-lang/libc/pull/4750)) +- DragonFly: Avoid usage of `thread_local` ([#3653](https://github.com/rust-lang/libc/pull/3653)) +- Linux: Update the definition for `ucontext_t` and unskip its tests ([#4760](https://github.com/rust-lang/libc/pull/4760)) +- MinGW: Set `L_tmpnam` and `TMP_MAX` to the UCRT value ([#4566](https://github.com/rust-lang/libc/pull/4566)) +- WASI: More closely align pthread type reprs ([#4747](https://github.com/rust-lang/libc/pull/4747)) +- Simplify rustc-check-cfg emission in build.rs ([#4724](https://github.com/rust-lang/libc/pull/4724)) +- Transition a number of definitions to the new source structure (internal change) + +### Removed + +- MIPS Musl: Remove rogue definition of `SIGSTKFLT` ([#4749](https://github.com/rust-lang/libc/pull/4749)) +- NetBSD: Make `statvfs.f_spare` non-public ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Remove BPF constants ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Remove `*_MAXID` constants and `AT_SUN_LDPGSIZE` ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Remove `IFF_NOTRAILERS` ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Remove `vm_size_t` ([#4782](https://github.com/rust-lang/libc/pull/4782)) +- NetBSD: Replace REG_ENOSYS with REG_ILLSEQ ([#4782](https://github.com/rust-lang/libc/pull/4782)) + + +## [0.2.177](https://github.com/rust-lang/libc/compare/0.2.176...0.2.177) - 2025-10-09 + +### Added + +- Apple: Add `TIOCGETA`, `TIOCSETA`, `TIOCSETAW`, `TIOCSETAF` constants ([#4736](https://github.com/rust-lang/libc/pull/4736)) +- Apple: Add `pthread_cond_timedwait_relative_np` ([#4719](https://github.com/rust-lang/libc/pull/4719)) +- BSDs: Add `_CS_PATH` constant ([#4738](https://github.com/rust-lang/libc/pull/4738)) +- Linux-like: Add `SIGEMT` for mips* and sparc* architectures ([#4730](https://github.com/rust-lang/libc/pull/4730)) +- OpenBSD: Add `elf_aux_info` ([#4729](https://github.com/rust-lang/libc/pull/4729)) +- Redox: Add more sysconf constants ([#4728](https://github.com/rust-lang/libc/pull/4728)) +- Windows: Add `wcsnlen` ([#4721](https://github.com/rust-lang/libc/pull/4721)) + +### Changed + +- WASIP2: Invert conditional to include p2 APIs ([#4733](https://github.com/rust-lang/libc/pull/4733)) + +## [0.2.176](https://github.com/rust-lang/libc/compare/0.2.175...0.2.176) - 2025-09-23 + +### Support + +- The default FreeBSD version has been raised from 11 to 12. This matches `rustc` since 1.78. ([#2406](https://github.com/rust-lang/libc/pull/2406)) +- `Debug` is now always implemented, rather than being gated behind the `extra_traits` feature. ([#4624](https://github.com/rust-lang/libc/pull/4624)) + +### Added + +- AIX: Restore some non-POSIX functions guarded by the `_KERNEL` macro. ([#4607](https://github.com/rust-lang/libc/pull/4607)) +- FreeBSD 14: Add `st_fileref` to `struct stat` ([#4642](https://github.com/rust-lang/libc/pull/4642)) +- Haiku: Add the `accept4` POSIX call ([#4586](https://github.com/rust-lang/libc/pull/4586)) +- Introduce a wrapper for representing padding ([#4632](https://github.com/rust-lang/libc/pull/4632)) +- Linux: Add `EM_RISCV` ([#4659](https://github.com/rust-lang/libc/pull/4659)) +- Linux: Add `MS_NOSYMFOLLOW` ([#4389](https://github.com/rust-lang/libc/pull/4389)) +- Linux: Add `backtrace_symbols(_fd)` ([#4668](https://github.com/rust-lang/libc/pull/4668)) +- Linux: Add missing `SOL_PACKET` optnames ([#4669](https://github.com/rust-lang/libc/pull/4669)) +- Musl s390x: Add `SYS_mseal` ([#4549](https://github.com/rust-lang/libc/pull/4549)) +- NuttX: Add `__errno` ([#4687](https://github.com/rust-lang/libc/pull/4687)) +- Redox: Add `dirfd`, `VDISABLE`, and resource consts ([#4660](https://github.com/rust-lang/libc/pull/4660)) +- Redox: Add more `resource.h`, `fcntl.h` constants ([#4666](https://github.com/rust-lang/libc/pull/4666)) +- Redox: Enable `strftime` and `mkostemp[s]` ([#4629](https://github.com/rust-lang/libc/pull/4629)) +- Unix, Windows: Add `qsort_r` (Unix), and `qsort(_s)` (Windows) ([#4677](https://github.com/rust-lang/libc/pull/4677)) +- Unix: Add `dlvsym` for Linux-gnu, FreeBSD, and NetBSD ([#4671](https://github.com/rust-lang/libc/pull/4671)) +- Unix: Add `sigqueue` ([#4620](https://github.com/rust-lang/libc/pull/4620)) + +### Changed + +- FreeBSD 15: Mark `kinfo_proc` as non-exhaustive ([#4553](https://github.com/rust-lang/libc/pull/4553)) +- FreeBSD: Set the ELF symbol version for `readdir_r` ([#4694](https://github.com/rust-lang/libc/pull/4694)) +- Linux: Correct the config for whether or not `epoll_event` is packed ([#4639](https://github.com/rust-lang/libc/pull/4639)) +- Tests: Replace the old `ctest` with the much more reliable new implementation ([#4655](https://github.com/rust-lang/libc/pull/4655) and many related PRs) + +### Fixed + +- AIX: Fix the type of the 4th arguement of `getgrnam_r` ([#4656](https://github.com/rust-lang/libc/pull/4656 +- FreeBSD: Limit `P_IDLEPROC` to FreeBSD 15 ([#4640](https://github.com/rust-lang/libc/pull/4640)) +- FreeBSD: Limit `mcontext_t::mc_tlsbase` to FreeBSD 15 ([#4640](https://github.com/rust-lang/libc/pull/464)) +- FreeBSD: Update gating of `mcontext_t.mc_tlsbase` ([#4703](https://github.com/rust-lang/libc/pull/4703)) +- Musl s390x: Correct the definition of `statfs[64]` ([#4549](https://github.com/rust-lang/libc/pull/4549)) +- Musl s390x: Make `fpreg_t` a union ([#4549](https://github.com/rust-lang/libc/pull/4549)) +- Redox: Fix the types of `gid_t` and `uid_t` ([#4689](https://github.com/rust-lang/libc/pull/4689)) +- Redox: Fix the value of `MAP_FIXED` ([#4684](https://github.com/rust-lang/libc/pull/4684)) + +### Deprecated + +- Apple: Correct the `deprecated` attribute for `iconv` ([`a97a0b53`](https://github.com/rust-lang/libc/commit/a97a0b53fb7faf5f99cd720ab12b1b8a5bf9f950)) +- FreeBSD: Deprecate `TIOCMGDTRWAIT` and `TIOCMSDTRWAIT` ([#4685](https://github.com/rust-lang/libc/pull/4685)) + +### Removed + +- FreeBSD: Remove `JAIL_{GET,SET}_MASK`, `_MC_FLAG_MASK` ([#4691](https://github.com/rust-lang/libc/pull/4691)) + +## [0.2.175](https://github.com/rust-lang/libc/compare/0.2.174...0.2.175) - 2025-08-10 + +### Added + +- AIX: Add `getpeereid` ([#4524](https://github.com/rust-lang/libc/pull/4524)) +- AIX: Add `struct ld_info` and friends ([#4578](https://github.com/rust-lang/libc/pull/4578)) +- AIX: Retore `struct winsize` ([#4577](https://github.com/rust-lang/libc/pull/4577)) +- Android: Add UDP socket option constants ([#4619](https://github.com/rust-lang/libc/pull/4619)) +- Android: Add `CLONE_CLEAR_SIGHAND` and `CLONE_INTO_CGROUP` ([#4502](https://github.com/rust-lang/libc/pull/4502)) +- Android: Add more `prctl` constants ([#4531](https://github.com/rust-lang/libc/pull/4531)) +- FreeBSD Add further TCP stack-related constants ([#4196](https://github.com/rust-lang/libc/pull/4196)) +- FreeBSD x86-64: Add `mcontext_t.mc_tlsbase ` ([#4503](https://github.com/rust-lang/libc/pull/4503)) +- FreeBSD15: Add `kinfo_proc.ki_uerrmsg` ([#4552](https://github.com/rust-lang/libc/pull/4552)) +- FreeBSD: Add `in_conninfo` ([#4482](https://github.com/rust-lang/libc/pull/4482)) +- FreeBSD: Add `xinpgen` and related types ([#4482](https://github.com/rust-lang/libc/pull/4482)) +- FreeBSD: Add `xktls_session` ([#4482](https://github.com/rust-lang/libc/pull/4482)) +- Haiku: Add functionality from `libbsd` ([#4221](https://github.com/rust-lang/libc/pull/4221)) +- Linux: Add `SECBIT_*` ([#4480](https://github.com/rust-lang/libc/pull/4480)) +- NetBSD, OpenBSD: Export `ioctl` request generator macros ([#4460](https://github.com/rust-lang/libc/pull/4460)) +- NetBSD: Add `ptsname_r` ([#4608](https://github.com/rust-lang/libc/pull/4608)) +- RISCV32: Add time-related syscalls ([#4612](https://github.com/rust-lang/libc/pull/4612)) +- Solarish: Add `strftime*` ([#4453](https://github.com/rust-lang/libc/pull/4453)) +- linux: Add `EXEC_RESTRICT_*` and `EXEC_DENY_*` ([#4545](https://github.com/rust-lang/libc/pull/4545)) + +### Changed + +- AIX: Add `const` to signatures to be consistent with other platforms ([#4563](https://github.com/rust-lang/libc/pull/4563)) + +### Fixed + +- AIX: Fix the type of `struct statvfs.f_fsid` ([#4576](https://github.com/rust-lang/libc/pull/4576)) +- AIX: Fix the type of constants for the `ioctl` `request` argument ([#4582](https://github.com/rust-lang/libc/pull/4582)) +- AIX: Fix the types of `stat{,64}.st_*tim` ([#4597](https://github.com/rust-lang/libc/pull/4597)) +- AIX: Use unique `errno` values ([#4507](https://github.com/rust-lang/libc/pull/4507)) +- Build: Fix an incorrect `target_os` -> `target_arch` check ([#4550](https://github.com/rust-lang/libc/pull/4550)) +- FreeBSD: Fix the type of `xktls_session_onedir.ifnet` ([#4552](https://github.com/rust-lang/libc/pull/4552)) +- Mips64 musl: Fix the type of `nlink_t` ([#4509](https://github.com/rust-lang/libc/pull/4509)) +- Mips64 musl: Use a special MIPS definition of `stack_t` ([#4528](https://github.com/rust-lang/libc/pull/4528)) +- Mips64: Fix `SI_TIMER`, `SI_MESGQ` and `SI_ASYNCIO` definitions ([#4529](https://github.com/rust-lang/libc/pull/4529)) +- Musl Mips64: Swap the order of `si_errno` and `si_code` in `siginfo_t` ([#4530](https://github.com/rust-lang/libc/pull/4530)) +- Musl Mips64: Use a special MIPS definition of `statfs` ([#4527](https://github.com/rust-lang/libc/pull/4527)) +- Musl: Fix the definition of `fanotify_event_metadata` ([#4510](https://github.com/rust-lang/libc/pull/4510)) +- NetBSD: Correct `enum fae_action` to be `#[repr(C)]` ([#60a8cfd5](https://github.com/rust-lang/libc/commit/60a8cfd564f83164d45b9533ff7a0d7371878f2a)) +- PSP: Correct `char` -> `c_char` ([eaab4fc3](https://github.com/rust-lang/libc/commit/eaab4fc3f05dc646a953d4fd5ba46dfa1f8bd6f6)) +- PowerPC musl: Fix `termios` definitions ([#4518](https://github.com/rust-lang/libc/pull/4518)) +- PowerPC musl: Fix the definition of `EDEADLK` ([#4517](https://github.com/rust-lang/libc/pull/4517)) +- PowerPC musl: Fix the definition of `NCCS` ([#4513](https://github.com/rust-lang/libc/pull/4513)) +- PowerPC musl: Fix the definitions of `MAP_LOCKED` and `MAP_NORESERVE` ([#4516](https://github.com/rust-lang/libc/pull/4516)) +- PowerPC64 musl: Fix the definition of `shmid_ds` ([#4519](https://github.com/rust-lang/libc/pull/4519)) + +### Deprecated + +- Linux: `MAP_32BIT` is only defined on x86 on non-x86 architectures ([#4511](https://github.com/rust-lang/libc/pull/4511)) + +### Removed + +- AIX: Remove duplicate constant definitions `FIND` and `ENTER` ([#4588](https://github.com/rust-lang/libc/pull/4588)) +- s390x musl: Remove `O_FSYNC` ([#4515](https://github.com/rust-lang/libc/pull/4515)) +- s390x musl: Remove `RTLD_DEEPBIND` ([#4515](https://github.com/rust-lang/libc/pull/4515)) + + +## [0.2.174](https://github.com/rust-lang/libc/compare/0.2.173...0.2.174) - 2025-06-17 + +### Added + +- Linux: Make `pidfd_info` fields pub ([#4487](https://github.com/rust-lang/libc/pull/4487)) + +### Fixed + +- Gnu x32: Add missing `timespec.tv_nsec` ([#4497](https://github.com/rust-lang/libc/pull/4497)) +- NuttX: Use `nlink_t` type for `st_nlink` in `struct stat` definition ([#4483](https://github.com/rust-lang/libc/pull/4483)) + +### Other + +- Allow new `unpredictable_function_pointer_comparisons` lints ([#4489](https://github.com/rust-lang/libc/pull/4489)) +- OpenBSD: Fix some clippy warnings to use `pointer::cast`. ([#4490](https://github.com/rust-lang/libc/pull/4490)) +- Remove unessecary semicolons from definitions of `CMSG_NXTHDR`. ([#4492](https://github.com/rust-lang/libc/pull/4492)) + + +## [0.2.173](https://github.com/rust-lang/libc/compare/0.2.172...0.2.173) - 2025-06-09 + +### Added + +- AIX: Add an AIX triple to Cargo.toml for doc ([#4475](https://github.com/rust-lang/libc/pull/4475)) +- FreeBSD: Add the `SO_SPLICE` socket option support for FreeBSD >= 14.2 ([#4451](https://github.com/rust-lang/libc/pull/4451)) +- Linux GNU: Prepare for supporting `_TIME_BITS=64` ([#4433](https://github.com/rust-lang/libc/pull/4433)) +- Linux: Add constant PACKET_IGNORE_OUTGOING ([#4319](https://github.com/rust-lang/libc/pull/4319)) +- Linux: Add constants and types for `nsfs` ioctls ([#4436](https://github.com/rust-lang/libc/pull/4436)) +- Linux: Add constants for Memory-Deny-Write-Execute `prctls` ([#4400](https://github.com/rust-lang/libc/pull/4400)) +- Linux: Add constants from `linux/cn_proc.h` and `linux/connector.h` ([#4434](https://github.com/rust-lang/libc/pull/4434)) +- Linux: Add new flags for `pwritev2` and `preadv2` ([#4452](https://github.com/rust-lang/libc/pull/4452)) +- Linux: Add pid_type enum values ([#4403](https://github.com/rust-lang/libc/pull/4403)) +- Linux: Update pidfd constants and types (Linux 6.9-6.15) ([#4402](https://github.com/rust-lang/libc/pull/4402)) +- Loongarch64 musl: Define the `MADV_SOFT_OFFLINE` constant ([#4448](https://github.com/rust-lang/libc/pull/4448)) +- Musl: Add new fields since 1.2.0/1.2.2 to `struct tcp_info` ([#4443](https://github.com/rust-lang/libc/pull/4443)) +- Musl: Prepare for supporting v1.2.3 ([#4443](https://github.com/rust-lang/libc/pull/4443)) +- NuttX: Add `arc4random` and `arc4random_buf` ([#4464](https://github.com/rust-lang/libc/pull/4464)) +- RISC-V Musl: Add `MADV_SOFT_OFFLINE` definition ([#4447](https://github.com/rust-lang/libc/pull/4447)) +- Redox: Define SCM_RIGHTS ([#4440](https://github.com/rust-lang/libc/pull/4440)) +- VxWorks: Add missing UTIME defines and TASK_RENAME_LENGTH ([#4407](https://github.com/rust-lang/libc/pull/4407)) +- Windows: Add more `time.h` functions ([#4427](https://github.com/rust-lang/libc/pull/4427)) + +### Changed + +- Redox: Update `SA_` constants. ([#4426](https://github.com/rust-lang/libc/pull/4426)) +- Redox: make `CMSG_ALIGN`, `CMSG_LEN`, and `CMSG_SPACE` const functions ([#4441](https://github.com/rust-lang/libc/pull/4441)) + +### Fixed + +- AIX: Enable libc-test and fix definitions/declarations. ([#4450](https://github.com/rust-lang/libc/pull/4450)) +- Emscripten: Fix querying emcc on windows (use emcc.bat) ([#4248](https://github.com/rust-lang/libc/pull/4248)) +- Hurd: Fix build from missing `fpos_t` ([#4472](https://github.com/rust-lang/libc/pull/4472)) +- Loongarch64 Musl: Fix the `struct ipc_perm` bindings ([#4384](https://github.com/rust-lang/libc/pull/4384)) +- Musl: Fix the `O_LARGEFILE` constant value. ([#4443](https://github.com/rust-lang/libc/pull/4443)) + +## [0.2.172](https://github.com/rust-lang/libc/compare/0.2.171...0.2.172) - 2025-04-14 + +### Added + +- Android: Add `getauxval` for 32-bit targets ([#4338](https://github.com/rust-lang/libc/pull/4338)) +- Android: Add `if_tun.h` ioctls ([#4379](https://github.com/rust-lang/libc/pull/4379)) +- Android: Define `SO_BINDTOIFINDEX` ([#4391](https://github.com/rust-lang/libc/pull/4391)) +- Cygwin: Add `posix_spawn_file_actions_add[f]chdir[_np]` ([#4387](https://github.com/rust-lang/libc/pull/4387)) +- Cygwin: Add new socket options ([#4350](https://github.com/rust-lang/libc/pull/4350)) +- Cygwin: Add statfs & fcntl ([#4321](https://github.com/rust-lang/libc/pull/4321)) +- FreeBSD: Add `filedesc` and `fdescenttbl` ([#4327](https://github.com/rust-lang/libc/pull/4327)) +- Glibc: Add unstable support for _FILE_OFFSET_BITS=64 ([#4345](https://github.com/rust-lang/libc/pull/4345)) +- Hermit: Add `AF_UNSPEC` ([#4344](https://github.com/rust-lang/libc/pull/4344)) +- Hermit: Add `AF_VSOCK` ([#4344](https://github.com/rust-lang/libc/pull/4344)) +- Illumos, NetBSD: Add `timerfd` APIs ([#4333](https://github.com/rust-lang/libc/pull/4333)) +- Linux: Add `_IO`, `_IOW`, `_IOR`, `_IOWR` to the exported API ([#4325](https://github.com/rust-lang/libc/pull/4325)) +- Linux: Add `tcp_info` to uClibc bindings ([#4347](https://github.com/rust-lang/libc/pull/4347)) +- Linux: Add further BPF program flags ([#4356](https://github.com/rust-lang/libc/pull/4356)) +- Linux: Add missing INPUT_PROP_XXX flags from `input-event-codes.h` ([#4326](https://github.com/rust-lang/libc/pull/4326)) +- Linux: Add missing TLS bindings ([#4296](https://github.com/rust-lang/libc/pull/4296)) +- Linux: Add more constants from `seccomp.h` ([#4330](https://github.com/rust-lang/libc/pull/4330)) +- Linux: Add more glibc `ptrace_sud_config` and related `PTRACE_*ET_SYSCALL_USER_DISPATCH_CONFIG`. ([#4386](https://github.com/rust-lang/libc/pull/4386)) +- Linux: Add new netlink flags ([#4288](https://github.com/rust-lang/libc/pull/4288)) +- Linux: Define ioctl codes on more architectures ([#4382](https://github.com/rust-lang/libc/pull/4382)) +- Linux: Add missing `pthread_attr_setstack` ([#4349](https://github.com/rust-lang/libc/pull/4349)) +- Musl: Add missing `utmpx` API ([#4332](https://github.com/rust-lang/libc/pull/4332)) +- Musl: Enable `getrandom` on all platforms ([#4346](https://github.com/rust-lang/libc/pull/4346)) +- NuttX: Add more signal constants ([#4353](https://github.com/rust-lang/libc/pull/4353)) +- QNX: Add QNX 7.1-iosock and 8.0 to list of additional cfgs ([#4169](https://github.com/rust-lang/libc/pull/4169)) +- QNX: Add support for alternative Neutrino network stack `io-sock` ([#4169](https://github.com/rust-lang/libc/pull/4169)) +- Redox: Add more `sys/socket.h` and `sys/uio.h` definitions ([#4388](https://github.com/rust-lang/libc/pull/4388)) +- Solaris: Temporarily define `O_DIRECT` and `SIGINFO` ([#4348](https://github.com/rust-lang/libc/pull/4348)) +- Solarish: Add `secure_getenv` ([#4342](https://github.com/rust-lang/libc/pull/4342)) +- VxWorks: Add missing `d_type` member to `dirent` ([#4352](https://github.com/rust-lang/libc/pull/4352)) +- VxWorks: Add missing signal-related constsants ([#4352](https://github.com/rust-lang/libc/pull/4352)) +- VxWorks: Add more error codes ([#4337](https://github.com/rust-lang/libc/pull/4337)) + +### Deprecated + +- FreeBSD: Deprecate `TCP_PCAP_OUT` and `TCP_PCAP_IN` ([#4381](https://github.com/rust-lang/libc/pull/4381)) + +### Fixed + +- Cygwin: Fix member types of `statfs` ([#4324](https://github.com/rust-lang/libc/pull/4324)) +- Cygwin: Fix tests ([#4357](https://github.com/rust-lang/libc/pull/4357)) +- Hermit: Make `AF_INET = 3` ([#4344](https://github.com/rust-lang/libc/pull/4344)) +- Musl: Fix the syscall table on RISC-V-32 ([#4335](https://github.com/rust-lang/libc/pull/4335)) +- Musl: Fix the value of `SA_ONSTACK` on RISC-V-32 ([#4335](https://github.com/rust-lang/libc/pull/4335)) +- VxWorks: Fix a typo in the `waitpid` parameter name ([#4334](https://github.com/rust-lang/libc/pull/4334)) + +### Removed + +- Musl: Remove `O_FSYNC` on RISC-V-32 (use `O_SYNC` instead) ([#4335](https://github.com/rust-lang/libc/pull/4335)) +- Musl: Remove `RTLD_DEEPBIND` on RISC-V-32 ([#4335](https://github.com/rust-lang/libc/pull/4335)) + +### Other + +- CI: Add matrix env variables to the environment ([#4345](https://github.com/rust-lang/libc/pull/4345)) +- CI: Always deny warnings ([#4363](https://github.com/rust-lang/libc/pull/4363)) +- CI: Always upload successfully created artifacts ([#4345](https://github.com/rust-lang/libc/pull/4345)) +- CI: Install musl from source for loongarch64 ([#4320](https://github.com/rust-lang/libc/pull/4320)) +- CI: Revert "Also skip `MFD_EXEC` and `MFD_NOEXEC_SEAL` on sparc64" ([#]()) +- CI: Use `$PWD` instead of `$(pwd)` in run-docker ([#4345](https://github.com/rust-lang/libc/pull/4345)) +- Solarish: Restrict `openpty` and `forkpty` polyfills to Illumos, replace Solaris implementation with bindings ([#4329](https://github.com/rust-lang/libc/pull/4329)) +- Testing: Ensure the makedev test does not emit unused errors ([#4363](https://github.com/rust-lang/libc/pull/4363)) + +## [0.2.171](https://github.com/rust-lang/libc/compare/0.2.170...0.2.171) - 2025-03-11 + +### Added + +- Android: Add `if_nameindex`/`if_freenameindex` support ([#4247](https://github.com/rust-lang/libc/pull/4247)) +- Apple: Add missing proc types and constants ([#4310](https://github.com/rust-lang/libc/pull/4310)) +- BSD: Add `devname` ([#4285](https://github.com/rust-lang/libc/pull/4285)) +- Cygwin: Add PTY and group API ([#4309](https://github.com/rust-lang/libc/pull/4309)) +- Cygwin: Add support ([#4279](https://github.com/rust-lang/libc/pull/4279)) +- FreeBSD: Make `spawn.h` interfaces available on all FreeBSD-like systems ([#4294](https://github.com/rust-lang/libc/pull/4294)) +- Linux: Add `AF_XDP` structs for all Linux environments ([#4163](https://github.com/rust-lang/libc/pull/4163)) +- Linux: Add SysV semaphore constants ([#4286](https://github.com/rust-lang/libc/pull/4286)) +- Linux: Add `F_SEAL_EXEC` ([#4316](https://github.com/rust-lang/libc/pull/4316)) +- Linux: Add `SO_PREFER_BUSY_POLL` and `SO_BUSY_POLL_BUDGET` ([#3917](https://github.com/rust-lang/libc/pull/3917)) +- Linux: Add `devmem` structs ([#4299](https://github.com/rust-lang/libc/pull/4299)) +- Linux: Add socket constants up to `SO_DEVMEM_DONTNEED` ([#4299](https://github.com/rust-lang/libc/pull/4299)) +- NetBSD, OpenBSD, DragonflyBSD: Add `closefrom` ([#4290](https://github.com/rust-lang/libc/pull/4290)) +- NuttX: Add `pw_passwd` field to `passwd` ([#4222](https://github.com/rust-lang/libc/pull/4222)) +- Solarish: define `IP_BOUND_IF` and `IPV6_BOUND_IF` ([#4287](https://github.com/rust-lang/libc/pull/4287)) +- Wali: Add bindings for `wasm32-wali-linux-musl` target ([#4244](https://github.com/rust-lang/libc/pull/4244)) + +### Changed + +- AIX: Use `sa_sigaction` instead of a union ([#4250](https://github.com/rust-lang/libc/pull/4250)) +- Make `msqid_ds.__msg_cbytes` public ([#4301](https://github.com/rust-lang/libc/pull/4301)) +- Unix: Make all `major`, `minor`, `makedev` into `const fn` ([#4208](https://github.com/rust-lang/libc/pull/4208)) + +### Deprecated + +- Linux: Deprecate obsolete packet filter interfaces ([#4267](https://github.com/rust-lang/libc/pull/4267)) + +### Fixed + +- Cygwin: Fix strerror_r ([#4308](https://github.com/rust-lang/libc/pull/4308)) +- Cygwin: Fix usage of f! ([#4308](https://github.com/rust-lang/libc/pull/4308)) +- Hermit: Make `stat::st_size` signed ([#4298](https://github.com/rust-lang/libc/pull/4298)) +- Linux: Correct values for `SI_TIMER`, `SI_MESGQ`, `SI_ASYNCIO` ([#4292](https://github.com/rust-lang/libc/pull/4292)) +- NuttX: Update `tm_zone` and `d_name` fields to use `c_char` type ([#4222](https://github.com/rust-lang/libc/pull/4222)) +- Xous: Include the prelude to define `c_int` ([#4304](https://github.com/rust-lang/libc/pull/4304)) + +### Other + +- Add labels to FIXMEs ([#4231](https://github.com/rust-lang/libc/pull/4231), [#4232](https://github.com/rust-lang/libc/pull/4232), [#4234](https://github.com/rust-lang/libc/pull/4234), [#4235](https://github.com/rust-lang/libc/pull/4235), [#4236](https://github.com/rust-lang/libc/pull/4236)) +- CI: Fix "cannot find libc" error on Sparc64 ([#4317](https://github.com/rust-lang/libc/pull/4317)) +- CI: Fix "cannot find libc" error on s390x ([#4317](https://github.com/rust-lang/libc/pull/4317)) +- CI: Pass `--no-self-update` to `rustup update` ([#4306](https://github.com/rust-lang/libc/pull/4306)) +- CI: Remove tests for the `i586-pc-windows-msvc` target ([#4311](https://github.com/rust-lang/libc/pull/4311)) +- CI: Remove the `check_cfg` job ([#4322](https://github.com/rust-lang/libc/pull/4312)) +- Change the range syntax that is giving `ctest` problems ([#4311](https://github.com/rust-lang/libc/pull/4311)) +- Linux: Split out the stat struct for gnu/b32/mips ([#4276](https://github.com/rust-lang/libc/pull/4276)) + +### Removed + +- NuttX: Remove `pthread_set_name_np` ([#4251](https://github.com/rust-lang/libc/pull/4251)) + +## [0.2.170](https://github.com/rust-lang/libc/compare/0.2.169...0.2.170) - 2025-02-23 + +### Added + +- Android: Declare `setdomainname` and `getdomainname` +- FreeBSD: Add `evdev` structures +- FreeBSD: Add the new `st_filerev` field to `stat32` ([#4254](https://github.com/rust-lang/libc/pull/4254)) +- Linux: Add `SI_*`` and `TRAP_*`` signal codes +- Linux: Add experimental configuration to enable 64-bit time in kernel APIs, set by `RUST_LIBC_UNSTABLE_LINUX_TIME_BITS64`. +- Linux: Add recent socket timestamping flags +- Linux: Added new CANFD_FDF flag for the flags field of canfd_frame +- Musl: add CLONE_NEWTIME +- Solarish: add the posix_spawn family of functions + +### Deprecated + +- Linux: deprecate kernel modules syscalls + +### Changed + +- Emscripten: Assume version is at least 3.1.42 + +### Fixed + +- BSD: Correct the definition of `WEXITSTATUS` +- Hurd: Fix CMSG_DATA on 64bit systems ([#4240](https://github.com/rust-lang/libc/pull/424)) +- NetBSD: fix `getmntinfo` ([#4265](https://github.com/rust-lang/libc/pull/4265) +- VxWorks: Fix the size of `time_t` + +### Other + +- Add labels to FIXMEs , , +- CI: Bump FreeBSD CI to 13.4 and 14.2 +- Copy definitions from core::ffi and centralize them +- Define c_char at top-level and remove per-target c_char definitions +- Port style.rs to syn and add tests for the style checker + +## [0.2.169](https://github.com/rust-lang/libc/compare/0.2.168...0.2.169) - 2024-12-18 + +### Added + +- FreeBSD: add more socket TCP stack constants +- Fuchsia: add a `sockaddr_vm` definition + +### Fixed + +**Breaking**: [rust-lang/rust#132975](https://github.com/rust-lang/rust/pull/132975) corrected the signedness of `core::ffi::c_char` on various Tier 2 and Tier 3 platforms (mostly Arm and RISC-V) to match Clang. This release contains the corresponding changes to `libc`, including the following specific pull requests: + +- ESP-IDF: Replace arch-conditional `c_char` with a reexport +- Fix `c_char` on various targets +- Mirror `c_char` configuration from `rust-lang/rust` + +### Cleanup + +- Do not re-export `c_void` in target-specific code + +## [0.2.168](https://github.com/rust-lang/libc/compare/0.2.167...0.2.168) - 2024-12-09 + +### Added + +- Linux: Add new process flags ([#4174](https://github.com/rust-lang/libc/pull/4174)) +- Linux: Make `IFA_*` constants available on all Linux targets +- Linux: add `MAP_DROPPABLE` +- Solaris, Illumos: add `SIGRTMIN` and `SIGRTMAX` +- Unix, Linux: adding POSIX `memccpy` and `mempcpy` GNU extension +- CI: Upload artifacts created by libc-test +- CI: Use workflow commands to group output by target +- CI: add caching + +## [0.2.167](https://github.com/rust-lang/libc/compare/0.2.166...0.2.167) - 2024-11-28 + +### Added + +- Solarish: add `st_fstype` to `stat` +- Trusty: Add `intptr_t` and `uintptr_t` ([#4161](https://github.com/rust-lang/libc/pull/4161)) + +### Fixed + +- Fix the build with `rustc-dep-of-std` +- Wasi: Add back unsafe block for `clockid_t` static variables ([#4157](https://github.com/rust-lang/libc/pull/4157)) + +### Cleanup + +- Create an internal prelude +- Fix `unused_qualifications` + +### Other + +- CI: Check various FreeBSD versions ([#4159](https://github.com/rust-lang/libc/pull/4159)) +- CI: add a timeout for all jobs +- CI: verify MSRV for `wasm32-wasi` +- Migrate to the 2021 edition + +### Removed + +- Remove one unused import after the edition 2021 bump + +## [0.2.166](https://github.com/rust-lang/libc/compare/0.2.165...0.2.166) - 2024-11-26 + +### Fixed + +This release resolves two cases of unintentional breakage from the previous release: + +- Revert removal of array size hacks [#4150](https://github.com/rust-lang/libc/pull/4150) +- Ensure `const extern` functions are always enabled [#4151](https://github.com/rust-lang/libc/pull/4151) + +## [0.2.165](https://github.com/rust-lang/libc/compare/0.2.164...0.2.165) - 2024-11-25 + +### Added + +- Android: add `mkostemp`, `mkostemps` +- Android: add a few API 30 calls +- Android: add missing syscall constants +- Apple: add `in6_ifreq` +- Apple: add missing `sysctl` net types (before release: remove `if_family_id` ([#4137](https://github.com/rust-lang/libc/pulls/4137))) +- Freebsd: add `kcmp` call support +- Hurd: add `MAP_32BIT` and `MAP_EXCL` +- Hurd: add `domainname` field to `utsname` ([#4089](https://github.com/rust-lang/libc/pulls/4089)) +- Linux GNU: add `f_flags` to struct `statfs` for arm, mips, powerpc and x86 +- Linux GNU: add `malloc_stats` +- Linux: add ELF relocation-related structs +- Linux: add `ptp_*` structs +- Linux: add `ptp_clock_caps` +- Linux: add `ptp_pin_function` and most `PTP_` constants +- Linux: add missing AF_XDP structs & constants +- Linux: add missing netfilter consts ([#3734](https://github.com/rust-lang/libc/pulls/3734)) +- Linux: add struct and constants for the `mount_setattr` syscall +- Linux: add wireless API +- Linux: expose the `len8_dlc` field of `can_frame` +- Musl: add `utmpx` API +- Musl: add missing syscall constants +- NetBSD: add `mcontext`-related data for RISCV64 +- Redox: add new `netinet` constants ) +- Solarish: add `_POSIX_VDISABLE` ([#4103](https://github.com/rust-lang/libc/pulls/4103)) +- Tests: Add a test that the `const extern fn` macro works +- Tests: Add test of primitive types against `std` +- Unix: Add `htonl`, `htons`, `ntohl`, `ntohs` +- Unix: add `aligned_alloc` +- Windows: add `aligned_realloc` + +### Fixed + +- **breaking** Hurd: fix `MAP_HASSEMAPHORE` name ([#4127](https://github.com/rust-lang/libc/pulls/4127)) +- **breaking** ulibc Mips: fix `SA_*` mismatched types ([#3211](https://github.com/rust-lang/libc/pulls/3211)) +- Aix: fix an enum FFI safety warning +- Haiku: fix some typos ([#3664](https://github.com/rust-lang/libc/pulls/3664)) +- Tests: fix `Elf{32,64}_Relr`-related tests +- Tests: fix libc-tests for `loongarch64-linux-musl` +- Tests: fix some clippy warnings +- Tests: fix tests on `riscv64gc-unknown-freebsd` + +### Deprecated + +- Apple: deprecate `iconv_open` +- Apple: deprecate `mach_task_self` +- Apple: update `mach` deprecation notices for things that were removed in `main` + +### Cleanup + +- Adjust the `f!` macro to be more flexible +- Aix: remove duplicate constants +- CI: make scripts more uniform +- Drop the `libc_align` conditional +- Drop the `libc_cfg_target_vendor` conditional +- Drop the `libc_const_size_of` conditional +- Drop the `libc_core_cvoid` conditional +- Drop the `libc_int128` conditional +- Drop the `libc_non_exhaustive` conditional +- Drop the `libc_packedN` conditional +- Drop the `libc_priv_mod_use` conditional +- Drop the `libc_union` conditional +- Drop the `long_array` conditional +- Drop the `ptr_addr_of` conditional +- Drop warnings about deprecated cargo features +- Eliminate uses of `struct_formatter` +- Fix a few other array size hacks +- Glibc: remove redundant definitions ([#3261](https://github.com/rust-lang/libc/pulls/3261)) +- Musl: remove redundant definitions ([#3261](https://github.com/rust-lang/libc/pulls/3261)) +- Musl: unify definitions of `siginfo_t` ([#3261](https://github.com/rust-lang/libc/pulls/3261)) +- Musl: unify definitions of statfs and statfs64 ([#3261](https://github.com/rust-lang/libc/pulls/3261)) +- Musl: unify definitions of statvfs and statvfs64 ([#3261](https://github.com/rust-lang/libc/pulls/3261)) +- Musl: unify statx definitions ([#3978](https://github.com/rust-lang/libc/pulls/3978)) +- Remove array size hacks for Rust < 1.47 +- Remove repetitive words +- Use #[derive] for Copy/Clone in s! and friends +- Use some tricks to format macro bodies + +### Other + +- Apply formatting to macro bodies +- Bump libc-test to Rust 2021 Edition +- CI: Add a check that semver files don't contain duplicate entries +- CI: Add `fanotify_event_info_fid` to FAM-exempt types +- CI: Allow rustfmt to organize imports ([#4136](https://github.com/rust-lang/libc/pulls/4136)) +- CI: Always run rustfmt +- CI: Change 32-bit Docker images to use EOL repos +- CI: Change 64-bit Docker images to ubuntu:24.10 +- CI: Disable the check for >1 s! invocation +- CI: Ensure build channels get run even if FILTER is unset +- CI: Ensure there is a fallback for no_std +- CI: Fix cases where unset variables cause errors +- CI: Naming adjustments and cleanup +- CI: Only invoke rustup if running in CI +- CI: Remove the logic to handle old rust versions +- CI: Set -u (error on unset) in all script files +- CI: add support for `loongarch64-unknown-linux-musl` +- CI: make `aarch64-apple-darwin` not a nightly-only target +- CI: run shellcheck on all scripts +- CI: update musl headers to Linux 6.6 +- CI: use qemu-sparc64 to run sparc64 tests +- Drop the `libc_const_extern_fn` conditional +- Drop the `libc_underscore_const_names` conditional +- Explicitly set the edition to 2015 +- Introduce a `git-blame-ignore-revs` file +- Tests: Ignore fields as required on Ubuntu 24.10 +- Tests: skip `ATF_*` constants for OpenBSD +- Triagebot: Add an autolabel for CI + +## [0.2.164](https://github.com/rust-lang/libc/compare/0.2.163...0.2.164) - 2024-11-16 + +### MSRV + +This release increases the MSRV of `libc` to 1.63. + +### Other + +- CI: remove tests with rust < 1.63 +- MSRV: document the MSRV of the stable channel to be 1.63 +- MacOS: move ifconf to s_no_extra_traits + +## [0.2.163](https://github.com/rust-lang/libc/compare/0.2.162...0.2.163) - 2024-11-16 + +### Added + +- Aix: add more `dlopen` flags +- Android: add group calls +- FreeBSD: add `TCP_FUNCTION_BLK` and `TCP_FUNCTION_ALIAS` +- Linux: add `confstr` +- Solarish: add `aio` +- Solarish: add `arc4random*` + +### Changed + +- Emscripten: upgrade emsdk to 3.1.68 +- Hurd: use more standard types +- Hurd: use the standard `ssize_t = isize` +- Solaris: fix `confstr` and `ucontext_t` + +### Other + +- CI: add Solaris +- CI: add `i686-unknown-freebsd` +- CI: ensure that calls to `sort` do not depend on locale +- Specify `rust-version` in `Cargo.toml` + +## [0.2.162](https://github.com/rust-lang/libc/compare/0.2.161...0.2.162) - 2024-11-07 + +### Added + +- Android: fix the alignment of `uc_mcontext` on arm64 +- Apple: add `host_cpu_load_info` +- ESP-IDF: add a time flag +- FreeBSD: add the `CLOSE_RANGE_CLOEXEC` flag +- FreeBSD: fix test errors regarding `__gregset_t` +- FreeBSD: fix tests on x86 FreeBSD 15 +- FreeBSD: make `ucontext_t` and `mcontext_t` available on all architectures +- Haiku: add `getentropy` +- Illumos: add `syncfs` +- Illumos: add some recently-added constants +- Linux: add `ioctl` flags +- Linux: add epoll busy polling parameters +- NuttX: add `pthread_[get/set]name_np` +- RTEMS: add `arc4random_buf` +- Trusty OS: add initial support +- WASIp2: expand socket support + +### Fixed + +- Emscripten: don't pass `-lc` +- Hurd: change `st_fsid` field to `st_dev` +- Hurd: fix the definition of `utsname` +- Illumos/Solaris: fix `FNM_CASEFOLD` definition +- Solaris: fix all tests + +### Other + +- CI: Add loongarch64 +- CI: Check that semver files are sorted +- CI: Re-enable the FreeBSD 15 job +- Clean up imports and `extern crate` usage +- Convert `mode_t` constants to octal +- Remove the `wasm32-wasi` target that has been deleted upstream + +## [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..5a5ac3e --- /dev/null +++ b/vendor/libc/CONTRIBUTING.md @@ -0,0 +1,152 @@ +# Contributing to `libc` + +Welcome! If you are reading this document, it means you are interested in +contributing to the `libc` crate. + +## v1.0 Roadmap + +`libc` has two active branches: `main` and `libc-0.2`. `main` is for active +development of the upcoming v1.0 release, and should be the target of all pull +requests. `libc-0.2` is for updates to the currently released version. + +If a pull request to `main` is a good candidate for inclusion in an `0.2.x` +release, include `@rustbot label stable-nominated` in a comment to propose this. +Almost everything should be included in stable, unless it involves breaking +changes. + +Once a `stable-nominated` PR targeting `main` has merged, it can be cherry +picked to the `libc-0.2` branch. A maintainer will likely do these cherry picks +in a batch before a release, so there is no need for any action as a PR author. + +When cherry picking, run the following after branching from `libc-0.2`: +`git cherry-pick -xe commit-sha-on-main` (or `git cherry-pick -xe +start-sha^..end-sha` if a range of commits is needed). `git` will automatically +add the "cherry picked from commit" note, but try to add a backport note so the +original PR gets crosslinked: + +``` +# ... original commit message ... + +(backport ) # add manually +(cherry picked from commit 104b6a4ae31c726814c36318dc718470cc96e167) # added by git +``` + +Cherry pick PRs can then target `libc-0.2`. + +See the [tracking issue](https://github.com/rust-lang/libc/issues/3248) for +details. + +## Adding an API + +Want to use an API which currently isn't bound in `libc`? It's quite easy to add +one! + +If you are adding API for a header that doesn't already have some bindings, +create a new file in the appropriate location in `src/new`. These modules should +approximately match source trees: try to follow the patterns that are there but +don't hesitate to ask maintainers if guidance is needed. + +If some bindings for the relevant header has already been added outside of +`src/new`, it is fine to extend what already exists. Everything outside of +`src/new` uses a hierarchial structure: a single path from root to a leaf node +represents a single platform, and adding API at a given level will make it +available on all children. + +We are currently in a reorganization process, moving from the hierarchial +structure to the source-mapped structure in `src/new`. + +New items (i.e. functions, constants etc.) should also be added to the symbol +list(s) found in the `libc-test/semver` directory. These lists track of what +API is 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` list[^1], 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 to add your API. +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 among all OSs that declare `#[cfg(unix)]`. + +## Test before you commit + +There are a few relevant tests in `libc`: + +1. `libc-test` is the main test suite. This can be run locally with `cargo test + --workspace`. + + If needed, the `skip_*()` functions in `libc-test/build.rs` can be used to + skip testing specific API. +2. Style checker and formatter, located at [`./ci/style.py`][style-py]. Running + this also invokes the code formatter. (This also formats code within macros, + which `cargo fmt` won't do.) +3. `ci/verify-build.py`, which checks the build on a wide range of targets. + Typically there is no need to run this locally. + +[style-py]: https://github.com/rust-lang/libc/blob/main/ci/style.py + +## Submitting a Pull Request + +When you submit a PR, please follow these guidelines to give your PR the best +chance of being accepted: + +1. All new API should be added to `libc-test/semver`, which makes sure it + doesn't get removed in the future. +2. All changes *must* have permalink to headers in commit messages. See + [Source links](#source-links) below for more details. +3. For any constants that are expected to change, e.g. `*LAST` or `*MAX`, try to + add the following doc comment: + + ```rust + /// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) + /// for details. + ``` +5. Run tests locally, following the directions at + [Test before you commit](test-before-you-commit). This is especially relevant + for platforms that aren't tested on CI. + +### Source links + +Please include permalinks to headers in commit messages for all API changes. +Common sources include: + +* Linux uapi: https://github.com/torvalds/linux/tree/master/include/uapi +* Glibc: https://sourceware.org/git/?p=glibc.git;a=tree +* Musl: https://github.com/kraj/musl (original is https://git.musl-libc.org/cgit/musl/tree/) +* Apple XNU: https://github.com/apple-oss-distributions/xnu, libc https://github.com/apple-oss-distributions/Libc/tree/main/include +* Android: https://cs.android.com/android/platform/superproject/main +* FreeBSD: https://github.com/freebsd/freebsd-src/tree/main/lib/libc +* Illumos: https://github.com/illumos/illumos-gate/tree/master/usr/src/lib/libc +* Fuchsia: https://cs.opensource.google/fuchsia/fuchsia/+/main:zircon/ + +After navigating to the relevant file and selecting relevant lines, get a +permalink. On GitHub this is available by clicking the triple dots and +selecting "copy permalink", and on the Android and Fuchsia source viewers +this is available via l-r (links->commit). + +If sources are closed, link to documentation or paste relevant C declarations. + +(Including this information in the PR description is fine too, commit messages +are preferred because they become part of history.) + +## Breaking change policy + +See `src/lib.rs` for details. + +## Supported target policy + +When Rust removes a support for a target, the libc crate also may remove the +support at any time. MSRV may be different for different targets. + +## Releasing change to crates.io + +This repository uses [release-plz] to handle releases. Once your pull request +has been merged, a maintainer needs to create the changelog and merge a PR +bumping the version. This will automatically publish to crates.io! + +[release-plz]: https://github.com/MarcoIeni/release-plz diff --git a/vendor/libc/Cargo.lock b/vendor/libc/Cargo.lock new file mode 100644 index 0000000..139e7a0 --- /dev/null +++ b/vendor/libc/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "libc" +version = "0.2.189" +dependencies = [ + "rustc-std-workspace-core", +] + +[[package]] +name = "rustc-std-workspace-core" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9c45b374136f52f2d6311062c7146bff20fec063c3f5d46a410bd937746955" diff --git a/vendor/libc/Cargo.toml b/vendor/libc/Cargo.toml new file mode 100644 index 0000000..381f64e --- /dev/null +++ b/vendor/libc/Cargo.toml @@ -0,0 +1,225 @@ +# 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.65" +name = "libc" +version = "0.2.189" +build = "build.rs" +exclude = [ + "/ci/*", + "/.github/*", + "/triagebot.toml", + "cherry-pick-stable.sh", +] +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Raw FFI bindings to platform libraries like 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] +features = ["extra_traits"] +default-target = "x86_64-unknown-linux-gnu" +targets = [ + "aarch64-apple-darwin", + "aarch64-pc-windows-msvc", + "aarch64-unknown-linux-gnu", + "i686-pc-windows-msvc", + "i686-unknown-linux-gnu", + "x86_64-pc-windows-gnu", + "x86_64-pc-windows-msvc", + "x86_64-unknown-linux-gnu", + "aarch64-pc-windows-gnullvm", + "aarch64-unknown-linux-musl", + "aarch64-unknown-linux-ohos", + "arm-unknown-linux-gnueabi", + "arm-unknown-linux-gnueabihf", + "armv7-unknown-linux-gnueabihf", + "armv7-unknown-linux-ohos", + "i686-pc-windows-gnu", + "loongarch64-unknown-linux-gnu", + "loongarch64-unknown-linux-musl", + "powerpc-unknown-linux-gnu", + "powerpc64-unknown-linux-gnu", + "powerpc64-unknown-linux-musl", + "powerpc64le-unknown-linux-gnu", + "powerpc64le-unknown-linux-musl", + "riscv64gc-unknown-linux-gnu", + "s390x-unknown-linux-gnu", + "sparcv9-sun-solaris", + "x86_64-apple-darwin", + "x86_64-pc-solaris", + "x86_64-pc-windows-gnullvm", + "x86_64-unknown-freebsd", + "x86_64-unknown-illumos", + "x86_64-unknown-linux-musl", + "x86_64-unknown-linux-ohos", + "x86_64-unknown-netbsd", + "aarch64-apple-ios", + "aarch64-apple-tvos", + "aarch64-apple-visionos", + "aarch64-apple-watchos", + "aarch64-linux-android", + "aarch64-unknown-fuchsia", + "arm-linux-androideabi", + "arm-unknown-linux-musleabi", + "arm-unknown-linux-musleabihf", + "arm64ec-pc-windows-msvc", + "armv5te-unknown-linux-gnueabi", + "armv5te-unknown-linux-musleabi", + "armv7-linux-androideabi", + "armv7-unknown-linux-musleabihf", + "i586-unknown-linux-gnu", + "i586-unknown-linux-musl", + "i686-linux-android", + "i686-unknown-freebsd", + "i686-unknown-linux-musl", + "nvptx64-nvidia-cuda", + "riscv64gc-unknown-linux-musl", + "sparc64-unknown-linux-gnu", + "thumbv7neon-linux-androideabi", + "thumbv7neon-unknown-linux-gnueabihf", + "wasm32-unknown-emscripten", + "wasm32-unknown-unknown", + "wasm32-wasip1", + "wasm32-wasip2", + "x86_64-fortanix-unknown-sgx", + "x86_64-linux-android", + "x86_64-unknown-fuchsia", + "x86_64-unknown-linux-gnux32", + "x86_64-unknown-redox", + "aarch64-unknown-freebsd", + "aarch64-unknown-hermit", + "aarch64-unknown-illumos", + "aarch64-unknown-netbsd", + "aarch64-unknown-qnx", + "aarch64-unknown-openbsd", + "aarch64-unknown-redox", + "aarch64-wrs-vxworks", + "aarch64_be-unknown-linux-gnu", + "aarch64_be-unknown-linux-musl", + "armebv7r-none-eabi", + "armebv7r-none-eabihf", + "armv7-linux-androideabi", + "armv7-wrs-vxworks-eabihf", + "armv7r-none-eabi", + "armv7r-none-eabihf", + "hexagon-unknown-linux-musl", + "i686-unknown-haiku", + "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", + "powerpc-unknown-linux-gnuspe", + "powerpc-unknown-netbsd", + "powerpc-wrs-vxworks", + "powerpc-wrs-vxworks-spe", + "powerpc64-ibm-aix", + "powerpc64-unknown-freebsd", + "powerpc64-unknown-linux-gnu", + "powerpc64-wrs-vxworks", + "riscv32-wrs-vxworks", + "riscv32gc-unknown-linux-musl", + "riscv32i-unknown-none-elf", + "riscv32imac-unknown-none-elf", + "riscv32imc-unknown-none-elf", + "riscv64-wrs-vxworks", + "riscv64gc-unknown-freebsd", + "riscv64gc-unknown-hermit", + "riscv64gc-unknown-none-elf", + "riscv64imac-unknown-none-elf", + "s390x-unknown-linux-musl", + "sparc-unknown-linux-gnu", + "sparc64-unknown-netbsd", + "thumbv6m-none-eabi", + "thumbv7em-none-eabi", + "thumbv7em-none-eabihf", + "thumbv7m-none-eabi", + "wasm32-wasip3", + "x86_64-apple-ios", + "x86_64-pc-cygwin", + "x86_64-unknown-dragonfly", + "x86_64-unknown-haiku", + "x86_64-unknown-hermit", + "x86_64-unknown-hurd-gnu", + "x86_64-unknown-l4re-uclibc", + "x86_64-unknown-openbsd", + "x86_64-wrs-vxworks", +] +cargo-args = ["-Zbuild-std=core"] + +[package.metadata.cargo-semver-checks.lints] +repr_align_removed = "warn" +global_value_marked_deprecated = "warn" + +[features] +align = [] +const-extern-fn = [] +default = ["std"] +extra_traits = [] +rustc-dep-of-std = [ + "align", + "rustc-std-workspace-core", +] +std = [] +use_std = ["std"] + +[lib] +name = "libc" +path = "src/lib.rs" + +[[test]] +name = "const_fn" +path = "tests/const_fn.rs" + +[dependencies.rustc-std-workspace-core] +version = "1.0.1" +optional = true + +[lints.clippy] +explicit_iter_loop = "warn" +identity_op = "allow" +manual_assert = "warn" +map_unwrap_or = "warn" +missing_safety_doc = "allow" +non_minimal_cfg = "allow" +ptr_as_ptr = "warn" +unnecessary_cast = "allow" +unnecessary_semicolon = "warn" + +[lints.rust] +unused_qualifications = "allow" diff --git a/vendor/libc/Cargo.toml.orig b/vendor/libc/Cargo.toml.orig new file mode 100644 index 0000000..380dd89 --- /dev/null +++ b/vendor/libc/Cargo.toml.orig @@ -0,0 +1,214 @@ +[package] +name = "libc" +version = "0.2.189" +keywords = ["libc", "ffi", "bindings", "operating", "system"] +categories = ["external-ffi-bindings", "no-std", "os"] +exclude = ["/ci/*", "/.github/*", "/triagebot.toml", "cherry-pick-stable.sh"] +description = "Raw FFI bindings to platform libraries like libc." +edition = "2021" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/libc" +rust-version = "1.65" + +[package.metadata.docs.rs] +features = ["extra_traits"] +default-target = "x86_64-unknown-linux-gnu" +targets = [ + # Note: Keep this in sync with ci/verify-build.py + # + # Tier 1 + "aarch64-apple-darwin", + "aarch64-pc-windows-msvc", + "aarch64-unknown-linux-gnu", + "i686-pc-windows-msvc", + "i686-unknown-linux-gnu", + "x86_64-pc-windows-gnu", + "x86_64-pc-windows-msvc", + "x86_64-unknown-linux-gnu", + # + # Tier 2 with host tools + "aarch64-pc-windows-gnullvm", + "aarch64-unknown-linux-musl", + "aarch64-unknown-linux-ohos", + "arm-unknown-linux-gnueabi", + "arm-unknown-linux-gnueabihf", + "armv7-unknown-linux-gnueabihf", + "armv7-unknown-linux-ohos", + "i686-pc-windows-gnu", + "loongarch64-unknown-linux-gnu", + "loongarch64-unknown-linux-musl", + "powerpc-unknown-linux-gnu", + "powerpc64-unknown-linux-gnu", + "powerpc64-unknown-linux-musl", + "powerpc64le-unknown-linux-gnu", + "powerpc64le-unknown-linux-musl", + "riscv64gc-unknown-linux-gnu", + "s390x-unknown-linux-gnu", + "sparcv9-sun-solaris", + "x86_64-apple-darwin", + "x86_64-pc-solaris", + "x86_64-pc-windows-gnullvm", + "x86_64-unknown-freebsd", + "x86_64-unknown-illumos", + "x86_64-unknown-linux-musl", + "x86_64-unknown-linux-ohos", + "x86_64-unknown-netbsd", + # + # Tier 2 without host tools + "aarch64-apple-ios", + "aarch64-apple-tvos", + "aarch64-apple-visionos", + "aarch64-apple-watchos", + "aarch64-linux-android", + "aarch64-unknown-fuchsia", + "arm-linux-androideabi", + "arm-unknown-linux-musleabi", + "arm-unknown-linux-musleabihf", + "arm64ec-pc-windows-msvc", + "armv5te-unknown-linux-gnueabi", + "armv5te-unknown-linux-musleabi", + "armv7-linux-androideabi", + "armv7-unknown-linux-musleabihf", + "i586-unknown-linux-gnu", + "i586-unknown-linux-musl", + "i686-linux-android", + "i686-unknown-freebsd", + "i686-unknown-linux-musl", + "nvptx64-nvidia-cuda", + "riscv64gc-unknown-linux-musl", + "sparc64-unknown-linux-gnu", + "thumbv7neon-linux-androideabi", + "thumbv7neon-unknown-linux-gnueabihf", + "wasm32-unknown-emscripten", + "wasm32-unknown-unknown", + "wasm32-wasip1", + "wasm32-wasip2", + "x86_64-fortanix-unknown-sgx", + "x86_64-linux-android", + "x86_64-unknown-fuchsia", + "x86_64-unknown-linux-gnux32", + "x86_64-unknown-redox", + # + # Tier 3 targets that are distinct enough to be useful, or have historically + # been documented. + "aarch64-unknown-freebsd", + "aarch64-unknown-hermit", + "aarch64-unknown-illumos", + "aarch64-unknown-netbsd", + "aarch64-unknown-qnx", + "aarch64-unknown-openbsd", + "aarch64-unknown-redox", + "aarch64-wrs-vxworks", + "aarch64_be-unknown-linux-gnu", + "aarch64_be-unknown-linux-musl", + "armebv7r-none-eabi", + "armebv7r-none-eabihf", + "armv7-linux-androideabi", + "armv7-wrs-vxworks-eabihf", + "armv7r-none-eabi", + "armv7r-none-eabihf", + "hexagon-unknown-linux-musl", + "i686-unknown-haiku", + "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", + "powerpc-unknown-linux-gnuspe", + "powerpc-unknown-netbsd", + "powerpc-wrs-vxworks", + "powerpc-wrs-vxworks-spe", + "powerpc64-ibm-aix", + "powerpc64-unknown-freebsd", + "powerpc64-unknown-linux-gnu", + "powerpc64-wrs-vxworks", + "riscv32-wrs-vxworks", + "riscv32gc-unknown-linux-musl", + "riscv32i-unknown-none-elf", + "riscv32imac-unknown-none-elf", + "riscv32imc-unknown-none-elf", + "riscv64-wrs-vxworks", + "riscv64gc-unknown-freebsd", + "riscv64gc-unknown-hermit", + "riscv64gc-unknown-none-elf", + "riscv64imac-unknown-none-elf", + "s390x-unknown-linux-musl", + "sparc-unknown-linux-gnu", + "sparc64-unknown-netbsd", + "thumbv6m-none-eabi", + "thumbv7em-none-eabi", + "thumbv7em-none-eabihf", + "thumbv7m-none-eabi", + "wasm32-wasip3", + "x86_64-apple-ios", + "x86_64-pc-cygwin", + "x86_64-unknown-dragonfly", + "x86_64-unknown-haiku", + "x86_64-unknown-hermit", + "x86_64-unknown-hurd-gnu", + "x86_64-unknown-l4re-uclibc", + "x86_64-unknown-openbsd", + "x86_64-wrs-vxworks" +] +cargo-args = ["-Zbuild-std=core"] + +[dependencies] +rustc-std-workspace-core = { version = "1.0.1", optional = true } + +[features] +default = ["std"] +std = [] +rustc-dep-of-std = ['align', 'rustc-std-workspace-core'] +extra_traits = [] + +# `const-extern-function` is deprecated and no longer does anything +const-extern-fn = [] + +# `align` is deprecated and no longer does anything +align = [] + +# use_std is deprecated, use `std` instead +use_std = ['std'] + +[workspace] +members = [ + "ctest", + "libc-test", +] + +[workspace.lints.rust] +# FIXME(cleanup): make ident usage consistent in each file +unused_qualifications = "allow" + +[workspace.lints.clippy] +# Enable pedantic lints - use this manually once in a while, but don't enable by default +# pedantic = { level = "warn", priority = -1 } + +# We are okay with the current state of these lints +explicit_iter_loop = "warn" +identity_op = "allow" # some expressions like `0 | x` are clearer for bit ops +manual_assert = "warn" +map_unwrap_or = "warn" +missing_safety_doc = "allow" # safety? in libc? seriously? +non_minimal_cfg = "allow" # for some reason cfg_if! sometimes trigger this +ptr_as_ptr = "warn" +unnecessary_semicolon = "warn" + +# FIXME(clippy): these should be fixed if possible +unnecessary_cast = "allow" # some casts like `as usize` are only needed for some targets + +[lints] +workspace = true + +[package.metadata.cargo-semver-checks.lints] +# Alignment is an internal detail that users must not rely upon +repr_align_removed = "warn" +# We deprecate things all the time +global_value_marked_deprecated = "warn" 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..f4095b2 --- /dev/null +++ b/vendor/libc/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 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..b05a52d --- /dev/null +++ b/vendor/libc/README.md @@ -0,0 +1,101 @@ +# libc - Raw FFI bindings to platforms' system libraries + +[![GHA Status]][GitHub Actions] [![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 + +## v1.0 Roadmap + +Currently, `libc` has two active branches: `main` for the upcoming v1.0 release, +and `libc-0.2` for the currently published version. By default all pull requests +should target `main`; once reviewed, they can be cherry picked to the `libc-0.2` +branch if needed. + +We will stop making new v0.2 releases once v1.0 is released. + +See the section in [CONTRIBUTING.md](CONTRIBUTING.md#v10-roadmap) for more +details. + +## Usage + +Add the following to your `Cargo.toml`: + +```toml +[dependencies] +libc = "0.2" +``` + +## Rust version support + +The minimum supported Rust toolchain version is currently **Rust 1.65**. + +Increases to the MSRV are allowed to change without a major (i.e. semver- +breaking) release in order to avoid a ripple effect in the ecosystem. A policy +for when this may change is a work in progress. + +`libc` may continue to compile with Rust versions older than the current MSRV +but this is not guaranteed. + +## Platform support + +You can see the platform(target)-specific docs on [docs.rs], select a platform +you want to see. + +See [`ci/verify-build.py`](https://github.com/rust-lang/libc/blob/HEAD/ci/verify-build.py) for +the platforms on which `libc` is guaranteed to build for each Rust toolchain. +The test matrices at [GitHub Actions] 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 +[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..67da9c6 --- /dev/null +++ b/vendor/libc/build.rs @@ -0,0 +1,393 @@ +use std::env::VarError; +use std::process::{ + Command, + Output, +}; +use std::sync::atomic::AtomicBool; +use std::sync::atomic::Ordering::Relaxed; +use std::{ + env, + 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: &[&str] = &[ + "emscripten_old_stat_abi", + // Should be enabled by users if esp-idf (>=6.0) is build with picolibc instead of newlib. + "espidf_picolibc", + "espidf_time32", + "freebsd10", + "freebsd11", + "freebsd12", + "freebsd13", + "freebsd14", + "freebsd15", + // Corresponds to `_FILE_OFFSET_BITS=64` in glibc + "gnu_file_offset_bits64", + // Corresponds to `_TIME_BITS=64` in glibc. Also used in x86 Windows with + // GNU to expose a 64-bit `time_t`. + "gnu_time_bits64", + "libc_deny_warnings", + // Corresponds to `__USE_TIME_BITS64` in UAPI + "linux_time_bits64", + "musl_v1_2_3", + // musl v1.2.3+ && 32-bit: time_t is i64, struct layouts change + "musl32_time64", + // Corresponds to `_REDIR_TIME64` in musl: symbol redirects to __*_time64 + "musl_redir_time64", + "vxworks_lt_25_09", + "libc_pauthtest", +]; + +// Extra values to allow for check-cfg. +const CHECK_CFG_EXTRA: &[(&str, &[&str])] = &[ + ( + "target_os", + &[ + "switch", "aix", "ohos", "hurd", "rtems", "visionos", "nuttx", "cygwin", "qurt", "qnx", + ], + ), + ( + "target_env", + &["illumos", "wasi", "aix", "ohos", "nto71_iosock"], + ), + ( + "target_arch", + &["loongarch64", "mips32r6", "mips64r6", "csky"], + ), +]; + +/// Musl architectures that define `_REDIR_TIME64` (i.e. those that transitioned +/// from 32-bit to 64-bit `time_t` and need `__*_time64` symbol redirects). +const MUSL_REDIR_TIME64_ARCHES: &[&str] = &["arm", "mips", "powerpc", "x86"]; + +/// Read from env, print more debug output via `cargo:warning` if set. +static VERBOSE_BUILD: AtomicBool = AtomicBool::new(false); + +/// Print info via warnings if `LIBC_BUILD_VERBOSE` is set. +macro_rules! info { + ($($tt:tt)+) => { + if VERBOSE_BUILD.load(Relaxed) { + println!("cargo:warning=info: {}", format_args!($($tt)*)); + } + } +} + +fn main() { + // Avoid unnecessary re-building. + println!("cargo:rerun-if-changed=build.rs"); + + println!("cargo:rerun-if-env-changed=LIBC_BUILD_VERBOSE"); + if env_flag("LIBC_BUILD_VERBOSE") { + VERBOSE_BUILD.store(true, Relaxed); + } + + let (rustc_minor_ver, _is_nightly) = rustc_minor_nightly(); + let libc_ci = env_flag("LIBC_CI"); + let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default(); + let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default(); + let target_ptr_width = env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap_or_default(); + let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default(); + let target_abi = env::var("CARGO_CFG_TARGET_ABI").unwrap_or_default(); + + // FIXME(msrv): Once the MSRV is 1.78, use `cfg(target_abi = "pauthtest")` + // directly instead of translating it to `libc_pauthtest`. `target_abi` + // cannot be used directly in cfg expressions on the current MSRV. + if target_abi == "pauthtest" { + set_cfg("libc_pauthtest"); + } + + // FIXME: this can be removed in 1-2 releases + println!("cargo:rerun-if-env-changed=RUST_LIBC_UNSTABLE_FREEBSD_VERSION"); + if env::var("RUST_LIBC_UNSTABLE_FREEBSD_VERSION").is_ok() { + println!( + "cargo:warning=RUST_LIBC_UNSTABLE_FREEBSD_VERSION has been removed; set \ + the cfg libc_unstable_freebsd_version via RUSTFLAGS 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 12. + // + // On CI, we detect the actual FreeBSD version and match its ABI exactly, + // running tests to ensure that the ABI is correct. + // Allow overriding the default version for testing + let which_freebsd = if let Ok(version) = env::var("CARGO_CFG_LIBC_UNSTABLE_FREEBSD_VERSION") { + let vers = version.parse().unwrap(); + println!("cargo:warning=setting FreeBSD version to {vers}"); + vers + } else if libc_ci { + which_freebsd().unwrap_or(12) + } else { + 12 + }; + + 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_old_stat_abi"), + // Non-Emscripten or version >= 3.1.42. + _ => (), + } + + match vxworks_version_code() { + Some(v) if (v < (25, 9)) => set_cfg("vxworks_lt_25_09"), + // VxWorks version >= 25.09 + _ => (), + } + + let mut musl_v1_2_3 = env_flag("CARGO_CFG_LIBC_UNSTABLE_MUSL_V1_2_3"); + + // OpenHarmony uses a fork of the musl libc + let musl = target_env == "musl" || target_env == "ohos"; + + // loongarch64, hexagon, ohos and pauthtest only exist with recent musl + if target_arch == "loongarch64" + || target_arch == "hexagon" + || target_env == "ohos" + || target_abi == "pauthtest" + { + musl_v1_2_3 = true; + } + + if musl && musl_v1_2_3 { + set_cfg("musl_v1_2_3"); + if target_ptr_width == "32" { + set_cfg("musl32_time64"); + set_cfg("linux_time_bits64"); + } + if MUSL_REDIR_TIME64_ARCHES.contains(&target_arch.as_str()) { + set_cfg("musl_redir_time64"); + } + } + + let uclibc_use_time64 = env_flag("CARGO_CFG_LIBC_UNSTABLE_UCLIBC_TIME64"); + if target_env == "uclibc" && uclibc_use_time64 { + set_cfg("linux_time_bits64"); + } + + if target_env == "gnu" + && matches!(target_os.as_str(), "linux" | "windows") + && target_ptr_width == "32" + && target_arch != "riscv32" + && target_arch != "x86_64" + { + let defaultbits = "32"; + + let mut tb_env = env::var("CARGO_CFG_LIBC_UNSTABLE_GNU_TIME_BITS"); + + // FIXME: remove these fallbacks in a few releases + if let Ok(old_tb_env) = env::var("RUST_LIBC_UNSTABLE_GNU_TIME_BITS") { + println!( + "cargo:warning=RUST_LIBC_UNSTABLE_GNU_TIME_BITS will be removed; \ + set `--cfg=libc_unstable_gnu_time_bits=\"...\"` via RUSTFLAGS instead" + ); + tb_env = tb_env.or(Ok(old_tb_env)); + } + if env::var("RUST_LIBC_UNSTABLE_GNU_FILE_OFFSET_BITS").is_ok() + || env::var("CARGO_CFG_LIBC_UNSTABLE_GNU_FILE_OFFSET_BITS").is_ok() + { + println!( + "cargo:warning=glibc file offset can no longer be set independently of \ + `gnu_time_bits`" + ); + } + + let timebits = match tb_env.as_deref() { + Err(_) => defaultbits, + Ok(tb) if tb == "64" => tb, + Ok(tb) if tb == "32" => tb, + Ok(_) => { + panic!("Invalid value for libc_unstable_gnu_time_bits. Must be 32, 64, or unset.") + } + }; + + if timebits == "64" { + set_cfg("linux_time_bits64"); + set_cfg("gnu_file_offset_bits64"); + set_cfg("gnu_time_bits64"); + } + } + + // On CI: deny all warnings + if libc_ci { + set_cfg("libc_deny_warnings"); + } + + // Since Rust 1.80, configuration that isn't recognized by default needs to be provided to + // avoid warnings. + if rustc_minor_ver >= 80 { + for cfg in ALLOWED_CFGS { + println!("cargo:rustc-check-cfg=cfg({cfg})"); + } + for &(name, values) in CHECK_CFG_EXTRA { + let values = values.join("\",\""); + println!("cargo:rustc-check-cfg=cfg({name},values(\"{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().expect("Failed to get rustc version"); + + assert!( + output.status.success(), + "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('.'); + + assert_eq!( + pieces.next(), + Some("rustc 1"), + "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_or(false, |raw| { + raw.starts_with("dev") || raw.starts_with("nightly") + }); + let minor = otry!(otry!(minor).parse().ok()); + + info!("detected rust 1.{minor}, nightly={nightly}"); + + (minor, nightly) +} + +fn which_freebsd() -> Option { + let output = Command::new("freebsd-version").output().ok()?; + if !output.status.success() { + return None; + } + + let stdout = String::from_utf8(output.stdout).ok()?; + + 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 emcc = if cfg!(target_os = "windows") { + "emcc.bat" + } else { + "emcc" + }; + + let output = Command::new(emcc).arg("-dumpversion").output().ok()?; + if !output.status.success() { + return None; + } + + let version = String::from_utf8(output.stdout).ok()?; + + // Some Emscripten versions come with `-git` attached, so split the + // version string also on the `-` char. + let mut pieces = version.trim().split(['.', '-']); + + 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) +} + +/// Retrieve the VxWorks release version from the environment variable set by the VxWorks build +/// environment, in `(minor, patch)` form. Currently the only major version supported by Rust +/// is 7. +fn vxworks_version_code() -> Option<(u32, u32)> { + let version = env::var("WIND_RELEASE_ID").ok()?; + + let mut pieces = version.trim().split(['.']); + + let major: u32 = pieces.next().and_then(|x| x.parse().ok()).unwrap_or(0); + let minor: u32 = pieces.next().and_then(|x| x.parse().ok()).unwrap_or(0); + + Some((major, minor)) +} + +fn set_cfg(cfg: &str) { + assert!( + ALLOWED_CFGS.contains(&cfg), + "trying to set cfg {cfg}, but it is not in ALLOWED_CFGS", + ); + println!("cargo:rustc-cfg={cfg}"); + info!("setting config `{cfg}`"); +} + +/// Return true if the env is set to a value other than `0`. +fn env_flag(key: &str) -> bool { + match env::var(key) { + Ok(x) if x == "0" => false, + Err(VarError::NotPresent) => false, + Err(VarError::NotUnicode(_)) => panic!("non-unicode var for `{key}`"), + Ok(_) => true, + } +} diff --git a/vendor/libc/etc/libc-util.py b/vendor/libc/etc/libc-util.py new file mode 100755 index 0000000..fc5f81f --- /dev/null +++ b/vendor/libc/etc/libc-util.py @@ -0,0 +1,1112 @@ +#!/usr/bin/env python3 +"""Helper utilities for common libc tasks.""" + +import argparse +import copy +import datetime as dt +from enum import StrEnum +import functools +import json +import os +import pprint +import re +import subprocess as sp +import sys +from dataclasses import dataclass +from inspect import cleandoc +from multiprocessing import Pool +from pathlib import Path + +REPO_OWNER = "rust-lang" +REPO = "libc" + + +def main() -> None: + p = argparse.ArgumentParser( + description="Utilities for helping with libc development" + ) + sub = p.add_subparsers(required=True) + + p_cat = sub.add_parser( + "check-all-targets", + aliases=["cat"], + help="run `cargo check` on some or all targets (see subcommand help for more)", + description=CheckAllTargets.__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + p_cat.add_argument("package", help="specify the package to build") + p_cat.add_argument("-o", "--only", help="filter tested targets by this regex") + p_cat.add_argument("-s", "--skip", help="skip targets matching this regex") + p_cat.add_argument( + "cargo_args", + nargs="*", + metavar="cargo-args", + help="extra arguments for `cargo check`", + ) + p_cat.set_defaults( + func=lambda args: CheckAllTargets.prepare().check_all_targets( + package=args.package, + only=args.only, + skip=args.skip, + cargo_args=args.cargo_args, + ) + ) + + p_rel = sub.add_parser( + "relabel", + help="replace the stable-nominated label with stable-applied", + description=Relabel.__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + p_rel.add_argument( + "pr_number", metavar="pr-number", help="pull request for the backport" + ) + p_rel.set_defaults(func=lambda args: Relabel(pr_number=args.pr_number).execute()) + + p_log = sub.add_parser( + "make-changelog", + help="collect changelog entries", + description=MakeChangelog.__doc__, + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + p_log.add_argument( + "--old-tag", + metavar="old-tag", + help="tag of the previous revision to serve as the changelog base", + required=True, + ) + p_log.add_argument( + "--new-ref", + metavar="new-ref", + help="ref to compare to the old tag", + default="libc-0.2", + ) + p_log.set_defaults( + func=lambda args: MakeChangelog( + old_tag=args.old_tag, new_ref=args.new_ref + ).execute() + ) + + p_bkp = sub.add_parser( + "backport", + help="prepare to cherry pick to `libc-0.2` (see subcommand help for more)", + description=Backporter.__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + p_bkp.add_argument( + "--branch", help="branch to backport to, must not be checked out", required=True + ) + p_bkp.set_defaults( + func=lambda args: Backporter(branch=args.branch).start_backports() + ) + + s = sub.add_parser( + "backport-pr-description", + help="create a PR description for a backport branch", + description=Backporter.backport_pr_description.__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + s.add_argument("--branch", help="name of the backport branch", required=True) + s.set_defaults(func=lambda args: Backporter.backport_pr_description(args.branch)) + + p_amd = sub.add_parser( + "add-backport-trailer", + help='add "(backport ...)" to the previous commit', + description=Backporter.add_backport_trailer.__doc__, + ) + p_amd.add_argument("pick", help="commit that was cherry picked") + p_amd.set_defaults(func=lambda args: Backporter.add_backport_trailer(args.pick)) + + p_seq = sub.add_parser( + "_sequence-editor", + help="hook to update the rebase todo, meant for internal use", + ) + p_seq.add_argument("path", help="path to the rebase todo") + p_seq.set_defaults(func=lambda args: Backporter.sequence_editor(args.path)) + + args = p.parse_args() + args.func(args) + + +@dataclass(kw_only=True) +class Relabel: + """ + Replace the stable-nominated label with stable-applied, given the number of + a PR listing backported PRs. + + The backport PR should have a list of items like `* http://.../libc/pull/1234`. + """ + + pr_number: int + + def execute(self) -> None: + num = self.pr_number + j = check_output( + [ + "gh", + "pr", + "view", + f"https://github.com/{REPO_OWNER}/{REPO}/pull/{num}", + "--json=baseRefName,body,state,title", + ] + ) + d = json.loads(j) + base: str = d["baseRefName"] + body: str = d["body"] + state: str = d["state"] + title: str = d["title"] + + if state != "MERGED": + print(f'expected MERGED state; got {state} for "{title}" (#{num})') + exit(1) + if base != "libc-0.2": + print(f'expected libc-0.2 base ref; got {base} for "{title}" (#{num})') + exit(1) + + print(f'Relabling PRs listed in {num} "{title}"') + + to_relabel = [] + for line in body.splitlines(): + if not re.match(r"^[-*]\s*http", line): + continue + + match = re.match( + r"^[-*]\s*https?://github.com/rust-lang/libc/pull/(\d+)", line + ) + if match is None: + print( + f"{E.YEL}Line `{line}` does not match expected link pattern{E.RST}" + ) + continue + + num = int(match.group(1)) + to_relabel.append(num) + + # `gh` requests can be pretty slow, parallelize to help with large lists + with Pool() as p: + p.map(Relabel.do_relabel_inner, to_relabel) + + print("Finished relabeling") + + @staticmethod + def do_relabel_inner(num: int): + j = check_output(["gh", "pr", "view", pr_url(num), "--json=state,title,labels"]) + d = json.loads(j) + state: str = d["state"] + title: str = d["title"] + labels: list[str] = [i["name"] for i in d["labels"]] + + if state != "MERGED": + print( + f'{E.YEL}expected MERGED state; got {state} for "{title}" (#{num}){E.RST}' + ) + return + if "stable-nominated" not in labels: + print( + f'{E.YEL}`stable-nominated` not in labels for "{title}" (#{num}){E.RST}' + ) + + # Use check_output to eat the stdout since otherwise `gh` draws a spinner that + # messes up interleaved stdout. + check_output( + [ + "gh", + "pr", + "edit", + "--remove-label=stable-nominated", + "--add-label=stable-applied", + pr_url(num), + ] + ) + + +@dataclass(kw_only=True) +class MakeChangelog: + """ + Prepare a template with commits merged between `old-tag` and `new-ref`, for + appending to the changelog. + """ + + old_tag: str + new_ref: str + + def execute(self) -> None: + old_tag: str = self.old_tag + new_ref: str = self.new_ref + date = dt.datetime.now(dt.UTC).strftime("%Y-%m-%d") + split = old_tag.split(".") + split[2] = str(int(split[2]) + 1) # increment patch version + next_tag = ".".join(split) + + ret = cleandoc(f""" + ## [{next_tag}](https://github.com/rust-lang/libc/compare/{old_tag}...{next_tag}) - {date} + + ### Support + ### Added + ### Deprecated + ### Fixed + ### Changed + ### Removed + ### Other + """) + ret += "\n\n" + + changes = check_output( + [ + "git", + "log", + f"{old_tag}..{new_ref}", + "--no-merges", + "--oneline", + "--reverse", + ], + ).splitlines() + + print( + f"Generating changelog for {old_tag}..{new_ref}. Make sure {new_ref} " + "is up to date!" + ) + + for logline in changes: + sha = logline.split()[0] + summary = check_output(["git", "log", sha, "--format=%s", "-1"], quiet=True) + body = check_output(["git", "log", sha, "--format=%b", "-1"], quiet=True) + summary = summary.strip() + body = body.strip() + + link = None + + # Extract expected trailers + orig_sha_opt = re.search(r"\(cherry picked from commit (\w+)\)", body, re.M) + url_opt = re.search(r"^\(backport <(.*)>\)", body, re.M) + + # Prefer a PR URL if available + if url_opt is not None: + pr_url = url_opt[1] + pr_opt = re.match( + rf"https://github.com/{REPO_OWNER}/{REPO}/pull/(\d+)", pr_url + ) + if pr_opt is not None: + pr_num = pr_opt[1] + link = f"[#{pr_num}]({pr_url})" + + # If there is no PR URL, link the backported commit + if link is None and orig_sha_opt is not None: + orig_sha = orig_sha_opt[1] + short = orig_sha[:12] + link = f"[{short}](https://github.com/rust-lang/libc/commit/{orig_sha})" + + # If there is no PR URL or cherry pick commit, link the commit itself + if link is None: + patch_sha = check_output(["git", "rev-parse", sha], quiet=True).strip() + short = patch_sha[:12] + link = ( + f"[{short}](https://github.com/rust-lang/libc/commit/{patch_sha})" + ) + + line = f"- {summary} ({link})" + + ret += "\n" + ret += line + + print( + "Copy the below to CHANGELOG.md, then sort log messages into the " + "relevant categories:\n" + ) + print(ret) + + +@dataclass(kw_only=True) +class CheckAllTargets: + """ + Run `cargo check` on all targets, possibly with filtering. + + Query `rustc` for a list of supported targets, then run `cargo check` on each. + `-Zbuild-std` is used if the toolchain is not installed. + + This uses a pinned toolchain and a separate target directory in + `~/.cache/libc-build`. This is done to avoid accidental cache deletion with `cargo + clean` or invalidation by changing toolchain, since the initial build takes so long + that it can be worth keeping the cache around. + + The pinned toolchain can be overridden by setting RUSTC_CACHE_TOOLCHAIN. + """ + + toolchain: str + targets: list["RustcTarget"] + checks: list["CheckInvocation"] + failure_limit: int + + FREEBSD_VERSIONS = [13, 14, 15] + + # Targets that don't pass for one reason or another + BROKEN_TARGETS = [ + # libc problems + ("aarch64-unknown-nto-qnx800", "libc error, unsupported arch"), + ("aarch64.*-gnu_ilp32.*time_bits=64", "libc error, time64 mismatches"), + ("armv6k-nintendo-3ds", "libc error, stat missing"), + ("armv7-sony-vita-newlibeabihf", "libc error, stat missing"), + ("csky.*gnu.*time_bits=64", "libc error, time64 mismatches"), + ("i686-pc-nto-qnx700", "libc error, unsupported arch"), + ("managarm-mlibc", "libc error, unresolved import"), + ("x86_64-lynx-lynxos178", "libc error, unresolved import"), + ("x86_64-pc-nto-qnx800", "libc error, unsupported arch"), + ("x86_64-unknown-linux-none", "libc error, unresolved import"), + # rustc problems + ("xtensa-esp32.*", "target string mismatch in rustc"), + ("amdgcn-amd-amdhsa", "unsupported instructions with some CPUs"), + # llvm problems + ("m68k-unknown-.*", "llvm crash building core"), + ("mipsisa32r6(el)?-.*", "llvm crash building core"), + ] + + # Flags that always need to be passed to specific targets + EXTRA_TARGET_FLAGS = { + # Target CPU must be specified + "avr-none": ["-Ctarget-cpu=atmega328p"], + # Emits a lot of warnings + "hexagon-unknown-qurt": ["-Aunused_imports"], + } + + @staticmethod + def prepare() -> "CheckAllTargets": + """Build a list of checks.""" + toolchain = CheckAllTargets.get_cache_toolchain() + target_dir = cache_dir() / "libc-build" / toolchain + all_targets = RustcTarget.fetch_all(toolchain) + installed_targets = check_output( + [ + "rustup", + "target", + "list", + "--installed", + f"--toolchain={toolchain}", + ] + ).splitlines() + checks: list[CheckInvocation] = [] + + # Add a check for each target and, if applicable, a variant for any cfg options + # that also make sense to check. + for t in all_targets: + base = CheckInvocation( + target=t.triple, + name="", + target_dir=target_dir, + attributes={}, + installed=t.triple in installed_targets, + skip=[], + extra_rustflags=[], + ) + + new_checks = [base] + + # When doing variants, use a separate target directory because otherwise + # running twice with different `RUSTFLAGS` is a cache miss. + + if t.os_ == "freebsd": + new_checks.clear() + for vers in CheckAllTargets.FREEBSD_VERSIONS: + new = copy.deepcopy(base) + new.attributes = base.attributes | {"freebsd": str(vers)} + new.target_dir = base.target_dir / f"freebsd-{vers}" + new.extra_rustflags = base.extra_rustflags + [ + f'--cfg=libc_unstable_freebsd_version="{vers}"' + ] + + new_checks.append(new) + + if t.env == "gnu" and t.bits == 32: + new = copy.deepcopy(base) + new.attributes = base.attributes | {"time_bits": "64"} + new.target_dir = base.target_dir / "time64" + new.extra_rustflags = base.extra_rustflags + [ + '--cfg=libc_unstable_gnu_time_bits="64"' + ] + new_checks.append(new) + + if t.env == "musl" and t.bits == 32: + new = copy.deepcopy(base) + new.attributes = base.attributes | {"time_bits": "64"} + new.target_dir = base.target_dir / "time64" + new.extra_rustflags = base.extra_rustflags + [ + "--cfg=libc_unstable_musl_v1_2_3" + ] + new_checks.append(new) + + # Update the name field and check whether there are any targets that we + # always need to skip, or that need flags. + for check in new_checks: + if len(check.attributes) == 0: + check.name = f"{check.target} (default)" + else: + attrs = ",".join(f"{k}={v}" for (k, v) in check.attributes.items()) + check.name = f"{check.target} ({attrs})" + + for pat, reason in CheckAllTargets.BROKEN_TARGETS: + if check.pattern_matches(pat): + check.skip.append(reason) + + for pat, flags in CheckAllTargets.EXTRA_TARGET_FLAGS.items(): + if check.pattern_matches(pat): + check.extra_rustflags.extend(flags) + + checks.extend(new_checks) + + return CheckAllTargets( + toolchain=toolchain, + targets=all_targets, + checks=checks, + failure_limit=5, + ) + + def check_all_targets( + self, + *, + package: str, + only: str | None = None, + skip: str | None = None, + cargo_args: list[str] = [], + ) -> None: + """Run checks from the populated list.""" + checks = self.checks + ran = 0 + passed = 0 + skipped = 0 + failures = [] + matched_only_already_skipped = [] + + if only is not None: + for t in checks: + if t.pattern_matches(only): + if t.skip: + matched_only_already_skipped.append(t.name) + continue + t.skip.append("does not match --only pattern") + + if skip is not None: + for t in checks: + if not t.pattern_matches(skip): + continue + t.skip.append("matches --skip pattern") + + # `sum(1 for _ in ...)` seems to be the best way to get an iterator's count + total = sum(1 for _ in (t for t in checks if not t.skip)) + + # List skips first so the interesting output is together at the bottom + checks.sort(key=lambda t: len(t.skip) == 0) + + env = os.environ.copy() + env_rustflags = env.get("RUSTFLAGS") + + for t in checks: + fulldesc = f"{t.name} ({ran + 1} / {total})" + + if len(t.skip) > 0: + print(f"{E.YEL}Skipping {fulldesc} ({", ".join(t.skip)}){E.RST}") + skipped += 1 + continue + + print(f"{E.CY_B}Checking {fulldesc}{E.RST}") + + extra_args = [] if t.installed else ["-Zbuild-std=core"] + common_args = [ + f"--package={package}", + f"--target={t.target}", + ] + + # We aim to be warning-free + rustflags = ["-Dwarnings"] + rustflags += t.extra_rustflags + + # Allow forwarding rustflags + if env_rustflags is not None: + rustflags += [env_rustflags] + + print(f" {E.GRN_D}Running build{E.RST}") + + try: + run( + [ + "cargo", + f"+{self.toolchain}", + "check", + f"--target-dir={t.target_dir}", + ] + + common_args + + extra_args + + cargo_args, + env=env | {"RUSTFLAGS": " ".join(rustflags)}, + ) + ok = True + except sp.CalledProcessError: + ok = False + + ran += 1 + + if ok: + passed += 1 + else: + print(f"{E.RED_B}failed: {t.target}{E.RST}") + failures.append(t.name) + + if len(failures) > self.failure_limit: + break + + print( + f"finished checking {ran} targets. {passed} passed, " + f"{len(failures)} failed, {skipped} skipped" + ) + if len(matched_only_already_skipped) > 0: + print( + f"note: {len(matched_only_already_skipped)} targets matched `--only` " + "but were already skipped" + ) + + if len(failures) > 0: + print("failures:") + pprint.pp(failures) + + @staticmethod + def get_cache_toolchain() -> str: + # Arbitrary but reasonably recent default if unset. + return os.environ.get("RUSTC_CACHE_TOOLCHAIN") or "nightly-2026-06-24" + + +@dataclass(kw_only=True) +class CheckInvocation: + """Config for a single invocation of `cargo check`.""" + + target: str + name: str # target plus attributes + target_dir: Path + installed: bool + attributes: dict[str, str] + # skip reasons, empty if we shouldn't skip + skip: list[str] + extra_rustflags: list[str] + + def pattern_matches(self, pat: str) -> bool: + """Ensure pattern matching is applied consistently""" + assert self.name != "" + return re.search(pat, self.name) is not None + + +@dataclass(kw_only=True) +class Backporter: + """Prepare an interactive rebase that will cherry pick commits to `libc-0.2`. + + This loosely does the following: + + * Create a git worktree at `.libc-backports` + * Switch to the specified branch + * Start an interactive rebase that runs `git cherry-pick -x ` for each needed + commit, then modify the commit to add the `(cherry picked from ...)` and + `(backport ...)` trailers. + + An interactive rebase is used because it's a nice way to create and execute a series + of shell commands with a chance to resolve conflicts and continue as needed. + + Because it is standard `git rebase`, it is possible to use typical options like + `git rebase --edit-todo` if it pauses due to conflicts. + """ + + branch: str + + WORKTREE_DIR = ".libc-backports" + WORKTREE_GIT = ["git", "-C", WORKTREE_DIR] + GQL_QUERY = """ + query ($endCursor: String) { + repository(name: "libc", owner: "rust-lang") { + pullRequests( + first: 25 + after: $endCursor + baseRefName: "main" + states: MERGED + labels: ["stable-nominated"] + # Ordering by merge date is not supported, we need to re-sort after fetch. + orderBy: {field: CREATED_AT, direction: ASC} + ) { + nodes { + title + number + state + url + author { + login + } + mergedAt + mergeCommit { + oid + committedDate + messageHeadline + author { + name + user { + login + } + } + } + commits(first: 100) { + totalCount + nodes { + commit { + oid + committedDate + messageHeadline + author { + name + user { + login + } + } + } + } + } + } + pageInfo { + hasNextPage + endCursor + } + } + } + } + """ + + def start_backports(self) -> None: + self.ensure_local_updated() + + try: + self.ensure_branch() + self.ensure_worktree() + self.prepare_rebase_todo() + seq_ed = "../etc/libc-util.py _sequence-editor" + run( + self.WORKTREE_GIT + ["rebase", "-i", "libc-0.2"], + env=os.environ | {"GIT_SEQUENCE_EDITOR": seq_ed}, + ) + # Give the user a chance to delete picks if desired + print("Presenting rebase todo to user for review...") + run(self.WORKTREE_GIT + ["rebase", "--edit-todo"]) + run(self.WORKTREE_GIT + ["rebase", "--continue"]) + except sp.CalledProcessError: + msg = f""" + {E.YEL}Rebase failed or incomplete; check the git error above for + details. + + If git stopped because of a conflict or other resolvable error, change + to the worktree directory at {self.WORKTREE_DIR}. From there, you can + resolve conflicts or `git rebase --quit` to stop trying to backport the + rest of the commits. + + If needed, `git worktree remove .libc-backports` will allow you to + delete the branch and start from scratch.{E.RST} + """ + print("\n" + mstr(msg)) + exit(1) + + def prepare_rebase_todo(self) -> None: + """Create a rebase todo list and cache it, to be picked up by the sequence + editor. + """ + # Start with a break so we can `--edit-todo` + rebase_todo = "break\n" + commit_map = "" + + pull_requests = self.fetch_needs_backport_list() + for pr in pull_requests: + last_sha = pr.merge_commit.oid + parents = check_output( + ["git", "log", last_sha, "--format=%P", "-1"], quiet=True + ).split() + + # If we have a merge commit, take only the second (incoming) commit. + if len(parents) > 2: + eprint("Can't backport commits with >1 parent") + exit(1) + if len(parents) == 2: + last_sha = parents[1] + + # The commit list is not what we actually want to cherry pick; it has the + # refs for the commits in the PR but not the ref after merge. The PR's + # "merge" commit is the last commit on `main` from this PR, so we can + # work backwards; given N commits, `merge_sha~(N-1)` will be the first PR + # from the commit on `main`. + for i in reversed(range(len(pr.commits))): + n_back = len(pr.commits) - i - 1 + pick_sha = check_output( + ["git", "rev-parse", f"{last_sha}~{n_back}"], quiet=True + ).strip() + subject = check_output( + ["git", "log", pick_sha, "--format=%s", "-1"], quiet=True + ).strip() + pick_short = pick_sha[:12] + rebase_todo += ( + f"exec printf '{E.CY_B.u}picking from PR{pr.number}: {pick_short} " + f'"{subject}"{E.RST.u}\\n\'' + "\n" + f'pick {pick_short} # pick "{subject}"' + "\n" + f"exec ../etc/libc-util.py add-backport-trailer {pick_short}" + "\n\n" + ) + commit_map += f"{pick_sha} {pr.number}\n" + + todo_path = self.rebase_todo_tmp_path() + # may need to create `target/libc-util` + todo_path.parent.parent.mkdir(exist_ok=True) + todo_path.parent.mkdir(exist_ok=True) + todo_path.write_text(rebase_todo) + + self.commit_map_path().write_text(commit_map) + + def fetch_needs_backport_list(self) -> list["PullRequest"]: + """Fetch PRs labeled `stable-nominated` via the GraphQL API""" + s = check_output( + [ + "gh", + "api", + "graphql", + "--paginate", + "--slurp", + "-f", + "query=" + self.GQL_QUERY, + ] + ) + j: list[dict] = json.loads(s) + + # The result is paginated so we get nested lists. Extract the data we want + # then flatten. + pages = [page["data"]["repository"]["pullRequests"]["nodes"] for page in j] + pr_nodes = [pr_node for page in pages for pr_node in page] + + pull_requests: list[PullRequest] = [] + for pr in pr_nodes: + commits = [node["commit"] for node in pr["commits"]["nodes"]] + + new = PullRequest( + title=pr["title"], + number=int(pr["number"]), + state=pr["state"], + url=pr["url"], + author_username=pr["author"]["login"], + merged_at=pr["mergedAt"], + merge_commit=Commit.from_object(pr["mergeCommit"]), + commits=[Commit.from_object(c) for c in commits], + ) + + total_commits = int(pr["commits"]["totalCount"]) + new_commit_count = len(new.commits) + if total_commits != new_commit_count: + print( + f"limit reached: {total_commits} total commits but could " + f"only fetch {new_commit_count}" + ) + exit(1) + + pull_requests.append(new) + + # Oldest to newest + pull_requests.sort(key=lambda pr: pr.merged_at) + return pull_requests + + def ensure_local_updated(self) -> None: + """Sanity check that whatever we want to rebase onto is actually updated, and + fetch `main` to ensure cherry pick sources exist locally.""" + + run(["git", "fetch", repo_fetch_url(), "main"]) + run(["git", "fetch", repo_fetch_url(), "libc-0.2"]) + upstream = check_output(["git", "rev-parse", "FETCH_HEAD"]).strip() + local = check_output(["git", "rev-parse", "libc-0.2"]).strip() + + if upstream != local: + print( + f"local libc-0.2@{local[:12]} does not match upstream/libc-0.2@{upstream[:12]}!" + "Fetch before retrying." + ) + exit(1) + + def ensure_branch(self) -> None: + """Create the branch if it doesn't exist.""" + try: + run(["git", "branch", self.branch, "libc-0.2"], stderr=sp.PIPE) + except sp.CalledProcessError: + pass + + def ensure_worktree(self) -> None: + """Set up a worktree pointing to the target branch.""" + # Prune in case the directory was deleted without going via git. + run(["git", "worktree", "prune"]) + + try: + print("creating worktree") + run( + ["git", "worktree", "add", ".libc-backports", self.branch], + stderr=sp.PIPE, + ) + except sp.CalledProcessError: + print("worktree already exists, checking out branch") + run(self.WORKTREE_GIT + ["switch", self.branch]) + + @staticmethod + def sequence_editor(path: str) -> None: + """The script-y way to construct a rebase is by setting the "sequence editor" to + a script that gets the rebase todo path. That's all this function does, the + needed contents have already been written. + """ + + print(f"editing rebase todo at {path}") + + txt = "\n\n" + txt += Backporter.rebase_todo_tmp_path().read_text() + + with Path(path).open("a") as f: + f.write(txt) + + @staticmethod + def add_backport_trailer(pick: str) -> None: + """Add `(backport ...)` to the previous commit, using `(cherry picked from ...)` + to know where the commit came from. + """ + head_summary = check_output(["git", "log", "-1", "HEAD", "--format=%s"]).strip() + pick_summary = check_output(["git", "log", "-1", pick, "--format=%s"]).strip() + head_message = check_output(["git", "log", "-1", "HEAD", "--format=%B"]).strip() + head = check_output(["git", "rev-parse", "HEAD"]).strip() + pick = check_output(["git", "rev-parse", pick]).strip() + + existing_pick_msg = re.search( + r"^\(cherry picked from commit (\w+)\)", head_message, re.M + ) + existing_backport_msg = re.search(r"^\(backport.*\)", head_message, re.M) + + if existing_pick_msg is not None: + print( + f"{E.YEL}Commit {head} already contains cherry-pick trailer; " + f"skipping{E.RST}" + ) + return + + if existing_backport_msg is not None: + print( + f"{E.YEL}Commit {head} already contains backport trailer; " + f"skipping{E.RST}" + ) + return + + if head_summary != pick_summary: + print( + f"{E.YEL}Commit {head} summary does not match pick {pick} " + f"summary; skipping{E.RST}" + ) + return + + commit_map = Backporter.commit_map_path().read_text() + pr = None + for line in commit_map.splitlines(): + if not line.startswith(pick): + continue + _, _, pr = line.partition(" ") + break + + if pr is None: + print(f"{E.YEL}could not locate PR for picked commit {pick}{E.RST}") + return + + new_message = head_message.strip() + new_message += f"\n\n(backport <{pr_url(int(pr))}>)" + new_message += f"\n(cherry picked from commit {pick})\n" + run(["git", "commit", "--amend", "--message", new_message]) + + @staticmethod + def backport_pr_description(branch: str) -> None: + """List all backported commits for a branch, for pasting into the PR body.""" + commits = check_output(["git", "log", f"libc-0.2..{branch}", "--format=%b"]) + urls = {x[1] for x in re.finditer(r"^\(backport <(.*)>\)", commits, re.M)} + urls = sorted(list(urls)) + + s = "Backport the following:\n\n" + for url in urls: + s += f"* {url}\n" + + print(s) + + @staticmethod + def rebase_todo_tmp_path() -> Path: + """Rebase todo to be appended to the default""" + return Path(__file__).parent.parent / "target" / "libc-util" / "rebase-todo.txt" + + @staticmethod + def commit_map_path() -> Path: + """List of ` ` mappings.""" + return Path(__file__).parent.parent / "target" / "libc-util" / "commit-map.txt" + + +@dataclass(kw_only=True) +class RustcTarget: + """Config queried from rustc.""" + + triple: str + arch: str + os_: str | None + env: str | None + bits: int + + @staticmethod + @functools.cache + def get_one(toolchain: str, triple: str) -> "RustcTarget": + target_cfg = check_output( + ["rustc", f"+{toolchain}", "--print=cfg", f"--target={triple}"], quiet=True + ) + return RustcTarget( + triple=triple, + arch=re.findall(r'target_arch="(.*)"', target_cfg)[0], + env=re.findall(r'target_env="(.*)"', target_cfg)[0], + os_=re.findall(r'target_os="(.*)"', target_cfg)[0], + bits=int(re.findall(r'target_pointer_width="(.*)"', target_cfg)[0]), + ) + + @staticmethod + @functools.cache + def fetch_all(toolchain: str) -> list["RustcTarget"]: + """Collect all targets for a given toolchain.""" + all_targets = check_output( + ["rustc", f"+{toolchain}", "--print=target-list"] + ).splitlines() + + # Iterating targets is really slow, throw some threads at it. + with Pool() as p: + ret = p.starmap(RustcTarget.get_one, [(toolchain, t) for t in all_targets]) + + ret.sort(key=lambda t: t.triple) + return ret + + +@dataclass(kw_only=True) +class PullRequest: + """Pull request built from a GitHub GraphQL API response""" + + title: str + number: int + state: str + url: str + author_username: str + merged_at: str + merge_commit: "Commit" + commits: list["Commit"] + + +@dataclass(kw_only=True) +class Commit: + """Commit built from a GitHub GraphQL API response""" + + oid: str + committed_date: str + subject: str + author_name: str + author_username: str | None + + def __post_init__(self) -> None: + # Give some protection against multiline summaries, since that may confuse + # scripts or log messages. + self.subject = trunc_lines(self.subject) + self.author_name = trunc_lines(self.author_name) + if self.author_username is not None: + self.author_username = trunc_lines(self.author_username) + + @staticmethod + def from_object(obj) -> "Commit": + user = obj["author"]["user"] + return Commit( + oid=obj["oid"], + committed_date=obj["committedDate"], + subject=obj["messageHeadline"], + author_name=obj["author"]["name"], + author_username=user["login"] if user is not None else None, + ) + + +class E(StrEnum): + """ANSI escapes.""" + + YEL = "\033[33m" + GRN = "\033[32m" + + # Bright colors + CY_B = "\033[1;36m" + YEL_B = "\033[1;33m" + RED_B = "\033[1;31m" + + # Dimmed colors + DIM = "\033[2m" + YEL_D = "\033[2;33m" + GRN_D = "\033[2;32m" + + RST = "\033[0m" + + @property + def u(self) -> str: + """Unescape, for passing to shell printf.""" + return self.replace("\033", "\\033") + + +@functools.cache +def cache_dir() -> Path: + xdg_cache = os.environ.get("XDG_CACHE_DIR") + if xdg_cache is not None: + return Path(xdg_cache) + return Path.home() / ".cache" + + +def repo_fetch_url() -> str: + return f"https://github.com/{REPO_OWNER}/{REPO}.git" + + +def pr_url(num: int) -> str: + return f"https://github.com/{REPO_OWNER}/{REPO}/pull/{num}" + + +def mstr(s: str) -> str: + """Message string: clean an indented string and convert singular `\\n`s to spaces.""" + return re.sub(r"(\S)\n(\S)", r"\1 \2", cleandoc(s)) + + +def check_output(args: list[str], *, quiet: bool = False, **kw) -> str: + if not quiet: + xtrace(args, env=kw.get("env")) + return sp.check_output(args, encoding="utf8", text=True, **kw) + + +def run(args: list[str], *, quiet: bool = False, **kw) -> sp.CompletedProcess: + if not quiet: + xtrace(args, env=kw.get("env")) + return sp.run(args, check=True, text=True, **kw) + + +def xtrace(args: list[str], *, env: dict[str, str] | None) -> None: + """Print commands before running them.""" + astr = " ".join(str(arg) for arg in args) + + # GQL commands are long, trim the next line + astr = trunc_lines(astr) + + if env is None: + eprint(f"{E.DIM}+ {astr}{E.RST}") + else: + envdiff = set(env.items()) - set(os.environ.items()) + estr = " ".join(f"{k}='{v}'" for (k, v) in envdiff) + eprint(f"{E.DIM}+ {estr} {astr}{E.RST}") + + +def trunc_lines(s: str) -> str: + """If >1 line, replace other lines with `...`.""" + first, _, rest = s.partition("\n") + if rest != "": + first += " ..." + return first + + +def eprint(*args, **kw) -> None: + print(*args, file=sys.stderr, **kw) + + +if __name__ == "__main__": + main() diff --git a/vendor/libc/src/fuchsia/aarch64.rs b/vendor/libc/src/fuchsia/aarch64.rs new file mode 100644 index 0000000..93090f7 --- /dev/null +++ b/vendor/libc/src/fuchsia/aarch64.rs @@ -0,0 +1,69 @@ +use crate::off_t; +use crate::prelude::*; + +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: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad0: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + __pad1: Padding, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_uint; 2]>, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad0: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + __pad1: Padding, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_uint; 2]>, + } + + pub struct ipc_perm { + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: c_ushort, + __unused1: Padding, + __unused2: Padding, + } +} + +// From https://cs.opensource.google/fuchsia/fuchsia/+/main:zircon/third_party/ulib/musl/include/bits/signal.h;l=20-21;drc=0827b18ab9540c46f8037f407d17ea15a79e9ba7 +pub const MINSIGSTKSZ: size_t = 6144; +pub const SIGSTKSZ: size_t = 12288; diff --git a/vendor/libc/src/fuchsia/mod.rs b/vendor/libc/src/fuchsia/mod.rs new file mode 100644 index 0000000..4c2dcec --- /dev/null +++ b/vendor/libc/src/fuchsia/mod.rs @@ -0,0 +1,4028 @@ +//! 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. + +use crate::prelude::*; + +// PUB_TYPE + +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; + +extern_ty! { + pub type timezone; + pub type DIR; + pub type fpos64_t; // FIXME(fuchsia): fill this out with a struct +} + +// Deprecated impls: see #5296 +unsafe impl Send for DIR {} +unsafe impl Sync for DIR {} + +// PUB_STRUCT + +s! { + pub struct group { + pub gr_name: *mut c_char, + pub gr_passwd: *mut c_char, + pub gr_gid: crate::gid_t, + pub gr_mem: *mut *mut c_char, + } + + pub struct utimbuf { + pub actime: time_t, + pub modtime: time_t, + } + + #[derive(Default)] + pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: suseconds_t, + } + + #[derive(Default)] + pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: c_long, + } + + // FIXME(fuchsia): 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: Padding, + pub ru_ixrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad2: Padding, + pub ru_idrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad3: Padding, + pub ru_isrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad4: Padding, + pub ru_minflt: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad5: Padding, + pub ru_majflt: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad6: Padding, + pub ru_nswap: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad7: Padding, + pub ru_inblock: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad8: Padding, + pub ru_oublock: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad9: Padding, + pub ru_msgsnd: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad10: Padding, + pub ru_msgrcv: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad11: Padding, + pub ru_nsignals: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad12: Padding, + pub ru_nvcsw: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad13: Padding, + pub ru_nivcsw: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad14: Padding, + } + + 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: crate::timeval, + pub it_value: crate::timeval, + } + + // + pub struct tms { + pub tms_utime: crate::clock_t, + pub tms_stime: crate::clock_t, + pub tms_cutime: crate::clock_t, + pub tms_cstime: crate::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: crate::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], + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + pub struct termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; crate::NCCS], + pub __c_ispeed: crate::speed_t, + pub __c_ospeed: crate::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: crate::pid_t, + } + + pub struct ucred { + pub pid: crate::pid_t, + pub uid: crate::uid_t, + pub gid: crate::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: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_zero: [u8; 8], + } + + pub struct sockaddr_in6 { + pub sin6_family: sa_family_t, + pub sin6_port: crate::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: crate::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct sockaddr_vm { + pub svm_family: sa_family_t, + svm_reserved1: Padding, + pub svm_port: crate::in_port_t, + pub svm_cid: c_uint, + pub svm_zero: [u8; 4], + } + + 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 crate::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 as usize / 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: crate::timespec, + pub sched_ss_init_budget: crate::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: Padding<*mut c_void>, + __unused2: Padding<*mut c_void>, + __unused3: Padding<*mut c_void>, + __unused4: Padding<*mut c_void>, + __unused5: Padding<*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 crate::sockaddr, + pub ifa_netmask: *mut crate::sockaddr, + pub ifa_ifu: *mut crate::sockaddr, // FIXME(union) 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: crate::uid_t, + pub pw_gid: crate::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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::fsfilcnt_t, + #[cfg(target_endian = "little")] + pub f_fsid: c_ulong, + #[cfg(all(target_pointer_width = "32", not(target_arch = "x86_64")))] + __f_unused: Padding, + #[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: Padding, + pub ssi_syscall: i32, + pub ssi_call_addr: u64, + pub ssi_arch: u32, + _pad: Padding<[u8; 28]>, + } + + pub struct itimerspec { + pub it_interval: crate::timespec, + pub it_value: crate::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: crate::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: crate::timeval, + pub type_: crate::__u16, + pub code: crate::__u16, + pub value: crate::__s32, + } + + pub struct input_id { + pub bustype: crate::__u16, + pub vendor: crate::__u16, + pub product: crate::__u16, + pub version: crate::__u16, + } + + pub struct input_absinfo { + pub value: crate::__s32, + pub minimum: crate::__s32, + pub maximum: crate::__s32, + pub fuzz: crate::__s32, + pub flat: crate::__s32, + pub resolution: crate::__s32, + } + + pub struct input_keymap_entry { + pub flags: crate::__u8, + pub len: crate::__u8, + pub index: crate::__u16, + pub keycode: crate::__u32, + pub scancode: [crate::__u8; 32], + } + + pub struct input_mask { + pub type_: crate::__u32, + pub codes_size: crate::__u32, + pub codes_ptr: crate::__u64, + } + + pub struct ff_replay { + pub length: crate::__u16, + pub delay: crate::__u16, + } + + pub struct ff_trigger { + pub button: crate::__u16, + pub interval: crate::__u16, + } + + pub struct ff_envelope { + pub attack_length: crate::__u16, + pub attack_level: crate::__u16, + pub fade_length: crate::__u16, + pub fade_level: crate::__u16, + } + + pub struct ff_constant_effect { + pub level: crate::__s16, + pub envelope: ff_envelope, + } + + pub struct ff_ramp_effect { + pub start_level: crate::__s16, + pub end_level: crate::__s16, + pub envelope: ff_envelope, + } + + pub struct ff_condition_effect { + pub right_saturation: crate::__u16, + pub left_saturation: crate::__u16, + + pub right_coeff: crate::__s16, + pub left_coeff: crate::__s16, + + pub deadband: crate::__u16, + pub center: crate::__s16, + } + + pub struct ff_periodic_effect { + pub waveform: crate::__u16, + pub period: crate::__u16, + pub magnitude: crate::__s16, + pub offset: crate::__s16, + pub phase: crate::__u16, + + pub envelope: ff_envelope, + + pub custom_len: crate::__u32, + pub custom_data: *mut crate::__s16, + } + + pub struct ff_rumble_effect { + pub strong_magnitude: crate::__u16, + pub weak_magnitude: crate::__u16, + } + + pub struct ff_effect { + pub type_: crate::__u16, + pub id: crate::__s16, + pub direction: crate::__u16, + pub trigger: ff_trigger, + pub replay: ff_replay, + // FIXME(1.0): 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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::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: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: c_ulong, + __pad1: Padding, + __pad2: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + pub msg_stime: crate::time_t, + pub msg_rtime: crate::time_t, + pub msg_ctime: crate::time_t, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __pad1: Padding, + __pad2: Padding, + } + + pub struct statfs { + pub f_type: c_ulong, + pub f_bsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::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: crate::socklen_t, + pub msg_iov: *mut crate::iovec, + pub msg_iovlen: c_int, + __pad1: Padding, + pub msg_control: *mut c_void, + pub msg_controllen: crate::socklen_t, + __pad2: Padding, + pub msg_flags: c_int, + } + + pub struct cmsghdr { + pub cmsg_len: crate::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: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; 19], + pub c_ispeed: crate::speed_t, + pub c_ospeed: crate::speed_t, + } + + pub struct in6_pktinfo { + pub ipi6_addr: crate::in6_addr, + pub ipi6_ifindex: c_uint, + } + + #[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; crate::__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; crate::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + size: [u8; crate::__SIZEOF_PTHREAD_CONDATTR_T], + } + + 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, + __reserved: Padding<[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: Padding<[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: crate::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: crate::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: Padding<[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: Padding<[c_long; 4]>, + } + + pub struct sockaddr_nl { + pub nl_family: crate::sa_family_t, + nl_pad: Padding, + pub nl_pid: u32, + pub nl_groups: u32, + } + + // FIXME(msrv): suggested method was added in 1.85 + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigevent { + pub sigev_value: crate::sigval, + pub sigev_signo: c_int, + pub sigev_notify: c_int, + pub sigev_notify_function: fn(crate::sigval), + pub sigev_notify_attributes: *mut pthread_attr_t, + pub __pad: [c_char; 56 - 3 * 8], + } + + #[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; crate::__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; crate::__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; crate::__SIZEOF_PTHREAD_COND_T], + } +} + +// 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: crate::clockid_t = 0; +pub const CLOCK_MONOTONIC: crate::clockid_t = 1; +pub const CLOCK_PROCESS_CPUTIME_ID: crate::clockid_t = 2; +pub const CLOCK_THREAD_CPUTIME_ID: crate::clockid_t = 3; +pub const CLOCK_MONOTONIC_RAW: crate::clockid_t = 4; +pub const CLOCK_REALTIME_COARSE: crate::clockid_t = 5; +pub const CLOCK_MONOTONIC_COARSE: crate::clockid_t = 6; +pub const CLOCK_BOOTTIME: crate::clockid_t = 7; +pub const CLOCK_REALTIME_ALARM: crate::clockid_t = 8; +pub const CLOCK_BOOTTIME_ALARM: crate::clockid_t = 9; +pub const CLOCK_SGI_CYCLE: crate::clockid_t = 10; +pub const CLOCK_TAI: crate::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 = 0o1_0000; +pub const S_IFCHR: mode_t = 0o2_0000; +pub const S_IFBLK: mode_t = 0o6_0000; +pub const S_IFDIR: mode_t = 0o4_0000; +pub const S_IFREG: mode_t = 0o10_0000; +pub const S_IFLNK: mode_t = 0o12_0000; +pub const S_IFSOCK: mode_t = 0o14_0000; +pub const S_IFMT: mode_t = 0o17_0000; +pub const S_IRWXU: mode_t = 0o0700; +pub const S_IXUSR: mode_t = 0o0100; +pub const S_IWUSR: mode_t = 0o0200; +pub const S_IRUSR: mode_t = 0o0400; +pub const S_IRWXG: mode_t = 0o0070; +pub const S_IXGRP: mode_t = 0o0010; +pub const S_IWGRP: mode_t = 0o0020; +pub const S_IRGRP: mode_t = 0o0040; +pub const S_IRWXO: mode_t = 0o0007; +pub const S_IXOTH: mode_t = 0o0001; +pub const S_IWOTH: mode_t = 0o0002; +pub const S_IROTH: mode_t = 0o0004; +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 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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 = u32_cast_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: crate::tcflag_t = 0x00000001; +pub const BRKINT: crate::tcflag_t = 0x00000002; +pub const IGNPAR: crate::tcflag_t = 0x00000004; +pub const PARMRK: crate::tcflag_t = 0x00000008; +pub const INPCK: crate::tcflag_t = 0x00000010; +pub const ISTRIP: crate::tcflag_t = 0x00000020; +pub const INLCR: crate::tcflag_t = 0x00000040; +pub const IGNCR: crate::tcflag_t = 0x00000080; +pub const ICRNL: crate::tcflag_t = 0x00000100; +pub const IXANY: crate::tcflag_t = 0x00000800; +pub const IMAXBEL: crate::tcflag_t = 0x00002000; +pub const OPOST: crate::tcflag_t = 0x1; +pub const CS5: crate::tcflag_t = 0x00000000; +pub const CRTSCTS: crate::tcflag_t = 0x80000000; +pub const ECHO: crate::tcflag_t = 0x00000008; +pub const OCRNL: crate::tcflag_t = 0o000010; +pub const ONOCR: crate::tcflag_t = 0o000020; +pub const ONLRET: crate::tcflag_t = 0o000040; +pub const OFILL: crate::tcflag_t = 0o000100; +pub const OFDEL: crate::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 = u32_cast_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 = u32_cast_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: crate::nl_item = 0x20000; +pub const ABDAY_2: crate::nl_item = 0x20001; +pub const ABDAY_3: crate::nl_item = 0x20002; +pub const ABDAY_4: crate::nl_item = 0x20003; +pub const ABDAY_5: crate::nl_item = 0x20004; +pub const ABDAY_6: crate::nl_item = 0x20005; +pub const ABDAY_7: crate::nl_item = 0x20006; + +pub const DAY_1: crate::nl_item = 0x20007; +pub const DAY_2: crate::nl_item = 0x20008; +pub const DAY_3: crate::nl_item = 0x20009; +pub const DAY_4: crate::nl_item = 0x2000A; +pub const DAY_5: crate::nl_item = 0x2000B; +pub const DAY_6: crate::nl_item = 0x2000C; +pub const DAY_7: crate::nl_item = 0x2000D; + +pub const ABMON_1: crate::nl_item = 0x2000E; +pub const ABMON_2: crate::nl_item = 0x2000F; +pub const ABMON_3: crate::nl_item = 0x20010; +pub const ABMON_4: crate::nl_item = 0x20011; +pub const ABMON_5: crate::nl_item = 0x20012; +pub const ABMON_6: crate::nl_item = 0x20013; +pub const ABMON_7: crate::nl_item = 0x20014; +pub const ABMON_8: crate::nl_item = 0x20015; +pub const ABMON_9: crate::nl_item = 0x20016; +pub const ABMON_10: crate::nl_item = 0x20017; +pub const ABMON_11: crate::nl_item = 0x20018; +pub const ABMON_12: crate::nl_item = 0x20019; + +pub const MON_1: crate::nl_item = 0x2001A; +pub const MON_2: crate::nl_item = 0x2001B; +pub const MON_3: crate::nl_item = 0x2001C; +pub const MON_4: crate::nl_item = 0x2001D; +pub const MON_5: crate::nl_item = 0x2001E; +pub const MON_6: crate::nl_item = 0x2001F; +pub const MON_7: crate::nl_item = 0x20020; +pub const MON_8: crate::nl_item = 0x20021; +pub const MON_9: crate::nl_item = 0x20022; +pub const MON_10: crate::nl_item = 0x20023; +pub const MON_11: crate::nl_item = 0x20024; +pub const MON_12: crate::nl_item = 0x20025; + +pub const AM_STR: crate::nl_item = 0x20026; +pub const PM_STR: crate::nl_item = 0x20027; + +pub const D_T_FMT: crate::nl_item = 0x20028; +pub const D_FMT: crate::nl_item = 0x20029; +pub const T_FMT: crate::nl_item = 0x2002A; +pub const T_FMT_AMPM: crate::nl_item = 0x2002B; + +pub const ERA: crate::nl_item = 0x2002C; +pub const ERA_D_FMT: crate::nl_item = 0x2002E; +pub const ALT_DIGITS: crate::nl_item = 0x2002F; +pub const ERA_D_T_FMT: crate::nl_item = 0x20030; +pub const ERA_T_FMT: crate::nl_item = 0x20031; + +pub const CODESET: crate::nl_item = 14; + +pub const CRNCYSTR: crate::nl_item = 0x4000F; + +pub const RUSAGE_THREAD: c_int = 1; +pub const RUSAGE_CHILDREN: c_int = -1; + +pub const RADIXCHAR: crate::nl_item = 0x10000; +pub const THOUSEP: crate::nl_item = 0x10001; + +pub const YESEXPR: crate::nl_item = 0x50000; +pub const NOEXPR: crate::nl_item = 0x50001; +pub const YESSTR: crate::nl_item = 0x50002; +pub const NOSTR: crate::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: crate::rlim_t = RLIM_INFINITY; +pub const RLIM_SAVED_CUR: crate::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 = 0o0100; +pub const S_IWRITE: mode_t = 0o0200; +pub const S_IREAD: mode_t = 0o0400; + +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 = ptr::null_mut(); +pub const RTLD_NODELETE: c_int = 0x1000; +pub const RTLD_NOW: c_int = 0x2; + +pub const TCP_MD5SIG: c_int = 14; + +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: crate::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 crate::sem_t = ptr::null_mut(); + +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: crate::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 = crate::ENODATA; + +pub const SO_ORIGINAL_DST: c_int = 80; +pub const IUTF8: crate::tcflag_t = 0x00004000; +pub const CMSPAR: crate::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 = u32_cast_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: crate::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: crate::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 = crate::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 = crate::O_NONBLOCK; + +pub const SFD_NONBLOCK: c_int = crate::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 = crate::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: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; + +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_BINDTODEVICE: c_int = 25; +pub const SO_TIMESTAMP: c_int = 29; +pub const SO_ACCEPTCONN: c_int = 30; +pub const SO_SNDBUFFORCE: c_int = 32; +pub const SO_RCVBUFFORCE: c_int = 33; +pub const SO_TIMESTAMPNS: c_int = 35; +pub const SO_MARK: c_int = 36; +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 SO_COOKIE: c_int = 57; +pub const SO_BINDTOIFINDEX: c_int = 62; +pub const SO_FUCHSIA_MARK: c_int = 10000; + +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: crate::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: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::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 unsafe fn FD_CLR(fd: c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] &= !(1 << (fd % size)); + return; + } + + pub unsafe fn FD_ISSET(fd: c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0; + } + + pub unsafe fn FD_SET(fd: c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] |= 1 << (fd % size); + return; + } + + pub unsafe fn FD_ZERO(set: *mut fd_set) -> () { + (*set).fds_bits.fill(0); + } + + pub unsafe fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + cpuset.bits.fill(0); + } + + pub unsafe fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits = 8 * 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 unsafe fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits = 8 * 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 unsafe fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + 0 != (cpuset.bits[idx] & (1 << offset)) + } + + pub unsafe fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.bits == set2.bits + } + + pub unsafe fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + cmsg.offset(1) as *mut c_uchar + } + + pub unsafe fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { + if ((*cmsg).cmsg_len as size_t) < size_of::() { + ptr::null_mut() + } else if __CMSG_NEXT(cmsg).add(size_of::()) >= __MHDR_END(mhdr) { + ptr::null_mut() + } else { + __CMSG_NEXT(cmsg).cast() + } + } + + pub unsafe fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as size_t >= size_of::() { + (*mhdr).msg_control.cast() + } else { + ptr::null_mut() + } + } + + pub const unsafe fn CMSG_ALIGN(len: size_t) -> size_t { + (len + size_of::() - 1) & !(size_of::() - 1) + } + + pub const unsafe fn CMSG_SPACE(len: c_uint) -> c_uint { + (CMSG_ALIGN(len as size_t) + CMSG_ALIGN(size_of::())) as c_uint + } + + pub const unsafe fn CMSG_LEN(len: c_uint) -> c_uint { + (CMSG_ALIGN(size_of::()) + len as size_t) as c_uint + } +} + +safe_f! { + pub const safe fn WIFSTOPPED(status: c_int) -> bool { + (status & 0xff) == 0x7f + } + + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + (status >> 8) & 0xff + } + + pub const safe fn WIFCONTINUED(status: c_int) -> bool { + status == 0xffff + } + + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + ((status & 0x7f) + 1) as i8 >= 2 + } + + pub const safe fn WTERMSIG(status: c_int) -> c_int { + status & 0x7f + } + + pub const safe fn WIFEXITED(status: c_int) -> bool { + (status & 0x7f) == 0 + } + + pub const safe fn WEXITSTATUS(status: c_int) -> c_int { + (status >> 8) & 0xff + } + + pub const safe fn WCOREDUMP(status: c_int) -> bool { + (status & 0x80) != 0 + } + + pub const safe fn QCMD(cmd: c_int, type_: c_int) -> c_int { + (cmd << 8) | (type_ & 0x00ff) + } + + pub const safe fn makedev(major: c_uint, minor: c_uint) -> crate::dev_t { + let major = major as crate::dev_t; + let minor = minor as crate::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 safe fn major(dev: crate::dev_t) -> c_uint { + let mut major = 0; + major |= (dev & 0x00000000000fff00) >> 8; + major |= (dev & 0xfffff00000000000) >> 32; + major as c_uint + } + + pub const safe fn minor(dev: crate::dev_t) -> c_uint { + let mut minor = 0; + minor |= (dev & 0x00000000000000ff) >> 0; + minor |= (dev & 0x00000ffffff00000) >> 12; + minor as c_uint + } +} + +fn __CMSG_LEN(cmsg: *const cmsghdr) -> ssize_t { + ((unsafe { (*cmsg).cmsg_len as size_t } + size_of::() - 1) & !(size_of::() - 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" {} + +extern_ty! { + pub type FILE; + pub type fpos_t; // FIXME(fuchsia): 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 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: crate::uid_t) -> *mut passwd; + + pub fn fprintf(stream: *mut crate::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 crate::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 crate::FILE) -> c_int; + pub fn fdopen(fd: c_int, mode: *const c_char) -> *mut crate::FILE; + pub fn fileno(stream: *mut crate::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 crate::DIR; + pub fn readdir(dirp: *mut crate::DIR) -> *mut crate::dirent; + pub fn readdir_r( + dirp: *mut crate::DIR, + entry: *mut crate::dirent, + result: *mut *mut crate::dirent, + ) -> c_int; + pub fn closedir(dirp: *mut crate::DIR) -> c_int; + pub fn rewinddir(dirp: *mut crate::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: crate::uid_t, group: crate::gid_t) -> c_int; + pub fn fchownat( + dirfd: c_int, + pathname: *const c_char, + owner: crate::uid_t, + group: crate::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; + + // DIFF(main): changed to `*const *mut` in e77f551de9 + 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: crate::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 crate::timeval, tz: *mut c_void) -> c_int; + pub fn times(buf: *mut crate::tms) -> crate::clock_t; + + pub fn pthread_self() -> crate::pthread_t; + pub fn pthread_join(native: crate::pthread_t, value: *mut *mut c_void) -> c_int; + pub fn pthread_exit(value: *mut c_void) -> !; + pub fn pthread_attr_init(attr: *mut crate::pthread_attr_t) -> c_int; + pub fn pthread_attr_destroy(attr: *mut crate::pthread_attr_t) -> c_int; + pub fn pthread_attr_getstacksize( + attr: *const crate::pthread_attr_t, + stacksize: *mut size_t, + ) -> c_int; + pub fn pthread_attr_setstacksize(attr: *mut crate::pthread_attr_t, stack_size: size_t) + -> c_int; + pub fn pthread_attr_setdetachstate(attr: *mut crate::pthread_attr_t, state: c_int) -> c_int; + pub fn pthread_detach(thread: crate::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 crate::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: crate::pthread_t, name: *mut c_char, len: size_t) -> c_int; + pub fn pthread_setname_np(thread: crate::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 crate::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 crate::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: crate::dev_t) -> c_int; + pub fn uname(buf: *mut crate::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 crate::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 crate::FILE, offset: off_t, whence: c_int) -> c_int; + pub fn ftello(stream: *mut crate::FILE) -> off_t; + pub fn tcdrain(fd: c_int) -> c_int; + pub fn cfgetispeed(termios: *const crate::termios) -> crate::speed_t; + pub fn cfgetospeed(termios: *const crate::termios) -> crate::speed_t; + pub fn cfmakeraw(termios: *mut crate::termios); + pub fn cfsetispeed(termios: *mut crate::termios, speed: crate::speed_t) -> c_int; + pub fn cfsetospeed(termios: *mut crate::termios, speed: crate::speed_t) -> c_int; + pub fn cfsetspeed(termios: *mut crate::termios, speed: crate::speed_t) -> c_int; + pub fn tcgetattr(fd: c_int, termios: *mut crate::termios) -> c_int; + pub fn tcsetattr(fd: c_int, optional_actions: c_int, termios: *const crate::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) -> crate::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: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_gettime(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_settime(clk_id: crate::clockid_t, tp: *const crate::timespec) -> c_int; + pub fn dirfd(dirp: *mut crate::DIR) -> c_int; + + pub fn pthread_getattr_np(native: crate::pthread_t, attr: *mut crate::pthread_attr_t) -> c_int; + pub fn pthread_attr_getstack( + attr: *const crate::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 crate::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 crate::timespec) -> c_int; + pub fn utimensat( + dirfd: c_int, + path: *const c_char, + times: *const crate::timespec, + flag: c_int, + ) -> c_int; + pub fn duplocale(base: crate::locale_t) -> crate::locale_t; + pub fn freelocale(loc: crate::locale_t); + pub fn newlocale(mask: c_int, locale: *const c_char, base: crate::locale_t) -> crate::locale_t; + pub fn uselocale(loc: crate::locale_t) -> crate::locale_t; + + pub fn fdopendir(fd: c_int) -> *mut crate::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: crate::clockid_t, + ) -> c_int; + pub fn accept4( + fd: c_int, + addr: *mut crate::sockaddr, + len: *mut crate::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 crate::siginfo_t, + options: c_int, + ) -> c_int; + pub fn setreuid(ruid: crate::uid_t, euid: crate::uid_t) -> c_int; + pub fn setregid(rgid: crate::gid_t, egid: crate::gid_t) -> c_int; + pub fn getresuid( + ruid: *mut crate::uid_t, + euid: *mut crate::uid_t, + suid: *mut crate::uid_t, + ) -> c_int; + pub fn getresgid( + rgid: *mut crate::gid_t, + egid: *mut crate::gid_t, + sgid: *mut crate::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: crate::gid_t, egid: crate::gid_t, sgid: crate::gid_t) -> c_int; + pub fn setresuid(ruid: crate::uid_t, euid: crate::uid_t, suid: crate::uid_t) -> c_int; + pub fn openpty( + amaster: *mut c_int, + aslave: *mut c_int, + name: *mut c_char, + termp: *const termios, + winp: *const crate::winsize, + ) -> c_int; + + // DIFF(main): changed to `*const *mut` in e77f551de9 + 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 crate::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: crate::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 crate::shmid_ds) -> c_int; + pub fn ftok(pathname: *const c_char, proj_id: c_int) -> crate::key_t; + pub fn semget(key: crate::key_t, nsems: c_int, semflag: c_int) -> c_int; + pub fn semop(semid: c_int, sops: *mut crate::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: crate::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 crate::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 crate::iovec, iovcnt: c_int, offset: off_t) -> ssize_t; + pub fn preadv(fd: c_int, iov: *const crate::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 crate::timespec, + ) -> c_int; + pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> c_int; + pub fn nl_langinfo_l(item: crate::nl_item, locale: crate::locale_t) -> *mut c_char; + pub fn getnameinfo( + sa: *const crate::sockaddr, + salen: crate::socklen_t, + host: *mut c_char, + hostlen: crate::socklen_t, + serv: *mut c_char, + servlen: crate::socklen_t, + flags: c_int, + ) -> c_int; + pub fn reboot(how_to: c_int) -> c_int; + pub fn setfsgid(gid: crate::gid_t) -> c_int; + pub fn setfsuid(uid: crate::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 crate::ifaddrs) -> c_int; + pub fn freeifaddrs(ifa: *mut crate::ifaddrs); + + pub fn glob( + pattern: *const c_char, + flags: c_int, + errfunc: Option c_int>, + pglob: *mut crate::glob_t, + ) -> c_int; + pub fn globfree(pglob: *mut crate::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 crate::DIR, loc: c_long); + + pub fn telldir(dirp: *mut crate::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 crate::sockaddr, + addrlen: *mut crate::socklen_t, + ) -> ssize_t; + pub fn mkstemps(template: *mut c_char, suffixlen: c_int) -> c_int; + pub fn futimes(fd: c_int, times: *const crate::timeval) -> c_int; + pub fn nl_langinfo(item: crate::nl_item) -> *mut c_char; + + pub fn bind( + socket: c_int, + address: *const crate::sockaddr, + address_len: crate::socklen_t, + ) -> c_int; + + pub fn writev(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + pub fn readv(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + + pub fn sendmsg(fd: c_int, msg: *const crate::msghdr, flags: c_int) -> ssize_t; + pub fn recvmsg(fd: c_int, msg: *mut crate::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 crate::timespec, + ) -> c_int; + pub fn sync(); + pub fn syscall(num: c_long, ...) -> c_long; + pub fn sched_getaffinity( + pid: crate::pid_t, + cpusetsize: size_t, + cpuset: *mut cpu_set_t, + ) -> c_int; + pub fn sched_setaffinity( + pid: crate::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 crate::timeval, tz: *const crate::timezone) -> c_int; + pub fn splice( + fd_in: c_int, + off_in: *mut crate::loff_t, + fd_out: c_int, + off_out: *mut crate::loff_t, + len: size_t, + flags: c_uint, + ) -> ssize_t; + pub fn eventfd(initval: c_uint, flags: c_int) -> c_int; + pub fn sched_rr_get_interval(pid: crate::pid_t, tp: *mut crate::timespec) -> c_int; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const crate::timespec) -> c_int; + pub fn sem_getvalue(sem: *mut sem_t, sval: *mut c_int) -> c_int; + pub fn sched_setparam(pid: crate::pid_t, param: *const crate::sched_param) -> c_int; + pub fn swapoff(puath: *const c_char) -> c_int; + pub fn vmsplice(fd: c_int, iov: *const crate::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: crate::pid_t, param: *mut crate::sched_param) -> c_int; + pub fn ppoll( + fds: *mut crate::pollfd, + nfds: nfds_t, + timeout: *const crate::timespec, + sigmask: *const sigset_t, + ) -> c_int; + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const crate::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: crate::pid_t) -> c_int; + pub fn clock_nanosleep( + clk_id: crate::clockid_t, + flags: c_int, + rqtp: *const crate::timespec, + rmtp: *mut crate::timespec, + ) -> c_int; + pub fn pthread_attr_getguardsize( + attr: *const crate::pthread_attr_t, + guardsize: *mut size_t, + ) -> c_int; + pub fn pthread_attr_setguardsize(attr: *mut crate::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: crate::pid_t, + policy: c_int, + param: *const crate::sched_param, + ) -> c_int; + pub fn sigsuspend(mask: *const crate::sigset_t) -> c_int; + pub fn getgrgid_r( + gid: crate::gid_t, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::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 crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn initgroups(user: *const c_char, group: crate::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 crate::group; + pub fn pthread_cancel(thread: crate::pthread_t) -> c_int; + pub fn pthread_kill(thread: crate::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: crate::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: crate::gid_t) -> *mut crate::group; + + pub fn setgrent(); + pub fn endgrent(); + pub fn getgrent() -> *mut crate::group; + + pub fn getgrouplist( + user: *const c_char, + group: crate::gid_t, + groups: *mut crate::gid_t, + ngroups: *mut c_int, + ) -> c_int; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut crate::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 crate::pthread_t, + attr: *const crate::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 crate::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 + } +} diff --git a/vendor/libc/src/fuchsia/riscv64.rs b/vendor/libc/src/fuchsia/riscv64.rs new file mode 100644 index 0000000..bc93cc3 --- /dev/null +++ b/vendor/libc/src/fuchsia/riscv64.rs @@ -0,0 +1,46 @@ +use crate::off_t; +use crate::prelude::*; + +// From psABI Calling Convention for RV64 +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: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + __pad0: Padding, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_long; 3]>, + } + + // Not actually used, IPC calls just return ENOSYS + pub struct ipc_perm { + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: c_ushort, + __unused1: Padding, + __unused2: Padding, + } +} diff --git a/vendor/libc/src/fuchsia/x86_64.rs b/vendor/libc/src/fuchsia/x86_64.rs new file mode 100644 index 0000000..fc42cd9 --- /dev/null +++ b/vendor/libc/src/fuchsia/x86_64.rs @@ -0,0 +1,110 @@ +use crate::off_t; +use crate::prelude::*; + +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: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + __pad0: Padding, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_long; 3]>, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino64_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + __pad0: Padding, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __reserved: Padding<[c_long; 3]>, + } + + pub struct mcontext_t { + __private: [u64; 32], + } + + pub struct ipc_perm { + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: c_int, + __unused1: Padding, + __unused2: Padding, + } + + pub struct ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: crate::sigset_t, + __private: [u8; 512], + } +} + +// 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..04699b1 --- /dev/null +++ b/vendor/libc/src/hermit.rs @@ -0,0 +1,562 @@ +//! Hermit C type definitions + +use crate::prelude::*; + +pub type intmax_t = i64; +pub type uintmax_t = u64; +pub type intptr_t = isize; +pub type uintptr_t = usize; + +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: Padding<[u8; 6]>, + __ss_align: i64, + __ss_pad2: Padding<[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: i64, + pub st_blksize: i64, + pub st_blocks: i64, + pub st_atim: timespec, + pub st_mtim: timespec, + pub st_ctim: timespec, + } + + #[derive(Default)] + pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: i32, + } +} + +pub const AF_UNSPEC: i32 = 0; +pub const AF_INET: i32 = 3; +pub const AF_INET6: i32 = 1; +pub const AF_VSOCK: i32 = 2; + +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 = u32_cast_int(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; +} diff --git a/vendor/libc/src/lib.rs b/vendor/libc/src/lib.rs new file mode 100644 index 0000000..a95a967 --- /dev/null +++ b/vendor/libc/src/lib.rs @@ -0,0 +1,309 @@ +//! Raw FFI bindings to platform system libraries. +//! +//! # Usage Guidelines +//! +//! `libc` exposes non-Rust interfaces in Rust, which makes for some caveats to its use that are +//! not present in most Rust libraries. Observing the following guidelines are recommended to help +//! avoid soundness and stability pitfalls. +//! +//! 1. *Never* construct a `libc` struct with `MaybeUninit::uninit()`, initialize it, then call +//! `assume_init`. Many structures have padding fields or may gain fields in the future, and +//! it is far too easy to end up calling `assume_init` on partially initialized data. +//! +//! Instead, use `MaybeUninit::zeroed()` or the `Default` implementations that are slowly being +//! added. Alternatively, access fields only via raw pointer without ever using `assume_init`. +//! +//! 2. Avoid relying on the exact value of constants, the exact length of arrays, or the exact +//! types of type aliases, as they may change across `libc` versions. That is, if `libc` +//! contains code like: +//! +//! +//! ```ignore +//! const IFNAMSIZ: usize = 16; +//! +//! pub struct ifreq { +//! pub ifr_name: [c_char; IFNAMSIZ], +//! // ... +//! } +//! +//! extern "C" { +//! pub fn time(time: *mut time_t) -> time_t; +//! } +//! ``` +//! +//! Then avoid writing code like: +//! +//! ```ignore +//! // Bad assumption that the length will always be 16. +//! fn takes_ifr_name(ifr_name: [c_char; 16]) { /* ... */ } +//! +//! fn process_ifr(ifr: ifreq) { +//! takes_ifr_name(ifr.ifr_name); +//! } +//! +//! // Bad assumption that `time_t` will always be an `i64`. Use `-> time_t` instead, or +//! // explicitly cast to an `i64`.` +//! fn get_time() -> i64 { +//! unsafe { time(ptr::null_mut()) } +//! } +//! +//! ``` +//! +//! For `takes_ifr_name`, use `[c_char; IFNAMSIZ]` or just `&[c_char]` instead. For `get_time`, +//! return a `time_t` or explicitly cast to an `i64`. +//! +//! Along the same lines, if you write code along the lines of `assert_eq!(libc::ELAST, 97)`, +//! expect that there may be a release where this starts to fail. +//! +//! 3. Do not name `__c_anonymous_*` types anywhere, which exist to represent anonymous fields in +//! C. For example, FreeBSD defines: +//! +//! ```c +//! struct filestat { +//! int fs_type; +//! // ... +//! struct { struct filestat stqe_next; } next; +//! }; +//! ``` +//! +//! Which is represented in `libc` as: +//! +//! ```ignore +//! struct filestat { +//! fs_type: c_int, +//! // ... +//! next: __c_anonymous_filestat, +//! } +//! +//! struct __c_anonymous_filestat { stqe_next: *mut filestat } +//! ``` +//! +//! Accessing `some_filestat.next.stqe_next` is completely fine, but `__c_anonymous_filestat` +//! should not be used anywhere (e.g. in a function signature). This is done to permit `libc` to +//! switch to anonymous fields if the feature is ever added to Rust. +//! +//! 4. Avoid accessing fields with names such as `__reserved`, `_pad`, or `_spare`. Usually the +//! platform libraries use these to allow adding new fields without changing the size of a +//! struct, but this means their types change frequently. +//! +//! 5. Be aware of deprecation warnings. These are used as a way to migrate necessary API changes. +//! +//! # Cargo Features +//! +//! - `std`: by default `libc` assumes that the standard library contains link directives necessary +//! to use the APIs in this crate. If `std` is disabled, `libc` will emit the directives instead. +//! +//! This feature is slated for removal in `libc` 1.0. The intention is that no-std users of +//! `libc` should use their own `#[link]` attributes, `rustc-link-lib` build script directives, +//! or `-l` arguments for only the system libraries they need to link, rather than `libc` +//! possibly linking more than is needed or available. If you are using `libc` without the `std` +//! feature, consider starting to add link directives now for a smoother 1.0 transition. +//! +//! - `extra_traits`: all types in `libc` implement `Clone`, `Copy`, and `Debug`. The +//! `extra_traits` feature adds `Eq`, `Hash`, and `PartialEq`. +//! +//! This feature is expected to be removed in libc 1.0. Libraries should instead hash or check +//! equality of only needed fields. +//! +//! - The features `const-extern-fn`, `align`, and `use_std` are all deprecated and do nothing. +//! +//! # Stability Expectations +//! +//! Due to `libc`'s position in the ecosystem, it can effectively never publish semver-breaking +//! releases. However, the API that `libc` binds changes _all the time_; sometimes in ways that +//! are harmless, sometimes in ways that are technically API-breaking for all users but unlikely +//! to be noticed (e.g. removing deprecated API), and sometimes in ways that are nonbreaking in +//! C but translate to breaking changes in Rust (e.g. changing the type of an integer). `libc` +//! tries to strike a balance but all of this means that unfortunately, `libc` must occasionally +//! ship changes within a semver-compatible release that are technically semver-breaking. +//! +//! The following are examples of changes that fall into this category: +//! +//! - Fields are added to a struct that is otherwise exhaustive. +//! - Fields with names such as `padding` or `reserved` change type or are removed. +//! - The length of an array type changes. +//! - A struct field (with available padding) is changed from `int` to `long`. +//! +//! In general, `libc` aims to follow platform API changes, even when this means changes that are +//! user-visible in Rust. There are a few guidelines used here: +//! +//! - Adding struct fields is not considered breaking, nor is changing fields named `reserved`, +//! `padding`, or similar. This is because users are expected to use field-by-field +//! initialization. +//! - Changing type aliases, values of constants, or array lengths is not considered breaking. +//! - If the platform libc has accepted breakage on the C side (typically in the form of removing +//! old API), the `libc` crate will follow suit. +//! - Where possible, `#[deprecated(...)]` will be used to warn about changes before applying them. +//! Alternative mitigations may be considered. +//! - Potentially breaking changes will be well-identified in release notes. +//! - Beyond this, public API is not expected to change on Tier 1 targets. Tier 2 targets have +//! relaxed API stability requirements, and API stability is not enforced on tier 3 targets. +//! +//! While this section seems scary, keep in mind that it is meant to cover worst-case scenarios. In +//! practice, breakage is rare and following the above-discussed [Usage Guidelines](#usage-guidelines) +//! means that most `libc` users will never encounter a problem. + +// Make it a bit easier to build without Cargo +#![crate_name = "libc"] +#![crate_type = "rlib"] +// Pretty much all C API doesn't match Rust conventions. +#![allow(nonstandard_style)] +// Not all macros and all patterns are used on all targets. +#![allow(unused_macros)] +#![allow(unused_macro_rules)] +// All traits should be `Copy` and `Debug`. +#![warn(missing_copy_implementations)] +#![warn(missing_debug_implementations)] +// Downgrade deny to a warning. +#![warn(overflowing_literals)] +// Prepare for a future upgrade. +#![warn(rust_2024_compatibility)] +// Things missing for 2024 that are blocked on MSRV or breakage. +#![allow(missing_unsafe_on_extern)] +#![allow(edition_2024_expr_fragment_specifier)] +// Allowed globally, the warning is enabled in individual modules as we work through them +#![allow(unsafe_op_in_unsafe_fn)] +#![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(feature = "rustc-dep-of-std", allow(internal_features))] +// Some targets don't need `link_cfg` and emit a warning. +#![cfg_attr(feature = "rustc-dep-of-std", allow(unused_features))] +// DIFF(1.0): The thread local references that raise this lint were removed in 1.0 +#![cfg_attr(feature = "rustc-dep-of-std", allow(static_mut_refs))] +#![cfg_attr(not(feature = "rustc-dep-of-std"), no_std)] +#![cfg_attr(feature = "rustc-dep-of-std", no_core)] + +#[macro_use] +mod macros; +mod new; + +cfg_if! { + if #[cfg(feature = "rustc-dep-of-std")] { + extern crate rustc_std_workspace_core as core; + } +} + +pub use core::ffi::c_void; + +#[allow(unused_imports)] // needed while the module is empty on some platforms +pub use new::*; + +cfg_if! { + if #[cfg(windows)] { + mod primitives; + pub use crate::primitives::*; + + mod windows; + pub use crate::windows::*; + + prelude!(); + } else if #[cfg(target_os = "fuchsia")] { + mod primitives; + pub use crate::primitives::*; + + mod fuchsia; + pub use crate::fuchsia::*; + + prelude!(); + } else if #[cfg(target_os = "switch")] { + mod primitives; + pub use primitives::*; + + mod switch; + pub use switch::*; + + prelude!(); + } else if #[cfg(target_os = "psp")] { + mod primitives; + pub use primitives::*; + + mod psp; + pub use crate::psp::*; + + prelude!(); + } else if #[cfg(target_os = "vxworks")] { + mod primitives; + pub use crate::primitives::*; + + mod vxworks; + pub use crate::vxworks::*; + + prelude!(); + } else if #[cfg(target_os = "qurt")] { + mod primitives; + pub use crate::primitives::*; + + mod qurt; + pub use crate::qurt::*; + + prelude!(); + } else if #[cfg(target_os = "solid_asp3")] { + mod primitives; + pub use crate::primitives::*; + + mod solid; + pub use crate::solid::*; + + prelude!(); + } else if #[cfg(unix)] { + mod primitives; + pub use crate::primitives::*; + + mod unix; + pub use crate::unix::*; + + prelude!(); + } else if #[cfg(target_os = "hermit")] { + mod primitives; + pub use crate::primitives::*; + + mod hermit; + pub use crate::hermit::*; + + prelude!(); + } else if #[cfg(target_os = "teeos")] { + mod primitives; + pub use primitives::*; + + mod teeos; + pub use teeos::*; + + prelude!(); + } else if #[cfg(target_os = "trusty")] { + mod primitives; + pub use crate::primitives::*; + + mod trusty; + pub use crate::trusty::*; + + prelude!(); + } else if #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))] { + mod primitives; + pub use crate::primitives::*; + + mod sgx; + pub use crate::sgx::*; + + prelude!(); + } else if #[cfg(any(target_env = "wasi", target_os = "wasi"))] { + mod primitives; + pub use crate::primitives::*; + + mod wasi; + pub use crate::wasi::*; + + prelude!(); + } else if #[cfg(target_os = "xous")] { + mod primitives; + pub use crate::primitives::*; + + mod xous; + pub use crate::xous::*; + + prelude!(); + } 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..0271d32 --- /dev/null +++ b/vendor/libc/src/macros.rs @@ -0,0 +1,700 @@ +/// 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)* + }; +} + +/// Create an internal crate prelude with `core` reexports and common types. +macro_rules! prelude { + () => { + mod types; + + /// Frequently-used types that are available on all platforms + /// + /// We need to reexport the core types so this works with `rust-dep-of-std`. + mod prelude { + // Exports from `core` + #[allow(unused_imports)] + pub(crate) use core::clone::Clone; + #[allow(unused_imports)] + pub(crate) use core::default::Default; + #[allow(unused_imports)] + pub(crate) use core::marker::{ + Copy, + Send, + Sync, + }; + #[allow(unused_imports)] + pub(crate) use core::option::Option; + #[allow(unused_imports)] + pub(crate) use core::prelude::v1::derive; + #[allow(unused_imports)] + pub(crate) use core::{ + assert, + cfg, + debug_assert, + fmt, + hash, + iter, + mem, + ptr, + }; + + #[allow(unused_imports)] + pub(crate) use fmt::Debug; + #[allow(unused_imports)] + pub(crate) use mem::{ + align_of, + align_of_val, + size_of, + size_of_val, + }; + + #[allow(unused_imports)] + #[cfg(any(target_os = "linux", target_os = "android", target_os = "l4re"))] + pub(crate) use crate::types::u32_cast_ioctl; + #[allow(unused_imports)] + pub(crate) use crate::types::{ + replace_array_items, + u16_cast_short, + u32_cast_int, + u32_cast_long, + u8_slice_cast_char_slice, + ulong_cast_int, + ulong_cast_uint, + CEnumRepr, + Padding, + }; + // Commonly used types defined in this crate + #[allow(unused_imports)] + pub(crate) use crate::{ + c_char, + c_double, + c_float, + c_int, + c_long, + c_longlong, + c_short, + c_uchar, + c_uint, + c_ulong, + c_ulonglong, + c_ushort, + c_void, + intptr_t, + size_t, + ssize_t, + uintptr_t, + }; + } + }; +} + +/// Implement `Clone`, `Copy`, and `Debug` for one or more structs, as well as `PartialEq`, `Eq`, +/// and `Hash` if the `extra_traits` feature is enabled. +/// +/// Also mark the type with `repr(C)`. +/// +/// Use [`s_no_extra_traits`] for structs where the `extra_traits` feature does not +/// make sense, and for unions. +macro_rules! s { + ($( + $(#[$attr:meta])* + $pub:vis $t:ident $i:ident { $($field:tt)* } + )*) => ($( + s!(it: $(#[$attr])* $pub $t $i { $($field)* }); + )*); + + (it: $(#[$attr:meta])* $pub:vis union $i:ident { $($field:tt)* }) => ( + compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead"); + ); + + (it: $(#[$attr:meta])* $pub:vis struct $i:ident { $($field:tt)* }) => ( + #[repr(C)] + #[::core::prelude::v1::derive( + ::core::clone::Clone, + ::core::marker::Copy, + ::core::fmt::Debug, + )] + #[cfg_attr( + feature = "extra_traits", + ::core::prelude::v1::derive(PartialEq, Eq, Hash) + )] + #[allow(deprecated)] + $(#[$attr])* + $pub struct $i { $($field)* } + ); +} + +/// Implement `Clone`, `Copy`, and `Debug` for a tuple struct, as well as `PartialEq`, `Eq`, +/// and `Hash` if the `extra_traits` feature is enabled. +/// +/// Unlike `s!`, this does *not* mark the type with `repr(C)`. Users should provide their own +/// `repr` attribute via `$attr` as necessary. +macro_rules! s_paren { + ($( + $(#[$attr:meta])* + $pub:vis struct $i:ident ( $($field:tt)* ); + )*) => ($( + #[::core::prelude::v1::derive( + ::core::clone::Clone, + ::core::marker::Copy, + ::core::fmt::Debug, + )] + #[cfg_attr( + feature = "extra_traits", + ::core::prelude::v1::derive(PartialEq, Eq, Hash) + )] + $(#[$attr])* + $pub struct $i ( $($field)* ); + )*); +} + +/// Implement `Clone`, `Copy`, and `Debug` for one or more structs/unions, but exclude `PartialEq`, +/// `Eq`, and `Hash`. +/// +/// Also mark the type with `repr(C)`. +/// +/// Most structs will prefer to use [`s`]. +macro_rules! s_no_extra_traits { + ($( + $(#[$attr:meta])* + $pub:vis $t:ident $i:ident { $($field:tt)* } + )*) => ($( + s_no_extra_traits!(it: $(#[$attr])* $pub $t $i { $($field)* }); + )*); + + (it: $(#[$attr:meta])* $pub:vis union $i:ident { $($field:tt)* }) => ( + #[repr(C)] + #[::core::prelude::v1::derive( + ::core::clone::Clone, + ::core::marker::Copy, + )] + $(#[$attr])* + $pub union $i { $($field)* } + + impl ::core::fmt::Debug for $i { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct(::core::stringify!($i)).finish_non_exhaustive() + } + } + ); + + (it: $(#[$attr:meta])* $pub:vis struct $i:ident { $($field:tt)* }) => ( + #[repr(C)] + #[::core::prelude::v1::derive( + ::core::clone::Clone, + ::core::marker::Copy, + ::core::fmt::Debug, + )] + $(#[$attr])* + $pub struct $i { $($field)* } + ); +} + +/// Create an uninhabited type that can't be constructed. It implements `Debug`, `Clone`, +/// and `Copy`, but these aren't meaningful for extern types so they should eventually +/// be removed. +/// +/// Really what we want here is something that also can't be named without indirection (in +/// ADTs or function signatures), but this doesn't exist. +macro_rules! extern_ty { + ($( + $(#[$attr:meta])* + $vis:vis type $i:ident; + )*) => ($( + $(#[$attr])* + /// This is an extern type ("opaque" or "incomplete" type in C). + /// + ///
+ /// This type's current representation allows inspecting some properties, such as via + /// size_of, and it is technically possible to construct the type within + /// MaybeUninit, However, this MUST NOT be relied upon + /// because a future version of libc may switch to a proper + /// extern type + /// representation when available. + ///
+ // ^ unfortunately warning blocks currently don't render markdown so we need to + // use raw HTML. + // + // Representation based on the Nomicon: + // . + // + // FIXME(1.0): These traits are unreachable and should be removed. + #[::core::prelude::v1::derive( + ::core::clone::Clone, + ::core::marker::Copy, + ::core::fmt::Debug, + )] + #[repr(C)] + $vis struct $i { + _data: (), + _marker: ::core::marker::PhantomData<(*mut u8, ::core::marker::PhantomPinned)>, + } + )*); +} + +/// Implement `Clone` and `Copy` for an enum, as well as `Debug`, `Eq`, `Hash`, and +/// `PartialEq` if the `extra_traits` feature is enabled. +// FIXME(#4419): Replace all uses of `e!` with `c_enum!` +macro_rules! e { + ($( + $(#[$attr:meta])* + pub enum $i:ident { $($field:tt)* } + )*) => ($( + #[cfg_attr( + feature = "extra_traits", + ::core::prelude::v1::derive(Eq, Hash, PartialEq) + )] + #[::core::prelude::v1::derive( + ::core::clone::Clone, + ::core::marker::Copy, + ::core::fmt::Debug, + )] + $(#[$attr])* + pub enum $i { $($field)* } + )*); +} + +/// Represent a C enum as Rust constants and a type. +/// +/// C enums can't soundly be mapped to Rust enums since C enums are allowed to have duplicates or +/// unlisted values, but this is UB in Rust. This enum doesn't implement any traits, its main +/// purpose is to calculate the correct enum values. +/// +/// Use the magic name `#anon` if the C enum doesn't create a type. +/// +/// See for more. +macro_rules! c_enum { + // Matcher for multiple enums + ($( + $(#[repr($repr:ty)])? + $vis:vis enum $($ty_name:ident)? $(#$anon:ident)? { + $($field_vis:vis $variant:ident $(= $value:expr)?,)+ + } + )+) => { + $(c_enum!(@single; + $(#[repr($repr)])? + $vis enum $($ty_name)? $(#$anon)? { + $($field_vis $variant $(= $value)?,)+ + } + );)+ + }; + + // Matcher for a single enum + (@single; + $(#[repr($repr:ty)])? + $vis:vis enum $ty_name:ident { + $($field_vis:vis $variant:ident $(= $value:expr)?,)+ + } + ) => { + $vis type $ty_name = c_enum!(@ty $($repr)?); + c_enum! { + @variant; + ty: $ty_name; + default: 0; + variants: [$($field_vis $variant $(= $value)?,)+] + } + }; + + // Matcher for a single anonymous enum + (@single; + $(#[repr($repr:ty)])? + $vis:vis enum #anon { + $($field_vis:vis $variant:ident $(= $value:expr)?,)+ + } + ) => { + c_enum! { + @variant; + ty: c_enum!(@ty $($repr)?); + default: 0; + variants: [$($field_vis $variant $(= $value)?,)+] + } + }; + + // Matcher for variants: eats a single variant then recurses with the rest + (@variant; ty: $_ty_name:ty; default: $_idx:expr; variants: []) => { /* end of the chain */ }; + ( + @variant; + ty: $ty_name:ty; + default: $default_val:expr; + variants: [ + $field_vis:vis $variant:ident $(= $value:expr)?, + $($tail:tt)* + ] + ) => { + $field_vis const $variant: $ty_name = { + #[allow(unused_variables)] + let r = $default_val; + $(let r = $value;)? + r + }; + + // The next value is always one more than the previous value, unless + // set explicitly. + c_enum! { + @variant; + ty: $ty_name; + default: $variant + 1; + variants: [$($tail)*] + } + }; + + // Use a specific type if provided, otherwise default to `CEnumRepr` + (@ty $repr:ty) => { $repr }; + (@ty) => { $crate::prelude::CEnumRepr }; +} + +/// Define a `unsafe` function. +macro_rules! f { + ($( + $(#[$attr:meta])* + pub $(const $($const_dummy:literal)?)? unsafe + fn $i:ident ($($arg:ident: $argty:ty),* $(,)?) -> $ret:ty + $body:block + )+) => {$( + #[inline] + $(#[$attr])* + pub $(const $($const_dummy)?)? unsafe extern "C" + fn $i ($($arg: $argty),*) -> $ret + $body + )+}; +} + +/// Define a safe function. +macro_rules! safe_f { + ($( + $(#[$attr:meta])* + pub $(const $($const_dummy:literal)?)? safe + fn $i:ident ($($arg:ident: $argty:ty),* $(,)?) -> $ret:ty + $body:block + )+) => {$( + #[inline] + $(#[$attr])* + pub $(const $($const_dummy)?)? extern "C" + fn $i ($($arg: $argty),*) -> $ret + $body + )+}; +} + +// 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; + ); + )* + } +} + +/// Polyfill for std's `offset_of`. +// FIXME(msrv): stabilized in std in 1.77 +macro_rules! offset_of { + ($Ty:path, $field:ident) => {{ + // Taken from bytemuck, avoids accidentally calling on deref + #[allow(clippy::unneeded_wildcard_pattern)] + let $Ty { $field: _, .. }; + let data = core::mem::MaybeUninit::<$Ty>::uninit(); + let ptr = data.as_ptr(); + // nested unsafe, see f! + #[allow(unused_unsafe)] + // SAFETY: computed address is inbounds since we have a stack alloc for T + let fptr = unsafe { core::ptr::addr_of!((*ptr).$field) }; + let off = (fptr as usize).checked_sub(ptr as usize).unwrap(); + core::assert!(off <= core::mem::size_of::<$Ty>()); + off + }}; +} + +#[cfg(test)] +mod tests { + use core::any::TypeId; + + use crate::types::CEnumRepr; + + #[test] + fn c_enum_basic() { + // By default, variants get sequential values. + c_enum! { + pub enum e { + VAR0, + VAR1, + VAR2, + } + + // Also check enums that don't create a type. + pub enum #anon { + ANON0, + ANON1, + ANON2, + } + + // No visibility required. + enum #anon { + ANON3, + ANON4, + ANON5, + } + } + + assert_eq!(TypeId::of::(), TypeId::of::()); + assert_eq!(VAR0, 0 as CEnumRepr); + assert_eq!(VAR1, 1 as CEnumRepr); + assert_eq!(VAR2, 2 as CEnumRepr); + + assert_eq!(type_id_of_val(&ANON0), TypeId::of::()); + assert_eq!(ANON0, 0 as CEnumRepr); + assert_eq!(ANON1, 1 as CEnumRepr); + assert_eq!(ANON2, 2 as CEnumRepr); + + assert_eq!(type_id_of_val(&ANON3), TypeId::of::()); + assert_eq!(ANON3, 0 as CEnumRepr); + assert_eq!(ANON4, 1 as CEnumRepr); + assert_eq!(ANON5, 2 as CEnumRepr); + } + + #[test] + fn c_enum_repr() { + // Check specifying the integer representation + c_enum! { + #[repr(u16)] + pub enum e { + VAR0, + } + + #[repr(u16)] + pub enum #anon { + ANON0, + } + } + + assert_eq!(TypeId::of::(), TypeId::of::()); + assert_eq!(VAR0, 0_u16); + + assert_eq!(type_id_of_val(&ANON0), TypeId::of::()); + assert_eq!(ANON0, 0_u16); + } + + #[test] + fn c_enum_set_value() { + // Setting an explicit value resets the count. + c_enum! { + pub enum e { + VAR2 = 2, + VAR3, + VAR4, + } + } + + assert_eq!(VAR2, 2 as CEnumRepr); + assert_eq!(VAR3, 3 as CEnumRepr); + assert_eq!(VAR4, 4 as CEnumRepr); + } + + #[test] + fn c_enum_multiple_set_value() { + // C enums always take one more than the previous value, unless set to a specific + // value. Duplicates are allowed. + c_enum! { + pub enum e { + VAR0, + VAR2_0 = 2, + VAR3_0, + VAR4_0, + VAR2_1 = 2, + VAR3_1, + VAR4_1, + } + } + + assert_eq!(VAR0, 0 as CEnumRepr); + assert_eq!(VAR2_0, 2 as CEnumRepr); + assert_eq!(VAR3_0, 3 as CEnumRepr); + assert_eq!(VAR4_0, 4 as CEnumRepr); + assert_eq!(VAR2_1, 2 as CEnumRepr); + assert_eq!(VAR3_1, 3 as CEnumRepr); + assert_eq!(VAR4_1, 4 as CEnumRepr); + } + + #[test] + fn c_enum_vis() { + mod priv1 { + c_enum! { + #[repr(u8)] + pub enum e1 { + PRIV_ON_1 = 10, + // Variant should still be usable within its visibility + pub PUB1 = PRIV_ON_1 * 2, + } + } + } + mod priv2 { + c_enum! { + #[repr(u16)] + pub enum e2 { + pub PRIV_ON_1 = 42, + pub PUB2 = PRIV_ON_1 * 2, + } + } + } + + use priv1::*; + use priv2::*; + + assert_eq!(TypeId::of::(), TypeId::of::()); + assert_eq!(TypeId::of::(), TypeId::of::()); + assert_eq!(PUB1, 10u8 * 2); + assert_eq!(PUB2, 42u16 * 2); + // Verify that the default is private. If `PRIV_ON_1` was actually public in `priv1`, this + // would be an ambiguous import and/or type mismatch error. + assert_eq!(PRIV_ON_1, 42u16); + } + + fn type_id_of_val(_: &T) -> TypeId { + TypeId::of::() + } + + #[test] + fn test_offset_of() { + #[repr(C)] + struct Off1 { + a: u8, + b: u32, + c: Off2, + d: u64, + } + + #[repr(C)] + #[repr(align(128))] + struct Off2 {} + + assert_eq!(core::mem::offset_of!(Off1, a), offset_of!(Off1, a)); + assert_eq!(core::mem::offset_of!(Off1, b), offset_of!(Off1, b)); + assert_eq!(core::mem::offset_of!(Off1, c), offset_of!(Off1, c)); + assert_eq!(core::mem::offset_of!(Off1, d), offset_of!(Off1, d)); + } +} + +#[cfg(test)] +#[allow(unused)] +mod macro_checks { + s! { + pub struct S1 { + pub a: u32, + b: u32, + } + + struct S1Priv { + pub a: u32, + b: u32, + } + } + + s_no_extra_traits! { + pub struct S2 { + pub a: u32, + b: u32, + } + + struct S2Priv { + pub a: u32, + b: u32, + } + + pub union U2 { + pub a: u32, + b: f32, + } + + union U2Priv { + pub a: u32, + b: f32, + } + } + + extern_ty! { + type Foo; + pub type Bar; + } +} diff --git a/vendor/libc/src/new/aix/mod.rs b/vendor/libc/src/new/aix/mod.rs new file mode 100644 index 0000000..c99b206 --- /dev/null +++ b/vendor/libc/src/new/aix/mod.rs @@ -0,0 +1,6 @@ +//! IBM AIX libc. +//! +//! * Headers are not public +//! * Manual pages: (under "Technical reference" for that version) + +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/aix/unistd.rs b/vendor/libc/src/new/aix/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/aix/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/apple/libc/signal.rs b/vendor/libc/src/new/apple/libc/signal.rs new file mode 100644 index 0000000..b5f8d59 --- /dev/null +++ b/vendor/libc/src/new/apple/libc/signal.rs @@ -0,0 +1,5 @@ +//! Header: `signal.h` +//! +//! + +pub use crate::sys::signal::*; diff --git a/vendor/libc/src/new/apple/libc/unistd.rs b/vendor/libc/src/new/apple/libc/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/apple/libc/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/apple/libpthread/mod.rs b/vendor/libc/src/new/apple/libpthread/mod.rs new file mode 100644 index 0000000..66f25e6 --- /dev/null +++ b/vendor/libc/src/new/apple/libpthread/mod.rs @@ -0,0 +1,20 @@ +//! Source from libpthread + +/// Directory: `pthread/` +/// +/// Note that this module has a trailing underscore to avoid conflicting with its child `pthread` +/// module. +/// +/// +pub(crate) mod pthread_ { + pub(crate) mod introspection; + pub(crate) mod pthread; + pub(crate) mod pthread_impl; + pub(crate) mod pthread_spis; + pub(crate) mod qos; + pub(crate) mod sched; + pub(crate) mod spawn; + pub(crate) mod stack_np; +} + +pub(crate) mod sys; diff --git a/vendor/libc/src/new/apple/libpthread/pthread_/introspection.rs b/vendor/libc/src/new/apple/libpthread/pthread_/introspection.rs new file mode 100644 index 0000000..6509e22 --- /dev/null +++ b/vendor/libc/src/new/apple/libpthread/pthread_/introspection.rs @@ -0,0 +1,36 @@ +//! Header: `pthread/introspection.h` +//! +//! + +use crate::prelude::*; +pub use crate::pthread_::pthread::*; + +c_enum! { + #[repr(c_uint)] + pub enum #anon { + pub PTHREAD_INTROSPECTION_THREAD_CREATE = 1, + pub PTHREAD_INTROSPECTION_THREAD_START, + pub PTHREAD_INTROSPECTION_THREAD_TERMINATE, + pub PTHREAD_INTROSPECTION_THREAD_DESTROY, + } +} + +pub type pthread_introspection_hook_t = + extern "C" fn(event: c_uint, thread: pthread_t, addr: *mut c_void, size: size_t); + +extern "C" { + // 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; +} diff --git a/vendor/libc/src/new/apple/libpthread/pthread_/pthread.rs b/vendor/libc/src/new/apple/libpthread/pthread_/pthread.rs new file mode 100644 index 0000000..a7e56be --- /dev/null +++ b/vendor/libc/src/new/apple/libpthread/pthread_/pthread.rs @@ -0,0 +1,76 @@ +//! Header: `pthread.h` or `pthread/pthread.h` +//! +//! + +use crate::prelude::*; +pub use crate::pthread_::qos::*; +pub use crate::pthread_::sched::*; +// No need to import from the `_pthread_attr_t` and similar modules since `_pthread_types` has +// everything we need. +pub use crate::sys::_pthread::_pthread_types::*; + +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_PROCESS_SHARED: c_int = 1; +pub const PTHREAD_PROCESS_PRIVATE: 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; + +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_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + __sig: _PTHREAD_RWLOCK_SIG_init, + __opaque: [0; __PTHREAD_RWLOCK_SIZE__], +}; + +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_ONCE_INIT: crate::pthread_once_t = crate::pthread_once_t { + __sig: _PTHREAD_ONCE_SIG_INIT, + __opaque: [0; __PTHREAD_ONCE_SIZE__], +}; + +pub use crate::new::common::posix::pthread::{ + pthread_attr_getinheritsched, + pthread_attr_getschedparam, + pthread_attr_getschedpolicy, + pthread_attr_setinheritsched, + pthread_attr_setschedparam, + pthread_attr_setschedpolicy, + pthread_condattr_getpshared, + pthread_condattr_setpshared, + pthread_getschedparam, + pthread_mutexattr_getpshared, + pthread_mutexattr_setpshared, + pthread_once, + pthread_rwlockattr_getpshared, + pthread_rwlockattr_setpshared, + pthread_setschedparam, +}; diff --git a/vendor/libc/src/new/apple/libpthread/pthread_/pthread_impl.rs b/vendor/libc/src/new/apple/libpthread/pthread_/pthread_impl.rs new file mode 100644 index 0000000..92c5e27 --- /dev/null +++ b/vendor/libc/src/new/apple/libpthread/pthread_/pthread_impl.rs @@ -0,0 +1,12 @@ +use crate::prelude::*; + +// FIXME(apple): these should all be `pub(crate)` +pub const _PTHREAD_MUTEX_SIG_init: c_long = 0x32AAABA7; + +pub const _PTHREAD_COND_SIG_init: c_long = 0x3CB0B1BB; +pub(crate) const _PTHREAD_ONCE_SIG_INIT: c_long = 0x30B1BCBA; +pub const _PTHREAD_RWLOCK_SIG_init: c_long = 0x2DA8B3B4; + +pub const SCHED_OTHER: c_int = 1; +pub const SCHED_FIFO: c_int = 4; +pub const SCHED_RR: c_int = 2; diff --git a/vendor/libc/src/new/apple/libpthread/pthread_/pthread_spis.rs b/vendor/libc/src/new/apple/libpthread/pthread_/pthread_spis.rs new file mode 100644 index 0000000..24e3fed --- /dev/null +++ b/vendor/libc/src/new/apple/libpthread/pthread_/pthread_spis.rs @@ -0,0 +1,14 @@ +//! Header: `pthread/pthread_spis.h` +//! +//! + +use crate::prelude::*; + +extern "C" { + pub fn pthread_create_from_mach_thread( + thread: *mut crate::pthread_t, + attr: *const crate::pthread_attr_t, + f: extern "C" fn(*mut c_void) -> *mut c_void, + value: *mut c_void, + ) -> c_int; +} diff --git a/vendor/libc/src/new/apple/libpthread/pthread_/qos.rs b/vendor/libc/src/new/apple/libpthread/pthread_/qos.rs new file mode 100644 index 0000000..8b68c78 --- /dev/null +++ b/vendor/libc/src/new/apple/libpthread/pthread_/qos.rs @@ -0,0 +1,25 @@ +//! Header: `pthread/qos.h` +//! +//! + +use crate::prelude::*; +pub use crate::sys::qos::*; + +extern "C" { + pub fn pthread_attr_set_qos_class_np( + attr: *mut crate::pthread_attr_t, + class: qos_class_t, + priority: c_int, + ) -> c_int; + pub fn pthread_attr_get_qos_class_np( + attr: *mut crate::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: crate::pthread_t, + class: *mut qos_class_t, + priority: *mut c_int, + ) -> c_int; +} diff --git a/vendor/libc/src/new/apple/libpthread/pthread_/sched.rs b/vendor/libc/src/new/apple/libpthread/pthread_/sched.rs new file mode 100644 index 0000000..d25a6cb --- /dev/null +++ b/vendor/libc/src/new/apple/libpthread/pthread_/sched.rs @@ -0,0 +1,9 @@ +pub use crate::new::pthread_::pthread_impl::*; +use crate::prelude::*; + +s! { + pub struct sched_param { + pub sched_priority: c_int, + __opaque: [c_char; 4], + } +} diff --git a/vendor/libc/src/new/apple/libpthread/pthread_/spawn.rs b/vendor/libc/src/new/apple/libpthread/pthread_/spawn.rs new file mode 100644 index 0000000..c5bdb7a --- /dev/null +++ b/vendor/libc/src/new/apple/libpthread/pthread_/spawn.rs @@ -0,0 +1,16 @@ +//! Header: `pthread/spawn.h` +//! +//! + +use crate::prelude::*; + +extern "C" { + pub fn posix_spawnattr_set_qos_class_np( + attr: *mut crate::posix_spawnattr_t, + qos_class: crate::qos_class_t, + ) -> c_int; + pub fn posix_spawnattr_get_qos_class_np( + attr: *const crate::posix_spawnattr_t, + qos_class: *mut crate::qos_class_t, + ) -> c_int; +} diff --git a/vendor/libc/src/new/apple/libpthread/pthread_/stack_np.rs b/vendor/libc/src/new/apple/libpthread/pthread_/stack_np.rs new file mode 100644 index 0000000..0d501cd --- /dev/null +++ b/vendor/libc/src/new/apple/libpthread/pthread_/stack_np.rs @@ -0,0 +1,12 @@ +//! Header: `pthread/stack_np.h` +//! +//! + +use crate::prelude::*; + +extern "C" { + pub fn pthread_stack_frame_decode_np( + frame_addr: uintptr_t, + return_addr: *mut uintptr_t, + ) -> uintptr_t; +} diff --git a/vendor/libc/src/new/apple/libpthread/sys/_pthread/_pthread_types.rs b/vendor/libc/src/new/apple/libpthread/sys/_pthread/_pthread_types.rs new file mode 100644 index 0000000..95e181c --- /dev/null +++ b/vendor/libc/src/new/apple/libpthread/sys/_pthread/_pthread_types.rs @@ -0,0 +1,79 @@ +//! Header: `sys/_pthread/_pthread_types.h` +//! +//! +//! +//! Note that the actual header defines `_opaque_pthread_*` structs which are typedefed to +//! `__darwin_pthread*` structs, and typedefed again in separate `_pthread_*.h` files to their final +//! `pthread_` name. This isn't useful for us so we simplify a bit and just define everything here. + +use crate::prelude::*; + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + pub const __PTHREAD_SIZE__: usize = 8176; + pub const __PTHREAD_ATTR_SIZE__: usize = 56; + pub const __PTHREAD_MUTEXATTR_SIZE__: usize = 8; + pub const __PTHREAD_MUTEX_SIZE__: usize = 56; + pub const __PTHREAD_CONDATTR_SIZE__: usize = 8; + pub const __PTHREAD_COND_SIZE__: usize = 40; + pub const __PTHREAD_ONCE_SIZE__: usize = 8; + pub const __PTHREAD_RWLOCK_SIZE__: usize = 192; + pub const __PTHREAD_RWLOCKATTR_SIZE__: usize = 16; + } else { + pub const __PTHREAD_SIZE__: usize = 4088; + pub const __PTHREAD_ATTR_SIZE__: usize = 36; + pub const __PTHREAD_MUTEXATTR_SIZE__: usize = 8; + pub const __PTHREAD_MUTEX_SIZE__: usize = 40; + pub const __PTHREAD_CONDATTR_SIZE__: usize = 4; + pub const __PTHREAD_COND_SIZE__: usize = 24; + pub const __PTHREAD_ONCE_SIZE__: usize = 4; + pub const __PTHREAD_RWLOCK_SIZE__: usize = 124; + pub const __PTHREAD_RWLOCKATTR_SIZE__: usize = 12; + } +} + +s! { + pub struct pthread_attr_t { + pub(crate) __sig: c_long, + pub(crate) __opaque: [c_char; __PTHREAD_ATTR_SIZE__], + } + + pub struct pthread_cond_t { + pub(crate) __sig: c_long, + pub(crate) __opaque: [u8; __PTHREAD_COND_SIZE__], + } + + pub struct pthread_condattr_t { + pub(crate) __sig: c_long, + pub(crate) __opaque: [u8; __PTHREAD_CONDATTR_SIZE__], + } + + pub struct pthread_mutex_t { + pub(crate) __sig: c_long, + pub(crate) __opaque: [u8; __PTHREAD_MUTEX_SIZE__], + } + + pub struct pthread_mutexattr_t { + pub(crate) __sig: c_long, + pub(crate) __opaque: [u8; __PTHREAD_MUTEXATTR_SIZE__], + } + + pub struct pthread_once_t { + pub(crate) __sig: c_long, + pub(crate) __opaque: [c_char; __PTHREAD_ONCE_SIZE__], + } + + pub struct pthread_rwlock_t { + pub(crate) __sig: c_long, + pub(crate) __opaque: [u8; __PTHREAD_RWLOCK_SIZE__], + } + + pub struct pthread_rwlockattr_t { + pub(crate) __sig: c_long, + pub(crate) __opaque: [u8; __PTHREAD_RWLOCKATTR_SIZE__], + } +} + +pub type pthread_key_t = c_ulong; + +pub use crate::pthread_t; diff --git a/vendor/libc/src/new/apple/libpthread/sys/mod.rs b/vendor/libc/src/new/apple/libpthread/sys/mod.rs new file mode 100644 index 0000000..da0a229 --- /dev/null +++ b/vendor/libc/src/new/apple/libpthread/sys/mod.rs @@ -0,0 +1,14 @@ +//! Directory: `sys/` +//! +//! + +/// Directory: `sys/_pthread/` +/// +/// +pub(crate) mod _pthread { + // We don't have the `_pthread_attr_t` and similar modules to match `_pthread_attr_t.h`, + // everything is defined in `_pthread_types`. + pub(crate) mod _pthread_types; +} + +pub(crate) mod qos; diff --git a/vendor/libc/src/new/apple/libpthread/sys/qos.rs b/vendor/libc/src/new/apple/libpthread/sys/qos.rs new file mode 100644 index 0000000..9d9a2eb --- /dev/null +++ b/vendor/libc/src/new/apple/libpthread/sys/qos.rs @@ -0,0 +1,22 @@ +//! Header: `sys/qos.h` +//! +//! + +use crate::prelude::*; + +#[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 + } +} diff --git a/vendor/libc/src/new/apple/mod.rs b/vendor/libc/src/new/apple/mod.rs new file mode 100644 index 0000000..1708cc3 --- /dev/null +++ b/vendor/libc/src/new/apple/mod.rs @@ -0,0 +1,19 @@ +//! Apple interfaces. +//! +//! The Xcode SDK includes interfaces that are split across a couple of different libraries. Most +//! of these are available at . + +/// Entrypoint for Apple headers, usually found as part of the Xcode SDK. +/// +/// +mod libc { + pub(crate) mod signal; + pub(crate) mod unistd; +} + +mod libpthread; +mod xnu; + +pub(crate) use libc::*; +pub(crate) use libpthread::pthread_; +pub(crate) use xnu::*; diff --git a/vendor/libc/src/new/apple/xnu/arm/_mcontext.rs b/vendor/libc/src/new/apple/xnu/arm/_mcontext.rs new file mode 100644 index 0000000..ae22f7a --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/arm/_mcontext.rs @@ -0,0 +1,15 @@ +//! Header: `arm/_mcontext.h` +//! +//! + +pub use crate::mach::machine::_structs::*; + +s! { + pub struct __darwin_mcontext64 { + pub __es: __darwin_arm_exception_state64, + pub __ss: __darwin_arm_thread_state64, + pub __ns: __darwin_arm_neon_state64, + } +} + +pub type mcontext_t = *mut __darwin_mcontext64; diff --git a/vendor/libc/src/new/apple/xnu/i386/_mcontext.rs b/vendor/libc/src/new/apple/xnu/i386/_mcontext.rs new file mode 100644 index 0000000..2b07ad1 --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/i386/_mcontext.rs @@ -0,0 +1,15 @@ +//! Header: `i386/_mcontext.h` +//! +//! + +pub use crate::mach::machine::_structs::*; + +s! { + pub struct __darwin_mcontext64 { + pub __es: __darwin_x86_exception_state64, + pub __ss: __darwin_x86_thread_state64, + pub __fs: __darwin_x86_float_state64, + } +} + +pub type mcontext_t = *mut __darwin_mcontext64; diff --git a/vendor/libc/src/new/apple/xnu/mach/arm/_structs.rs b/vendor/libc/src/new/apple/xnu/mach/arm/_structs.rs new file mode 100644 index 0000000..6160e77 --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/mach/arm/_structs.rs @@ -0,0 +1,37 @@ +//! Header: `arm/_structs.h` +//! +//! + +#[cfg(target_arch = "arm")] +use crate::prelude::*; + +s! { + 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, + } + + #[cfg(target_arch = "aarch64")] + pub struct __darwin_arm_neon_state64 { + pub __v: [u128; 32], + pub __fpsr: u32, + pub __fpcr: u32, + } + + #[cfg(target_arch = "arm")] + #[repr(align(16))] + pub struct __darwin_arm_neon_state64 { + opaque: [c_char; (32 * 16) + (2 * size_of::())], + } +} diff --git a/vendor/libc/src/new/apple/xnu/mach/i386/_structs.rs b/vendor/libc/src/new/apple/xnu/mach/i386/_structs.rs new file mode 100644 index 0000000..15822f7 --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/mach/i386/_structs.rs @@ -0,0 +1,92 @@ +//! Header: `i386/_structs.h` +//! +//! + +use crate::prelude::*; + +s! { + 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 __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_exception_state64 { + pub __trapno: u16, + pub __cpu: u16, + pub __err: u32, + pub __faultvaddr: 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, + // FIXME(apple): 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, + } +} diff --git a/vendor/libc/src/new/apple/xnu/mach/machine/_structs.rs b/vendor/libc/src/new/apple/xnu/mach/machine/_structs.rs new file mode 100644 index 0000000..6acae8d --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/mach/machine/_structs.rs @@ -0,0 +1,13 @@ +//! Header: `mach/machine/_structs.h` +//! +//! + +cfg_if! { + if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + pub use crate::mach::i386::_structs::*; + } else if #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] { + pub use crate::mach::arm::_structs::*; + } else { + // Unsupported arch + } +} diff --git a/vendor/libc/src/new/apple/xnu/mach/mod.rs b/vendor/libc/src/new/apple/xnu/mach/mod.rs new file mode 100644 index 0000000..9075126 --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/mach/mod.rs @@ -0,0 +1,20 @@ +//! Directory: `mach/` +//! +//! + +/// Directory: `mach/arm` +#[cfg(any(target_arch = "arm", target_arch = "aarch64"))] +pub(crate) mod arm { + pub(crate) mod _structs; +} + +/// Directory: `mach/i386` +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +pub(crate) mod i386 { + pub(crate) mod _structs; +} + +/// Directory: `mach/machine` +pub(crate) mod machine { + pub(crate) mod _structs; +} diff --git a/vendor/libc/src/new/apple/xnu/machine/_mcontext.rs b/vendor/libc/src/new/apple/xnu/machine/_mcontext.rs new file mode 100644 index 0000000..004b947 --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/machine/_mcontext.rs @@ -0,0 +1,11 @@ +//! Header: `machine/_mcontext.h` + +cfg_if! { + if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + pub use crate::i386::_mcontext::*; + } else if #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] { + pub use crate::arm::_mcontext::*; + } else { + // Unsupported arch + } +} diff --git a/vendor/libc/src/new/apple/xnu/mod.rs b/vendor/libc/src/new/apple/xnu/mod.rs new file mode 100644 index 0000000..a81d38d --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/mod.rs @@ -0,0 +1,34 @@ +//! Source from XNU +//! +//! We omit nesting for the `bsd` module since most items of interest are in there. + +/// Directory: `arm/` +/// +/// https://github.com/apple-oss-distributions/xnu/tree/main/bsd/arm +#[cfg(any(target_arch = "arm", target_arch = "aarch64"))] +pub(crate) mod arm { + pub(crate) mod _mcontext; +} + +/// Directory: `i386/` +/// +/// https://github.com/apple-oss-distributions/xnu/tree/main/bsd/i386 +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +pub(crate) mod i386 { + pub(crate) mod _mcontext; +} + +pub(crate) mod mach; + +/// Directory: `machine/` +/// +/// https://github.com/apple-oss-distributions/xnu/tree/main/bsd/machine +pub(crate) mod machine { + pub(crate) mod _mcontext; +} + +pub(crate) mod net; + +pub(crate) mod netinet6; + +pub(crate) mod sys; diff --git a/vendor/libc/src/new/apple/xnu/net/bpf.rs b/vendor/libc/src/new/apple/xnu/net/bpf.rs new file mode 100644 index 0000000..dc0aae8 --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/net/bpf.rs @@ -0,0 +1,57 @@ +//! Header: `net/bpf.h` +//! +//! + +use crate::prelude::*; +use crate::sys::ioccom::*; + +s! { + pub struct bpf_insn { + pub code: c_ushort, + pub jt: c_uchar, + pub jf: c_uchar, + pub k: u32, + } + + pub struct bpf_program { + pub bf_len: c_uint, + pub bf_insns: *mut bpf_insn, + } +} + +s_no_extra_traits! { + #[repr(packed(4))] + pub struct bpf_dltlist { + pub bfl_len: u32, + pub bfl_u: __c_anonymous_bfl_u, + } + + pub union __c_anonymous_bfl_u { + pub bflu_list: *mut u32, + pub bflu_pad: u64, + } +} + +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; + +pub const BPF_ALIGNMENT: c_int = size_of::() as c_int; + +pub const BIOCGRSIG: c_ulong = _IOR::('B' as c_ulong, 114); +pub const BIOCSRSIG: c_ulong = _IOW::('B' as c_ulong, 115); +pub const BIOCGSEESENT: c_ulong = _IOR::('B' as c_ulong, 118); +pub const BIOCSSEESENT: c_ulong = _IOW::('B' as c_ulong, 119); +pub const BIOCSDLT: c_ulong = _IOW::('B' as c_ulong, 120); +pub const BIOCGDLTLIST: c_ulong = _IOWR::('B' as c_ulong, 121); diff --git a/vendor/libc/src/new/apple/xnu/net/mod.rs b/vendor/libc/src/new/apple/xnu/net/mod.rs new file mode 100644 index 0000000..c2844db --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/net/mod.rs @@ -0,0 +1,5 @@ +//! Directory: `net/` +//! +//! + +pub(crate) mod bpf; diff --git a/vendor/libc/src/new/apple/xnu/netinet6/in6_var.rs b/vendor/libc/src/new/apple/xnu/netinet6/in6_var.rs new file mode 100644 index 0000000..f7fcc04 --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/netinet6/in6_var.rs @@ -0,0 +1,22 @@ +//! Header: `netinet6/in6_var.h` +//! +//! + +use crate::prelude::*; +use crate::sys::ioccom::*; + +pub const IN6_IFF_ANYCAST: c_int = 0x0001; +pub const IN6_IFF_TENTATIVE: c_int = 0x0002; +pub const IN6_IFF_DUPLICATED: c_int = 0x0004; +pub const IN6_IFF_DETACHED: c_int = 0x0008; +pub const IN6_IFF_DEPRECATED: c_int = 0x0010; +pub const IN6_IFF_NODAD: c_int = 0x0020; +pub const IN6_IFF_AUTOCONF: c_int = 0x0040; +pub const IN6_IFF_TEMPORARY: c_int = 0x0080; +pub const IN6_IFF_DYNAMIC: c_int = 0x0100; +pub const IN6_IFF_OPTIMISTIC: c_int = 0x0200; +pub const IN6_IFF_SECURED: c_int = 0x0400; +pub const IN6_IFF_CLAT46: c_int = 0x1000; +pub const IN6_IFF_NOPFX: c_int = 0x8000; + +pub const SIOCGIFAFLAG_IN6: c_ulong = _IOWR::('i' as c_ulong, 73); diff --git a/vendor/libc/src/new/apple/xnu/netinet6/mod.rs b/vendor/libc/src/new/apple/xnu/netinet6/mod.rs new file mode 100644 index 0000000..1592863 --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/netinet6/mod.rs @@ -0,0 +1,5 @@ +//! Directory: `netinet6/` +//! +//! + +pub(crate) mod in6_var; diff --git a/vendor/libc/src/new/apple/xnu/sys/_types/_ucontext.rs b/vendor/libc/src/new/apple/xnu/sys/_types/_ucontext.rs new file mode 100644 index 0000000..53bc0f2 --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/sys/_types/_ucontext.rs @@ -0,0 +1,17 @@ +//! Header: `sys/_types/_ucontext.h` + +pub use crate::machine::_mcontext::*; +use crate::prelude::*; + +s! { + pub struct __darwin_ucontext { + pub uc_onstack: c_int, + pub uc_sigmask: crate::sigset_t, + pub uc_stack: crate::stack_t, + pub uc_link: *mut ucontext_t, + pub uc_mcsize: usize, + pub uc_mcontext: mcontext_t, + } +} + +pub type ucontext_t = __darwin_ucontext; diff --git a/vendor/libc/src/new/apple/xnu/sys/ioccom.rs b/vendor/libc/src/new/apple/xnu/sys/ioccom.rs new file mode 100644 index 0000000..dcc0d07 --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/sys/ioccom.rs @@ -0,0 +1,49 @@ +//! Header: `sys/ioccom.h` +//! +//! + +use crate::prelude::*; + +const IOCPARM_MASK: c_ulong = 0x1fff; + +const IOCPARM_MAX: c_ulong = IOCPARM_MASK + 1; + +// These are u32 in source but would probably be more practical as c_ulong if we ever need +// to make them public. +pub(crate) const IOC_VOID: u32 = 0x20000000; +pub(crate) const IOC_OUT: u32 = 0x40000000; +pub(crate) const IOC_IN: u32 = 0x80000000; +pub(crate) const IOC_INOUT: u32 = IOC_IN | IOC_OUT; +pub(crate) const IOC_DIRMASK: u32 = 0xe0000000; + +// Only pub(crate) for the above reason. +pub(crate) const fn _IOC(inout: u32, group: c_ulong, num: c_ulong, len: c_ulong) -> c_ulong { + debug_assert!(inout <= IOC_DIRMASK); + debug_assert!(group <= 0xff); + debug_assert!(num <= 0xff); + debug_assert!(len <= IOCPARM_MAX); + + // Sanity check the cast + assert!(size_of::() <= size_of::()); + + (inout as c_ulong) | ((len & IOCPARM_MASK) << 16) | (group << 8) | num +} + +pub const fn _IO(g: c_ulong, n: c_ulong) -> c_ulong { + _IOC(IOC_VOID, g, n, 0) +} + +/// Build an ioctl number for an read-only ioctl. +pub const fn _IOR(g: c_ulong, n: c_ulong) -> c_ulong { + _IOC(IOC_OUT, g, n, mem::size_of::() as c_ulong) +} + +/// Build an ioctl number for an write-only ioctl. +pub const fn _IOW(g: c_ulong, n: c_ulong) -> c_ulong { + _IOC(IOC_IN, g, n, mem::size_of::() as c_ulong) +} + +/// Build an ioctl number for a read-write ioctl. +pub const fn _IOWR(g: c_ulong, n: c_ulong) -> c_ulong { + _IOC(IOC_INOUT, g, n, mem::size_of::() as c_ulong) +} diff --git a/vendor/libc/src/new/apple/xnu/sys/mod.rs b/vendor/libc/src/new/apple/xnu/sys/mod.rs new file mode 100644 index 0000000..8c7108c --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/sys/mod.rs @@ -0,0 +1,18 @@ +//! Directory: `sys/` +//! +//! + +pub(crate) mod ioccom; +pub(crate) mod signal; +pub(crate) mod sockio; +pub(crate) mod ttycom; + +/// Directory: `sys/_types` +/// +/// https://github.com/apple-oss-distributions/xnu/tree/main/bsd/sys/_types +pub(crate) mod _types { + pub(crate) mod _ucontext; +} + +// Bit of a hack since the directories get merged and we can't have >1 sys module. +pub(crate) use crate::new::apple::libpthread::sys::*; diff --git a/vendor/libc/src/new/apple/xnu/sys/signal.rs b/vendor/libc/src/new/apple/xnu/sys/signal.rs new file mode 100644 index 0000000..844793e --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/sys/signal.rs @@ -0,0 +1,6 @@ +//! Header: `sys/signal.h` +//! +//! + +pub use crate::machine::_mcontext::*; +pub use crate::sys::_types::_ucontext::*; diff --git a/vendor/libc/src/new/apple/xnu/sys/sockio.rs b/vendor/libc/src/new/apple/xnu/sys/sockio.rs new file mode 100644 index 0000000..7ca4e03 --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/sys/sockio.rs @@ -0,0 +1,88 @@ +//! Header: `sys/sockio.h` +//! +//! + +use crate::prelude::*; +use crate::sys::ioccom::*; + +pub const SIOCSHIWAT: c_ulong = _IOW::('s' as c_ulong, 0); +pub const SIOCGHIWAT: c_ulong = _IOR::('s' as c_ulong, 1); +pub const SIOCSLOWAT: c_ulong = _IOW::('s' as c_ulong, 2); +pub const SIOCGLOWAT: c_ulong = _IOR::('s' as c_ulong, 3); +pub const SIOCATMARK: c_ulong = _IOR::('s' as c_ulong, 7); +pub const SIOCSPGRP: c_ulong = _IOW::('s' as c_ulong, 8); +pub const SIOCGPGRP: c_ulong = _IOR::('s' as c_ulong, 9); + +pub const SIOCSIFADDR: c_ulong = _IOW::('i' as c_ulong, 12); +pub const SIOCSIFDSTADDR: c_ulong = _IOW::('i' as c_ulong, 14); +pub const SIOCSIFFLAGS: c_ulong = _IOW::('i' as c_ulong, 16); +pub const SIOCGIFFLAGS: c_ulong = _IOWR::('i' as c_ulong, 17); +pub const SIOCSIFBRDADDR: c_ulong = _IOW::('i' as c_ulong, 19); +pub const SIOCSIFNETMASK: c_ulong = _IOW::('i' as c_ulong, 22); +pub const SIOCGIFMETRIC: c_ulong = _IOWR::('i' as c_ulong, 23); +pub const SIOCSIFMETRIC: c_ulong = _IOW::('i' as c_ulong, 24); +pub const SIOCDIFADDR: c_ulong = _IOW::('i' as c_ulong, 25); +// struct ifaliasreq +pub const SIOCAIFADDR: c_ulong = _IOC(IOC_IN, 'i' as c_ulong, 26, 64); +pub const SIOCGIFDSTADDR: c_ulong = _IOWR::('i' as c_ulong, 34); +pub const SIOCGIFBRDADDR: c_ulong = _IOWR::('i' as c_ulong, 35); +pub const SIOCGIFCONF: c_ulong = _IOWR::('i' as c_ulong, 36); +pub const SIOCGIFNETMASK: c_ulong = _IOWR::('i' as c_ulong, 37); +pub const SIOCAUTOADDR: c_ulong = _IOWR::('i' as c_ulong, 38); +pub const SIOCAUTONETMASK: c_ulong = _IOW::('i' as c_ulong, 39); +pub const SIOCARPIPLL: c_ulong = _IOWR::('i' as c_ulong, 40); +pub const SIOCADDMULTI: c_ulong = _IOW::('i' as c_ulong, 49); +pub const SIOCDELMULTI: c_ulong = _IOW::('i' as c_ulong, 50); +pub const SIOCGIFMTU: c_ulong = _IOWR::('i' as c_ulong, 51); +pub const SIOCSIFMTU: c_ulong = _IOW::('i' as c_ulong, 52); +pub const SIOCGIFPHYS: c_ulong = _IOWR::('i' as c_ulong, 53); +pub const SIOCSIFPHYS: c_ulong = _IOW::('i' as c_ulong, 54); +pub const SIOCSIFMEDIA: c_ulong = _IOWR::('i' as c_ulong, 55); +// struct ifmediareq +pub const SIOCGIFMEDIA: c_ulong = _IOC(IOC_INOUT, 'i' as c_ulong, 56, 44); +pub const SIOCSIFGENERIC: c_ulong = _IOW::('i' as c_ulong, 57); +pub const SIOCGIFGENERIC: c_ulong = _IOWR::('i' as c_ulong, 58); +// struct rslvmulti_req +pub const SIOCRSLVMULTI: c_ulong = _IOC(IOC_INOUT, 'i' as c_ulong, 59, 16); +pub const SIOCSIFLLADDR: c_ulong = _IOW::('i' as c_ulong, 60); +// struct ifstat +pub const SIOCGIFSTATUS: c_ulong = _IOC(IOC_INOUT, 'i' as c_ulong, 61, 817); +// struct ifaliasreq +pub const SIOCSIFPHYADDR: c_ulong = _IOC(IOC_IN, 'i' as c_ulong, 62, 64); +pub const SIOCGIFPSRCADDR: c_ulong = _IOWR::('i' as c_ulong, 63); +pub const SIOCGIFPDSTADDR: c_ulong = _IOWR::('i' as c_ulong, 64); +pub const SIOCDIFPHYADDR: c_ulong = _IOW::('i' as c_ulong, 65); +pub const SIOCGIFDEVMTU: c_ulong = _IOWR::('i' as c_ulong, 68); +pub const SIOCSIFALTMTU: c_ulong = _IOW::('i' as c_ulong, 69); +pub const SIOCGIFALTMTU: c_ulong = _IOWR::('i' as c_ulong, 72); +pub const SIOCSIFBOND: c_ulong = _IOW::('i' as c_ulong, 70); +pub const SIOCGIFBOND: c_ulong = _IOWR::('i' as c_ulong, 71); +// struct ifmediareq +pub const SIOCGIFXMEDIA: c_ulong = _IOC(IOC_INOUT, 'i' as c_ulong, 72, 44); +pub const SIOCSIFCAP: c_ulong = _IOW::('i' as c_ulong, 90); +pub const SIOCGIFCAP: c_ulong = _IOWR::('i' as c_ulong, 91); +pub const SIOCSIFMANAGEMENT: c_ulong = _IOWR::('i' as c_ulong, 92); +pub const SIOCIFCREATE: c_ulong = _IOWR::('i' as c_ulong, 120); +pub const SIOCIFDESTROY: c_ulong = _IOW::('i' as c_ulong, 121); +pub const SIOCIFCREATE2: c_ulong = _IOWR::('i' as c_ulong, 122); +// struct ifdrv +pub const SIOCSDRVSPEC: c_ulong = _IOC(IOC_IN, 'i' as c_ulong, 123, 40); +// struct ifdrv +pub const SIOCGDRVSPEC: c_ulong = _IOC(IOC_INOUT, 'i' as c_ulong, 123, 40); +pub const SIOCSIFVLAN: c_ulong = _IOW::('i' as c_ulong, 126); +pub const SIOCGIFVLAN: c_ulong = _IOWR::('i' as c_ulong, 127); +pub const SIOCSETVLAN: c_ulong = SIOCSIFVLAN; +pub const SIOCGETVLAN: c_ulong = SIOCGIFVLAN; +// struct if_clonereq +pub const SIOCIFGCLONERS: c_ulong = _IOC(IOC_INOUT, 'i' as c_ulong, 129, 16); +pub const SIOCGIFASYNCMAP: c_ulong = _IOWR::('i' as c_ulong, 124); +pub const SIOCSIFASYNCMAP: c_ulong = _IOW::('i' as c_ulong, 125); +pub const SIOCGIFMAC: c_ulong = _IOWR::('i' as c_ulong, 130); +pub const SIOCSIFMAC: c_ulong = _IOW::('i' as c_ulong, 131); +pub const SIOCSIFKPI: c_ulong = _IOW::('i' as c_ulong, 134); +pub const SIOCGIFKPI: c_ulong = _IOWR::('i' as c_ulong, 135); +pub const SIOCGIFWAKEFLAGS: c_ulong = _IOWR::('i' as c_ulong, 136); +pub const SIOCGIFFUNCTIONALTYPE: c_ulong = _IOWR::('i' as c_ulong, 173); +pub const SIOCSIF6LOWPAN: c_ulong = _IOW::('i' as c_ulong, 196); +pub const SIOCGIF6LOWPAN: c_ulong = _IOWR::('i' as c_ulong, 197); +pub const SIOCGIFDIRECTLINK: c_ulong = _IOWR::('i' as c_ulong, 222); diff --git a/vendor/libc/src/new/apple/xnu/sys/ttycom.rs b/vendor/libc/src/new/apple/xnu/sys/ttycom.rs new file mode 100644 index 0000000..55e680c --- /dev/null +++ b/vendor/libc/src/new/apple/xnu/sys/ttycom.rs @@ -0,0 +1,93 @@ +//! Header: `sys/ttycom.h` +//! +//! + +use crate::prelude::*; +use crate::sys::ioccom::*; + +/* FIXME(1.0): a number of ioctl numbers are `c_int` or `c_uint` and should be changed to + * `c_ulong` to match the others. */ + +pub const TIOCMODG: c_ulong = _IOR::('t' as c_ulong, 3); +pub const TIOCMODS: c_ulong = _IOW::('t' as c_ulong, 4); + +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 TIOCEXCL: c_int = ulong_cast_int(_IO('t' as c_ulong, 13)); +pub const TIOCNXCL: c_int = ulong_cast_int(_IO('t' as c_ulong, 14)); + +pub const TIOCFLUSH: c_ulong = _IOW::('t' as c_ulong, 16); + +pub const TIOCGETA: c_ulong = _IOR::('t' as c_ulong, 19); +pub const TIOCSETA: c_ulong = _IOW::('t' as c_ulong, 20); +pub const TIOCSETAW: c_ulong = _IOW::('t' as c_ulong, 21); +pub const TIOCSETAF: c_ulong = _IOW::('t' as c_ulong, 22); + +pub const TIOCGETD: c_ulong = _IOR::('t' as c_ulong, 26); +pub const TIOCSETD: c_ulong = _IOW::('t' as c_ulong, 27); + +pub const TIOCIXON: c_int = ulong_cast_int(_IO('t' as c_ulong, 129)); +pub const TIOCIXOFF: c_int = ulong_cast_int(_IO('t' as c_ulong, 128)); + +pub const TIOCSBRK: c_int = ulong_cast_int(_IO('t' as c_ulong, 123)); +pub const TIOCCBRK: c_int = ulong_cast_int(_IO('t' as c_ulong, 122)); +pub const TIOCSDTR: c_int = ulong_cast_int(_IO('t' as c_ulong, 121)); +pub const TIOCCDTR: c_int = ulong_cast_int(_IO('t' as c_ulong, 120)); +pub const TIOCGPGRP: c_ulong = _IOR::('t' as c_ulong, 119); +pub const TIOCSPGRP: c_ulong = _IOW::('t' as c_ulong, 118); + +pub const TIOCOUTQ: c_ulong = _IOR::('t' as c_ulong, 115); +pub const TIOCSTI: c_ulong = _IOW::('t' as c_ulong, 114); +pub const TIOCNOTTY: c_ulong = _IO('t' as c_ulong, 113); +pub const TIOCPKT: c_ulong = _IOW::('t' as c_ulong, 112); + +pub const TIOCPKT_DATA: c_int = 0x00; +pub const TIOCPKT_FLUSHREAD: c_int = 0x01; +pub const TIOCPKT_FLUSHWRITE: c_int = 0x02; +pub const TIOCPKT_STOP: c_int = 0x04; +pub const TIOCPKT_START: c_int = 0x08; +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 = ulong_cast_uint(_IO('t' as c_ulong, 111)); +pub const TIOCSTART: c_uint = ulong_cast_uint(_IO('t' as c_ulong, 110)); +pub const TIOCMSET: c_ulong = _IOW::('t' as c_ulong, 109); +pub const TIOCMBIS: c_ulong = _IOW::('t' as c_ulong, 108); +pub const TIOCMBIC: c_ulong = _IOW::('t' as c_ulong, 107); +pub const TIOCMGET: c_ulong = _IOR::('t' as c_ulong, 106); + +#[deprecated(since = "0.2.178", note = "Removed in MacOSX 12.0.1")] +pub const TIOCREMOTE: c_ulong = 0x80047469; + +pub const TIOCGWINSZ: c_ulong = _IOR::('t' as c_ulong, 104); +pub const TIOCSWINSZ: c_ulong = _IOW::('t' as c_ulong, 103); +pub const TIOCUCNTL: c_ulong = _IOW::('t' as c_ulong, 102); +pub const TIOCSTAT: c_uint = ulong_cast_uint(_IO('t' as c_ulong, 101)); + +pub const TIOCSCONS: c_uint = ulong_cast_uint(_IO('t' as c_ulong, 99)); +pub const TIOCCONS: c_ulong = _IOW::('t' as c_ulong, 98); +pub const TIOCSCTTY: c_uint = ulong_cast_uint(_IO('t' as c_ulong, 97)); +pub const TIOCEXT: c_ulong = _IOW::('t' as c_ulong, 96); +pub const TIOCSIG: c_uint = ulong_cast_uint(_IO('t' as c_ulong, 95)); +pub const TIOCDRAIN: c_uint = ulong_cast_uint(_IO('t' as c_ulong, 94)); +pub const TIOCMSDTRWAIT: c_ulong = _IOW::('t' as c_ulong, 91); +pub const TIOCMGDTRWAIT: c_ulong = _IOR::('t' as c_ulong, 90); +pub const TIOCTIMESTAMP: c_ulong = _IOR::('t' as c_ulong, 89); +pub const TIOCDCDTIMESTAMP: c_ulong = _IOR::('t' as c_ulong, 88); +pub const TIOCSDRAINWAIT: c_ulong = _IOW::('t' as c_ulong, 87); +pub const TIOCGDRAINWAIT: c_ulong = _IOR::('t' as c_ulong, 86); +pub const TIOCDSIMICROCODE: c_uint = ulong_cast_uint(_IO('t' as c_ulong, 85)); +pub const TIOCPTYGRANT: c_uint = ulong_cast_uint(_IO('t' as c_ulong, 84)); +pub const TIOCPTYGNAME: c_uint = ulong_cast_uint(_IOC(IOC_OUT, 't' as c_ulong, 83, 128)); +pub const TIOCPTYUNLK: c_uint = ulong_cast_uint(_IO('t' as c_ulong, 82)); diff --git a/vendor/libc/src/new/bionic_libc/kernel_uapi/linux/mod.rs b/vendor/libc/src/new/bionic_libc/kernel_uapi/linux/mod.rs new file mode 100644 index 0000000..57cf2dd --- /dev/null +++ b/vendor/libc/src/new/bionic_libc/kernel_uapi/linux/mod.rs @@ -0,0 +1,5 @@ +//! Directory: `bionic/libc/kernel/uapi/linux/` +//! +//! + +pub(crate) mod types; diff --git a/vendor/libc/src/new/bionic_libc/kernel_uapi/linux/types.rs b/vendor/libc/src/new/bionic_libc/kernel_uapi/linux/types.rs new file mode 100644 index 0000000..e142abd --- /dev/null +++ b/vendor/libc/src/new/bionic_libc/kernel_uapi/linux/types.rs @@ -0,0 +1,21 @@ +//! * Header: `bionic/libc/kernel/uapi/linux/types.h` +//! * Header: `bionic/libc/kernel/uapi/asm-generic/int-ll64.h` + +use crate::prelude::*; + +/* Definitions from `asm/types.h` -> `asm-generic/types.h` -> `asm-generic/int-ll64.h` */ + +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 __s64 = c_longlong; +pub type __u64 = c_ulonglong; + +/* From `uapi/linux/types.h` */ + +pub type __be16 = __u16; diff --git a/vendor/libc/src/new/bionic_libc/kernel_uapi/mod.rs b/vendor/libc/src/new/bionic_libc/kernel_uapi/mod.rs new file mode 100644 index 0000000..5c879bd --- /dev/null +++ b/vendor/libc/src/new/bionic_libc/kernel_uapi/mod.rs @@ -0,0 +1,3 @@ +//! Directory: `bionic/libc/kernel/uapi` + +pub(crate) mod linux; diff --git a/vendor/libc/src/new/bionic_libc/mod.rs b/vendor/libc/src/new/bionic_libc/mod.rs new file mode 100644 index 0000000..3ffdc07 --- /dev/null +++ b/vendor/libc/src/new/bionic_libc/mod.rs @@ -0,0 +1,10 @@ +//! This directory maps to `bionic/libc/include` in the Android source. `bionic/libc/kernel` is +//! the source of UAPI definitions, which are a cleaned form of the default Linux headers. +//! +//! , +//! + +pub(crate) mod kernel_uapi; +pub(crate) mod pthread; +pub(crate) mod sys; +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/bionic_libc/pthread.rs b/vendor/libc/src/new/bionic_libc/pthread.rs new file mode 100644 index 0000000..4997547 --- /dev/null +++ b/vendor/libc/src/new/bionic_libc/pthread.rs @@ -0,0 +1,42 @@ +//! Header: `unistd.h` + +pub use crate::new::common::linux_like::pthread::{ + pthread_getattr_np, + pthread_setname_np, +}; +pub use crate::new::common::posix::pthread::{ + pthread_atfork, + pthread_attr_getguardsize, + pthread_attr_getinheritsched, + pthread_attr_getstack, + pthread_attr_setguardsize, + pthread_attr_setinheritsched, + pthread_attr_setstack, + pthread_barrier_destroy, + pthread_barrier_init, + pthread_barrier_wait, + pthread_barrierattr_destroy, + pthread_barrierattr_getpshared, + pthread_barrierattr_init, + pthread_barrierattr_setpshared, + pthread_condattr_getclock, + pthread_condattr_getpshared, + pthread_condattr_setclock, + pthread_condattr_setpshared, + pthread_create, + pthread_getcpuclockid, + pthread_getschedparam, + pthread_kill, + pthread_mutex_timedlock, + pthread_mutexattr_getpshared, + pthread_mutexattr_setpshared, + pthread_rwlockattr_getpshared, + pthread_rwlockattr_setpshared, + pthread_setschedparam, + pthread_sigmask, + pthread_spin_destroy, + pthread_spin_init, + pthread_spin_lock, + pthread_spin_trylock, + pthread_spin_unlock, +}; diff --git a/vendor/libc/src/new/bionic_libc/sys/mod.rs b/vendor/libc/src/new/bionic_libc/sys/mod.rs new file mode 100644 index 0000000..a882cbd --- /dev/null +++ b/vendor/libc/src/new/bionic_libc/sys/mod.rs @@ -0,0 +1,3 @@ +//! Directory: `sys/` + +pub(crate) mod socket; diff --git a/vendor/libc/src/new/bionic_libc/sys/socket.rs b/vendor/libc/src/new/bionic_libc/sys/socket.rs new file mode 100644 index 0000000..c4a4e78 --- /dev/null +++ b/vendor/libc/src/new/bionic_libc/sys/socket.rs @@ -0,0 +1,51 @@ +//! Header: `sys/socket.h` + +use crate::prelude::*; + +s! { + pub struct msghdr { + pub msg_name: *mut c_void, + pub msg_namelen: crate::socklen_t, + pub msg_iov: *mut crate::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 ucred { + pub pid: crate::pid_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + } +} + +extern "C" { + pub fn recvmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: c_uint, + flags: c_int, + timeout: *const crate::timespec, + ) -> c_int; + pub fn sendmmsg( + sockfd: c_int, + msgvec: *const crate::mmsghdr, + vlen: c_uint, + flags: c_int, + ) -> c_int; + pub fn recvfrom( + socket: c_int, + buf: *mut c_void, + len: size_t, + flags: c_int, + addr: *mut crate::sockaddr, + addrlen: *mut crate::socklen_t, + ) -> ssize_t; +} diff --git a/vendor/libc/src/new/bionic_libc/unistd.rs b/vendor/libc/src/new/bionic_libc/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/bionic_libc/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/common/bsd.rs b/vendor/libc/src/new/common/bsd.rs new file mode 100644 index 0000000..818daf9 --- /dev/null +++ b/vendor/libc/src/new/common/bsd.rs @@ -0,0 +1 @@ +//! Interfaces common across the BSD family. diff --git a/vendor/libc/src/new/common/freebsd_like.rs b/vendor/libc/src/new/common/freebsd_like.rs new file mode 100644 index 0000000..f49f2c9 --- /dev/null +++ b/vendor/libc/src/new/common/freebsd_like.rs @@ -0,0 +1 @@ +//! Interfaces common in FreeBSD-derived operating systems. This includes FreeBSD and DragonFlyBSD. diff --git a/vendor/libc/src/new/common/linux_like/mod.rs b/vendor/libc/src/new/common/linux_like/mod.rs new file mode 100644 index 0000000..9c41fe2 --- /dev/null +++ b/vendor/libc/src/new/common/linux_like/mod.rs @@ -0,0 +1,9 @@ +//! API that primarily comes from Linux but is also used other platforms (e.g. Android). + +#[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux" +))] +pub(crate) mod pthread; diff --git a/vendor/libc/src/new/common/linux_like/pthread.rs b/vendor/libc/src/new/common/linux_like/pthread.rs new file mode 100644 index 0000000..b54d385 --- /dev/null +++ b/vendor/libc/src/new/common/linux_like/pthread.rs @@ -0,0 +1,25 @@ +use crate::prelude::*; + +extern "C" { + #[cfg(any(target_os = "linux", target_os = "l4re"))] + pub fn pthread_getaffinity_np( + thread: crate::pthread_t, + cpusetsize: size_t, + cpuset: *mut crate::cpu_set_t, + ) -> c_int; + + pub fn pthread_getattr_np(native: crate::pthread_t, attr: *mut crate::pthread_attr_t) -> c_int; + + #[cfg(target_os = "linux")] + pub fn pthread_getname_np(thread: crate::pthread_t, name: *mut c_char, len: size_t) -> c_int; + + #[cfg(any(target_os = "linux", target_os = "l4re"))] + pub fn pthread_setaffinity_np( + thread: crate::pthread_t, + cpusetsize: size_t, + cpuset: *const crate::cpu_set_t, + ) -> c_int; + + #[cfg(any(target_os = "android", target_os = "linux"))] + pub fn pthread_setname_np(thread: crate::pthread_t, name: *const c_char) -> c_int; +} diff --git a/vendor/libc/src/new/common/mod.rs b/vendor/libc/src/new/common/mod.rs new file mode 100644 index 0000000..acb1891 --- /dev/null +++ b/vendor/libc/src/new/common/mod.rs @@ -0,0 +1,39 @@ +//! Interfaces that are common across multiple platforms +//! +//! We make these available everywhere but each platform must opt in to reexporting. +//! +//! There shouldn't be any repeated definitions or complex configuration in this module. On +//! platforms that don't use common APIs it is fine to use `#[cfg(not(...))]`, but if a platform +//! needs a custom definition then it should be defined in the platform-specific module. +//! +//! The goal is that platforms need to opt in to the definitions here, so that worst case we have +//! an unused warning on untested platforms (rather than exposing incorrect API). + +#[cfg(any( + target_vendor = "apple", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", +))] +pub(crate) mod bsd; + +#[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux", +))] +pub(crate) mod linux_like; + +#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] +pub(crate) mod freebsd_like; + +#[cfg(any(target_os = "netbsd", target_os = "openbsd"))] +pub(crate) mod netbsd_like; + +#[cfg(any(target_os = "illumos", target_os = "solaris"))] +pub(crate) mod solarish; + +#[cfg(target_family = "unix")] +pub(crate) mod posix; diff --git a/vendor/libc/src/new/common/netbsd_like.rs b/vendor/libc/src/new/common/netbsd_like.rs new file mode 100644 index 0000000..4267357 --- /dev/null +++ b/vendor/libc/src/new/common/netbsd_like.rs @@ -0,0 +1 @@ +//! Interfaces common in NetBSD-derived operating systems. This includes NetBSD and OpenBSD. diff --git a/vendor/libc/src/new/common/posix/mod.rs b/vendor/libc/src/new/common/posix/mod.rs new file mode 100644 index 0000000..44ae64a --- /dev/null +++ b/vendor/libc/src/new/common/posix/mod.rs @@ -0,0 +1,15 @@ +//! POSIX APIs that are used by a number of platforms +//! +//! These can be found at: . + +// FIXME(pthread): eventually all platforms should use this module +#[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux", + target_os = "qurt", + target_vendor = "apple", +))] +pub(crate) mod pthread; +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/common/posix/pthread.rs b/vendor/libc/src/new/common/posix/pthread.rs new file mode 100644 index 0000000..b50c21f --- /dev/null +++ b/vendor/libc/src/new/common/posix/pthread.rs @@ -0,0 +1,332 @@ +//! Header: `pthread.h` +//! +//! + +use crate::prelude::*; + +extern "C" { + #[cfg(any(target_os = "android", target_os = "linux"))] + pub fn pthread_atfork( + prepare: Option, + parent: Option, + child: Option, + ) -> c_int; + + #[cfg(any(target_os = "android", target_os = "l4re", target_os = "linux"))] + pub fn pthread_attr_getguardsize( + attr: *const crate::pthread_attr_t, + guardsize: *mut size_t, + ) -> c_int; + + #[cfg(any( + target_os = "android", + target_os = "l4re", + target_os = "linux", + target_vendor = "apple", + ))] + pub fn pthread_attr_getinheritsched( + attr: *const crate::pthread_attr_t, + inheritsched: *mut c_int, + ) -> c_int; + + #[cfg(any(target_os = "l4re", target_os = "linux", target_vendor = "apple"))] + pub fn pthread_attr_getschedparam( + attr: *const crate::pthread_attr_t, + param: *mut crate::sched_param, + ) -> c_int; + + #[cfg(any(target_os = "l4re", target_os = "linux", target_vendor = "apple"))] + pub fn pthread_attr_getschedpolicy( + attr: *const crate::pthread_attr_t, + policy: *mut c_int, + ) -> c_int; + + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "linux", + target_os = "l4re" + ))] + pub fn pthread_attr_getstack( + attr: *const crate::pthread_attr_t, + stackaddr: *mut *mut c_void, + stacksize: *mut size_t, + ) -> c_int; + + #[cfg(any(target_os = "android", target_os = "l4re", target_os = "linux"))] + pub fn pthread_attr_setguardsize(attr: *mut crate::pthread_attr_t, guardsize: size_t) -> c_int; + + #[cfg(any( + target_os = "android", + target_os = "l4re", + target_os = "linux", + target_vendor = "apple" + ))] + pub fn pthread_attr_setinheritsched( + attr: *mut crate::pthread_attr_t, + inheritsched: c_int, + ) -> c_int; + + #[cfg(any(target_os = "l4re", target_os = "linux", target_vendor = "apple"))] + pub fn pthread_attr_setschedparam( + attr: *mut crate::pthread_attr_t, + param: *const crate::sched_param, + ) -> c_int; + + #[cfg(any(target_os = "l4re", target_os = "linux", target_vendor = "apple"))] + pub fn pthread_attr_setschedpolicy(attr: *mut crate::pthread_attr_t, policy: c_int) -> c_int; + + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "linux", + target_os = "l4re" + ))] + pub fn pthread_attr_setstack( + attr: *mut crate::pthread_attr_t, + stackaddr: *mut c_void, + stacksize: size_t, + ) -> c_int; + + #[cfg(any(target_os = "android", target_os = "l4re", target_os = "linux"))] + pub fn pthread_barrier_destroy(barrier: *mut crate::pthread_barrier_t) -> c_int; + + #[cfg(any(target_os = "android", target_os = "l4re", target_os = "linux"))] + pub fn pthread_barrier_init( + barrier: *mut crate::pthread_barrier_t, + attr: *const crate::pthread_barrierattr_t, + count: c_uint, + ) -> c_int; + + #[cfg(any(target_os = "android", target_os = "l4re", target_os = "linux"))] + pub fn pthread_barrier_wait(barrier: *mut crate::pthread_barrier_t) -> c_int; + + #[cfg(any(target_os = "android", target_os = "l4re", target_os = "linux"))] + pub fn pthread_barrierattr_destroy(attr: *mut crate::pthread_barrierattr_t) -> c_int; + + #[cfg(any(target_os = "android", target_os = "linux"))] + pub fn pthread_barrierattr_getpshared( + attr: *const crate::pthread_barrierattr_t, + shared: *mut c_int, + ) -> c_int; + + #[cfg(any(target_os = "android", target_os = "l4re", target_os = "linux"))] + pub fn pthread_barrierattr_init(attr: *mut crate::pthread_barrierattr_t) -> c_int; + + #[cfg(any(target_os = "android", target_os = "l4re", target_os = "linux"))] + pub fn pthread_barrierattr_setpshared( + attr: *mut crate::pthread_barrierattr_t, + shared: c_int, + ) -> c_int; + + #[cfg(any(target_os = "l4re", all(target_os = "linux", not(target_env = "ohos"))))] + pub fn pthread_cancel(thread: crate::pthread_t) -> c_int; + + #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux",))] + pub fn pthread_condattr_getclock( + attr: *const crate::pthread_condattr_t, + clock_id: *mut crate::clockid_t, + ) -> c_int; + + #[cfg(any( + target_os = "android", + target_os = "l4re", + target_os = "linux", + target_vendor = "apple", + ))] + pub fn pthread_condattr_getpshared( + attr: *const crate::pthread_condattr_t, + pshared: *mut c_int, + ) -> c_int; + + #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux",))] + pub fn pthread_condattr_setclock( + attr: *mut crate::pthread_condattr_t, + clock_id: crate::clockid_t, + ) -> c_int; + + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "linux", + target_os = "l4re", + target_vendor = "apple", + ))] + pub fn pthread_condattr_setpshared( + attr: *mut crate::pthread_condattr_t, + pshared: c_int, + ) -> c_int; + + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux", + ))] + pub fn pthread_create( + native: *mut crate::pthread_t, + attr: *const crate::pthread_attr_t, + f: extern "C" fn(*mut c_void) -> *mut c_void, + value: *mut c_void, + ) -> c_int; + + #[cfg(any(target_os = "android", target_os = "linux"))] + pub fn pthread_getcpuclockid(thread: crate::pthread_t, clk_id: *mut crate::clockid_t) -> c_int; + + #[cfg(any( + target_os = "android", + target_os = "l4re", + target_os = "linux", + target_vendor = "apple", + ))] + pub fn pthread_getschedparam( + native: crate::pthread_t, + policy: *mut c_int, + param: *mut crate::sched_param, + ) -> c_int; + + // FIXME(reorg): In recent POSIX versions, this is a signal.h function and not required + // in pthread. + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux" + ))] + pub fn pthread_kill(thread: crate::pthread_t, sig: c_int) -> c_int; + + #[cfg(all(target_os = "linux", not(target_env = "ohos")))] + pub fn pthread_mutex_consistent(mutex: *mut crate::pthread_mutex_t) -> c_int; + + #[cfg(any(target_os = "android", target_os = "l4re", target_os = "linux"))] + #[cfg_attr(gnu_time_bits64, link_name = "__pthread_mutex_timedlock64")] + #[cfg_attr(musl_redir_time64, link_name = "__pthread_mutex_timedlock_time64")] + pub fn pthread_mutex_timedlock( + lock: *mut crate::pthread_mutex_t, + abstime: *const crate::timespec, + ) -> c_int; + + #[cfg(target_os = "linux")] + pub fn pthread_mutexattr_getprotocol( + attr: *const crate::pthread_mutexattr_t, + protocol: *mut c_int, + ) -> c_int; + + #[cfg(any( + target_os = "android", + target_os = "l4re", + target_os = "linux", + target_vendor = "apple", + ))] + pub fn pthread_mutexattr_getpshared( + attr: *const crate::pthread_mutexattr_t, + pshared: *mut c_int, + ) -> c_int; + + #[cfg(all(target_os = "linux", not(target_env = "ohos")))] + pub fn pthread_mutexattr_getrobust( + attr: *const crate::pthread_mutexattr_t, + robustness: *mut c_int, + ) -> c_int; + + #[cfg(target_os = "linux")] + pub fn pthread_mutexattr_setprotocol( + attr: *mut crate::pthread_mutexattr_t, + protocol: c_int, + ) -> c_int; + + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "linux", + target_os = "l4re", + target_vendor = "apple", + ))] + pub fn pthread_mutexattr_setpshared( + attr: *mut crate::pthread_mutexattr_t, + pshared: c_int, + ) -> c_int; + + #[cfg(all(target_os = "linux", not(target_env = "ohos")))] + pub fn pthread_mutexattr_setrobust( + attr: *mut crate::pthread_mutexattr_t, + robustness: c_int, + ) -> c_int; + + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "linux", + target_os = "l4re", + target_vendor = "apple", + ))] + pub fn pthread_rwlockattr_getpshared( + attr: *const crate::pthread_rwlockattr_t, + val: *mut c_int, + ) -> c_int; + + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "linux", + target_os = "l4re", + target_vendor = "apple", + ))] + pub fn pthread_rwlockattr_setpshared( + attr: *mut crate::pthread_rwlockattr_t, + val: c_int, + ) -> c_int; + + // FIXME(1.0): These shoul be combined to the version that takes an optional unsafe function. + #[cfg(any(target_os = "l4re", target_os = "linux"))] + pub fn pthread_once(control: *mut crate::pthread_once_t, routine: extern "C" fn()) -> c_int; + #[cfg(target_vendor = "apple")] + pub fn pthread_once( + once_control: *mut crate::pthread_once_t, + init_routine: Option, + ) -> c_int; + + #[cfg(any( + target_os = "android", + target_os = "l4re", + target_os = "linux", + target_vendor = "apple", + ))] + pub fn pthread_setschedparam( + native: crate::pthread_t, + policy: c_int, + param: *const crate::sched_param, + ) -> c_int; + + #[cfg(target_os = "linux")] + pub fn pthread_setschedprio(native: crate::pthread_t, priority: c_int) -> c_int; + + // FIXME(reorg): In recent POSIX versions, this is a signal.h function and not required + // in pthread. + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux" + ))] + pub fn pthread_sigmask( + how: c_int, + set: *const crate::sigset_t, + oldset: *mut crate::sigset_t, + ) -> c_int; + + #[cfg(any(target_os = "android", target_os = "l4re", target_os = "linux"))] + pub fn pthread_spin_destroy(lock: *mut crate::pthread_spinlock_t) -> c_int; + + #[cfg(any(target_os = "android", target_os = "l4re", target_os = "linux"))] + pub fn pthread_spin_init(lock: *mut crate::pthread_spinlock_t, pshared: c_int) -> c_int; + + #[cfg(any(target_os = "android", target_os = "l4re", target_os = "linux"))] + pub fn pthread_spin_lock(lock: *mut crate::pthread_spinlock_t) -> c_int; + + #[cfg(any(target_os = "android", target_os = "l4re", target_os = "linux"))] + pub fn pthread_spin_trylock(lock: *mut crate::pthread_spinlock_t) -> c_int; + + #[cfg(any(target_os = "android", target_os = "l4re", target_os = "linux"))] + pub fn pthread_spin_unlock(lock: *mut crate::pthread_spinlock_t) -> c_int; +} diff --git a/vendor/libc/src/new/common/posix/unistd.rs b/vendor/libc/src/new/common/posix/unistd.rs new file mode 100644 index 0000000..0c02cba --- /dev/null +++ b/vendor/libc/src/new/common/posix/unistd.rs @@ -0,0 +1,9 @@ +//! Header: `unistd.h` +//! +//! + +use crate::prelude::*; + +pub const STDIN_FILENO: c_int = 0; +pub const STDOUT_FILENO: c_int = 1; +pub const STDERR_FILENO: c_int = 2; diff --git a/vendor/libc/src/new/common/solarish.rs b/vendor/libc/src/new/common/solarish.rs new file mode 100644 index 0000000..f966114 --- /dev/null +++ b/vendor/libc/src/new/common/solarish.rs @@ -0,0 +1 @@ +//! Interfaces common in solaris-derived operating systems. This includes Solaris and Illumos. diff --git a/vendor/libc/src/new/cygwin/mod.rs b/vendor/libc/src/new/cygwin/mod.rs new file mode 100644 index 0000000..356ae58 --- /dev/null +++ b/vendor/libc/src/new/cygwin/mod.rs @@ -0,0 +1,5 @@ +//! Cygwin libc. +//! +//! * Headers: + +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/cygwin/unistd.rs b/vendor/libc/src/new/cygwin/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/cygwin/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/dragonfly/mod.rs b/vendor/libc/src/new/dragonfly/mod.rs new file mode 100644 index 0000000..4a1b2c4 --- /dev/null +++ b/vendor/libc/src/new/dragonfly/mod.rs @@ -0,0 +1,6 @@ +//! DragonFly BSD libc. +//! +//! * Headers: +//! * Manual pages: + +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/dragonfly/unistd.rs b/vendor/libc/src/new/dragonfly/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/dragonfly/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/emscripten/mod.rs b/vendor/libc/src/new/emscripten/mod.rs new file mode 100644 index 0000000..9b74464 --- /dev/null +++ b/vendor/libc/src/new/emscripten/mod.rs @@ -0,0 +1,7 @@ +//! Emscripten libc. +//! +//! * Headers: + +pub(crate) mod pthread; +pub(crate) mod sched; +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/emscripten/pthread.rs b/vendor/libc/src/new/emscripten/pthread.rs new file mode 100644 index 0000000..cfd7a05 --- /dev/null +++ b/vendor/libc/src/new/emscripten/pthread.rs @@ -0,0 +1,16 @@ +//! Header: `pthread.h` + +pub use crate::new::common::linux_like::pthread::pthread_getattr_np; +pub use crate::new::common::posix::pthread::{ + pthread_attr_getstack, + pthread_attr_setstack, + pthread_condattr_getclock, + pthread_condattr_setclock, + pthread_condattr_setpshared, + pthread_create, + pthread_kill, + pthread_mutexattr_setpshared, + pthread_rwlockattr_getpshared, + pthread_rwlockattr_setpshared, + pthread_sigmask, +}; diff --git a/vendor/libc/src/new/emscripten/sched.rs b/vendor/libc/src/new/emscripten/sched.rs new file mode 100644 index 0000000..3bf854e --- /dev/null +++ b/vendor/libc/src/new/emscripten/sched.rs @@ -0,0 +1,38 @@ +use crate::prelude::*; + +cfg_if! { + if #[cfg(musl_v1_2_3)] { + s! { + struct __c_anon_sched_param__reserved2 { + __reserved1: crate::time_t, + __reserved2: c_long, + } + + pub struct sched_param { + pub sched_priority: c_int, + + __reserved1: Padding, + #[cfg(musl32_time64)] + __reserved2: Padding<[c_long; 4]>, + #[cfg(not(musl32_time64))] + __reserved2: Padding<[__c_anon_sched_param__reserved2; 2]>, + __reserved3: Padding, + } + } + } else { + s! { + pub struct sched_param { + pub sched_priority: c_int, + + #[deprecated(since = "0.2.173", note = "This field has been removed upstream")] + pub sched_ss_low_priority: c_int, + #[deprecated(since = "0.2.173", note = "This field has been removed upstream")] + pub sched_ss_repl_period: crate::timespec, + #[deprecated(since = "0.2.173", note = "This field has been removed upstream")] + pub sched_ss_init_budget: crate::timespec, + #[deprecated(since = "0.2.173", note = "This field has been removed upstream")] + pub sched_ss_max_repl: c_int, + } + } + } +} diff --git a/vendor/libc/src/new/emscripten/unistd.rs b/vendor/libc/src/new/emscripten/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/emscripten/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/espidf/mod.rs b/vendor/libc/src/new/espidf/mod.rs new file mode 100644 index 0000000..061ea6e --- /dev/null +++ b/vendor/libc/src/new/espidf/mod.rs @@ -0,0 +1,2 @@ +//! Expressif libc. +// FIXME(espidf): link to headers needed. diff --git a/vendor/libc/src/new/freebsd/mod.rs b/vendor/libc/src/new/freebsd/mod.rs new file mode 100644 index 0000000..c0036c2 --- /dev/null +++ b/vendor/libc/src/new/freebsd/mod.rs @@ -0,0 +1,9 @@ +//! FreeBSD libc. +//! +//! * Headers: +//! * Symbol map: + +pub(crate) mod net; +pub(crate) mod netinet6; +pub(crate) mod sys; +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/freebsd/net/dlt.rs b/vendor/libc/src/new/freebsd/net/dlt.rs new file mode 100644 index 0000000..e3dddce --- /dev/null +++ b/vendor/libc/src/new/freebsd/net/dlt.rs @@ -0,0 +1,20 @@ +//! Header: `net/dlt.h` +//! +//! https://github.com/freebsd/freebsd-src/blob/main/sys/net/dlt.h + +use crate::prelude::*; + +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; diff --git a/vendor/libc/src/new/freebsd/net/mod.rs b/vendor/libc/src/new/freebsd/net/mod.rs new file mode 100644 index 0000000..e270c54 --- /dev/null +++ b/vendor/libc/src/new/freebsd/net/mod.rs @@ -0,0 +1,5 @@ +//! Directory: `net/` +//! +//! https://github.com/freebsd/freebsd-src/tree/main/sys/net + +pub(crate) mod dlt; diff --git a/vendor/libc/src/new/freebsd/netinet6/in6_var.rs b/vendor/libc/src/new/freebsd/netinet6/in6_var.rs new file mode 100644 index 0000000..f9e4530 --- /dev/null +++ b/vendor/libc/src/new/freebsd/netinet6/in6_var.rs @@ -0,0 +1,107 @@ +//! Header: `netinet6/in6_var.h` +//! +//! https://github.com/freebsd/freebsd-src/blob/main/sys/netinet6/in6_var.h + +use crate::prelude::*; +use crate::sys::ioccom::*; + +s! { + pub struct in6_addrlifetime { + pub ia6t_expire: crate::time_t, + pub ia6t_preferred: crate::time_t, + pub ia6t_vltime: u32, + pub ia6t_pltime: u32, + } + + pub struct in6_ifstat { + pub ifs6_in_receive: u64, + pub ifs6_in_hdrerr: u64, + pub ifs6_in_toobig: u64, + pub ifs6_in_noroute: u64, + pub ifs6_in_addrerr: u64, + pub ifs6_in_protounknown: u64, + pub ifs6_in_truncated: u64, + pub ifs6_in_discard: u64, + pub ifs6_in_deliver: u64, + pub ifs6_out_forward: u64, + pub ifs6_out_request: u64, + pub ifs6_out_discard: u64, + pub ifs6_out_fragok: u64, + pub ifs6_out_fragfail: u64, + pub ifs6_out_fragcreat: u64, + pub ifs6_reass_reqd: u64, + pub ifs6_reass_ok: u64, + pub ifs6_reass_fail: u64, + pub ifs6_in_mcast: u64, + pub ifs6_out_mcast: u64, + } + + pub struct icmp6_ifstat { + pub ifs6_in_msg: u64, + pub ifs6_in_error: u64, + pub ifs6_in_dstunreach: u64, + pub ifs6_in_adminprohib: u64, + pub ifs6_in_timeexceed: u64, + pub ifs6_in_paramprob: u64, + pub ifs6_in_pkttoobig: u64, + pub ifs6_in_echo: u64, + pub ifs6_in_echoreply: u64, + pub ifs6_in_routersolicit: u64, + pub ifs6_in_routeradvert: u64, + pub ifs6_in_neighborsolicit: u64, + pub ifs6_in_neighboradvert: u64, + pub ifs6_in_redirect: u64, + pub ifs6_in_mldquery: u64, + pub ifs6_in_mldreport: u64, + pub ifs6_in_mlddone: u64, + pub ifs6_out_msg: u64, + pub ifs6_out_error: u64, + pub ifs6_out_dstunreach: u64, + pub ifs6_out_adminprohib: u64, + pub ifs6_out_timeexceed: u64, + pub ifs6_out_paramprob: u64, + pub ifs6_out_pkttoobig: u64, + pub ifs6_out_echo: u64, + pub ifs6_out_echoreply: u64, + pub ifs6_out_routersolicit: u64, + pub ifs6_out_routeradvert: u64, + pub ifs6_out_neighborsolicit: u64, + pub ifs6_out_neighboradvert: u64, + pub ifs6_out_redirect: u64, + pub ifs6_out_mldquery: u64, + pub ifs6_out_mldreport: u64, + pub ifs6_out_mlddone: u64, + } +} + +s_no_extra_traits! { + pub struct in6_ifreq { + pub ifr_name: [c_char; crate::IFNAMSIZ], + pub ifr_ifru: __c_anonymous_ifr_ifru6, + } + + pub union __c_anonymous_ifr_ifru6 { + pub ifru_addr: crate::sockaddr_in6, + pub ifru_dstaddr: crate::sockaddr_in6, + pub ifru_flags: c_int, + pub ifru_flags6: c_int, + pub ifru_metric: c_int, + pub ifru_data: crate::caddr_t, + pub ifru_lifetime: in6_addrlifetime, + pub ifru_stat: in6_ifstat, + pub ifru_icmp6stat: icmp6_ifstat, + pub ifru_scope_id: [u32; 16], + } +} + +pub const IN6_IFF_ANYCAST: c_int = 0x01; +pub const IN6_IFF_TENTATIVE: c_int = 0x02; +pub const IN6_IFF_DUPLICATED: c_int = 0x04; +pub const IN6_IFF_DETACHED: c_int = 0x08; +pub const IN6_IFF_DEPRECATED: c_int = 0x10; +pub const IN6_IFF_NODAD: c_int = 0x20; +pub const IN6_IFF_AUTOCONF: c_int = 0x40; +pub const IN6_IFF_TEMPORARY: c_int = 0x80; +pub const IN6_IFF_PREFER_SOURCE: c_int = 0x0100; + +pub const SIOCGIFAFLAG_IN6: c_ulong = _IOWR::('i' as c_ulong, 73); diff --git a/vendor/libc/src/new/freebsd/netinet6/mod.rs b/vendor/libc/src/new/freebsd/netinet6/mod.rs new file mode 100644 index 0000000..848e809 --- /dev/null +++ b/vendor/libc/src/new/freebsd/netinet6/mod.rs @@ -0,0 +1,5 @@ +//! Directory: `netinet6/` +//! +//! https://github.com/freebsd/freebsd-src/tree/main/sys/netinet6 + +pub(crate) mod in6_var; diff --git a/vendor/libc/src/new/freebsd/sys/file.rs b/vendor/libc/src/new/freebsd/sys/file.rs new file mode 100644 index 0000000..3072c1d --- /dev/null +++ b/vendor/libc/src/new/freebsd/sys/file.rs @@ -0,0 +1,46 @@ +//! Header: `sys/file.h` +//! +//! https://github.com/freebsd/freebsd-src/blob/main/sys/sys/file.h + +use crate::prelude::*; + +pub const DTYPE_NONE: c_int = 0; +pub const DTYPE_VNODE: c_int = 1; +pub const DTYPE_SOCKET: c_int = 2; +pub const DTYPE_PIPE: c_int = 3; +pub const DTYPE_FIFO: c_int = 4; +pub const DTYPE_KQUEUE: c_int = 5; +pub const DTYPE_CRYPTO: c_int = 6; +pub const DTYPE_MQUEUE: c_int = 7; +pub const DTYPE_SHM: c_int = 8; +pub const DTYPE_SEM: c_int = 9; +pub const DTYPE_PTS: c_int = 10; +pub const DTYPE_DEV: c_int = 11; +pub const DTYPE_PROCDESC: c_int = 12; +pub const DTYPE_EVENTFD: c_int = 13; +pub const DTYPE_TIMERFD: c_int = 14; +pub const DTYPE_INOTIFY: c_int = 15; +pub const DTYPE_JAILDESC: c_int = 16; + +s! { + #[cfg(not(any(freebsd10, freebsd11)))] + pub struct xfile { + pub xf_size: crate::ksize_t, + pub xf_pid: crate::pid_t, + pub xf_uid: crate::uid_t, + pub xf_fd: c_int, + _xf_int_pad1: Padding, + pub xf_file: crate::kvaddr_t, + pub xf_type: c_short, + _xf_short_pad1: Padding, + pub xf_count: c_int, + pub xf_msgcount: c_int, + _xf_int_pad2: Padding, + pub xf_offset: crate::off_t, + pub xf_data: crate::kvaddr_t, + pub xf_vnode: crate::kvaddr_t, + pub xf_flag: c_uint, + _xf_int_pad3: Padding, + _xf_int64_pad: Padding<[i64; 6]>, + } +} diff --git a/vendor/libc/src/new/freebsd/sys/ioccom.rs b/vendor/libc/src/new/freebsd/sys/ioccom.rs new file mode 100644 index 0000000..64261b9 --- /dev/null +++ b/vendor/libc/src/new/freebsd/sys/ioccom.rs @@ -0,0 +1,49 @@ +//! Header: `sys/ioccom.h` +//! +//! https://github.com/freebsd/freebsd-src/blob/main/sys/sys/ioccom.h + +use crate::prelude::*; + +const IOCPARM_SHIFT: c_ulong = 13; +const IOCPARM_MASK: c_ulong = (1 << IOCPARM_SHIFT) - 1; + +const IOCPARM_MAX: c_ulong = 1 << IOCPARM_SHIFT; + +pub(crate) const IOC_VOID: c_ulong = 0x20000000; +pub(crate) const IOC_OUT: c_ulong = 0x40000000; +pub(crate) const IOC_IN: c_ulong = 0x80000000; +pub(crate) const IOC_INOUT: c_ulong = IOC_IN | IOC_OUT; +pub(crate) const IOC_DIRMASK: c_ulong = IOC_VOID | IOC_OUT | IOC_IN; + +pub(crate) const fn _IOC(inout: c_ulong, group: c_ulong, num: c_ulong, len: c_ulong) -> c_ulong { + debug_assert!(inout <= IOC_DIRMASK); + debug_assert!(group <= 0xff); + debug_assert!(num <= 0xff); + debug_assert!(len <= IOCPARM_MAX); + + inout | ((len & IOCPARM_MASK) << 16) | (group << 8) | num +} + +pub const fn _IO(g: c_ulong, n: c_ulong) -> c_ulong { + _IOC(IOC_VOID, g, n, 0) +} + +/// Build an ioctl number for an ioctl that passes an `int` by value. +pub const fn _IOWINT(g: c_ulong, n: c_ulong) -> c_ulong { + _IOC(IOC_VOID, g, n, mem::size_of::() as c_ulong) +} + +/// Build an ioctl number for an read-only ioctl. +pub const fn _IOR(g: c_ulong, n: c_ulong) -> c_ulong { + _IOC(IOC_OUT, g, n, mem::size_of::() as c_ulong) +} + +/// Build an ioctl number for an write-only ioctl. +pub const fn _IOW(g: c_ulong, n: c_ulong) -> c_ulong { + _IOC(IOC_IN, g, n, mem::size_of::() as c_ulong) +} + +/// Build an ioctl number for a read-write ioctl. +pub const fn _IOWR(g: c_ulong, n: c_ulong) -> c_ulong { + _IOC(IOC_INOUT, g, n, mem::size_of::() as c_ulong) +} diff --git a/vendor/libc/src/new/freebsd/sys/mod.rs b/vendor/libc/src/new/freebsd/sys/mod.rs new file mode 100644 index 0000000..4afb1d4 --- /dev/null +++ b/vendor/libc/src/new/freebsd/sys/mod.rs @@ -0,0 +1,7 @@ +//! Directory: `sys/` +//! +//! https://github.com/freebsd/freebsd-src/tree/main/sys/sys' + +pub(crate) mod file; +pub(crate) mod ioccom; +pub(crate) mod socket; diff --git a/vendor/libc/src/new/freebsd/sys/socket.rs b/vendor/libc/src/new/freebsd/sys/socket.rs new file mode 100644 index 0000000..ba52872 --- /dev/null +++ b/vendor/libc/src/new/freebsd/sys/socket.rs @@ -0,0 +1,7 @@ +//! Header: `sys/socket.h` +//! +//! https://github.com/freebsd/freebsd-src/blob/main/sys/sys/socket.h + +use crate::prelude::*; + +pub const SO_RERROR: c_int = 0x0002_0000; diff --git a/vendor/libc/src/new/freebsd/unistd.rs b/vendor/libc/src/new/freebsd/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/freebsd/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/fuchsia/mod.rs b/vendor/libc/src/new/fuchsia/mod.rs new file mode 100644 index 0000000..b3a9083 --- /dev/null +++ b/vendor/libc/src/new/fuchsia/mod.rs @@ -0,0 +1,4 @@ +//! Fuschia libc. +// FIXME(fuchsia): link to headers needed. + +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/fuchsia/unistd.rs b/vendor/libc/src/new/fuchsia/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/fuchsia/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/glibc/mod.rs b/vendor/libc/src/new/glibc/mod.rs new file mode 100644 index 0000000..e11c026 --- /dev/null +++ b/vendor/libc/src/new/glibc/mod.rs @@ -0,0 +1,34 @@ +//! GNU libc. +//! +//! * Headers: (official) +//! * Headers: (mirror) +//! +//! This module structure is modeled after glibc's source tree. Its build system selects headers +//! from different locations based on the platform, which we mimic here with reexports. + +/// Source directory: `posix/` +/// +/// +mod posix { + pub(crate) mod unistd; +} + +/// Source directory: `sysdeps/` +/// +/// +mod sysdeps { + // FIXME(pthread): eventually all platforms should use this module + #[cfg(target_os = "linux")] + pub(crate) mod nptl; + pub(crate) mod unix; + + // You'll notice some directories that provide a `bits` module. These are included via + // `path = "..."` wherever the generic implementation lives. +} + +pub(crate) use posix::*; +// FIXME(pthread): eventually all platforms should use this module +#[cfg(target_os = "linux")] +pub(crate) use sysdeps::nptl::*; +#[cfg(target_os = "linux")] +pub(crate) use sysdeps::unix::linux::*; diff --git a/vendor/libc/src/new/glibc/posix/unistd.rs b/vendor/libc/src/new/glibc/posix/unistd.rs new file mode 100644 index 0000000..907066c --- /dev/null +++ b/vendor/libc/src/new/glibc/posix/unistd.rs @@ -0,0 +1,9 @@ +//! Header: `unistd.h` +//! +//! + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/glibc/sysdeps/mips/mod.rs b/vendor/libc/src/new/glibc/sysdeps/mips/mod.rs new file mode 100644 index 0000000..03c3cc3 --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/mips/mod.rs @@ -0,0 +1,6 @@ +//! Directory: `sysdeps/mips` + +#[cfg(target_os = "linux")] +pub(crate) mod nptl { + pub(crate) mod bits; +} diff --git a/vendor/libc/src/new/glibc/sysdeps/mips/nptl/bits/mod.rs b/vendor/libc/src/new/glibc/sysdeps/mips/nptl/bits/mod.rs new file mode 100644 index 0000000..2da22c3 --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/mips/nptl/bits/mod.rs @@ -0,0 +1,3 @@ +//! Directory: `sysdeps/mips/nptl/bits` + +pub(crate) mod struct_mutex; diff --git a/vendor/libc/src/new/glibc/sysdeps/mips/nptl/bits/struct_mutex.rs b/vendor/libc/src/new/glibc/sysdeps/mips/nptl/bits/struct_mutex.rs new file mode 100644 index 0000000..11d0dc0 --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/mips/nptl/bits/struct_mutex.rs @@ -0,0 +1,19 @@ +//! Header: `sysdeps/mips/nptl/bits/struct_mutex.h` + +use crate::prelude::*; + +pub const fn __PTHREAD_MUTEX_INITIALIZER(__kind: c_int) -> crate::pthread_mutex_t { + // We don't need the whole complicated `__pthread_mutex_s` definition, just use the + // offset of the `__kind` field. + let kind_offset = if cfg!(target_abi = "abi64") { + 4 * size_of::() + } else { + 3 * size_of::() + }; + + let size = [0; crate::__SIZEOF_PTHREAD_MUTEX_T]; + let kind_bytes = __kind.to_ne_bytes(); + let repl = u8_slice_cast_char_slice(&kind_bytes); + let size = replace_array_items(size, repl, kind_offset); + crate::pthread_mutex_t { size } +} diff --git a/vendor/libc/src/new/glibc/sysdeps/nptl/bits/struct_mutex.rs b/vendor/libc/src/new/glibc/sysdeps/nptl/bits/struct_mutex.rs new file mode 100644 index 0000000..451f86c --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/nptl/bits/struct_mutex.rs @@ -0,0 +1,20 @@ +//! Header: `sysdeps/nptl/bits/struct_mutex.h` + +use crate::prelude::*; + +pub const fn __PTHREAD_MUTEX_INITIALIZER(__kind: c_int) -> crate::pthread_mutex_t { + // We don't need the whole complicated `__pthread_mutex_s` definition, just use the + // offset of the `__kind` field. + let __PTHREAD_MUTEX_HAVE_PREV = cfg!(target_pointer_width = "64"); + let kind_offset = if __PTHREAD_MUTEX_HAVE_PREV { + 4 * size_of::() + } else { + 3 * size_of::() + }; + + let size = [0; crate::__SIZEOF_PTHREAD_MUTEX_T]; + let kind_bytes = __kind.to_ne_bytes(); + let repl = u8_slice_cast_char_slice(&kind_bytes); + let size = replace_array_items(size, repl, kind_offset); + crate::pthread_mutex_t { size } +} diff --git a/vendor/libc/src/new/glibc/sysdeps/nptl/mod.rs b/vendor/libc/src/new/glibc/sysdeps/nptl/mod.rs new file mode 100644 index 0000000..92b8e9a --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/nptl/mod.rs @@ -0,0 +1,29 @@ +//! Source directory: `sysdeps/nptl/`o +//! +//! Native POSIX threading library. +//! +//! + +pub(crate) mod bits { + #[cfg_attr( + any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips", + target_arch = "mips32r6", + ), + path = "../../mips/nptl/bits/struct_mutex.rs" + )] + #[cfg_attr( + any(target_arch = "powerpc", target_arch = "powerpc64"), + path = "../../powerpc/nptl/bits/struct_mutex.rs" + )] + #[cfg_attr(target_arch = "s390x", path = "../../s390/nptl/bits/struct_mutex.rs")] + #[cfg_attr( + any(target_arch = "x86", target_arch = "x86_64"), + path = "../../x86/nptl/bits/struct_mutex.rs" + )] + pub(crate) mod struct_mutex; +} + +pub(crate) mod pthread; diff --git a/vendor/libc/src/new/glibc/sysdeps/nptl/pthread.rs b/vendor/libc/src/new/glibc/sysdeps/nptl/pthread.rs new file mode 100644 index 0000000..cefc9e3 --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/nptl/pthread.rs @@ -0,0 +1,81 @@ +//! Source header: `sysdeps/nptl/pthread.h` +//! +//! + +use super::bits::struct_mutex::*; +use crate::prelude::*; + +c_enum! { + #[repr(c_int)] + enum #anon { + PTHREAD_MUTEX_TIMED_NP, + PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK_NP, + pub PTHREAD_MUTEX_ADAPTIVE_NP, + } +} + +pub const PTHREAD_MUTEX_INITIALIZER: crate::pthread_mutex_t = + __PTHREAD_MUTEX_INITIALIZER(PTHREAD_MUTEX_TIMED_NP); +pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: crate::pthread_mutex_t = + __PTHREAD_MUTEX_INITIALIZER(PTHREAD_MUTEX_RECURSIVE_NP); +pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: crate::pthread_mutex_t = + __PTHREAD_MUTEX_INITIALIZER(PTHREAD_MUTEX_ERRORCHECK_NP); +pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: crate::pthread_mutex_t = + __PTHREAD_MUTEX_INITIALIZER(PTHREAD_MUTEX_ADAPTIVE_NP); + +pub use crate::new::common::linux_like::pthread::{ + pthread_getaffinity_np, + pthread_getattr_np, + pthread_getname_np, + pthread_setaffinity_np, + pthread_setname_np, +}; +pub use crate::new::common::posix::pthread::{ + pthread_atfork, + pthread_attr_getguardsize, + pthread_attr_getinheritsched, + pthread_attr_getschedparam, + pthread_attr_getschedpolicy, + pthread_attr_getstack, + pthread_attr_setguardsize, + pthread_attr_setinheritsched, + pthread_attr_setschedparam, + pthread_attr_setschedpolicy, + pthread_attr_setstack, + pthread_barrier_destroy, + pthread_barrier_init, + pthread_barrier_wait, + pthread_barrierattr_destroy, + pthread_barrierattr_getpshared, + pthread_barrierattr_init, + pthread_barrierattr_setpshared, + pthread_cancel, + pthread_condattr_getclock, + pthread_condattr_getpshared, + pthread_condattr_setclock, + pthread_condattr_setpshared, + pthread_create, + pthread_getcpuclockid, + pthread_getschedparam, + pthread_kill, + pthread_mutex_consistent, + pthread_mutex_timedlock, + pthread_mutexattr_getprotocol, + pthread_mutexattr_getpshared, + pthread_mutexattr_getrobust, + pthread_mutexattr_setprotocol, + pthread_mutexattr_setpshared, + pthread_mutexattr_setrobust, + pthread_once, + pthread_rwlockattr_getpshared, + pthread_rwlockattr_setpshared, + pthread_setschedparam, + pthread_setschedprio, + pthread_sigmask, + pthread_spin_destroy, + pthread_spin_init, + pthread_spin_lock, + pthread_spin_trylock, + pthread_spin_unlock, +}; diff --git a/vendor/libc/src/new/glibc/sysdeps/powerpc/mod.rs b/vendor/libc/src/new/glibc/sysdeps/powerpc/mod.rs new file mode 100644 index 0000000..eed0adc --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/powerpc/mod.rs @@ -0,0 +1,6 @@ +//! Directory: `sysdeps/powerpc` + +#[cfg(target_os = "linux")] +pub(crate) mod nptl { + pub(crate) mod bits; +} diff --git a/vendor/libc/src/new/glibc/sysdeps/powerpc/nptl/bits/mod.rs b/vendor/libc/src/new/glibc/sysdeps/powerpc/nptl/bits/mod.rs new file mode 100644 index 0000000..7af82d2 --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/powerpc/nptl/bits/mod.rs @@ -0,0 +1,3 @@ +//! Directory: `sysdeps/powerpc/nptl/bits` + +pub(crate) mod struct_mutex; diff --git a/vendor/libc/src/new/glibc/sysdeps/powerpc/nptl/bits/struct_mutex.rs b/vendor/libc/src/new/glibc/sysdeps/powerpc/nptl/bits/struct_mutex.rs new file mode 100644 index 0000000..65d4deb --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/powerpc/nptl/bits/struct_mutex.rs @@ -0,0 +1,19 @@ +//! Header: `sysdeps/powerpc/nptl/bits/struct_mutex.h` + +use crate::prelude::*; + +pub const fn __PTHREAD_MUTEX_INITIALIZER(__kind: c_int) -> crate::pthread_mutex_t { + // We don't need the whole complicated `__pthread_mutex_s` definition, just use the + // offset of the `__kind` field. + let kind_offset = if cfg!(target_pointer_width = "64") { + 4 * size_of::() + } else { + 3 * size_of::() + }; + + let size = [0; crate::__SIZEOF_PTHREAD_MUTEX_T]; + let kind_bytes = __kind.to_ne_bytes(); + let repl = u8_slice_cast_char_slice(&kind_bytes); + let size = replace_array_items(size, repl, kind_offset); + crate::pthread_mutex_t { size } +} diff --git a/vendor/libc/src/new/glibc/sysdeps/s390/mod.rs b/vendor/libc/src/new/glibc/sysdeps/s390/mod.rs new file mode 100644 index 0000000..ced44ec --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/s390/mod.rs @@ -0,0 +1,6 @@ +//! Directory: `sysdeps/s390` + +#[cfg(target_os = "linux")] +pub(crate) mod nptl { + pub(crate) mod bits; +} diff --git a/vendor/libc/src/new/glibc/sysdeps/s390/nptl/bits/mod.rs b/vendor/libc/src/new/glibc/sysdeps/s390/nptl/bits/mod.rs new file mode 100644 index 0000000..1283f09 --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/s390/nptl/bits/mod.rs @@ -0,0 +1,3 @@ +//! Directory: `sysdeps/s390/nptl/bits` + +pub(crate) mod struct_mutex; diff --git a/vendor/libc/src/new/glibc/sysdeps/s390/nptl/bits/struct_mutex.rs b/vendor/libc/src/new/glibc/sysdeps/s390/nptl/bits/struct_mutex.rs new file mode 100644 index 0000000..3962cac --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/s390/nptl/bits/struct_mutex.rs @@ -0,0 +1,19 @@ +//! Header: `sysdeps/s390/nptl/bits/struct_mutex.h` + +use crate::prelude::*; + +pub const fn __PTHREAD_MUTEX_INITIALIZER(__kind: c_int) -> crate::pthread_mutex_t { + // We don't need the whole complicated `__pthread_mutex_s` definition, just use the + // offset of the `__kind` field. + let kind_offset = if cfg!(target_pointer_width = "64") { + 4 * size_of::() + } else { + 3 * size_of::() + }; + + let size = [0; crate::__SIZEOF_PTHREAD_MUTEX_T]; + let kind_bytes = __kind.to_ne_bytes(); + let repl = u8_slice_cast_char_slice(&kind_bytes); + let size = replace_array_items(size, repl, kind_offset); + crate::pthread_mutex_t { size } +} diff --git a/vendor/libc/src/new/glibc/sysdeps/unix/linux/mod.rs b/vendor/libc/src/new/glibc/sysdeps/unix/linux/mod.rs new file mode 100644 index 0000000..0ecee59 --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/unix/linux/mod.rs @@ -0,0 +1,10 @@ +//! Source directory: `sysdeps/unix/sysv/linux` (the `sysv` is flattened). +//! +//! + +/// Directory: `net/` +/// +/// Source directory: `sysdeps/unix/sysv/linux/net` +pub(crate) mod net { + pub(crate) mod route; +} diff --git a/vendor/libc/src/new/glibc/sysdeps/unix/linux/net/route.rs b/vendor/libc/src/new/glibc/sysdeps/unix/linux/net/route.rs new file mode 100644 index 0000000..2851451 --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/unix/linux/net/route.rs @@ -0,0 +1,30 @@ +//! Header: `net/route.h` +//! +//! Source header: `sysdeps/unix/sysv/linux/net/route.h` +//! + +use crate::prelude::*; + +s! { + pub struct rtentry { + pub rt_pad1: c_ulong, + pub rt_dst: crate::sockaddr, + pub rt_gateway: crate::sockaddr, + pub rt_genmask: crate::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, + // FIXME(1.0): private padding fields + #[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, + } +} diff --git a/vendor/libc/src/new/glibc/sysdeps/unix/mod.rs b/vendor/libc/src/new/glibc/sysdeps/unix/mod.rs new file mode 100644 index 0000000..55a895d --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/unix/mod.rs @@ -0,0 +1,6 @@ +//! Source directory: `sysdeps/unix/` +//! +//! + +#[cfg(target_os = "linux")] +pub(crate) mod linux; diff --git a/vendor/libc/src/new/glibc/sysdeps/x86/mod.rs b/vendor/libc/src/new/glibc/sysdeps/x86/mod.rs new file mode 100644 index 0000000..0da2b18 --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/x86/mod.rs @@ -0,0 +1,6 @@ +//! Directory: `sysdeps/x86` + +#[cfg(target_os = "linux")] +pub(crate) mod nptl { + pub(crate) mod bits; +} diff --git a/vendor/libc/src/new/glibc/sysdeps/x86/nptl/bits/mod.rs b/vendor/libc/src/new/glibc/sysdeps/x86/nptl/bits/mod.rs new file mode 100644 index 0000000..e6c5e5b --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/x86/nptl/bits/mod.rs @@ -0,0 +1,3 @@ +//! Directory: `sysdeps/x86/nptl/bits` + +pub(crate) mod struct_mutex; diff --git a/vendor/libc/src/new/glibc/sysdeps/x86/nptl/bits/struct_mutex.rs b/vendor/libc/src/new/glibc/sysdeps/x86/nptl/bits/struct_mutex.rs new file mode 100644 index 0000000..7e2c675 --- /dev/null +++ b/vendor/libc/src/new/glibc/sysdeps/x86/nptl/bits/struct_mutex.rs @@ -0,0 +1,19 @@ +//! Header: `sysdeps/x86/nptl/bits/struct_mutex.h` + +use crate::prelude::*; + +pub const fn __PTHREAD_MUTEX_INITIALIZER(__kind: c_int) -> crate::pthread_mutex_t { + // We don't need the whole complicated `__pthread_mutex_s` definition, just use the + // offset of the `__kind` field. + let kind_offset = if cfg!(target_pointer_width = "64") { + 4 * size_of::() + } else { + 3 * size_of::() + }; + + let size = [0; crate::__SIZEOF_PTHREAD_MUTEX_T]; + let kind_bytes = __kind.to_ne_bytes(); + let repl = u8_slice_cast_char_slice(&kind_bytes); + let size = replace_array_items(size, repl, kind_offset); + crate::pthread_mutex_t { size } +} diff --git a/vendor/libc/src/new/haiku/mod.rs b/vendor/libc/src/new/haiku/mod.rs new file mode 100644 index 0000000..a565afe --- /dev/null +++ b/vendor/libc/src/new/haiku/mod.rs @@ -0,0 +1,4 @@ +//! Haiku OS libc. +// FIXME(haiku): link to headers needed. + +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/haiku/unistd.rs b/vendor/libc/src/new/haiku/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/haiku/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/hermit_abi/mod.rs b/vendor/libc/src/new/hermit_abi/mod.rs new file mode 100644 index 0000000..65f59fe --- /dev/null +++ b/vendor/libc/src/new/hermit_abi/mod.rs @@ -0,0 +1,3 @@ +//! Hermit kernel libc. +//! +//! * Headers: diff --git a/vendor/libc/src/new/horizon/mod.rs b/vendor/libc/src/new/horizon/mod.rs new file mode 100644 index 0000000..338e9f0 --- /dev/null +++ b/vendor/libc/src/new/horizon/mod.rs @@ -0,0 +1,2 @@ +//! Switch libc. +// FIXME(horizon): link to headers or manpages needed. diff --git a/vendor/libc/src/new/hurd/mod.rs b/vendor/libc/src/new/hurd/mod.rs new file mode 100644 index 0000000..12198d5 --- /dev/null +++ b/vendor/libc/src/new/hurd/mod.rs @@ -0,0 +1,2 @@ +//! GNU Hurd libc. +// FIXME(hurd): link to headers needed. diff --git a/vendor/libc/src/new/illumos/mod.rs b/vendor/libc/src/new/illumos/mod.rs new file mode 100644 index 0000000..83d15da --- /dev/null +++ b/vendor/libc/src/new/illumos/mod.rs @@ -0,0 +1,4 @@ +//! Illumos libc. +// FIXME(illumos): link to headers needed. + +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/illumos/unistd.rs b/vendor/libc/src/new/illumos/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/illumos/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/l4re/mod.rs b/vendor/libc/src/new/l4re/mod.rs new file mode 100644 index 0000000..1c5c885 --- /dev/null +++ b/vendor/libc/src/new/l4re/mod.rs @@ -0,0 +1,5 @@ +//! L4re. +//! +//! * Headers: + +pub(crate) mod packet; diff --git a/vendor/libc/src/new/l4re/packet.rs b/vendor/libc/src/new/l4re/packet.rs new file mode 100644 index 0000000..f9df799 --- /dev/null +++ b/vendor/libc/src/new/l4re/packet.rs @@ -0,0 +1,29 @@ +//! Header: `netpacket/packet.h` + +use crate::prelude::*; + +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_ADD_MEMBERSHIP: c_int = 1; +pub const PACKET_DROP_MEMBERSHIP: c_int = 2; +pub const PACKET_RECV_OUTPUT: c_int = 3; +pub const PACKET_RX_RING: c_int = 5; +pub const PACKET_STATISTICS: c_int = 6; + +s! { + 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 const PACKET_MR_MULTICAST: c_int = 0; +pub const PACKET_MR_PROMISC: c_int = 1; +pub const PACKET_MR_ALLMULTI: c_int = 2; diff --git a/vendor/libc/src/new/linux_uapi/linux/can.rs b/vendor/libc/src/new/linux_uapi/linux/can.rs new file mode 100644 index 0000000..c4ae2da --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/can.rs @@ -0,0 +1,135 @@ +//! Header: `uapi/linux/can.h` + +pub(crate) mod bcm; +pub(crate) mod error; +pub(crate) mod j1939; +pub(crate) mod netlink; +pub(crate) mod raw; + +use crate::prelude::*; + +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: crate::canid_t = CAN_SFF_MASK; + +pub type canid_t = u32; + +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 type can_err_mask_t = u32; + +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 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; + +s! { + #[repr(align(8))] + pub struct can_frame { + pub can_id: canid_t, + // FIXME(1.0): this field was renamed to `len` in Linux 5.11 + pub can_dlc: u8, + __pad: Padding, + __res0: u8, + pub len8_dlc: u8, + pub data: [u8; CAN_MAX_DLEN], + } +} + +pub const CANFD_BRS: c_int = 0x01; +pub const CANFD_ESI: c_int = 0x02; +pub const CANFD_FDF: c_int = 0x04; + +s! { + #[repr(align(8))] + 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], + } +} + +pub const CANXL_XLF: c_int = 0x80; +pub const CANXL_SEC: c_int = 0x01; + +s! { + 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], + } +} + +pub const CAN_MTU: usize = size_of::(); +pub const CANFD_MTU: usize = size_of::(); +pub const CANXL_MTU: usize = size_of::(); +// FIXME(offset_of): 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; + +s_no_extra_traits! { + pub struct sockaddr_can { + pub can_family: crate::sa_family_t, + pub can_ifindex: c_int, + pub can_addr: __c_anonymous_sockaddr_can_can_addr, + } + + pub union __c_anonymous_sockaddr_can_can_addr { + pub tp: __c_anonymous_sockaddr_can_tp, + pub j1939: __c_anonymous_sockaddr_can_j1939, + } +} + +s! { + 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, + } +} + +pub const CAN_INV_FILTER: canid_t = 0x20000000; diff --git a/vendor/libc/src/new/linux_uapi/linux/can/bcm.rs b/vendor/libc/src/new/linux_uapi/linux/can/bcm.rs new file mode 100644 index 0000000..853f85f --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/can/bcm.rs @@ -0,0 +1,52 @@ +//! Header: `linux/can/bcm.h` + +pub use crate::linux::can::*; + +s! { + pub struct bcm_timeval { + pub tv_sec: c_long, + pub tv_usec: c_long, + } + + pub struct bcm_msg_head { + pub opcode: u32, + pub flags: u32, + pub count: u32, + pub ival1: bcm_timeval, + pub ival2: bcm_timeval, + pub can_id: canid_t, + pub nframes: u32, + pub frames: [can_frame; 0], + } +} + +c_enum! { + #[repr(u32)] + pub enum #anon { + pub TX_SETUP = 1, + pub TX_DELETE, + pub TX_READ, + pub TX_SEND, + pub RX_SETUP, + pub RX_DELETE, + pub RX_READ, + pub TX_STATUS, + pub TX_EXPIRED, + pub RX_STATUS, + pub RX_TIMEOUT, + pub RX_CHANGED, + } +} + +pub const SETTIMER: u32 = 0x0001; +pub const STARTTIMER: u32 = 0x0002; +pub const TX_COUNTEVT: u32 = 0x0004; +pub const TX_ANNOUNCE: u32 = 0x0008; +pub const TX_CP_CAN_ID: u32 = 0x0010; +pub const RX_FILTER_ID: u32 = 0x0020; +pub const RX_CHECK_DLC: u32 = 0x0040; +pub const RX_NO_AUTOTIMER: u32 = 0x0080; +pub const RX_ANNOUNCE_RESUME: u32 = 0x0100; +pub const TX_RESET_MULTI_IDX: u32 = 0x0200; +pub const RX_RTR_FRAME: u32 = 0x0400; +pub const CAN_FD_FRAME: u32 = 0x0800; diff --git a/vendor/libc/src/new/linux_uapi/linux/can/error.rs b/vendor/libc/src/new/linux_uapi/linux/can/error.rs new file mode 100644 index 0000000..1b298ca --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/can/error.rs @@ -0,0 +1,73 @@ +//! Header: `linux/can/error.h` + +pub use crate::linux::can::*; + +pub const CAN_ERR_DLC: c_int = 8; + +pub const CAN_ERR_TX_TIMEOUT: c_uint = 0x00000001; +pub const CAN_ERR_LOSTARB: c_uint = 0x00000002; +pub const CAN_ERR_CRTL: c_uint = 0x00000004; +pub const CAN_ERR_PROT: c_uint = 0x00000008; +pub const CAN_ERR_TRX: c_uint = 0x00000010; +pub const CAN_ERR_ACK: c_uint = 0x00000020; +pub const CAN_ERR_BUSOFF: c_uint = 0x00000040; +pub const CAN_ERR_BUSERROR: c_uint = 0x00000080; +pub const CAN_ERR_RESTARTED: c_uint = 0x00000100; +pub const CAN_ERR_CNT: c_uint = 0x00000200; + +pub const CAN_ERR_LOSTARB_UNSPEC: c_int = 0x00; + +pub const CAN_ERR_CRTL_UNSPEC: c_int = 0x00; +pub const CAN_ERR_CRTL_RX_OVERFLOW: c_int = 0x01; +pub const CAN_ERR_CRTL_TX_OVERFLOW: c_int = 0x02; +pub const CAN_ERR_CRTL_RX_WARNING: c_int = 0x04; +pub const CAN_ERR_CRTL_TX_WARNING: c_int = 0x08; +pub const CAN_ERR_CRTL_RX_PASSIVE: c_int = 0x10; +pub const CAN_ERR_CRTL_TX_PASSIVE: c_int = 0x20; +pub const CAN_ERR_CRTL_ACTIVE: c_int = 0x40; + +pub const CAN_ERR_PROT_UNSPEC: c_int = 0x00; +pub const CAN_ERR_PROT_BIT: c_int = 0x01; +pub const CAN_ERR_PROT_FORM: c_int = 0x02; +pub const CAN_ERR_PROT_STUFF: c_int = 0x04; +pub const CAN_ERR_PROT_BIT0: c_int = 0x08; +pub const CAN_ERR_PROT_BIT1: c_int = 0x10; +pub const CAN_ERR_PROT_OVERLOAD: c_int = 0x20; +pub const CAN_ERR_PROT_ACTIVE: c_int = 0x40; +pub const CAN_ERR_PROT_TX: c_int = 0x80; + +pub const CAN_ERR_PROT_LOC_UNSPEC: c_int = 0x00; +pub const CAN_ERR_PROT_LOC_SOF: c_int = 0x03; +pub const CAN_ERR_PROT_LOC_ID28_21: c_int = 0x02; +pub const CAN_ERR_PROT_LOC_ID20_18: c_int = 0x06; +pub const CAN_ERR_PROT_LOC_SRTR: c_int = 0x04; +pub const CAN_ERR_PROT_LOC_IDE: c_int = 0x05; +pub const CAN_ERR_PROT_LOC_ID17_13: c_int = 0x07; +pub const CAN_ERR_PROT_LOC_ID12_05: c_int = 0x0F; +pub const CAN_ERR_PROT_LOC_ID04_00: c_int = 0x0E; +pub const CAN_ERR_PROT_LOC_RTR: c_int = 0x0C; +pub const CAN_ERR_PROT_LOC_RES1: c_int = 0x0D; +pub const CAN_ERR_PROT_LOC_RES0: c_int = 0x09; +pub const CAN_ERR_PROT_LOC_DLC: c_int = 0x0B; +pub const CAN_ERR_PROT_LOC_DATA: c_int = 0x0A; +pub const CAN_ERR_PROT_LOC_CRC_SEQ: c_int = 0x08; +pub const CAN_ERR_PROT_LOC_CRC_DEL: c_int = 0x18; +pub const CAN_ERR_PROT_LOC_ACK: c_int = 0x19; +pub const CAN_ERR_PROT_LOC_ACK_DEL: c_int = 0x1B; +pub const CAN_ERR_PROT_LOC_EOF: c_int = 0x1A; +pub const CAN_ERR_PROT_LOC_INTERM: c_int = 0x12; + +pub const CAN_ERR_TRX_UNSPEC: c_int = 0x00; +pub const CAN_ERR_TRX_CANH_NO_WIRE: c_int = 0x04; +pub const CAN_ERR_TRX_CANH_SHORT_TO_BAT: c_int = 0x05; +pub const CAN_ERR_TRX_CANH_SHORT_TO_VCC: c_int = 0x06; +pub const CAN_ERR_TRX_CANH_SHORT_TO_GND: c_int = 0x07; +pub const CAN_ERR_TRX_CANL_NO_WIRE: c_int = 0x40; +pub const CAN_ERR_TRX_CANL_SHORT_TO_BAT: c_int = 0x50; +pub const CAN_ERR_TRX_CANL_SHORT_TO_VCC: c_int = 0x60; +pub const CAN_ERR_TRX_CANL_SHORT_TO_GND: c_int = 0x70; +pub const CAN_ERR_TRX_CANL_SHORT_TO_CANH: c_int = 0x80; + +pub const CAN_ERROR_WARNING_THRESHOLD: c_int = 96; +pub const CAN_ERROR_PASSIVE_THRESHOLD: c_int = 128; +pub const CAN_BUS_OFF_THRESHOLD: c_int = 256; diff --git a/vendor/libc/src/new/linux_uapi/linux/can/j1939.rs b/vendor/libc/src/new/linux_uapi/linux/can/j1939.rs new file mode 100644 index 0000000..7f132b8 --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/can/j1939.rs @@ -0,0 +1,62 @@ +//! `linux/can/j1939.h` + +pub use crate::linux::can::*; + +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 type pgn_t = u32; +pub type priority_t = u8; +pub type name_t = u64; + +pub const SOL_CAN_J1939: c_int = SOL_CAN_BASE + CAN_J1939; + +// FIXME(cleanup): these could use c_enum if it can accept anonymous enums. + +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; + +s! { + 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, + } +} + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const J1939_FILTER_MAX: c_int = 512; diff --git a/vendor/libc/src/new/linux_uapi/linux/can/netlink.rs b/vendor/libc/src/new/linux_uapi/linux/can/netlink.rs new file mode 100644 index 0000000..2892941 --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/can/netlink.rs @@ -0,0 +1,125 @@ +//! Header: `linux/can/netlink.h` + +use crate::prelude::*; + +s! { + pub struct can_bittiming { + pub bitrate: u32, + pub sample_point: u32, + pub tq: u32, + pub prop_seg: u32, + pub phase_seg1: u32, + pub phase_seg2: u32, + pub sjw: u32, + pub brp: u32, + } + + pub struct can_bittiming_const { + pub name: [c_char; 16], + pub tseg1_min: u32, + pub tseg1_max: u32, + pub tseg2_min: u32, + pub tseg2_max: u32, + pub sjw_max: u32, + pub brp_min: u32, + pub brp_max: u32, + pub brp_inc: u32, + } + + pub struct can_clock { + pub freq: u32, + } + + pub struct can_berr_counter { + pub txerr: u16, + pub rxerr: u16, + } + + pub struct can_ctrlmode { + pub mask: u32, + pub flags: u32, + } + + pub struct can_device_stats { + pub bus_error: u32, + pub error_warning: u32, + pub error_passive: u32, + pub bus_off: u32, + pub arbitration_lost: u32, + pub restarts: u32, + } +} + +c_enum! { + #[repr(c_uint)] + pub enum can_state { + pub CAN_STATE_ERROR_ACTIVE = 0, + pub CAN_STATE_ERROR_WARNING, + pub CAN_STATE_ERROR_PASSIVE, + pub CAN_STATE_BUS_OFF, + pub CAN_STATE_STOPPED, + pub CAN_STATE_SLEEPING, + } +} + +pub const CAN_CTRLMODE_LOOPBACK: u32 = 0x01; +pub const CAN_CTRLMODE_LISTENONLY: u32 = 0x02; +pub const CAN_CTRLMODE_3_SAMPLES: u32 = 0x04; +pub const CAN_CTRLMODE_ONE_SHOT: u32 = 0x08; +pub const CAN_CTRLMODE_BERR_REPORTING: u32 = 0x10; +pub const CAN_CTRLMODE_FD: u32 = 0x20; +pub const CAN_CTRLMODE_PRESUME_ACK: u32 = 0x40; +pub const CAN_CTRLMODE_FD_NON_ISO: u32 = 0x80; +pub const CAN_CTRLMODE_CC_LEN8_DLC: u32 = 0x100; +pub const CAN_CTRLMODE_TDC_AUTO: u32 = 0x200; +pub const CAN_CTRLMODE_TDC_MANUAL: u32 = 0x400; + +c_enum! { + #[repr(c_int)] + pub enum #anon { + pub IFLA_CAN_UNSPEC = 0, + pub IFLA_CAN_BITTIMING, + pub IFLA_CAN_BITTIMING_CONST, + pub IFLA_CAN_CLOCK, + pub IFLA_CAN_STATE, + pub IFLA_CAN_CTRLMODE, + pub IFLA_CAN_RESTART_MS, + pub IFLA_CAN_RESTART, + pub IFLA_CAN_BERR_COUNTER, + pub IFLA_CAN_DATA_BITTIMING, + pub IFLA_CAN_DATA_BITTIMING_CONST, + pub IFLA_CAN_TERMINATION, + pub IFLA_CAN_TERMINATION_CONST, + pub IFLA_CAN_BITRATE_CONST, + pub IFLA_CAN_DATA_BITRATE_CONST, + pub IFLA_CAN_BITRATE_MAX, + pub IFLA_CAN_TDC, + pub IFLA_CAN_CTRLMODE_EXT, + } +} + +c_enum! { + #[repr(c_int)] + pub enum #anon { + pub IFLA_CAN_TDC_UNSPEC = 0, + pub IFLA_CAN_TDC_TDCV_MIN, + pub IFLA_CAN_TDC_TDCV_MAX, + pub IFLA_CAN_TDC_TDCO_MIN, + pub IFLA_CAN_TDC_TDCO_MAX, + pub IFLA_CAN_TDC_TDCF_MIN, + pub IFLA_CAN_TDC_TDCF_MAX, + pub IFLA_CAN_TDC_TDCV, + pub IFLA_CAN_TDC_TDCO, + pub IFLA_CAN_TDC_TDCF, + } +} + +c_enum! { + #[repr(c_int)] + pub enum #anon { + pub IFLA_CAN_CTRLMODE_UNSPEC = 0, + pub IFLA_CAN_CTRLMODE_SUPPORTED, + } +} + +pub const CAN_TERMINATION_DISABLED: u16 = 0; diff --git a/vendor/libc/src/new/linux_uapi/linux/can/raw.rs b/vendor/libc/src/new/linux_uapi/linux/can/raw.rs new file mode 100644 index 0000000..217badf --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/can/raw.rs @@ -0,0 +1,18 @@ +//! Header: `linux/can/raw.h` + +pub use crate::linux::can::*; + +pub const SOL_CAN_RAW: c_int = SOL_CAN_BASE + CAN_RAW; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const CAN_RAW_FILTER_MAX: c_int = 512; + +// FIXME(cleanup): use `c_enum!`, which needs to be adapted to allow omitting a type. +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; diff --git a/vendor/libc/src/new/linux_uapi/linux/futex.rs b/vendor/libc/src/new/linux_uapi/linux/futex.rs new file mode 100644 index 0000000..893dee0 --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/futex.rs @@ -0,0 +1,73 @@ +//! Header: `linux/futex.h` + +use crate::prelude::*; + +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 FUTEX2_SIZE_U8: c_int = 0x00; +pub const FUTEX2_SIZE_U16: c_int = 0x01; +pub const FUTEX2_SIZE_U32: c_int = 0x02; +pub const FUTEX2_SIZE_U64: c_int = 0x03; +pub const FUTEX2_NUMA: c_int = 0x04; +pub const FUTEX2_PRIVATE: c_int = FUTEX_PRIVATE_FLAG; +pub const FUTEX2_SIZE_MASK: c_int = 0x03; + +#[deprecated( + since = "0.2.187", + note = "UAPI headers indicate this should not be used" +)] +pub const FUTEX_32: c_int = FUTEX2_SIZE_U32; + +pub const FUTEX_WAITV_MAX: c_int = 128; + +s! { + pub struct futex_waitv { + pub val: crate::__u64, + pub uaddr: crate::__u64, + pub flags: crate::__u32, + __reserved: Padding, + } +} + +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 = u32_cast_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) +} diff --git a/vendor/libc/src/new/linux_uapi/linux/if_addr.rs b/vendor/libc/src/new/linux_uapi/linux/if_addr.rs new file mode 100644 index 0000000..a009f35 --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/if_addr.rs @@ -0,0 +1,37 @@ +//! Header: `uapi/linux/if_addr.h` + +use crate::prelude::*; + +s! { + pub struct ifaddrmsg { + pub ifa_family: u8, + pub ifa_prefixlen: u8, + pub ifa_flags: u8, + pub ifa_scope: u8, + pub ifa_index: u32, + } +} + +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_FLAGS: c_ushort = 8; + +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; +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; diff --git a/vendor/libc/src/new/linux_uapi/linux/if_link.rs b/vendor/libc/src/new/linux_uapi/linux/if_link.rs new file mode 100644 index 0000000..2c9bb52 --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/if_link.rs @@ -0,0 +1,83 @@ +//! Header: `uapi/linux/if_link.h` + +use crate::prelude::*; + +c_enum! { + #[repr(c_ushort)] + pub enum #anon { + pub IFLA_UNSPEC, + pub IFLA_ADDRESS, + pub IFLA_BROADCAST, + pub IFLA_IFNAME, + pub IFLA_MTU, + pub IFLA_LINK, + pub IFLA_QDISC, + pub IFLA_STATS, + pub IFLA_COST, + pub IFLA_PRIORITY, + pub IFLA_MASTER, + pub IFLA_WIRELESS, + pub IFLA_PROTINFO, + pub IFLA_TXQLEN, + pub IFLA_MAP, + pub IFLA_WEIGHT, + pub IFLA_OPERSTATE, + pub IFLA_LINKMODE, + pub IFLA_LINKINFO, + pub IFLA_NET_NS_PID, + pub IFLA_IFALIAS, + pub IFLA_NUM_VF, + pub IFLA_VFINFO_LIST, + pub IFLA_STATS64, + pub IFLA_VF_PORTS, + pub IFLA_PORT_SELF, + pub IFLA_AF_SPEC, + pub IFLA_GROUP, + pub IFLA_NET_NS_FD, + pub IFLA_EXT_MASK, + pub IFLA_PROMISCUITY, + pub IFLA_NUM_TX_QUEUES, + pub IFLA_NUM_RX_QUEUES, + pub IFLA_CARRIER, + pub IFLA_PHYS_PORT_ID, + pub IFLA_CARRIER_CHANGES, + pub IFLA_PHYS_SWITCH_ID, + pub IFLA_LINK_NETNSID, + pub IFLA_PHYS_PORT_NAME, + pub IFLA_PROTO_DOWN, + pub IFLA_GSO_MAX_SEGS, + pub IFLA_GSO_MAX_SIZE, + pub IFLA_PAD, + pub IFLA_XDP, + pub IFLA_EVENT, + pub IFLA_NEW_NETNSID, + pub IFLA_IF_NETNSID, + pub IFLA_TARGET_NETNSID = IFLA_IF_NETNSID, + pub IFLA_CARRIER_UP_COUNT, + pub IFLA_CARRIER_DOWN_COUNT, + pub IFLA_NEW_IFINDEX, + pub IFLA_MIN_MTU, + pub IFLA_MAX_MTU, + pub IFLA_PROP_LIST, + pub IFLA_ALT_IFNAME, + pub IFLA_PERM_ADDRESS, + pub IFLA_PROTO_DOWN_REASON, + + pub IFLA_PARENT_DEV_NAME, + pub IFLA_PARENT_DEV_BUS_NAME, + pub IFLA_GRO_MAX_SIZE, + pub IFLA_TSO_MAX_SIZE, + pub IFLA_TSO_MAX_SEGS, + pub IFLA_ALLMULTI, + } + + #[repr(c_ushort)] + pub enum #anon { + pub IFLA_INFO_UNSPEC, + pub IFLA_INFO_KIND, + pub IFLA_INFO_DATA, + pub IFLA_INFO_XSTATS, + pub IFLA_INFO_SLAVE_KIND, + pub IFLA_INFO_SLAVE_DATA, + } +} diff --git a/vendor/libc/src/new/linux_uapi/linux/if_packet.rs b/vendor/libc/src/new/linux_uapi/linux/if_packet.rs new file mode 100644 index 0000000..5e99a12 --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/if_packet.rs @@ -0,0 +1,258 @@ +//! Header: `uapi/linux/if_packet.h` + +use crate::prelude::*; + +s! { + #[deprecated(since = "0.2.70", note = "sockaddr_ll type should be used instead")] + pub struct sockaddr_pkt { + pub spkt_family: c_ushort, + pub spkt_device: [c_uchar; 14], + pub spkt_protocol: c_ushort, + } +} + +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_RECV_OUTPUT: c_int = 3; +pub const PACKET_RX_RING: c_int = 5; +pub const PACKET_STATISTICS: c_int = 6; +pub const PACKET_COPY_THRESH: c_int = 7; +pub const PACKET_AUXDATA: c_int = 8; +pub const PACKET_ORIGDEV: c_int = 9; +pub const PACKET_VERSION: c_int = 10; +pub const PACKET_HDRLEN: c_int = 11; +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_VNET_HDR: c_int = 15; +pub const PACKET_TX_TIMESTAMP: c_int = 16; +pub const PACKET_TIMESTAMP: c_int = 17; +pub const PACKET_FANOUT: c_int = 18; +pub const PACKET_TX_HAS_OFF: c_int = 19; +pub const PACKET_QDISC_BYPASS: c_int = 20; +pub const PACKET_ROLLOVER_STATS: c_int = 21; +pub const PACKET_FANOUT_DATA: c_int = 22; +pub const PACKET_IGNORE_OUTGOING: c_int = 23; +pub const PACKET_VNET_HDR_SZ: c_int = 24; + +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_IGNORE_OUTGOING: c_uint = 0x4000; +pub const PACKET_FANOUT_FLAG_DEFRAG: c_uint = 0x8000; + +s! { + 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, + } + + #[repr(align(8))] + pub struct tpacket_rollover_stats { + pub tp_all: crate::__u64, + pub tp_huge: crate::__u64, + pub tp_failed: crate::__u64, + } + + 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 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; + +s! { + 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 const TPACKET_ALIGNMENT: usize = 16; +f! { + pub unsafe fn TPACKET_ALIGN(x: usize) -> usize { + (x + TPACKET_ALIGNMENT - 1) & !(TPACKET_ALIGNMENT - 1) + } +} +pub const TPACKET_HDRLEN: usize = ((size_of::() + TPACKET_ALIGNMENT - 1) + & !(TPACKET_ALIGNMENT - 1)) + + size_of::(); + +s! { + 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_hdr_variant1 { + pub tp_rxhash: u32, + pub tp_vlan_tci: u32, + pub tp_vlan_tpid: u16, + pub tp_padding: u16, + } + + 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, + } + + #[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: crate::__u64, + pub ts_first_pkt: tpacket_bd_ts, + pub ts_last_pkt: tpacket_bd_ts, + } +} + +s_no_extra_traits! { + pub union tpacket_bd_header_u { + pub bh1: tpacket_hdr_v1, + } + + pub struct tpacket_block_desc { + pub version: u32, + pub offset_to_priv: u32, + pub hdr: tpacket_bd_header_u, + } +} + +pub const TPACKET2_HDRLEN: usize = ((size_of::() + TPACKET_ALIGNMENT - 1) + & !(TPACKET_ALIGNMENT - 1)) + + size_of::(); +pub const TPACKET3_HDRLEN: usize = ((size_of::() + TPACKET_ALIGNMENT - 1) + & !(TPACKET_ALIGNMENT - 1)) + + size_of::(); + +e! { + #[repr(u32)] + pub enum tpacket_versions { + TPACKET_V1, + TPACKET_V2, + TPACKET_V3, + } +} + +s! { + 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, + } +} + +s_no_extra_traits! { + pub union tpacket_req_u { + pub req: tpacket_req, + pub req3: tpacket_req3, + } +} + +s! { + 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 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 const PACKET_MR_MULTICAST: c_int = 0; +pub const PACKET_MR_PROMISC: c_int = 1; +pub const PACKET_MR_ALLMULTI: c_int = 2; diff --git a/vendor/libc/src/new/linux_uapi/linux/keyctl.rs b/vendor/libc/src/new/linux_uapi/linux/keyctl.rs new file mode 100644 index 0000000..cc6527a --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/keyctl.rs @@ -0,0 +1,69 @@ +//! Header: `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 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_MOVE: u32 = 30; +pub const KEYCTL_CAPABILITIES: u32 = 31; + +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; + +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; diff --git a/vendor/libc/src/new/linux_uapi/linux/membarrier.rs b/vendor/libc/src/new/linux_uapi/linux/membarrier.rs new file mode 100644 index 0000000..4446202 --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/membarrier.rs @@ -0,0 +1,20 @@ +//! Header: `uapi/linux/membarrier.h` + +use crate::prelude::*; + +c_enum! { + // FIXME(1.0): incorrect repr signedness, this should be removed in a breaking change. + #[repr(c_int)] + pub enum membarrier_cmd { + pub MEMBARRIER_CMD_QUERY = 0, + pub MEMBARRIER_CMD_GLOBAL = 1 << 0, + pub MEMBARRIER_CMD_GLOBAL_EXPEDITED = 1 << 1, + pub MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED = 1 << 2, + pub MEMBARRIER_CMD_PRIVATE_EXPEDITED = 1 << 3, + pub MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = 1 << 4, + pub MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE = 1 << 5, + pub MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = 1 << 6, + pub MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ = 1 << 7, + pub MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ = 1 << 8, + } +} diff --git a/vendor/libc/src/new/linux_uapi/linux/mod.rs b/vendor/libc/src/new/linux_uapi/linux/mod.rs new file mode 100644 index 0000000..209454a --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/mod.rs @@ -0,0 +1,17 @@ +//! Directory: `linux/` +//! +//! + +pub(crate) mod can; +pub(crate) mod futex; +pub(crate) mod if_addr; +pub(crate) mod if_link; +pub(crate) mod if_packet; +pub(crate) mod keyctl; +pub(crate) mod membarrier; +pub(crate) mod mount; +pub(crate) mod netlink; +pub(crate) mod pidfd; +pub(crate) mod sctp; +pub(crate) mod tls; +pub(crate) mod types; diff --git a/vendor/libc/src/new/linux_uapi/linux/mount.rs b/vendor/libc/src/new/linux_uapi/linux/mount.rs new file mode 100644 index 0000000..bf736ac --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/mount.rs @@ -0,0 +1,68 @@ +//! Header: `uapi/linux/mount.h` + +use crate::prelude::*; + +pub const MS_RMT_MASK: c_ulong = crate::MS_RDONLY + | crate::MS_SYNCHRONOUS + | crate::MS_MANDLOCK + | crate::MS_I_VERSION + | crate::MS_LAZYTIME; + +pub const OPEN_TREE_CLONE: c_uint = 0x01; +pub const OPEN_TREE_NAMESPACE: c_uint = 0x02; +pub const OPEN_TREE_CLOEXEC: c_uint = crate::O_CLOEXEC as c_uint; + +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; + +pub const FSOPEN_CLOEXEC: c_uint = 0x00000001; + +pub const FSPICK_CLOEXEC: c_uint = 0x00000001; +pub const FSPICK_SYMLINK_NOFOLLOW: c_uint = 0x00000002; +pub const FSPICK_NO_AUTOMOUNT: c_uint = 0x00000004; +pub const FSPICK_EMPTY_PATH: c_uint = 0x00000008; + +c_enum! { + pub enum fsconfig_command { + pub FSCONFIG_SET_FLAG, + pub FSCONFIG_SET_STRING, + pub FSCONFIG_SET_BINARY, + pub FSCONFIG_SET_PATH, + pub FSCONFIG_SET_PATH_EMPTY, + pub FSCONFIG_SET_FD, + pub FSCONFIG_CMD_CREATE, + pub FSCONFIG_CMD_RECONFIGURE, + pub FSCONFIG_CMD_CREATE_EXCL, + } +} + +pub const FSMOUNT_CLOEXEC: c_uint = 0x00000001; + +pub const MOUNT_ATTR_RDONLY: u64 = 0x00000001; +pub const MOUNT_ATTR_NOSUID: u64 = 0x00000002; +pub const MOUNT_ATTR_NODEV: u64 = 0x00000004; +pub const MOUNT_ATTR_NOEXEC: u64 = 0x00000008; +pub const MOUNT_ATTR__ATIME: u64 = 0x00000070; +pub const MOUNT_ATTR_RELATIME: u64 = 0x00000000; +pub const MOUNT_ATTR_NOATIME: u64 = 0x00000010; +pub const MOUNT_ATTR_STRICTATIME: u64 = 0x00000020; +pub const MOUNT_ATTR_NODIRATIME: u64 = 0x00000080; +pub const MOUNT_ATTR_IDMAP: u64 = 0x00100000; +pub const MOUNT_ATTR_NOSYMFOLLOW: u64 = 0x00200000; + +s! { + pub struct mount_attr { + pub attr_set: crate::__u64, + pub attr_clr: crate::__u64, + pub propagation: crate::__u64, + pub userns_fd: crate::__u64, + } +} + +pub const MOUNT_ATTR_SIZE_VER0: c_int = 32; diff --git a/vendor/libc/src/new/linux_uapi/linux/netlink.rs b/vendor/libc/src/new/linux_uapi/linux/netlink.rs new file mode 100644 index 0000000..eb78eca --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/netlink.rs @@ -0,0 +1,136 @@ +//! Header: `uapi/linux/netlink.h` + +use crate::prelude::*; + +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; + +s! { + pub struct sockaddr_nl { + pub nl_family: crate::sa_family_t, + nl_pad: Padding, + pub nl_pid: u32, + pub nl_groups: 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 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 NLM_F_NONREC: c_int = 0x100; + +pub const NLM_F_CAPPED: c_int = 0x100; +pub const NLM_F_ACK_TLVS: c_int = 0x200; + +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; + +s! { + pub struct nlmsgerr { + pub error: c_int, + pub msg: nlmsghdr, + } +} + +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; + +s! { + 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, + } +} + +s! { + pub struct nlattr { + pub nla_len: u16, + pub nla_type: u16, + } +} + +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; + +f! { + pub unsafe fn NLA_ALIGN(len: c_int) -> c_int { + return ((len) + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1); + } +} diff --git a/vendor/libc/src/new/linux_uapi/linux/pidfd.rs b/vendor/libc/src/new/linux_uapi/linux/pidfd.rs new file mode 100644 index 0000000..1835184 --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/pidfd.rs @@ -0,0 +1,59 @@ +//! Header: `uapi/linux/pidfd.h` + +use crate::prelude::*; +use crate::{ + Ioctl, + _IO, + _IOWR, +}; + +/* Flags for pidfd_open(). */ +pub const PIDFD_NONBLOCK: c_uint = crate::O_NONBLOCK as c_uint; +pub const PIDFD_THREAD: c_uint = crate::O_EXCL as c_uint; + +/* Flags for pidfd_send_signal(). */ +pub const PIDFD_SIGNAL_THREAD: c_uint = 1 << 0; +pub const PIDFD_SIGNAL_THREAD_GROUP: c_uint = 1 << 1; +pub const PIDFD_SIGNAL_PROCESS_GROUP: c_uint = 1 << 2; + +/* Flags for pidfd_info. */ +pub const PIDFD_INFO_PID: c_uint = 1 << 0; +pub const PIDFD_INFO_CREDS: c_uint = 1 << 1; +pub const PIDFD_INFO_CGROUPID: c_uint = 1 << 2; +pub const PIDFD_INFO_EXIT: c_uint = 1 << 3; + +pub const PIDFD_INFO_SIZE_VER0: c_uint = 64; + +s! { + #[non_exhaustive] + pub struct pidfd_info { + pub mask: crate::__u64, + pub cgroupid: crate::__u64, + pub pid: crate::__u32, + pub tgid: crate::__u32, + pub ppid: crate::__u32, + pub ruid: crate::__u32, + pub rgid: crate::__u32, + pub euid: crate::__u32, + pub egid: crate::__u32, + pub suid: crate::__u32, + pub sgid: crate::__u32, + pub fsuid: crate::__u32, + pub fsgid: crate::__u32, + pub exit_code: crate::__s32, + } +} + +const PIDFS_IOCTL_MAGIC: c_uint = 0xFF; + +pub const PIDFD_GET_CGROUP_NAMESPACE: Ioctl = _IO(PIDFS_IOCTL_MAGIC, 1); +pub const PIDFD_GET_IPC_NAMESPACE: Ioctl = _IO(PIDFS_IOCTL_MAGIC, 2); +pub const PIDFD_GET_MNT_NAMESPACE: Ioctl = _IO(PIDFS_IOCTL_MAGIC, 3); +pub const PIDFD_GET_NET_NAMESPACE: Ioctl = _IO(PIDFS_IOCTL_MAGIC, 4); +pub const PIDFD_GET_PID_NAMESPACE: Ioctl = _IO(PIDFS_IOCTL_MAGIC, 5); +pub const PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE: Ioctl = _IO(PIDFS_IOCTL_MAGIC, 6); +pub const PIDFD_GET_TIME_NAMESPACE: Ioctl = _IO(PIDFS_IOCTL_MAGIC, 7); +pub const PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE: Ioctl = _IO(PIDFS_IOCTL_MAGIC, 8); +pub const PIDFD_GET_USER_NAMESPACE: Ioctl = _IO(PIDFS_IOCTL_MAGIC, 9); +pub const PIDFD_GET_UTS_NAMESPACE: Ioctl = _IO(PIDFS_IOCTL_MAGIC, 10); +pub const PIDFD_GET_INFO: Ioctl = _IOWR::(PIDFS_IOCTL_MAGIC, 11); diff --git a/vendor/libc/src/new/linux_uapi/linux/sctp.rs b/vendor/libc/src/new/linux_uapi/linux/sctp.rs new file mode 100644 index 0000000..3a9ad6d --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/sctp.rs @@ -0,0 +1,177 @@ +use crate::prelude::*; +use crate::{ + __s32, + __u16, + __u32, +}; + +pub type sctp_assoc_t = __s32; + +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; +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const SCTP_PR_SCTP_MAX: c_int = SCTP_PR_SCTP_PRIO; +pub const SCTP_PR_SCTP_MASK: c_int = 0x0030; + +f! { + pub unsafe fn SCTP_PR_INDEX(policy: c_int) -> c_int { + policy >> (4 - 1) + } + + pub unsafe fn SCTP_PR_POLICY(policy: c_int) -> c_int { + policy & SCTP_PR_SCTP_MASK + } + + pub unsafe fn SCTP_PR_SET_POLICY(flags: &mut c_int, policy: c_int) -> () { + *flags &= !SCTP_PR_SCTP_MASK; + *flags |= policy; + } +} + +safe_f! { + pub const safe fn SCTP_PR_TTL_ENABLED(policy: c_int) -> bool { + policy == SCTP_PR_SCTP_TTL + } + + pub const safe fn SCTP_PR_RTX_ENABLED(policy: c_int) -> bool { + policy == SCTP_PR_SCTP_RTX + } + + pub const safe fn SCTP_PR_PRIO_ENABLED(policy: c_int) -> bool { + policy == SCTP_PR_SCTP_PRIO + } +} + +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 MSG_NOTIFICATION: c_int = 0x8000; + +s! { + 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: crate::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: crate::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: crate::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: crate::sctp_assoc_t, + } + + pub struct sctp_prinfo { + pub pr_policy: __u16, + pub pr_value: __u32, + } + + pub struct sctp_authinfo { + pub auth_keynumber: __u16, + } +} + +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 = crate::MSG_FIN; + +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; diff --git a/vendor/libc/src/new/linux_uapi/linux/tls.rs b/vendor/libc/src/new/linux_uapi/linux/tls.rs new file mode 100644 index 0000000..913a93f --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/tls.rs @@ -0,0 +1,177 @@ +//! Header: `uapi/linux/tls.h` + +use crate::prelude::*; +use crate::{ + __u16, + __u8, +}; + +pub const TLS_TX: c_int = 1; +pub const TLS_RX: c_int = 2; +pub const TLS_TX_ZEROCOPY_RO: c_int = 3; +pub const TLS_RX_EXPECT_NO_PAD: c_int = 4; + +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_AES_CCM_128: __u16 = 53; +pub const TLS_CIPHER_AES_CCM_128_IV_SIZE: usize = 8; +pub const TLS_CIPHER_AES_CCM_128_KEY_SIZE: usize = 16; +pub const TLS_CIPHER_AES_CCM_128_SALT_SIZE: usize = 4; +pub const TLS_CIPHER_AES_CCM_128_TAG_SIZE: usize = 16; +pub const TLS_CIPHER_AES_CCM_128_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_CIPHER_SM4_GCM: __u16 = 55; +pub const TLS_CIPHER_SM4_GCM_IV_SIZE: usize = 8; +pub const TLS_CIPHER_SM4_GCM_KEY_SIZE: usize = 16; +pub const TLS_CIPHER_SM4_GCM_SALT_SIZE: usize = 4; +pub const TLS_CIPHER_SM4_GCM_TAG_SIZE: usize = 16; +pub const TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE: usize = 8; + +pub const TLS_CIPHER_SM4_CCM: __u16 = 56; +pub const TLS_CIPHER_SM4_CCM_IV_SIZE: usize = 8; +pub const TLS_CIPHER_SM4_CCM_KEY_SIZE: usize = 16; +pub const TLS_CIPHER_SM4_CCM_SALT_SIZE: usize = 4; +pub const TLS_CIPHER_SM4_CCM_TAG_SIZE: usize = 16; +pub const TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE: usize = 8; + +pub const TLS_CIPHER_ARIA_GCM_128: __u16 = 57; +pub const TLS_CIPHER_ARIA_GCM_128_IV_SIZE: usize = 8; +pub const TLS_CIPHER_ARIA_GCM_128_KEY_SIZE: usize = 16; +pub const TLS_CIPHER_ARIA_GCM_128_SALT_SIZE: usize = 4; +pub const TLS_CIPHER_ARIA_GCM_128_TAG_SIZE: usize = 16; +pub const TLS_CIPHER_ARIA_GCM_128_REC_SEQ_SIZE: usize = 8; + +pub const TLS_CIPHER_ARIA_GCM_256: __u16 = 58; +pub const TLS_CIPHER_ARIA_GCM_256_IV_SIZE: usize = 8; +pub const TLS_CIPHER_ARIA_GCM_256_KEY_SIZE: usize = 32; +pub const TLS_CIPHER_ARIA_GCM_256_SALT_SIZE: usize = 4; +pub const TLS_CIPHER_ARIA_GCM_256_TAG_SIZE: usize = 16; +pub const TLS_CIPHER_ARIA_GCM_256_REC_SEQ_SIZE: usize = 8; + +pub const TLS_SET_RECORD_TYPE: c_int = 1; +pub const TLS_GET_RECORD_TYPE: c_int = 2; + +s! { + 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_aes_ccm_128 { + pub info: tls_crypto_info, + pub iv: [c_uchar; TLS_CIPHER_AES_CCM_128_IV_SIZE], + pub key: [c_uchar; TLS_CIPHER_AES_CCM_128_KEY_SIZE], + pub salt: [c_uchar; TLS_CIPHER_AES_CCM_128_SALT_SIZE], + pub rec_seq: [c_uchar; TLS_CIPHER_AES_CCM_128_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], + } + + pub struct tls12_crypto_info_sm4_gcm { + pub info: tls_crypto_info, + pub iv: [c_uchar; TLS_CIPHER_SM4_GCM_IV_SIZE], + pub key: [c_uchar; TLS_CIPHER_SM4_GCM_KEY_SIZE], + pub salt: [c_uchar; TLS_CIPHER_SM4_GCM_SALT_SIZE], + pub rec_seq: [c_uchar; TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE], + } + + pub struct tls12_crypto_info_sm4_ccm { + pub info: tls_crypto_info, + pub iv: [c_uchar; TLS_CIPHER_SM4_CCM_IV_SIZE], + pub key: [c_uchar; TLS_CIPHER_SM4_CCM_KEY_SIZE], + pub salt: [c_uchar; TLS_CIPHER_SM4_CCM_SALT_SIZE], + pub rec_seq: [c_uchar; TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE], + } + + pub struct tls12_crypto_info_aria_gcm_128 { + pub info: tls_crypto_info, + pub iv: [c_uchar; TLS_CIPHER_ARIA_GCM_128_IV_SIZE], + pub key: [c_uchar; TLS_CIPHER_ARIA_GCM_128_KEY_SIZE], + pub salt: [c_uchar; TLS_CIPHER_ARIA_GCM_128_SALT_SIZE], + pub rec_seq: [c_uchar; TLS_CIPHER_ARIA_GCM_128_REC_SEQ_SIZE], + } + + pub struct tls12_crypto_info_aria_gcm_256 { + pub info: tls_crypto_info, + pub iv: [c_uchar; TLS_CIPHER_ARIA_GCM_256_IV_SIZE], + pub key: [c_uchar; TLS_CIPHER_ARIA_GCM_256_KEY_SIZE], + pub salt: [c_uchar; TLS_CIPHER_ARIA_GCM_256_SALT_SIZE], + pub rec_seq: [c_uchar; TLS_CIPHER_ARIA_GCM_256_REC_SEQ_SIZE], + } +} + +c_enum! { + // FIXME(1.0): This is an i32 in `libc` but enum reprs are `u32`. + #[repr(c_int)] + pub enum #anon { + pub TLS_INFO_UNSPEC, + pub TLS_INFO_VERSION, + pub TLS_INFO_CIPHER, + pub TLS_INFO_TXCONF, + pub TLS_INFO_RXCONF, + pub TLS_INFO_ZC_RO_TX, + pub TLS_INFO_RX_NO_PAD, + pub TLS_INFO_TX_MAX_PAYLOAD_LEN, + __TLS_INFO_MAX, + } +} + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const TLS_INFO_MAX: c_int = __TLS_INFO_MAX - 1; + +pub const TLS_CONF_BASE: c_int = 1; +pub const TLS_CONF_SW: c_int = 2; +pub const TLS_CONF_HW: c_int = 3; +pub const TLS_CONF_HW_RECORD: c_int = 4; diff --git a/vendor/libc/src/new/linux_uapi/linux/types.rs b/vendor/libc/src/new/linux_uapi/linux/types.rs new file mode 100644 index 0000000..d0eecd3 --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/linux/types.rs @@ -0,0 +1,17 @@ +//! * Header: `uapi/linux/types.h` +//! * Header: `uapi/asm-generic/int-ll64.h` + +use crate::prelude::*; + +/* Definitions from `asm/types.h` -> `asm-generic/types.h` -> `asm-generic/int-ll64.h` */ + +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 __s64 = c_longlong; +pub type __u64 = c_ulonglong; diff --git a/vendor/libc/src/new/linux_uapi/mod.rs b/vendor/libc/src/new/linux_uapi/mod.rs new file mode 100644 index 0000000..8ac3022 --- /dev/null +++ b/vendor/libc/src/new/linux_uapi/mod.rs @@ -0,0 +1,3 @@ +//! This directory maps to `include/uapi` in the Linux source tree. + +pub(crate) mod linux; diff --git a/vendor/libc/src/new/mod.rs b/vendor/libc/src/new/mod.rs new file mode 100644 index 0000000..f4387e7 --- /dev/null +++ b/vendor/libc/src/new/mod.rs @@ -0,0 +1,257 @@ +//! This module contains the future directory structure. If possible, new definitions should +//! get added here. +//! +//! Eventually everything should be moved over, and we will move this directory to the top +//! level in `src`. +//! +//! # Basic structure +//! +//! Each child module here represents a library or group of libraries that we are binding. Each of +//! these has several submodules, representing either a directory or a header file in that library. +//! +//! `#include`s turn into `pub use ...*;` statements. Then at the root level (here), we choose +//! which top-level headers we want to reexport the definitions for. +//! +//! All modules are only crate-public since we don't reexport this structure. + +mod common; + +/* The `pub(crate) use ...` statements are commented while the modules are empty */ + +// Platform libraries and combined platform+libc +// +// Not supported or not needed: +// * amdhsa +// * cuda +// * lynxos178 +// * managarm +// * motor +// * none +// * psp +// * psx +// * uefi +// * unknown +// * vexos +// * zkvm +// +// Combined to target_vendor = "apple" +// * ios +// * macos +// * tvos +// * visionos +// * watchos +cfg_if! { + if #[cfg(target_os = "aix")] { + mod aix; + pub(crate) use aix::*; + } else if #[cfg(target_os = "android")] { + mod bionic_libc; + pub(crate) use bionic_libc::*; + } else if #[cfg(target_vendor = "apple")] { + mod apple; + pub(crate) use apple::*; + } else if #[cfg(target_os = "cygwin")] { + mod cygwin; + pub(crate) use cygwin::*; + } else if #[cfg(target_os = "dragonfly")] { + mod dragonfly; + pub(crate) use dragonfly::*; + } else if #[cfg(target_os = "emscripten")] { + mod emscripten; + pub use emscripten::sched::*; + pub(crate) use emscripten::*; + } else if #[cfg(target_os = "espidf")] { + mod espidf; + // pub(crate) use espidf::*; + } else if #[cfg(target_os = "freebsd")] { + mod freebsd; + pub(crate) use freebsd::*; + } else if #[cfg(target_os = "fuchsia")] { + mod fuchsia; + pub(crate) use fuchsia::*; + } else if #[cfg(target_os = "haiku")] { + mod haiku; + pub(crate) use haiku::*; + } else if #[cfg(target_os = "hermit")] { + mod hermit_abi; + // pub(crate) use hermit_abi::*; + } else if #[cfg(target_os = "horizon")] { + mod horizon; + // pub(crate) use horizon::*; + } else if #[cfg(target_os = "hurd")] { + mod hurd; + // pub(crate) use hurd::*; + } else if #[cfg(target_os = "illumos")] { + mod illumos; + pub(crate) use illumos::*; + } else if #[cfg(target_os = "l4re")] { + mod l4re; + // pub(crate) use l4re::*; + } else if #[cfg(target_os = "linux")] { + mod linux_uapi; + pub(crate) use linux_uapi::*; + } else if #[cfg(target_os = "netbsd")] { + mod netbsd; + pub(crate) use netbsd::*; + } else if #[cfg(any(target_os = "nto", target_os = "qnx"))] { + mod nto; + pub(crate) use nto::*; + } else if #[cfg(target_os = "nuttx")] { + mod nuttx; + pub(crate) use nuttx::*; + } else if #[cfg(target_os = "openbsd")] { + mod openbsd; + pub(crate) use openbsd::*; + } else if #[cfg(target_os = "qurt")] { + pub mod qurt; + } else if #[cfg(target_os = "redox")] { + mod redox; + // pub(crate) use redox::*; + } else if #[cfg(target_os = "rtems")] { + mod rtems; + // pub(crate) use rtems::*; + } else if #[cfg(target_os = "solaris")] { + mod solaris; + pub(crate) use solaris::*; + } else if #[cfg(target_os = "solid_asp3")] { + mod solid; + // pub(crate) use solid::*; + } else if #[cfg(target_os = "teeos")] { + mod teeos; + // pub(crate) use teeos::*; + } else if #[cfg(target_os = "trusty")] { + mod trusty; + // pub(crate) use trusty::*; + } else if #[cfg(target_os = "vita")] { + mod vita; + // pub(crate) use vita::*; + } else if #[cfg(target_os = "vxworks")] { + mod vxworks; + pub(crate) use vxworks::*; + } else if #[cfg(target_os = "wasi")] { + mod wasi; + // pub(crate) use wasi::*; + } else if #[cfg(target_os = "windows")] { + mod ucrt; + // pub(crate) use ucrt::*; + } else if #[cfg(target_os = "xous")] { + mod xous; + // pub(crate) use xous::*; + } +} + +// Multi-platform libc +cfg_if! { + // FIXME(vxworks): vxworks sets `target_env = "gnu"` but maybe shouldn't. + if #[cfg(all( + target_family = "unix", + target_env = "gnu", + not(target_os = "vxworks") + ))] { + mod glibc; + pub(crate) use glibc::*; + } else if #[cfg(any(target_env = "musl", target_env = "ohos"))] { + // OhOS also uses the musl libc + mod musl; + pub use musl::sched::*; + pub(crate) use musl::*; + } else if #[cfg(target_env = "newlib")] { + mod newlib; + pub(crate) use newlib::*; + } else if #[cfg(target_env = "relibc")] { + mod relibc; + pub(crate) use relibc::*; + } else if #[cfg(target_env = "sgx")] { + mod sgx; + // pub(crate) use sgx::*; + } else if #[cfg(target_env = "uclibc")] { + mod uclibc; + pub(crate) use uclibc::*; + } +} + +// Per-OS headers we export +cfg_if! { + if #[cfg(target_os = "android")] { + use bionic_libc::kernel_uapi::linux; + pub use linux::types::*; + pub use sys::socket::*; + } else if #[cfg(target_os = "linux")] { + pub use linux::can::bcm::*; + pub use linux::can::error::*; + pub use linux::can::j1939::*; + pub use linux::can::netlink::*; + pub use linux::can::raw::*; + pub use linux::futex::*; + pub use linux::if_addr::*; + pub use linux::if_link::*; + pub use linux::if_packet::*; + pub use linux::keyctl::*; + pub use linux::membarrier::*; + pub use linux::mount::*; + pub use linux::netlink::*; + pub use linux::pidfd::*; + pub use linux::sctp::*; + pub use linux::tls::*; + pub use linux::types::*; + #[cfg(target_env = "gnu")] + pub use net::route::*; + } else if #[cfg(target_vendor = "apple")] { + pub use net::bpf::*; + pub use netinet6::in6_var::*; + pub use pthread_::introspection::*; + pub use pthread_::pthread_spis::*; + pub use pthread_::spawn::*; + pub use pthread_::stack_np::*; + pub use signal::*; + pub use sys::ioccom::*; + pub use sys::sockio::*; + pub use sys::ttycom::*; + } else if #[cfg(target_os = "l4re")] { + pub use l4re::packet::*; + } else if #[cfg(target_os = "netbsd")] { + pub use net::if_::*; + pub use sys::file::*; + pub use sys::ipc::*; + pub use sys::socket::*; + pub use sys::statvfs::*; + pub use sys::time::*; + pub use sys::timex::*; + pub use sys::types::*; + pub use utmp_::*; + pub use utmpx_::*; + } else if #[cfg(target_os = "openbsd")] { + pub use sys::ipc::*; + } else if #[cfg(any(target_os = "nto", target_os = "qnx"))] { + pub use net::bpf::*; + pub use net::if_::*; + } else if #[cfg(target_os = "freebsd")] { + pub use net::dlt::*; + pub use netinet6::in6_var::*; + pub use sys::file::*; + pub use sys::ioccom::*; + pub use sys::socket::*; + } +} + +// Per-env headers we export +cfg_if! { + if #[cfg(any(target_env = "musl", target_env = "ohos"))] { + pub use sys::socket::*; + } +} + +// Per-family headers we export +cfg_if! { + if #[cfg(all(target_family = "unix", not(target_os = "qurt")))] { + // FIXME(pthread): eventually all platforms should use this module + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux" + ))] + pub use pthread::*; + pub use unistd::*; + } +} diff --git a/vendor/libc/src/new/musl/arch/generic/mod.rs b/vendor/libc/src/new/musl/arch/generic/mod.rs new file mode 100644 index 0000000..ac02505 --- /dev/null +++ b/vendor/libc/src/new/musl/arch/generic/mod.rs @@ -0,0 +1,7 @@ +//! Source directory: `arch/generic/` +//! +//! + +pub(crate) mod bits { + // Currently unused +} diff --git a/vendor/libc/src/new/musl/arch/mips/bits/socket.rs b/vendor/libc/src/new/musl/arch/mips/bits/socket.rs new file mode 100644 index 0000000..77b53e4 --- /dev/null +++ b/vendor/libc/src/new/musl/arch/mips/bits/socket.rs @@ -0,0 +1,4 @@ +use crate::prelude::*; + +pub const SOCK_STREAM: c_int = 2; +pub const SOCK_DGRAM: c_int = 1; diff --git a/vendor/libc/src/new/musl/arch/mips/mod.rs b/vendor/libc/src/new/musl/arch/mips/mod.rs new file mode 100644 index 0000000..2f02036 --- /dev/null +++ b/vendor/libc/src/new/musl/arch/mips/mod.rs @@ -0,0 +1,7 @@ +//! Source directory: `arch/mips/` +//! +//! + +pub(crate) mod bits { + pub(crate) mod socket; +} diff --git a/vendor/libc/src/new/musl/arch/mips64/bits/socket.rs b/vendor/libc/src/new/musl/arch/mips64/bits/socket.rs new file mode 100644 index 0000000..77b53e4 --- /dev/null +++ b/vendor/libc/src/new/musl/arch/mips64/bits/socket.rs @@ -0,0 +1,4 @@ +use crate::prelude::*; + +pub const SOCK_STREAM: c_int = 2; +pub const SOCK_DGRAM: c_int = 1; diff --git a/vendor/libc/src/new/musl/arch/mips64/mod.rs b/vendor/libc/src/new/musl/arch/mips64/mod.rs new file mode 100644 index 0000000..6a45b06 --- /dev/null +++ b/vendor/libc/src/new/musl/arch/mips64/mod.rs @@ -0,0 +1,7 @@ +//! Source directory: `arch/mips64/` +//! +//! + +pub(crate) mod bits { + pub(crate) mod socket; +} diff --git a/vendor/libc/src/new/musl/arch/mod.rs b/vendor/libc/src/new/musl/arch/mod.rs new file mode 100644 index 0000000..514d7b4 --- /dev/null +++ b/vendor/libc/src/new/musl/arch/mod.rs @@ -0,0 +1,10 @@ +//! Source directory: `arch/` +//! +//! + +pub(crate) mod generic; + +#[cfg(target_arch = "mips")] +pub(crate) mod mips; +#[cfg(target_arch = "mips64")] +pub(crate) mod mips64; diff --git a/vendor/libc/src/new/musl/mod.rs b/vendor/libc/src/new/musl/mod.rs new file mode 100644 index 0000000..a6551c3 --- /dev/null +++ b/vendor/libc/src/new/musl/mod.rs @@ -0,0 +1,33 @@ +//! Musl libc. +//! +//! * Headers: (official) +//! * Headers: (mirror) + +// The musl build system includes `arch/$(ARCH)` (preferred if it exists) and `arch/generic` (used +// as the fallback). We can't exactly mirror this with glob exports, so instead we selectively +// reexport in a new module. +mod arch; + +pub(crate) mod bits { + cfg_if! { + if #[cfg(target_arch = "mips")] { + pub(crate) use super::arch::mips::bits::socket; + } else if #[cfg(target_arch = "mips64")] { + pub(crate) use super::arch::mips64::bits::socket; + } else { + // Reexports from generic will live here once we need them. + } + } +} + +pub(crate) mod pthread; + +/// Directory: `sys/` +/// +/// +pub(crate) mod sys { + pub(crate) mod socket; +} + +pub(crate) mod sched; +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/musl/pthread.rs b/vendor/libc/src/new/musl/pthread.rs new file mode 100644 index 0000000..0d578bc --- /dev/null +++ b/vendor/libc/src/new/musl/pthread.rs @@ -0,0 +1,62 @@ +//! Header: `pthread.h` +//! +//! + +pub use crate::new::common::linux_like::pthread::{ + pthread_getaffinity_np, + pthread_getattr_np, + pthread_getname_np, + pthread_setaffinity_np, + pthread_setname_np, +}; +pub use crate::new::common::posix::pthread::{ + pthread_atfork, + pthread_attr_getguardsize, + pthread_attr_getinheritsched, + pthread_attr_getschedparam, + pthread_attr_getschedpolicy, + pthread_attr_getstack, + pthread_attr_setguardsize, + pthread_attr_setinheritsched, + pthread_attr_setschedparam, + pthread_attr_setschedpolicy, + pthread_attr_setstack, + pthread_barrier_destroy, + pthread_barrier_init, + pthread_barrier_wait, + pthread_barrierattr_destroy, + pthread_barrierattr_getpshared, + pthread_barrierattr_init, + pthread_barrierattr_setpshared, + pthread_condattr_getclock, + pthread_condattr_getpshared, + pthread_condattr_setclock, + pthread_condattr_setpshared, + pthread_create, + pthread_getcpuclockid, + pthread_getschedparam, + pthread_kill, + pthread_mutex_timedlock, + pthread_mutexattr_getprotocol, + pthread_mutexattr_getpshared, + pthread_mutexattr_setprotocol, + pthread_mutexattr_setpshared, + pthread_once, + pthread_rwlockattr_getpshared, + pthread_rwlockattr_setpshared, + pthread_setschedparam, + pthread_setschedprio, + pthread_sigmask, + pthread_spin_destroy, + pthread_spin_init, + pthread_spin_lock, + pthread_spin_trylock, + pthread_spin_unlock, +}; +#[cfg(not(target_env = "ohos"))] +pub use crate::new::common::posix::pthread::{ + pthread_cancel, + pthread_mutex_consistent, + pthread_mutexattr_getrobust, + pthread_mutexattr_setrobust, +}; diff --git a/vendor/libc/src/new/musl/sched.rs b/vendor/libc/src/new/musl/sched.rs new file mode 100644 index 0000000..3bf854e --- /dev/null +++ b/vendor/libc/src/new/musl/sched.rs @@ -0,0 +1,38 @@ +use crate::prelude::*; + +cfg_if! { + if #[cfg(musl_v1_2_3)] { + s! { + struct __c_anon_sched_param__reserved2 { + __reserved1: crate::time_t, + __reserved2: c_long, + } + + pub struct sched_param { + pub sched_priority: c_int, + + __reserved1: Padding, + #[cfg(musl32_time64)] + __reserved2: Padding<[c_long; 4]>, + #[cfg(not(musl32_time64))] + __reserved2: Padding<[__c_anon_sched_param__reserved2; 2]>, + __reserved3: Padding, + } + } + } else { + s! { + pub struct sched_param { + pub sched_priority: c_int, + + #[deprecated(since = "0.2.173", note = "This field has been removed upstream")] + pub sched_ss_low_priority: c_int, + #[deprecated(since = "0.2.173", note = "This field has been removed upstream")] + pub sched_ss_repl_period: crate::timespec, + #[deprecated(since = "0.2.173", note = "This field has been removed upstream")] + pub sched_ss_init_budget: crate::timespec, + #[deprecated(since = "0.2.173", note = "This field has been removed upstream")] + pub sched_ss_max_repl: c_int, + } + } + } +} diff --git a/vendor/libc/src/new/musl/sys/socket.rs b/vendor/libc/src/new/musl/sys/socket.rs new file mode 100644 index 0000000..7d3f495 --- /dev/null +++ b/vendor/libc/src/new/musl/sys/socket.rs @@ -0,0 +1,64 @@ +//! Header: `sys/socket.h` +//! +//! + +use crate::prelude::*; + +s! { + pub struct msghdr { + pub msg_name: *mut c_void, + pub msg_namelen: crate::socklen_t, + pub msg_iov: *mut crate::iovec, + #[cfg(all(target_pointer_width = "64", target_endian = "big"))] + __pad1: Padding, + pub msg_iovlen: c_int, + #[cfg(all(target_pointer_width = "64", target_endian = "little"))] + __pad1: Padding, + pub msg_control: *mut c_void, + #[cfg(all(target_pointer_width = "64", target_endian = "big"))] + __pad2: Padding, + pub msg_controllen: crate::socklen_t, + #[cfg(all(target_pointer_width = "64", target_endian = "little"))] + __pad2: Padding, + pub msg_flags: c_int, + } + + pub struct cmsghdr { + #[cfg(all(target_pointer_width = "64", target_endian = "big"))] + pub __pad1: c_int, + pub cmsg_len: crate::socklen_t, + #[cfg(all(target_pointer_width = "64", target_endian = "little"))] + pub __pad1: c_int, + pub cmsg_level: c_int, + pub cmsg_type: c_int, + } +} + +extern "C" { + pub fn sendmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: c_uint, + flags: c_uint, + ) -> c_int; + #[cfg_attr(musl_redir_time64, link_name = "__recvmmsg_time64")] + pub fn recvmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: c_uint, + flags: c_uint, + timeout: *mut crate::timespec, + ) -> c_int; +} + +cfg_if! { + if #[cfg(any(target_arch = "mips", target_arch = "mips64"))] { + pub use crate::bits::socket::{ + SOCK_DGRAM, + SOCK_STREAM, + }; + } else { + pub const SOCK_STREAM: c_int = 1; + pub const SOCK_DGRAM: c_int = 2; + } +} diff --git a/vendor/libc/src/new/musl/unistd.rs b/vendor/libc/src/new/musl/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/musl/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/netbsd/mod.rs b/vendor/libc/src/new/netbsd/mod.rs new file mode 100644 index 0000000..5db7176 --- /dev/null +++ b/vendor/libc/src/new/netbsd/mod.rs @@ -0,0 +1,14 @@ +//! NetBSD libc. +//! +//! * Headers: +//! * Sys headers: +//! * Manual pages: + +pub(crate) mod net { + pub(crate) mod if_; +} + +pub(crate) mod sys; +pub(crate) mod unistd; +pub(crate) mod utmp_; +pub(crate) mod utmpx_; diff --git a/vendor/libc/src/new/netbsd/net/if_.rs b/vendor/libc/src/new/netbsd/net/if_.rs new file mode 100644 index 0000000..68f2d91 --- /dev/null +++ b/vendor/libc/src/new/netbsd/net/if_.rs @@ -0,0 +1,101 @@ +//! Header: `net/if.h` +//! +//! + +use crate::prelude::*; +use crate::IFNAMSIZ; + +s! { + 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: crate::timespec, + } +} + +pub const LINK_STATE_UNKNOWN: c_int = 0; // link invalid/unknown +pub const LINK_STATE_DOWN: c_int = 1; // link is down +pub const LINK_STATE_UP: c_int = 2; // link is up + +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_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 + +s! { + #[repr(C, align(8))] + 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, + } +} + +s_no_extra_traits! { + pub struct ifreq { + pub ifr_name: [c_char; IFNAMSIZ], + pub ifr_ifru: __c_anonymous_ifr_ifru, + } + + pub union __c_anonymous_ifr_ifru { + pub ifru_addr: crate::sockaddr, + pub ifru_dstaddr: crate::sockaddr, + pub ifru_broadaddr: crate::sockaddr, + pub space: crate::sockaddr_storage, + pub ifru_flags: c_short, + pub ifru_addrflags: c_int, + pub ifru_metrics: c_int, + pub ifru_mtu: c_int, + pub ifru_dlt: c_int, + pub ifru_value: c_uint, + pub ifru_data: *mut c_void, + // buf and buflen are deprecated but they contribute to union size + ifru_b: __c_anonymous_ifr_ifru_ifru_b, + } + + struct __c_anonymous_ifr_ifru_ifru_b { + b_buflen: u32, + b_buf: *mut c_void, + } + + pub struct ifconf { + pub ifc_len: c_int, + pub ifc_ifcu: __c_anonymous_ifc_ifcu, + } + + pub union __c_anonymous_ifc_ifcu { + pub ifcu_buf: *mut c_void, + pub ifcu_req: *mut ifreq, + } +} diff --git a/vendor/libc/src/new/netbsd/sys/file.rs b/vendor/libc/src/new/netbsd/sys/file.rs new file mode 100644 index 0000000..103b68d --- /dev/null +++ b/vendor/libc/src/new/netbsd/sys/file.rs @@ -0,0 +1,16 @@ +//! Header: `sys/file.h` +//! +//! + +use crate::prelude::*; + +pub const DTYPE_VNODE: c_int = 1; +pub const DTYPE_SOCKET: c_int = 2; +pub const DTYPE_PIPE: c_int = 3; +pub const DTYPE_KQUEUE: c_int = 4; +pub const DTYPE_MISC: c_int = 5; +pub const DTYPE_CRYPTO: c_int = 6; +pub const DTYPE_MQUEUE: c_int = 7; +pub const DTYPE_SEM: c_int = 8; +pub const DTYPE_EVENTFD: c_int = 9; +pub const DTYPE_TIMERFD: c_int = 10; diff --git a/vendor/libc/src/new/netbsd/sys/ipc.rs b/vendor/libc/src/new/netbsd/sys/ipc.rs new file mode 100644 index 0000000..49a1c84 --- /dev/null +++ b/vendor/libc/src/new/netbsd/sys/ipc.rs @@ -0,0 +1,17 @@ +//! Header: `sys/ipc.h` +//! +//! + +use crate::prelude::*; + +s! { + pub struct ipc_perm { + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub _seq: c_ushort, + pub _key: crate::key_t, + } +} diff --git a/vendor/libc/src/new/netbsd/sys/mod.rs b/vendor/libc/src/new/netbsd/sys/mod.rs new file mode 100644 index 0000000..b7255d8 --- /dev/null +++ b/vendor/libc/src/new/netbsd/sys/mod.rs @@ -0,0 +1,11 @@ +//! Directory: `sys/` +//! +//! https://github.com/NetBSD/src/tree/trunk/sys/sys + +pub(crate) mod file; +pub(crate) mod ipc; +pub(crate) mod socket; +pub(crate) mod statvfs; +pub(crate) mod time; +pub(crate) mod timex; +pub(crate) mod types; diff --git a/vendor/libc/src/new/netbsd/sys/socket.rs b/vendor/libc/src/new/netbsd/sys/socket.rs new file mode 100644 index 0000000..9535260 --- /dev/null +++ b/vendor/libc/src/new/netbsd/sys/socket.rs @@ -0,0 +1,44 @@ +//! Header: `sys/socket.h` +//! +//! +//! + +use crate::prelude::*; + +s_no_extra_traits! { + pub union __c_anonymous_pcb_sockaddr_src { + pub _kis_src: crate::sockaddr, + _kis_pad: Padding<[c_char; 256 + 8]>, + } + + pub union __c_anonymous_pcb_sockaddr_dst { + pub _kid_dst: crate::sockaddr, + _kid_pad: Padding<[c_char; 256 + 8]>, + } + + pub struct kinfo_pcb { + pub ki_pcbaddr: u64, + pub ki_ppcbaddr: u64, + pub ki_sockaddr: u64, + pub ki_family: u32, + pub ki_type: u32, + pub ki_protocol: u32, + pub ki_pflags: u32, + pub ki_sostate: u32, + pub ki_prstate: u32, + pub ki_tstate: i32, + pub ki_tflags: u32, + pub ki_rcvq: u64, + pub ki_sndq: u64, + pub ki_s: __c_anonymous_pcb_sockaddr_src, + pub ki_d: __c_anonymous_pcb_sockaddr_dst, + pub ki_inode: u64, + pub ki_vnode: u64, + pub ki_conn: u64, + pub ki_refs: u64, + pub ki_nextref: u64, + } +} + +pub const PCB_SLOP: c_int = 20; +pub const PCB_ALL: c_int = 0; diff --git a/vendor/libc/src/new/netbsd/sys/statvfs.rs b/vendor/libc/src/new/netbsd/sys/statvfs.rs new file mode 100644 index 0000000..eee3766 --- /dev/null +++ b/vendor/libc/src/new/netbsd/sys/statvfs.rs @@ -0,0 +1,47 @@ +//! Header: `sys/statvfs.h` +//! +//! + +use crate::prelude::*; + +const _VFS_NAMELEN: usize = 32; +const _VFS_MNAMELEN: usize = 1024; + +s! { + 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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_bresvd: crate::fsblkcnt_t, + + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::fsfilcnt_t, + pub f_fresvd: crate::fsfilcnt_t, + + pub f_syncreads: u64, + pub f_syncwrites: u64, + + pub f_asyncreads: u64, + pub f_asyncwrites: u64, + + pub f_fsidx: crate::fsid_t, + pub f_fsid: c_ulong, + pub f_namemax: c_ulong, + pub f_owner: crate::uid_t, + + // This type is updated in a future version + f_spare: [u32; 4], + + pub f_fstypename: [c_char; _VFS_NAMELEN], + pub f_mntonname: [c_char; _VFS_MNAMELEN], + pub f_mntfromname: [c_char; _VFS_MNAMELEN], + // Added in NetBSD10 + // pub f_mntfromlabel: [c_char; _VFS_MNAMELEN], + } +} diff --git a/vendor/libc/src/new/netbsd/sys/time.rs b/vendor/libc/src/new/netbsd/sys/time.rs new file mode 100644 index 0000000..b776b2a --- /dev/null +++ b/vendor/libc/src/new/netbsd/sys/time.rs @@ -0,0 +1,15 @@ +//! Header: `sys/time.h` +//! +//! + +s! { + pub struct itimerspec { + pub it_interval: crate::timespec, + pub it_value: crate::timespec, + } +} + +pub const CLOCK_VIRTUAL: crate::clockid_t = 1; +pub const CLOCK_PROF: crate::clockid_t = 2; +pub const CLOCK_THREAD_CPUTIME_ID: crate::clockid_t = 0x20000000; +pub const CLOCK_PROCESS_CPUTIME_ID: crate::clockid_t = 0x40000000; diff --git a/vendor/libc/src/new/netbsd/sys/timex.rs b/vendor/libc/src/new/netbsd/sys/timex.rs new file mode 100644 index 0000000..82844bf --- /dev/null +++ b/vendor/libc/src/new/netbsd/sys/timex.rs @@ -0,0 +1,95 @@ +//! Header: `sys/timex.h` +//! +//! + +use crate::prelude::*; + +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; + +s! { + pub struct ntptimeval { + pub time: crate::timespec, + pub maxerror: c_long, + pub esterror: c_long, + pub tai: c_long, + pub time_state: c_int, + } + + 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, + } +} + +extern "C" { + #[link_name = "__ntp_gettime50"] + pub fn ntp_gettime(buf: *mut ntptimeval) -> c_int; + pub fn ntp_adjtime(buf: *mut timex) -> c_int; +} diff --git a/vendor/libc/src/new/netbsd/sys/types.rs b/vendor/libc/src/new/netbsd/sys/types.rs new file mode 100644 index 0000000..8dfc049 --- /dev/null +++ b/vendor/libc/src/new/netbsd/sys/types.rs @@ -0,0 +1,16 @@ +//! Header: `sys/types.h` +//! +//! + +use crate::prelude::*; + +pub type dev_t = u64; + +pub type lwpid_t = i32; + +pub type mqd_t = c_int; +pub type cpuid_t = c_ulong; + +pub type clock_t = c_uint; +pub type timer_t = c_int; +pub type suseconds_t = c_int; diff --git a/vendor/libc/src/new/netbsd/unistd.rs b/vendor/libc/src/new/netbsd/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/netbsd/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/netbsd/utmp_.rs b/vendor/libc/src/new/netbsd/utmp_.rs new file mode 100644 index 0000000..2047449 --- /dev/null +++ b/vendor/libc/src/new/netbsd/utmp_.rs @@ -0,0 +1,33 @@ +//! Header: `utmp.h` +//! +//! + +use crate::prelude::*; + +pub const UT_NAMESIZE: usize = 8; +pub const UT_LINESIZE: usize = 8; +pub const UT_HOSTSIZE: usize = 16; + +s! { + pub struct lastlog { + pub ll_time: crate::time_t, + pub ll_line: [c_char; UT_LINESIZE], + pub 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: crate::time_t, + } +} + +#[link(name = "util")] +extern "C" { + pub fn utmpname(file: *const c_char) -> c_int; + pub fn setutent(); + #[link_name = "__getutent50"] + pub fn getutent() -> *mut utmp; + pub fn endutent(); +} diff --git a/vendor/libc/src/new/netbsd/utmpx_.rs b/vendor/libc/src/new/netbsd/utmpx_.rs new file mode 100644 index 0000000..7b07b0c --- /dev/null +++ b/vendor/libc/src/new/netbsd/utmpx_.rs @@ -0,0 +1,92 @@ +//! Header: `utmpx.h` +//! +//! + +use crate::prelude::*; + +// 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 _UTX_USERSIZE: usize = 32; +pub const _UTX_LINESIZE: usize = 32; +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; + +// Expression based on the comment in NetBSD source. +pub const _UTX_PADSIZE: usize = if cfg!(target_pointer_width = "64") { + 36 +} else { + 40 +}; + +s! { + 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: crate::pid_t, + pub ut_exit: __exit_status, // FIXME(netbsd): when anonymous struct are supported + pub ut_ss: crate::sockaddr_storage, + pub ut_tv: crate::timeval, + ut_pad: Padding<[u8; _UTX_PADSIZE]>, + } + + pub struct __exit_status { + pub e_termination: u16, + pub e_exit: u16, + } + + pub struct lastlogx { + pub ll_tv: crate::timeval, + pub ll_line: [c_char; _UTX_LINESIZE], + pub ll_host: [c_char; _UTX_HOSTSIZE], + pub ll_ss: crate::sockaddr_storage, + } +} + +#[link(name = "util")] +extern "C" { + pub fn setutxent(); + pub fn endutxent(); + + #[link_name = "__getutxent50"] + pub fn getutxent() -> *mut utmpx; + #[link_name = "__getutxid50"] + pub fn getutxid(ut: *const utmpx) -> *mut utmpx; + #[link_name = "__getutxline50"] + pub fn getutxline(ut: *const utmpx) -> *mut utmpx; + #[link_name = "__pututxline50"] + pub fn pututxline(ut: *const utmpx) -> *mut utmpx; + + #[link_name = "__updwtmpx50"] + pub fn updwtmpx(file: *const c_char, ut: *const utmpx) -> c_int; + #[link_name = "__getlastlogx50"] + pub fn getlastlogx(fname: *const c_char, uid: crate::uid_t, ll: *mut lastlogx) + -> *mut lastlogx; + + #[link_name = "__updlastlogx50"] + pub fn updlastlogx(fname: *const c_char, uid: crate::uid_t, ll: *mut lastlogx) -> c_int; + #[link_name = "__getutmp50"] + pub fn getutmp(ux: *const utmpx, u: *mut crate::utmp); + #[link_name = "__getutmpx50"] + pub fn getutmpx(u: *const crate::utmp, ux: *mut utmpx); + pub fn utmpxname(file: *const c_char) -> c_int; +} diff --git a/vendor/libc/src/new/newlib/mod.rs b/vendor/libc/src/new/newlib/mod.rs new file mode 100644 index 0000000..b5c7e3d --- /dev/null +++ b/vendor/libc/src/new/newlib/mod.rs @@ -0,0 +1,4 @@ +//! Newlib libc. +// FIXME(newlib): link to headers needed. + +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/newlib/unistd.rs b/vendor/libc/src/new/newlib/unistd.rs new file mode 100644 index 0000000..6b240be --- /dev/null +++ b/vendor/libc/src/new/newlib/unistd.rs @@ -0,0 +1,159 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; +use crate::prelude::*; + +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 = 5; +pub const _SC_SAVED_IDS: c_int = 6; +pub const _SC_VERSION: c_int = 7; +pub const _SC_PAGESIZE: c_int = 8; +pub const _SC_PAGE_SIZE: c_int = _SC_PAGESIZE; +pub const _SC_NPROCESSORS_CONF: c_int = 9; +pub const _SC_NPROCESSORS_ONLN: c_int = 10; +pub const _SC_PHYS_PAGES: c_int = 11; +pub const _SC_AVPHYS_PAGES: c_int = 12; +pub const _SC_MQ_OPEN_MAX: c_int = 13; +pub const _SC_MQ_PRIO_MAX: c_int = 14; +pub const _SC_RTSIG_MAX: c_int = 15; +pub const _SC_SEM_NSEMS_MAX: c_int = 16; +pub const _SC_SEM_VALUE_MAX: c_int = 17; +pub const _SC_SIGQUEUE_MAX: c_int = 18; +pub const _SC_TIMER_MAX: c_int = 19; +pub const _SC_TZNAME_MAX: c_int = 20; +pub const _SC_ASYNCHRONOUS_IO: c_int = 21; +pub const _SC_FSYNC: c_int = 22; +pub const _SC_MAPPED_FILES: c_int = 23; +pub const _SC_MEMLOCK: c_int = 24; +pub const _SC_MEMLOCK_RANGE: c_int = 25; +pub const _SC_MEMORY_PROTECTION: c_int = 26; +pub const _SC_MESSAGE_PASSING: c_int = 27; +pub const _SC_PRIORITIZED_IO: c_int = 28; +pub const _SC_REALTIME_SIGNALS: c_int = 29; +pub const _SC_SEMAPHORES: c_int = 30; +pub const _SC_SHARED_MEMORY_OBJECTS: c_int = 31; +pub const _SC_SYNCHRONIZED_IO: c_int = 32; +pub const _SC_TIMERS: c_int = 33; +pub const _SC_AIO_LISTIO_MAX: c_int = 34; +pub const _SC_AIO_MAX: c_int = 35; +pub const _SC_AIO_PRIO_DELTA_MAX: c_int = 36; +pub const _SC_DELAYTIMER_MAX: c_int = 37; +pub const _SC_THREAD_KEYS_MAX: c_int = 38; +pub const _SC_THREAD_STACK_MIN: c_int = 39; +pub const _SC_THREAD_THREADS_MAX: c_int = 40; +pub const _SC_TTY_NAME_MAX: c_int = 41; +pub const _SC_THREADS: c_int = 42; +pub const _SC_THREAD_ATTR_STACKADDR: c_int = 43; +pub const _SC_THREAD_ATTR_STACKSIZE: c_int = 44; +pub const _SC_THREAD_PRIORITY_SCHEDULING: c_int = 45; +pub const _SC_THREAD_PRIO_INHERIT: c_int = 46; +pub const _SC_THREAD_PRIO_PROTECT: c_int = 47; +pub const _SC_THREAD_PRIO_CEILING: c_int = _SC_THREAD_PRIO_PROTECT; +pub const _SC_THREAD_PROCESS_SHARED: c_int = 48; +pub const _SC_THREAD_SAFE_FUNCTIONS: c_int = 49; +pub const _SC_GETGR_R_SIZE_MAX: c_int = 50; +pub const _SC_GETPW_R_SIZE_MAX: c_int = 51; +pub const _SC_LOGIN_NAME_MAX: c_int = 52; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: c_int = 53; +pub const _SC_ADVISORY_INFO: c_int = 54; +pub const _SC_ATEXIT_MAX: c_int = 55; +pub const _SC_BARRIERS: c_int = 56; +pub const _SC_BC_BASE_MAX: c_int = 57; +pub const _SC_BC_DIM_MAX: c_int = 58; +pub const _SC_BC_SCALE_MAX: c_int = 59; +pub const _SC_BC_STRING_MAX: c_int = 60; +pub const _SC_CLOCK_SELECTION: c_int = 61; +pub const _SC_COLL_WEIGHTS_MAX: c_int = 62; +pub const _SC_CPUTIME: c_int = 63; +pub const _SC_EXPR_NEST_MAX: c_int = 64; +pub const _SC_HOST_NAME_MAX: c_int = 65; +pub const _SC_IOV_MAX: c_int = 66; +pub const _SC_IPV6: c_int = 67; +pub const _SC_LINE_MAX: c_int = 68; +pub const _SC_MONOTONIC_CLOCK: c_int = 69; +pub const _SC_RAW_SOCKETS: c_int = 70; +pub const _SC_READER_WRITER_LOCKS: c_int = 71; +pub const _SC_REGEXP: c_int = 72; +pub const _SC_RE_DUP_MAX: c_int = 73; +pub const _SC_SHELL: c_int = 74; +pub const _SC_SPAWN: c_int = 75; +pub const _SC_SPIN_LOCKS: c_int = 76; +pub const _SC_SPORADIC_SERVER: c_int = 77; +pub const _SC_SS_REPL_MAX: c_int = 78; +pub const _SC_SYMLOOP_MAX: c_int = 79; +pub const _SC_THREAD_CPUTIME: c_int = 80; +pub const _SC_THREAD_SPORADIC_SERVER: c_int = 81; +pub const _SC_TIMEOUTS: c_int = 82; +pub const _SC_TRACE: c_int = 83; +pub const _SC_TRACE_EVENT_FILTER: c_int = 84; +pub const _SC_TRACE_EVENT_NAME_MAX: c_int = 85; +pub const _SC_TRACE_INHERIT: c_int = 86; +pub const _SC_TRACE_LOG: c_int = 87; +pub const _SC_TRACE_NAME_MAX: c_int = 88; +pub const _SC_TRACE_SYS_MAX: c_int = 89; +pub const _SC_TRACE_USER_EVENT_MAX: c_int = 90; +pub const _SC_TYPED_MEMORY_OBJECTS: c_int = 91; +pub const _SC_V7_ILP32_OFF32: c_int = 92; +pub const _SC_V6_ILP32_OFF32: c_int = _SC_V7_ILP32_OFF32; +pub const _SC_XBS5_ILP32_OFF32: c_int = _SC_V7_ILP32_OFF32; +pub const _SC_V7_ILP32_OFFBIG: c_int = 93; +pub const _SC_V6_ILP32_OFFBIG: c_int = _SC_V7_ILP32_OFFBIG; +pub const _SC_XBS5_ILP32_OFFBIG: c_int = _SC_V7_ILP32_OFFBIG; +pub const _SC_V7_LP64_OFF64: c_int = 94; +pub const _SC_V6_LP64_OFF64: c_int = _SC_V7_LP64_OFF64; +pub const _SC_XBS5_LP64_OFF64: c_int = _SC_V7_LP64_OFF64; +pub const _SC_V7_LPBIG_OFFBIG: c_int = 95; +pub const _SC_V6_LPBIG_OFFBIG: c_int = _SC_V7_LPBIG_OFFBIG; +pub const _SC_XBS5_LPBIG_OFFBIG: c_int = _SC_V7_LPBIG_OFFBIG; +pub const _SC_XOPEN_CRYPT: c_int = 96; +pub const _SC_XOPEN_ENH_I18N: c_int = 97; +pub const _SC_XOPEN_LEGACY: c_int = 98; +pub const _SC_XOPEN_REALTIME: c_int = 99; +pub const _SC_STREAM_MAX: c_int = 100; +pub const _SC_PRIORITY_SCHEDULING: c_int = 101; +pub const _SC_XOPEN_REALTIME_THREADS: c_int = 102; +pub const _SC_XOPEN_SHM: c_int = 103; +pub const _SC_XOPEN_STREAMS: c_int = 104; +pub const _SC_XOPEN_UNIX: c_int = 105; +pub const _SC_XOPEN_VERSION: c_int = 106; +pub const _SC_2_CHAR_TERM: c_int = 107; +pub const _SC_2_C_BIND: c_int = 108; +pub const _SC_2_C_DEV: c_int = 109; +pub const _SC_2_FORT_DEV: c_int = 110; +pub const _SC_2_FORT_RUN: c_int = 111; +pub const _SC_2_LOCALEDEF: c_int = 112; +pub const _SC_2_PBS: c_int = 113; +pub const _SC_2_PBS_ACCOUNTING: c_int = 114; +pub const _SC_2_PBS_CHECKPOINT: c_int = 115; +pub const _SC_2_PBS_LOCATE: c_int = 116; +pub const _SC_2_PBS_MESSAGE: c_int = 117; +pub const _SC_2_PBS_TRACK: c_int = 118; +pub const _SC_2_SW_DEV: c_int = 119; +pub const _SC_2_UPE: c_int = 120; +pub const _SC_2_VERSION: c_int = 121; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: c_int = 122; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: c_int = 123; +pub const _SC_XOPEN_UUCP: c_int = 124; +pub const _SC_LEVEL1_ICACHE_SIZE: c_int = 125; +pub const _SC_LEVEL1_ICACHE_ASSOC: c_int = 126; +pub const _SC_LEVEL1_ICACHE_LINESIZE: c_int = 127; +pub const _SC_LEVEL1_DCACHE_SIZE: c_int = 128; +pub const _SC_LEVEL1_DCACHE_ASSOC: c_int = 129; +pub const _SC_LEVEL1_DCACHE_LINESIZE: c_int = 130; +pub const _SC_LEVEL2_CACHE_SIZE: c_int = 131; +pub const _SC_LEVEL2_CACHE_ASSOC: c_int = 132; +pub const _SC_LEVEL2_CACHE_LINESIZE: c_int = 133; +pub const _SC_LEVEL3_CACHE_SIZE: c_int = 134; +pub const _SC_LEVEL3_CACHE_ASSOC: c_int = 135; +pub const _SC_LEVEL3_CACHE_LINESIZE: c_int = 136; +pub const _SC_LEVEL4_CACHE_SIZE: c_int = 137; +pub const _SC_LEVEL4_CACHE_ASSOC: c_int = 138; +pub const _SC_LEVEL4_CACHE_LINESIZE: c_int = 139; diff --git a/vendor/libc/src/new/nto/mod.rs b/vendor/libc/src/new/nto/mod.rs new file mode 100644 index 0000000..a625127 --- /dev/null +++ b/vendor/libc/src/new/nto/mod.rs @@ -0,0 +1,9 @@ +//! QNX Neutrino libc. +// FIXME(nto): link to manpages needed. + +pub(crate) mod unistd; + +pub(crate) mod net { + pub(crate) mod bpf; + pub(crate) mod if_; +} diff --git a/vendor/libc/src/new/nto/net/bpf.rs b/vendor/libc/src/new/nto/net/bpf.rs new file mode 100644 index 0000000..6ee9f53 --- /dev/null +++ b/vendor/libc/src/new/nto/net/bpf.rs @@ -0,0 +1,83 @@ +use crate::bpf_insn; + +pub const BPF_LD: u16 = 0x00; +pub const BPF_LDX: u16 = 0x01; +pub const BPF_ST: u16 = 0x02; +pub const BPF_STX: u16 = 0x03; +pub const BPF_ALU: u16 = 0x04; +pub const BPF_JMP: u16 = 0x05; +pub const BPF_RET: u16 = 0x06; +pub const BPF_MISC: u16 = 0x07; +pub const BPF_W: u16 = 0x00; +pub const BPF_H: u16 = 0x08; +pub const BPF_B: u16 = 0x10; +pub const BPF_IMM: u16 = 0x00; +pub const BPF_ABS: u16 = 0x20; +pub const BPF_IND: u16 = 0x40; +pub const BPF_MEM: u16 = 0x60; +pub const BPF_LEN: u16 = 0x80; +pub const BPF_MSH: u16 = 0xa0; +pub const BPF_ADD: u16 = 0x00; +pub const BPF_SUB: u16 = 0x10; +pub const BPF_MUL: u16 = 0x20; +pub const BPF_DIV: u16 = 0x30; +pub const BPF_OR: u16 = 0x40; +pub const BPF_AND: u16 = 0x50; +pub const BPF_LSH: u16 = 0x60; +pub const BPF_RSH: u16 = 0x70; +pub const BPF_NEG: u16 = 0x80; +pub const BPF_MOD: u16 = 0x90; +pub const BPF_XOR: u16 = 0xa0; +pub const BPF_JA: u16 = 0x00; +pub const BPF_JEQ: u16 = 0x10; +pub const BPF_JGT: u16 = 0x20; +pub const BPF_JGE: u16 = 0x30; +pub const BPF_JSET: u16 = 0x40; +pub const BPF_K: u16 = 0x00; +pub const BPF_X: u16 = 0x08; +pub const BPF_A: u16 = 0x10; +pub const BPF_TAX: u16 = 0x00; +pub const BPF_TXA: u16 = 0x80; + +f! { + pub unsafe fn BPF_CLASS(code: u32) -> u32 { + code & 0x07 + } + + pub unsafe fn BPF_SIZE(code: u32) -> u32 { + code & 0x18 + } + + pub unsafe fn BPF_MODE(code: u32) -> u32 { + code & 0xe0 + } + + pub unsafe fn BPF_OP(code: u32) -> u32 { + code & 0xf0 + } + + pub unsafe fn BPF_SRC(code: u32) -> u32 { + code & 0x08 + } + + pub unsafe fn BPF_RVAL(code: u32) -> u32 { + code & 0x18 + } + + pub unsafe fn BPF_MISCOP(code: u32) -> u32 { + code & 0xf8 + } + + pub unsafe fn BPF_STMT(code: u16, k: u32) -> bpf_insn { + bpf_insn { + code, + jt: 0, + jf: 0, + k, + } + } + + pub unsafe fn BPF_JUMP(code: u16, k: u32, jt: u8, jf: u8) -> bpf_insn { + bpf_insn { code, jt, jf, k } + } +} diff --git a/vendor/libc/src/new/nto/net/if_.rs b/vendor/libc/src/new/nto/net/if_.rs new file mode 100644 index 0000000..d71c1bb --- /dev/null +++ b/vendor/libc/src/new/nto/net/if_.rs @@ -0,0 +1,32 @@ +use crate::prelude::*; + +s_no_extra_traits! { + pub union __c_anonymous_ifr_ifru { + pub ifru_addr: crate::sockaddr, + pub ifru_dstaddr: crate::sockaddr, + pub ifru_broadaddr: crate::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: *mut c_char, + 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; crate::IFNAMSIZ], + pub ifr_ifru: __c_anonymous_ifr_ifru, + } + + pub struct ifreq_buffer { + pub length: size_t, + pub buffer: *mut c_void, + } +} diff --git a/vendor/libc/src/new/nto/unistd.rs b/vendor/libc/src/new/nto/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/nto/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/nuttx/mod.rs b/vendor/libc/src/new/nuttx/mod.rs new file mode 100644 index 0000000..513c945 --- /dev/null +++ b/vendor/libc/src/new/nuttx/mod.rs @@ -0,0 +1,4 @@ +//! RTEMS libc. +// FIXME(nuttx): link to headers needed. + +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/nuttx/unistd.rs b/vendor/libc/src/new/nuttx/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/nuttx/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/openbsd/mod.rs b/vendor/libc/src/new/openbsd/mod.rs new file mode 100644 index 0000000..25fa784 --- /dev/null +++ b/vendor/libc/src/new/openbsd/mod.rs @@ -0,0 +1,7 @@ +//! OpenBSD libc. +//! +//! * Headers: +//! * Manual pages: + +pub(crate) mod sys; +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/openbsd/sys/ipc.rs b/vendor/libc/src/new/openbsd/sys/ipc.rs new file mode 100644 index 0000000..5977440 --- /dev/null +++ b/vendor/libc/src/new/openbsd/sys/ipc.rs @@ -0,0 +1,17 @@ +//! Header: `sys/ipc.h` +//! +//! + +use crate::prelude::*; + +s! { + pub struct ipc_perm { + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub mode: crate::mode_t, + pub seq: c_ushort, + pub key: crate::key_t, + } +} diff --git a/vendor/libc/src/new/openbsd/sys/mod.rs b/vendor/libc/src/new/openbsd/sys/mod.rs new file mode 100644 index 0000000..7ba77c5 --- /dev/null +++ b/vendor/libc/src/new/openbsd/sys/mod.rs @@ -0,0 +1,5 @@ +//! Directory: `sys/` +//! +//! https://github.com/openbsd/src/tree/trunk/sys/sys + +pub(crate) mod ipc; diff --git a/vendor/libc/src/new/openbsd/unistd.rs b/vendor/libc/src/new/openbsd/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/openbsd/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/qurt/dlfcn.rs b/vendor/libc/src/new/qurt/dlfcn.rs new file mode 100644 index 0000000..668fcab --- /dev/null +++ b/vendor/libc/src/new/qurt/dlfcn.rs @@ -0,0 +1,26 @@ +//! Header: `dlfcn.h` +//! +//! Dynamic linking functions and constants from Hexagon toolchain. + +use crate::prelude::*; + +// Values for dlopen `mode` +pub const RTLD_LAZY: c_int = 1; +pub const RTLD_NOW: c_int = 2; +pub const RTLD_GLOBAL: c_int = 0x100; +pub const RTLD_LOCAL: c_int = 0x200; + +// Compatibility constant +pub const DL_LAZY: c_int = RTLD_LAZY; + +// Special handles +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; + +extern "C" { + pub fn dlopen(filename: *const c_char, flag: c_int) -> *mut c_void; + pub fn dlclose(handle: *mut c_void) -> c_int; + pub fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void; + pub fn dlerror() -> *mut c_char; +} diff --git a/vendor/libc/src/new/qurt/errno.rs b/vendor/libc/src/new/qurt/errno.rs new file mode 100644 index 0000000..09db55c --- /dev/null +++ b/vendor/libc/src/new/qurt/errno.rs @@ -0,0 +1,154 @@ +//! Header: `errno.h` + +use super::*; +use crate::prelude::*; + +// Standard error codes - verified to match QuRT SDK +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 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; + +extern "C" { + // Error number access + #[link_name = "__errno_location"] + pub fn __errno_location() -> *mut c_int; +} + +pub unsafe fn errno() -> c_int { + *__errno_location() +} + +pub unsafe fn set_errno(value: c_int) { + *__errno_location() = value; +} diff --git a/vendor/libc/src/new/qurt/fcntl.rs b/vendor/libc/src/new/qurt/fcntl.rs new file mode 100644 index 0000000..615a712 --- /dev/null +++ b/vendor/libc/src/new/qurt/fcntl.rs @@ -0,0 +1,51 @@ +//! Header: `fcntl.h` + +use super::*; +use crate::prelude::*; + +// File access modes +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; + +// File creation flags +pub const O_CREAT: c_int = 0x0040; +pub const O_EXCL: c_int = 0x0080; +pub const O_NOCTTY: c_int = 0x0100; +pub const O_TRUNC: c_int = 0x0200; + +// File status flags +pub const O_APPEND: c_int = 0x0400; +pub const O_NONBLOCK: c_int = 0x0800; +pub const O_SYNC: c_int = 0x1000; +pub const O_FSYNC: c_int = O_SYNC; +pub const O_DSYNC: c_int = 0x1000; +pub const O_DIRECTORY: c_int = 0x10000; +pub const O_NOFOLLOW: c_int = 0x20000; +pub const O_CLOEXEC: c_int = 0x80000; + +// fcntl() commands +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_GETLK: c_int = 5; +pub const F_SETLK: c_int = 6; +pub const F_SETLKW: c_int = 7; +pub const F_DUPFD_CLOEXEC: c_int = 1030; + +// File descriptor flags +pub const FD_CLOEXEC: c_int = 1; + +// Lock types for fcntl() +pub const F_RDLCK: c_int = 0; +pub const F_WRLCK: c_int = 1; +pub const F_UNLCK: c_int = 2; + +// Functions +extern "C" { + pub fn open(pathname: *const c_char, flags: c_int, ...) -> c_int; + pub fn fcntl(fd: c_int, cmd: c_int, ...) -> c_int; +} diff --git a/vendor/libc/src/new/qurt/limits.rs b/vendor/libc/src/new/qurt/limits.rs new file mode 100644 index 0000000..8bf772c --- /dev/null +++ b/vendor/libc/src/new/qurt/limits.rs @@ -0,0 +1,53 @@ +//! Header: `limits.h` + +use super::*; +use crate::prelude::*; + +// Character properties +pub const CHAR_BIT: c_uint = 8; +pub const CHAR_MAX: c_char = 255; // unsigned char on Hexagon +pub const CHAR_MIN: c_char = 0; +pub const SCHAR_MAX: i8 = 127; +pub const SCHAR_MIN: i8 = -128; +pub const UCHAR_MAX: c_uchar = 255; + +// Integer properties +pub const INT_MAX: c_int = 2147483647; +pub const INT_MIN: c_int = -2147483647 - 1; +pub const UINT_MAX: c_uint = 4294967295; + +pub const LONG_MAX: c_long = 2147483647; +pub const LONG_MIN: c_long = -2147483647 - 1; +pub const ULONG_MAX: c_ulong = 4294967295; + +pub const SHRT_MAX: c_short = 32767; +pub const SHRT_MIN: c_short = -32768; +pub const USHRT_MAX: c_ushort = 65535; + +// POSIX Limits +pub const ARG_MAX: c_int = 4096; +pub const CHILD_MAX: c_int = 25; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const LINK_MAX: c_int = 8; + +pub const MAX_CANON: c_int = 255; +pub const MAX_INPUT: c_int = 255; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const NAME_MAX: c_int = 255; + +pub const OPEN_MAX: c_int = 20; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PATH_MAX: c_int = 260; + +pub const PIPE_BUF: c_int = 512; +pub const STREAM_MAX: c_int = 20; +pub const TZNAME_MAX: c_int = 50; + +// Additional limits +pub const IOV_MAX: c_int = 16; diff --git a/vendor/libc/src/new/qurt/mod.rs b/vendor/libc/src/new/qurt/mod.rs new file mode 100644 index 0000000..a557266 --- /dev/null +++ b/vendor/libc/src/new/qurt/mod.rs @@ -0,0 +1,337 @@ +//! QuRT (Qualcomm Real-Time OS) bindings +//! +//! QuRT is Qualcomm's real-time operating system for Hexagon DSP architectures. +//! Headers available via the +//! Hexagon SDK: https://softwarecenter.qualcomm.com/catalog/item/Hexagon_SDK + +use crate::prelude::*; + +// Basic C types for QuRT +pub type intptr_t = isize; +pub type uintptr_t = usize; +pub type ptrdiff_t = isize; +pub type size_t = uintptr_t; +pub type ssize_t = c_int; + +// Process and system types +pub type pid_t = c_int; +pub type uid_t = c_uint; +pub type gid_t = c_uint; + +// Time types +pub type time_t = c_long; +pub type suseconds_t = c_long; +pub type useconds_t = c_ulong; +pub type clockid_t = c_int; +pub type timer_t = *mut c_void; + +// File system types +pub type dev_t = c_ulonglong; +pub type ino_t = c_ulonglong; +pub type mode_t = c_uint; +pub type nlink_t = c_uint; +pub type off_t = c_long; +pub type blkcnt_t = c_long; +pub type blksize_t = c_long; + +// Thread types based on QuRT pthread implementation +pub type pthread_t = c_uint; +pub type pthread_key_t = c_int; +pub type pthread_once_t = c_int; +pub type pthread_mutex_t = c_uint; +// QuRT pthread_mutexattr_t is a struct with 4 ints (is_initialized, type, pshared, protocol) +pub type pthread_mutexattr_t = [c_uint; 4]; +pub type pthread_cond_t = c_uint; +// QuRT pthread_condattr_t is a struct with 3 ints (is_initialized, pshared, clock_id) +pub type pthread_condattr_t = [c_uint; 3]; +// pthread_attr_t is defined as a struct in the s! block below +pub type pthread_rwlock_t = *mut c_void; +pub type pthread_rwlockattr_t = *mut c_void; +pub type pthread_spinlock_t = c_uint; +pub type pthread_barrier_t = c_uint; +// QuRT pthread_barrierattr_t is a struct with 2 ints (is_initialized, pshared) +pub type pthread_barrierattr_t = [c_uint; 2]; + +// Network types +pub type socklen_t = c_uint; +pub type sa_family_t = c_ushort; +pub type in_addr_t = c_uint; +pub type in_port_t = c_ushort; + +// File descriptor types - QuRT defines fd_set as a struct in mqueue.h +// FD_SETSIZE = 256, NFDBITS = 32, so fds_bits has 8 elements + +// Standard C library types +extern_ty! { + pub type FILE; +} +pub type fpos_t = c_long; +pub type clock_t = c_long; + +// POSIX semaphore types - QuRT sem_t is a struct with an opaque pointer + +// Message queue types +pub type mqd_t = c_int; + +// Additional file system types +pub type nfds_t = c_ulong; + +// Signal types +pub type sigset_t = c_ulong; + +// Variadic argument list type +pub type va_list = *mut c_char; + +// Wide character type (hexagon uses signed wchar_t) +pub type wchar_t = i32; + +// Error type (compatible with std expectations) +pub type errno_t = c_int; + +// Division result types and structures +s! { + pub struct div_t { + pub quot: c_int, + pub rem: c_int, + } + + pub struct ldiv_t { + pub quot: c_long, + pub rem: c_long, + } + + pub struct lldiv_t { + pub quot: c_longlong, + pub rem: c_longlong, + } + + 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_rdev: dev_t, + pub st_size: off_t, + pub st_atime: time_t, + pub st_mtime: time_t, + pub st_ctime: time_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, + } + + #[derive(Default)] + pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: c_long, + } + + #[derive(Default)] + pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: suseconds_t, + } + + pub struct itimerspec { + pub it_interval: timespec, + pub it_value: timespec, + } + + pub struct dirent { + pub d_ino: c_long, + pub d_name: [c_char; 255], + } + + pub struct DIR { + pub index: c_int, + pub entry: dirent, + } + + // File lock structure (from toolchain generic fcntl.h) + 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, + } + + // QuRT fd_set from mqueue.h: FD_SETSIZE=256, NFDBITS=32 (sizeof(fd_mask)*8) + pub struct fd_set { + pub fds_bits: [c_ulong; 8], + } + + // QuRT sem_t from semaphore.h: struct with opaque pointer + pub struct sem_t { + pub opaque: *mut c_uint, + } + + // QuRT pthread_attr_t - matches pthread_types.h struct layout + pub struct pthread_attr_t { + pub stackaddr: *mut c_void, + pub internal_stack: c_int, + pub stacksize: size_t, + pub priority: c_int, + pub timetest_id: c_ushort, + __bitfield: c_ushort, + pub cpumask: cpu_set_t, + pub name: [c_char; 16], + pub ext_context: c_int, + pub detachstate: c_int, + } +} + +// Additional pthread constants +pub const PTHREAD_NAME_LEN: c_int = 16; +pub const PTHREAD_MAX_THREADS: c_uint = 512; +pub const PTHREAD_MIN_STACKSIZE: c_int = 512; +pub const PTHREAD_MAX_STACKSIZE: c_int = 1048576; +pub const PTHREAD_DEFAULT_STACKSIZE: c_int = 16384; +pub const PTHREAD_DEFAULT_PRIORITY: c_int = 1; +pub const PTHREAD_SPINLOCK_UNLOCKED: c_int = 0; +pub const PTHREAD_SPINLOCK_LOCKED: c_int = 1; + +// Additional time constants +pub const TIME_CONV_SCLK_FREQ: c_int = 19200000; +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; + +// Stdio constants +pub const L_tmpnam: c_uint = 260; +pub const TMP_MAX: c_uint = 25; +pub const FOPEN_MAX: c_uint = 20; + +// Error constants +pub const EOK: c_int = 0; + +// Semaphore constants +pub const SEM_FAILED: *mut sem_t = ptr::null_mut(); + +// fd_set constants from mqueue.h +pub const FD_SETSIZE: c_uint = 256; +pub const NFDBITS: c_uint = 32; + +// Page size constants (hexagon-specific) +pub const PAGESIZE: size_t = 4096; +pub const PAGE_SIZE: size_t = 4096; + +// Directory entry types (hexagon-specific) +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; + +// Directory functions (dirent.h) +extern "C" { + pub fn opendir(name: *const c_char) -> *mut DIR; + pub fn readdir(dirp: *mut DIR) -> *mut dirent; + pub fn closedir(dirp: *mut DIR) -> c_int; + pub fn mkdir(path: *const c_char, mode: mode_t) -> c_int; +} + +// Additional time functions +extern "C" { + pub fn clock_getcpuclockid(pid: pid_t, clock_id: *mut clockid_t) -> c_int; +} + +// POSIX semaphore functions +extern "C" { + pub fn sem_open(name: *const c_char, oflag: c_int, ...) -> *mut sem_t; + pub fn sem_close(sem: *mut sem_t) -> c_int; + pub fn sem_unlink(name: *const c_char) -> c_int; +} + +// Additional stdlib functions +extern "C" { + pub fn aligned_alloc(alignment: size_t, size: size_t) -> *mut c_void; +} + +// String functions (string.h) +extern "C" { + pub fn strlen(s: *const c_char) -> size_t; + pub fn strcpy(dest: *mut c_char, src: *const c_char) -> *mut c_char; + pub fn strncpy(dest: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char; + pub fn strcat(dest: *mut c_char, src: *const c_char) -> *mut c_char; + pub fn strncat(dest: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char; + pub fn strcmp(s1: *const c_char, s2: *const c_char) -> c_int; + pub fn strncmp(s1: *const c_char, s2: *const c_char, n: size_t) -> c_int; + pub fn strcoll(s1: *const c_char, s2: *const c_char) -> c_int; + pub fn strxfrm(dest: *mut c_char, src: *const c_char, n: size_t) -> size_t; + pub fn strchr(s: *const c_char, c: c_int) -> *mut c_char; + pub fn strrchr(s: *const c_char, c: c_int) -> *mut c_char; + pub fn strspn(s: *const c_char, accept: *const c_char) -> size_t; + pub fn strcspn(s: *const c_char, reject: *const c_char) -> size_t; + pub fn strpbrk(s: *const c_char, accept: *const c_char) -> *mut c_char; + pub fn strstr(haystack: *const c_char, needle: *const c_char) -> *mut c_char; + pub fn strtok(s: *mut c_char, delim: *const c_char) -> *mut c_char; + pub fn strerror(errnum: c_int) -> *mut c_char; + pub fn memchr(s: *const c_void, c: c_int, n: size_t) -> *mut c_void; + pub fn memcmp(s1: *const c_void, s2: *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(s: *mut c_void, c: c_int, n: size_t) -> *mut c_void; +} + +// Character classification functions (ctype.h) +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 tolower(c: c_int) -> c_int; + pub fn toupper(c: c_int) -> c_int; +} + +pub(crate) mod dlfcn; +pub(crate) mod errno; +pub(crate) mod fcntl; +pub(crate) mod limits; +pub(crate) mod mqueue; +pub(crate) mod pthread; +pub(crate) mod semaphore; +pub(crate) mod signal; +pub(crate) mod stdio; +pub(crate) mod stdlib; +pub(crate) mod sys; +pub(crate) mod time; +pub(crate) mod unistd; + +// Re-export public items from submodules +pub use dlfcn::*; +pub use errno::*; +pub use fcntl::*; +pub use limits::*; +pub use mqueue::*; +pub use pthread::*; +pub use semaphore::*; +pub use signal::*; +pub use stdio::*; +pub use stdlib::*; +pub use sys::mman::*; +pub use sys::sched::*; +pub use sys::stat::*; +pub use sys::types::*; +pub use time::*; +pub use unistd::*; diff --git a/vendor/libc/src/new/qurt/mqueue.rs b/vendor/libc/src/new/qurt/mqueue.rs new file mode 100644 index 0000000..88ecef5 --- /dev/null +++ b/vendor/libc/src/new/qurt/mqueue.rs @@ -0,0 +1,74 @@ +//! Header: `mqueue.h` +//! +//! QuRT POSIX message queue API. Also provides select/pselect and fd_set +//! operations since these are declared in QuRT's mqueue.h. + +use super::*; +use crate::prelude::*; + +// Message queue priority constants +pub const MQ_PRIO_DEFAULT: c_int = 0; + +// Bits per byte +pub const NBBY: c_uint = 8; + +s! { + pub struct mq_attr { + pub mq_flags: c_long, + pub mq_maxmsg: c_long, + pub mq_msgsize: c_long, + pub mq_curmsgs: c_long, + } +} + +extern "C" { + // Message queue operations + pub fn mq_open(name: *const c_char, oflag: c_int, ...) -> mqd_t; + pub fn mq_close(mq_desc: mqd_t) -> c_int; + pub fn mq_unlink(name: *const c_char) -> c_int; + 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_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_receive( + mqdes: mqd_t, + msg_ptr: *mut c_char, + msg_len: size_t, + msg_prio: *mut c_uint, + ) -> ssize_t; + 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_getattr(mqdes: mqd_t, mqstat: *mut mq_attr) -> c_int; + pub fn mq_setattr(mqdes: mqd_t, mqstat: *const mq_attr, omqstat: *mut mq_attr) -> c_int; + + // select/pselect (declared in QuRT mqueue.h) + 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 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; +} diff --git a/vendor/libc/src/new/qurt/pthread.rs b/vendor/libc/src/new/qurt/pthread.rs new file mode 100644 index 0000000..80ae47f --- /dev/null +++ b/vendor/libc/src/new/qurt/pthread.rs @@ -0,0 +1,275 @@ +//! Header: `pthread.h` +//! +//! QuRT provides a subset of POSIX pthread functionality optimized for real-time systems. + +use super::*; +use crate::prelude::*; + +// Thread creation attributes (QuRT values differ from POSIX/Linux defaults) +pub const PTHREAD_CREATE_DETACHED: c_int = 0; +pub const PTHREAD_CREATE_JOINABLE: c_int = 1; + +// Mutex types (QuRT values differ from POSIX/Linux defaults) +pub const PTHREAD_MUTEX_ERRORCHECK: c_int = 0; +pub const PTHREAD_MUTEX_NORMAL: c_int = 1; +pub const PTHREAD_MUTEX_RECURSIVE: c_int = 2; +pub const PTHREAD_MUTEX_DEFAULT: c_int = 3; + +// Process sharing +pub const PTHREAD_PROCESS_PRIVATE: c_int = 0; +pub const PTHREAD_PROCESS_SHARED: c_int = 1; + +// Mutex protocol +pub const PTHREAD_PRIO_NONE: c_int = 0; +pub const PTHREAD_PRIO_INHERIT: c_int = 1; +pub const PTHREAD_PRIO_PROTECT: c_int = 2; + +// Thread priority constants +pub const PTHREAD_MIN_PRIORITY: c_int = 0; +pub const PTHREAD_MAX_PRIORITY: c_int = 255; + +// Initializer constants +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = 0xFFFFFFFF; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = 0xFFFFFFFF; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = !0usize as pthread_rwlock_t; +pub const PTHREAD_ONCE_INIT: pthread_once_t = 0; + +// Stack size +pub const PTHREAD_STACK_MIN: size_t = 8192; + +// Contention scope +pub const PTHREAD_SCOPE_SYSTEM: c_int = 0; +pub const PTHREAD_SCOPE_PROCESS: c_int = 1; + +// Scheduler inheritance (QuRT values differ from POSIX/Linux defaults) +pub const PTHREAD_EXPLICIT_SCHED: c_int = 0; +pub const PTHREAD_INHERIT_SCHED: c_int = 1; + +extern "C" { + // Thread management + 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, + ) -> c_int; + pub fn pthread_join(thread: pthread_t, retval: *mut *mut c_void) -> c_int; + pub fn pthread_detach(thread: pthread_t) -> c_int; + pub fn pthread_exit(retval: *mut c_void) -> !; + pub fn pthread_self() -> pthread_t; + // Note: pthread_equal is static inline in QuRT pthread.h, no linkable symbol + pub fn pthread_cancel(thread: pthread_t) -> c_int; + pub fn pthread_kill(thread: pthread_t, sig: c_int) -> c_int; + pub fn pthread_setcancelstate(state: c_int, oldstate: *mut c_int) -> c_int; + pub fn pthread_setcanceltype(r#type: c_int, oldtype: *mut c_int) -> c_int; + + // Thread scheduling + 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; + pub fn pthread_setschedprio(thread: pthread_t, prio: c_int) -> c_int; + + // Thread attributes + 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_setstacksize(attr: *mut pthread_attr_t, stacksize: size_t) -> c_int; + pub fn pthread_attr_getstacksize(attr: *const pthread_attr_t, stacksize: *mut size_t) -> c_int; + pub fn pthread_attr_setstackaddr(attr: *mut pthread_attr_t, stackaddr: *mut c_void) -> 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_getstack( + attr: *const pthread_attr_t, + stackaddr: *mut *mut c_void, + stacksize: *mut size_t, + ) -> c_int; + pub fn pthread_attr_setdetachstate(attr: *mut pthread_attr_t, detachstate: c_int) -> c_int; + pub fn pthread_attr_getdetachstate( + attr: *const pthread_attr_t, + detachstate: *mut c_int, + ) -> c_int; + pub fn pthread_attr_setscope(attr: *mut pthread_attr_t, scope: c_int) -> c_int; + pub fn pthread_attr_getscope(attr: *const pthread_attr_t, scope: *mut c_int) -> c_int; + pub fn pthread_attr_setinheritsched(attr: *mut pthread_attr_t, inheritsched: c_int) -> c_int; + pub fn pthread_attr_getinheritsched( + attr: *const pthread_attr_t, + inheritsched: *mut c_int, + ) -> c_int; + pub fn pthread_attr_setschedparam( + attr: *mut pthread_attr_t, + param: *const sched_param, + ) -> c_int; + pub fn pthread_attr_getschedparam( + attr: *const pthread_attr_t, + param: *mut sched_param, + ) -> c_int; + pub fn pthread_attr_getguardsize(attr: *const pthread_attr_t, guardsize: *mut size_t) -> c_int; + + // Mutex operations + pub fn pthread_mutex_init( + mutex: *mut pthread_mutex_t, + attr: *const pthread_mutexattr_t, + ) -> c_int; + pub fn pthread_mutex_destroy(mutex: *mut pthread_mutex_t) -> c_int; + pub fn pthread_mutex_lock(mutex: *mut pthread_mutex_t) -> c_int; + pub fn pthread_mutex_trylock(mutex: *mut pthread_mutex_t) -> c_int; + pub fn pthread_mutex_unlock(mutex: *mut pthread_mutex_t) -> c_int; + pub fn pthread_mutex_getprioceiling( + mutex: *const pthread_mutex_t, + prioceiling: *mut c_int, + ) -> c_int; + pub fn pthread_mutex_setprioceiling( + mutex: *mut pthread_mutex_t, + prioceiling: c_int, + old_ceiling: *mut c_int, + ) -> c_int; + + // Mutex attributes + 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, kind: c_int) -> c_int; + pub fn pthread_mutexattr_gettype(attr: *const pthread_mutexattr_t, kind: *mut c_int) -> c_int; + pub fn pthread_mutexattr_setprotocol(attr: *mut pthread_mutexattr_t, protocol: c_int) -> c_int; + pub fn pthread_mutexattr_getprotocol( + attr: *const pthread_mutexattr_t, + protocol: *mut c_int, + ) -> 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_mutexattr_setprioceiling( + attr: *mut pthread_mutexattr_t, + prioceiling: c_int, + ) -> c_int; + pub fn pthread_mutexattr_getprioceiling( + attr: *const pthread_mutexattr_t, + prioceiling: *mut c_int, + ) -> c_int; + + // Condition variables + pub fn pthread_cond_init(cond: *mut pthread_cond_t, attr: *const pthread_condattr_t) -> c_int; + pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> c_int; + pub fn pthread_cond_wait(cond: *mut pthread_cond_t, mutex: *mut pthread_mutex_t) -> c_int; + pub fn pthread_cond_timedwait( + cond: *mut pthread_cond_t, + mutex: *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; + + // Condition variable attributes + 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_condattr_setclock(attr: *mut pthread_condattr_t, clock_id: clockid_t) -> c_int; + pub fn pthread_condattr_getclock( + attr: *const pthread_condattr_t, + clock_id: *mut clockid_t, + ) -> c_int; + 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; + + // Spinlocks + 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; + + // Barriers + 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_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; + + // Read-write locks + pub fn pthread_rwlock_init( + rwlock: *mut pthread_rwlock_t, + attr: *const pthread_rwlockattr_t, + ) -> c_int; + pub fn pthread_rwlock_destroy(rwlock: *mut pthread_rwlock_t) -> c_int; + pub fn pthread_rwlock_rdlock(rwlock: *mut pthread_rwlock_t) -> c_int; + pub fn pthread_rwlock_tryrdlock(rwlock: *mut pthread_rwlock_t) -> c_int; + pub fn pthread_rwlock_wrlock(rwlock: *mut pthread_rwlock_t) -> c_int; + pub fn pthread_rwlock_trywrlock(rwlock: *mut pthread_rwlock_t) -> c_int; + pub fn pthread_rwlock_unlock(rwlock: *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_rwlockattr_getpshared( + attr: *const pthread_rwlockattr_t, + pshared: *mut c_int, + ) -> c_int; + pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t, pshared: c_int) -> c_int; + + // Thread-local storage + pub fn pthread_key_create( + key: *mut pthread_key_t, + destructor: 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; + + // One-time initialization + pub fn pthread_once(once_control: *mut pthread_once_t, init_routine: extern "C" fn()) -> c_int; + + // GNU/QuRT non-portable extensions + pub fn pthread_getname_np(thread: pthread_t, name: *mut c_char, len: size_t) -> c_int; + pub fn pthread_getattr_np(thread: pthread_t, attr: *mut pthread_attr_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 pthread_attr_getaffinity_np( + attr: *mut pthread_attr_t, + cpusetsize: size_t, + cpuset: *mut cpu_set_t, + ) -> c_int; + + // QuRT-specific thread attribute extensions + pub fn pthread_attr_setthreadname(attr: *mut pthread_attr_t, name: *const c_char) -> c_int; + pub fn pthread_attr_getthreadname( + attr: *const pthread_attr_t, + name: *mut c_char, + size: c_int, + ) -> c_int; + pub fn pthread_attr_settimetestid(attr: *mut pthread_attr_t, tid: c_uint) -> c_int; + pub fn pthread_attr_gettimetestid(attr: *const pthread_attr_t, tid: *mut c_uint) -> c_int; + pub fn pthread_attr_setautostack(attr: *mut pthread_attr_t) -> c_int; + pub fn pthread_attr_setbuspriority(attr: *mut pthread_attr_t, bus_priority: c_ushort) -> c_int; + + // POSIX standard (declared in QuRT pthread.h) + pub fn posix_memalign(memptr: *mut *mut c_void, alignment: size_t, size: size_t) -> c_int; +} diff --git a/vendor/libc/src/new/qurt/semaphore.rs b/vendor/libc/src/new/qurt/semaphore.rs new file mode 100644 index 0000000..86b3743 --- /dev/null +++ b/vendor/libc/src/new/qurt/semaphore.rs @@ -0,0 +1,13 @@ +//! Header: `semaphore.h` + +use super::*; +use crate::prelude::*; + +extern "C" { + 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_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_getvalue(sem: *mut sem_t, sval: *mut c_int) -> c_int; +} diff --git a/vendor/libc/src/new/qurt/signal.rs b/vendor/libc/src/new/qurt/signal.rs new file mode 100644 index 0000000..63e7251 --- /dev/null +++ b/vendor/libc/src/new/qurt/signal.rs @@ -0,0 +1,119 @@ +//! Header: `signal.h` + +use super::*; +use crate::prelude::*; + +// Signal numbers from toolchain signal.h (non-_LINUX_C_LIB_H_ path) +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 = 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 SIGPROF: c_int = 27; +pub const SIGWINCH: c_int = 28; +pub const SIGPOLL: c_int = 29; +pub const SIGIO: c_int = 29; +pub const SIGPWR: c_int = 30; +pub const SIGSYS: c_int = 31; + +// Signal handling constants +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; + +// Signal mask operations (QuRT uses different values than Linux) +pub const SIG_BLOCK: c_int = 1; +pub const SIG_UNBLOCK: c_int = 2; +pub const SIG_SETMASK: c_int = 3; + +// QuRT-specific signal constants +pub const POSIX_MSG: c_int = 7; +pub const POSIX_NOTIF: c_int = 8; +pub const SIGRTMIN: c_int = 10; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const SIGRTMAX: c_int = 32; + +// Notification types (from QuRT signal.h) +pub const SIGEV_NONE: c_int = 0; +pub const SIGEV_SIGNAL: c_int = 1; +pub const SIGEV_THREAD: c_int = 2; +pub const SA_SIGINFO: c_int = 1; + +pub type sighandler_t = size_t; + +// Signal structures based on QuRT SDK headers + +// sigval is a union in C (4 bytes on 32-bit hexagon) +s_no_extra_traits! { + pub union sigval { + pub sival_int: c_int, + pub sival_ptr: *mut c_void, + } +} + +s! { + pub struct sigevent { + pub sigev_notify: c_int, + pub sigev_signo: c_int, + pub sigev_value: sigval, + pub sigev_notify_function: Option, + pub sigev_notify_attributes: *mut pthread_attr_t, + } + + pub struct siginfo_t { + pub si_signo: c_int, + pub si_code: c_int, + pub si_value: sigval, + } + + pub struct sigaction { + pub sa_handler: Option, + pub sa_mask: sigset_t, + pub sa_flags: c_int, + pub sa_sigaction: Option, + } +} + +extern "C" { + // From generic signal.h (toolchain) + pub fn signal(sig: c_int, handler: sighandler_t) -> sighandler_t; + pub fn raise(sig: c_int) -> c_int; + + // QuRT POSIX signal functions + pub fn sigemptyset(set: *mut sigset_t) -> c_int; + pub fn sigfillset(set: *mut sigset_t) -> c_int; + pub fn sigaddset(set: *mut sigset_t, signum: c_int) -> 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 sigsuspend(mask: *const sigset_t) -> c_int; + pub fn sigwait(set: *const sigset_t, sig: *mut c_int) -> c_int; + pub fn _sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int; + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const timespec, + ) -> c_int; +} diff --git a/vendor/libc/src/new/qurt/stdio.rs b/vendor/libc/src/new/qurt/stdio.rs new file mode 100644 index 0000000..7130717 --- /dev/null +++ b/vendor/libc/src/new/qurt/stdio.rs @@ -0,0 +1,73 @@ +//! Header: `stdio.h` + +use super::*; +use crate::prelude::*; + +// Buffer size +pub const BUFSIZ: c_uint = 1024; +pub const FILENAME_MAX: c_uint = 260; + +// End of file +pub const EOF: c_int = -1; + +extern "C" { + // File operations + pub fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE; + pub fn freopen(filename: *const c_char, mode: *const c_char, stream: *mut FILE) -> *mut FILE; + pub fn fclose(stream: *mut FILE) -> c_int; + pub fn fflush(stream: *mut FILE) -> c_int; + pub fn fread(ptr: *mut c_void, size: size_t, nmemb: size_t, stream: *mut FILE) -> size_t; + pub fn fwrite(ptr: *const c_void, size: size_t, nmemb: size_t, stream: *mut FILE) -> size_t; + + // Character I/O + pub fn fgetc(stream: *mut FILE) -> c_int; + pub fn fputc(c: c_int, stream: *mut FILE) -> c_int; + pub fn getchar() -> c_int; + pub fn putchar(c: c_int) -> c_int; + pub fn ungetc(c: c_int, stream: *mut FILE) -> c_int; + + // Line I/O + pub fn fgets(s: *mut c_char, size: c_int, stream: *mut FILE) -> *mut c_char; + pub fn fputs(s: *const c_char, stream: *mut FILE) -> c_int; + pub fn gets(s: *mut c_char) -> *mut c_char; + pub fn puts(s: *const c_char) -> c_int; + + // Formatted I/O + pub fn printf(format: *const c_char, ...) -> c_int; + pub fn fprintf(stream: *mut FILE, format: *const c_char, ...) -> c_int; + pub fn sprintf(s: *mut c_char, format: *const c_char, ...) -> c_int; + pub fn snprintf(s: *mut c_char, n: size_t, format: *const c_char, ...) -> c_int; + pub fn vprintf(format: *const c_char, ap: crate::va_list) -> c_int; + pub fn vfprintf(stream: *mut FILE, format: *const c_char, ap: crate::va_list) -> c_int; + pub fn vsprintf(s: *mut c_char, format: *const c_char, ap: crate::va_list) -> c_int; + pub fn vsnprintf(s: *mut c_char, n: size_t, format: *const c_char, ap: crate::va_list) + -> c_int; + + // Input formatted functions + pub fn scanf(format: *const c_char, ...) -> c_int; + pub fn fscanf(stream: *mut FILE, format: *const c_char, ...) -> c_int; + pub fn sscanf(s: *const c_char, format: *const c_char, ...) -> c_int; + + // File positioning + 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, pos: *mut fpos_t) -> c_int; + pub fn fsetpos(stream: *mut FILE, pos: *const fpos_t) -> c_int; + + // Error handling + pub fn clearerr(stream: *mut FILE); + pub fn feof(stream: *mut FILE) -> c_int; + pub fn ferror(stream: *mut FILE) -> c_int; + pub fn perror(s: *const c_char); + + // File management + pub fn remove(filename: *const c_char) -> c_int; + pub fn rename(old: *const c_char, new: *const c_char) -> c_int; + pub fn tmpfile() -> *mut FILE; + pub fn tmpnam(s: *mut c_char) -> *mut c_char; + + // Buffer control + pub fn setvbuf(stream: *mut FILE, buffer: *mut c_char, mode: c_int, size: size_t) -> c_int; + pub fn setbuf(stream: *mut FILE, buffer: *mut c_char); +} diff --git a/vendor/libc/src/new/qurt/stdlib.rs b/vendor/libc/src/new/qurt/stdlib.rs new file mode 100644 index 0000000..dc96e36 --- /dev/null +++ b/vendor/libc/src/new/qurt/stdlib.rs @@ -0,0 +1,67 @@ +//! Header: `stdlib.h` + +use super::*; +use crate::prelude::*; + +// Exit status constants +pub const EXIT_SUCCESS: c_int = 0; +pub const EXIT_FAILURE: c_int = 1; + +// Maximum values +pub const RAND_MAX: c_int = 32767; + +extern "C" { + // Memory management + pub fn malloc(size: size_t) -> *mut c_void; + pub fn calloc(nmemb: size_t, size: size_t) -> *mut c_void; + pub fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void; + pub fn free(ptr: *mut c_void); + + // Process control + pub fn abort() -> !; + pub fn exit(status: c_int) -> !; + pub fn atexit(function: extern "C" fn()) -> c_int; + + // Environment + pub fn getenv(name: *const c_char) -> *mut c_char; + pub fn setenv(name: *const c_char, value: *const c_char, overwrite: c_int) -> c_int; + pub fn unsetenv(name: *const c_char) -> c_int; + + // String/number conversion + pub fn atoi(nptr: *const c_char) -> c_int; + pub fn atol(nptr: *const c_char) -> c_long; + pub fn atoll(nptr: *const c_char) -> c_longlong; + pub fn strtol(nptr: *const c_char, endptr: *mut *mut c_char, base: c_int) -> c_long; + pub fn strtoul(nptr: *const c_char, endptr: *mut *mut c_char, base: c_int) -> c_ulong; + pub fn strtoll(nptr: *const c_char, endptr: *mut *mut c_char, base: c_int) -> c_longlong; + pub fn strtoull(nptr: *const c_char, endptr: *mut *mut c_char, base: c_int) -> c_ulonglong; + pub fn strtod(nptr: *const c_char, endptr: *mut *mut c_char) -> c_double; + pub fn strtof(nptr: *const c_char, endptr: *mut *mut c_char) -> c_float; + + // Random numbers + pub fn rand() -> c_int; + pub fn srand(seed: c_uint); + + // Searching and sorting + pub fn qsort( + base: *mut c_void, + nmemb: size_t, + size: size_t, + compar: extern "C" fn(*const c_void, *const c_void) -> c_int, + ); + pub fn bsearch( + key: *const c_void, + base: *const c_void, + nmemb: size_t, + size: size_t, + compar: extern "C" fn(*const c_void, *const c_void) -> c_int, + ) -> *mut c_void; + + // Integer arithmetic + pub fn abs(j: c_int) -> c_int; + pub fn labs(j: c_long) -> c_long; + pub fn llabs(j: c_longlong) -> c_longlong; + pub fn div(numer: c_int, denom: c_int) -> div_t; + pub fn ldiv(numer: c_long, denom: c_long) -> ldiv_t; + pub fn lldiv(numer: c_longlong, denom: c_longlong) -> lldiv_t; +} diff --git a/vendor/libc/src/new/qurt/sys/mman.rs b/vendor/libc/src/new/qurt/sys/mman.rs new file mode 100644 index 0000000..a0a3b3a --- /dev/null +++ b/vendor/libc/src/new/qurt/sys/mman.rs @@ -0,0 +1,55 @@ +//! Header: `sys/mman.h` +//! +//! Memory mapping functions and constants from Hexagon toolchain. + +use super::super::*; +use crate::prelude::*; + +// Memory protection constants +pub const PROT_NONE: c_int = 0x00; +pub const PROT_READ: c_int = 0x01; +pub const PROT_WRITE: c_int = 0x02; +pub const PROT_EXEC: c_int = 0x04; + +// Memory mapping constants +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_FILE: c_int = 0x0000; +pub const MAP_RENAME: c_int = 0x0020; +pub const MAP_NORESERVE: c_int = 0x0040; +pub const MAP_INHERIT: c_int = 0x0080; +pub const MAP_HASSEMAPHORE: c_int = 0x0200; +pub const MAP_TRYFIXED: c_int = 0x0400; +pub const MAP_WIRED: c_int = 0x0800; + +pub const MAP_FAILED: *mut c_void = !0 as *mut c_void; + +// Memory sync constants +pub const MS_ASYNC: c_int = 0x01; +pub const MS_INVALIDATE: c_int = 0x02; +pub const MS_SYNC: c_int = 0x04; + +// Memory lock constants +pub const MCL_CURRENT: c_int = 0x01; +pub const MCL_FUTURE: c_int = 0x02; + +extern "C" { + 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 mprotect(addr: *mut c_void, len: size_t, prot: 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 msync(addr: *mut c_void, len: size_t, flags: c_int) -> c_int; +} diff --git a/vendor/libc/src/new/qurt/sys/mod.rs b/vendor/libc/src/new/qurt/sys/mod.rs new file mode 100644 index 0000000..f9ef6a4 --- /dev/null +++ b/vendor/libc/src/new/qurt/sys/mod.rs @@ -0,0 +1,6 @@ +//! System headers (`sys/*`) + +pub(crate) mod mman; +pub(crate) mod sched; +pub(crate) mod stat; +pub(crate) mod types; diff --git a/vendor/libc/src/new/qurt/sys/sched.rs b/vendor/libc/src/new/qurt/sys/sched.rs new file mode 100644 index 0000000..d56a4bc --- /dev/null +++ b/vendor/libc/src/new/qurt/sys/sched.rs @@ -0,0 +1,27 @@ +//! Header: `sys/sched.h` +//! +//! QuRT scheduling parameters and functions. + +use crate::prelude::*; + +// Scheduling policies (from QuRT sys/sched.h) +pub const SCHED_FIFO: c_int = 0; +pub const SCHED_RR: c_int = 1; +pub const SCHED_SPORADIC: c_int = 2; +pub const SCHED_OTHER: c_int = 3; + +s! { + pub struct sched_param { + pub unimplemented: *mut c_void, + pub sched_priority: c_int, + } +} + +extern "C" { + // Note: sched_yield is static inline in QuRT sys/sched.h, so there is no + // linkable symbol in the SDK libraries. Programs must provide their own + // implementation or use --defsym=sched_yield=abort at link time. + pub fn sched_yield() -> c_int; + pub fn sched_get_priority_max(policy: c_int) -> c_int; + pub fn sched_get_priority_min(policy: c_int) -> c_int; +} diff --git a/vendor/libc/src/new/qurt/sys/stat.rs b/vendor/libc/src/new/qurt/sys/stat.rs new file mode 100644 index 0000000..a8ee211 --- /dev/null +++ b/vendor/libc/src/new/qurt/sys/stat.rs @@ -0,0 +1,36 @@ +//! Header: `sys/stat.h` + +use super::super::*; +use crate::prelude::*; + +// File type constants for stat.st_mode +pub const S_IFMT: mode_t = 0o170000; +pub const S_IFSOCK: mode_t = 0o140000; +pub const S_IFLNK: mode_t = 0o120000; +pub const S_IFREG: mode_t = 0o100000; +pub const S_IFBLK: mode_t = 0o060000; +pub const S_IFDIR: mode_t = 0o040000; +pub const S_IFCHR: mode_t = 0o020000; +pub const S_IFIFO: mode_t = 0o010000; + +// File permission constants +pub const S_ISUID: mode_t = 0o4000; +pub const S_ISGID: mode_t = 0o2000; +pub const S_ISVTX: mode_t = 0o1000; +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; + +extern "C" { + pub fn stat(pathname: *const c_char, statbuf: *mut stat) -> c_int; + pub fn fstat(fd: c_int, statbuf: *mut stat) -> c_int; +} diff --git a/vendor/libc/src/new/qurt/sys/types.rs b/vendor/libc/src/new/qurt/sys/types.rs new file mode 100644 index 0000000..a5db516 --- /dev/null +++ b/vendor/libc/src/new/qurt/sys/types.rs @@ -0,0 +1,9 @@ +//! Header: `sys/types.h` +//! +//! Note: Basic types are defined at the crate root level for qurt. +//! This module provides sys/types.h specific functions and constants. + +use super::super::*; +use crate::prelude::*; + +pub type cpu_set_t = c_uint; diff --git a/vendor/libc/src/new/qurt/time.rs b/vendor/libc/src/new/qurt/time.rs new file mode 100644 index 0000000..732297e --- /dev/null +++ b/vendor/libc/src/new/qurt/time.rs @@ -0,0 +1,45 @@ +//! Header: `time.h` + +use super::*; +use crate::prelude::*; + +// Clock types +pub const CLOCK_REALTIME: clockid_t = 0; +pub const CLOCK_MONOTONIC: clockid_t = 1; +pub const CLOCK_THREAD_CPUTIME_ID: clockid_t = 2; +pub const CLOCK_PROCESS_CPUTIME_ID: clockid_t = 3; + +extern "C" { + pub fn time(tloc: *mut time_t) -> time_t; + pub fn clock() -> clock_t; + pub fn difftime(time1: time_t, time0: time_t) -> c_double; + pub fn mktime(tm: *mut tm) -> time_t; + pub fn gmtime(timep: *const time_t) -> *mut tm; + pub fn gmtime_r(timep: *const time_t, result: *mut tm) -> *mut tm; + pub fn localtime(timep: *const time_t) -> *mut tm; + pub fn localtime_r(timep: *const time_t, result: *mut tm) -> *mut tm; + pub fn asctime(tm: *const tm) -> *mut c_char; + pub fn asctime_r(tm: *const tm, buf: *mut c_char) -> *mut c_char; + pub fn ctime(timep: *const time_t) -> *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, + maxsize: size_t, + format: *const c_char, + timeptr: *const tm, + ) -> size_t; + pub fn strptime(s: *const c_char, format: *const c_char, tm: *mut tm) -> *mut c_char; + pub fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int; + pub fn nanosleep(req: *const timespec, rem: *mut timespec) -> c_int; + + // POSIX timer functions (from QuRT time.h) + pub fn timer_create(clockid: clockid_t, evp: *mut sigevent, timerid: *mut timer_t) -> c_int; + pub fn timer_delete(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; +} diff --git a/vendor/libc/src/new/qurt/unistd.rs b/vendor/libc/src/new/qurt/unistd.rs new file mode 100644 index 0000000..654d02a --- /dev/null +++ b/vendor/libc/src/new/qurt/unistd.rs @@ -0,0 +1,264 @@ +//! Header: `unistd.h` + +use super::*; +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; +use crate::prelude::*; + +// Access mode constants +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; + +// Whence constants for lseek +pub const SEEK_SET: c_int = 0; +pub const SEEK_CUR: c_int = 1; +pub const SEEK_END: c_int = 2; + +// pathconf constants (from bits/confname.h) +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; + +// sysconf constants (from bits/confname.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_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_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 = _SC_UIO_MAXIOV; +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_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_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; + +extern "C" { + // File operations + pub fn access(pathname: *const c_char, mode: c_int) -> c_int; + pub fn close(fd: c_int) -> c_int; + pub fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t; + pub fn read(fd: c_int, buf: *mut c_void, count: size_t) -> ssize_t; + pub fn write(fd: c_int, buf: *const c_void, count: size_t) -> ssize_t; + pub fn ftruncate(fd: c_int, length: off_t) -> c_int; + pub fn unlink(pathname: *const c_char) -> c_int; + + // Directory operations + pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char; + pub fn rmdir(pathname: *const c_char) -> c_int; + + // Process operations + pub fn getpid() -> pid_t; + pub fn getppid() -> pid_t; + pub fn getpgid(pid: pid_t) -> pid_t; + pub fn getpgrp() -> pid_t; + pub fn getuid() -> uid_t; + pub fn geteuid() -> uid_t; + pub fn getgid() -> gid_t; + pub fn getegid() -> gid_t; + pub fn seteuid(uid: uid_t) -> c_int; + pub fn setuid(uid: uid_t) -> c_int; + pub fn setpgid(pid: pid_t, pgid: pid_t) -> c_int; + pub fn setpgrp() -> pid_t; + pub fn setsid() -> pid_t; + + // Sleep functions + pub fn sleep(seconds: c_uint) -> c_uint; + + // Sync operations + pub fn fsync(fd: c_int) -> c_int; + + // System configuration + pub fn sysconf(name: c_int) -> c_long; + pub fn pathconf(path: *const c_char, name: c_int) -> c_long; +} diff --git a/vendor/libc/src/new/redox/mod.rs b/vendor/libc/src/new/redox/mod.rs new file mode 100644 index 0000000..cf7806a --- /dev/null +++ b/vendor/libc/src/new/redox/mod.rs @@ -0,0 +1,3 @@ +//! Redox libc. +//! +//! * Headers: diff --git a/vendor/libc/src/new/relibc/mod.rs b/vendor/libc/src/new/relibc/mod.rs new file mode 100644 index 0000000..d244912 --- /dev/null +++ b/vendor/libc/src/new/relibc/mod.rs @@ -0,0 +1,5 @@ +//! Redox OS libc. +//! +//! * Headers: + +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/relibc/unistd.rs b/vendor/libc/src/new/relibc/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/relibc/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/rtems/mod.rs b/vendor/libc/src/new/rtems/mod.rs new file mode 100644 index 0000000..bd3dc39 --- /dev/null +++ b/vendor/libc/src/new/rtems/mod.rs @@ -0,0 +1,2 @@ +//! RTEMS libc. +// FIXME(rtems): link to headers needed. diff --git a/vendor/libc/src/new/sgx/mod.rs b/vendor/libc/src/new/sgx/mod.rs new file mode 100644 index 0000000..8c15dad --- /dev/null +++ b/vendor/libc/src/new/sgx/mod.rs @@ -0,0 +1 @@ +//! Fortanix SGX. diff --git a/vendor/libc/src/new/sgx/unistd.rs b/vendor/libc/src/new/sgx/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/sgx/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/solaris/mod.rs b/vendor/libc/src/new/solaris/mod.rs new file mode 100644 index 0000000..97ae473 --- /dev/null +++ b/vendor/libc/src/new/solaris/mod.rs @@ -0,0 +1,5 @@ +//! Solaris libc. +//! +//! * Manual pages: (under "Reference Manuals") + +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/solaris/unistd.rs b/vendor/libc/src/new/solaris/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/solaris/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/solid/mod.rs b/vendor/libc/src/new/solid/mod.rs new file mode 100644 index 0000000..4a197cf --- /dev/null +++ b/vendor/libc/src/new/solid/mod.rs @@ -0,0 +1,2 @@ +//! Kyoto Microcomputer SOLID. +// FIXME(solid): link to headers needed. diff --git a/vendor/libc/src/new/teeos/mod.rs b/vendor/libc/src/new/teeos/mod.rs new file mode 100644 index 0000000..96f44d3 --- /dev/null +++ b/vendor/libc/src/new/teeos/mod.rs @@ -0,0 +1,2 @@ +//! Per the target docs, TEEOS uses part of musl as its libc. +// FIXME(teeos): link to headers needed. diff --git a/vendor/libc/src/new/trusty/mod.rs b/vendor/libc/src/new/trusty/mod.rs new file mode 100644 index 0000000..261ecb0 --- /dev/null +++ b/vendor/libc/src/new/trusty/mod.rs @@ -0,0 +1,2 @@ +//! Trusty libc. +// FIXME(trusty): link to headers needed. diff --git a/vendor/libc/src/new/uclibc/mod.rs b/vendor/libc/src/new/uclibc/mod.rs new file mode 100644 index 0000000..6bf83ef --- /dev/null +++ b/vendor/libc/src/new/uclibc/mod.rs @@ -0,0 +1,7 @@ +//! uClibc. +//! +//! * About: +//! * Headers: (mirror) + +pub(crate) mod pthread; +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/uclibc/pthread.rs b/vendor/libc/src/new/uclibc/pthread.rs new file mode 100644 index 0000000..c0f1731 --- /dev/null +++ b/vendor/libc/src/new/uclibc/pthread.rs @@ -0,0 +1,66 @@ +//! Header: `pthread.h` +//! +//! Note that The l4re port of uclibc doesn't yet support all `pthread_*` API that is +//! available upstream. + +pub use crate::new::common::linux_like::pthread::{ + pthread_getaffinity_np, + pthread_getattr_np, + pthread_setaffinity_np, +}; +#[cfg(not(target_os = "l4re"))] +pub use crate::new::common::linux_like::pthread::{ + pthread_getname_np, + pthread_setname_np, +}; +#[cfg(not(target_os = "l4re"))] +pub use crate::new::common::posix::pthread::{ + pthread_atfork, + pthread_barrierattr_getpshared, + pthread_condattr_getclock, + pthread_condattr_setclock, + pthread_getcpuclockid, + pthread_mutex_consistent, + pthread_mutexattr_getprotocol, + pthread_mutexattr_getrobust, + pthread_mutexattr_setprotocol, + pthread_mutexattr_setrobust, + pthread_setschedprio, +}; +pub use crate::new::common::posix::pthread::{ + pthread_attr_getguardsize, + pthread_attr_getinheritsched, + pthread_attr_getschedparam, + pthread_attr_getschedpolicy, + pthread_attr_getstack, + pthread_attr_setguardsize, + pthread_attr_setinheritsched, + pthread_attr_setschedparam, + pthread_attr_setschedpolicy, + pthread_attr_setstack, + pthread_barrier_destroy, + pthread_barrier_init, + pthread_barrier_wait, + pthread_barrierattr_destroy, + pthread_barrierattr_init, + pthread_barrierattr_setpshared, + pthread_cancel, + pthread_condattr_getpshared, + pthread_condattr_setpshared, + pthread_create, + pthread_getschedparam, + pthread_kill, + pthread_mutex_timedlock, + pthread_mutexattr_getpshared, + pthread_mutexattr_setpshared, + pthread_once, + pthread_rwlockattr_getpshared, + pthread_rwlockattr_setpshared, + pthread_setschedparam, + pthread_sigmask, + pthread_spin_destroy, + pthread_spin_init, + pthread_spin_lock, + pthread_spin_trylock, + pthread_spin_unlock, +}; diff --git a/vendor/libc/src/new/uclibc/unistd.rs b/vendor/libc/src/new/uclibc/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/uclibc/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/ucrt/mod.rs b/vendor/libc/src/new/ucrt/mod.rs new file mode 100644 index 0000000..f6b5f5d --- /dev/null +++ b/vendor/libc/src/new/ucrt/mod.rs @@ -0,0 +1,4 @@ +//! Windows Universal C Runtime. +//! +//! * Manual pages: +//! * UCRT information: diff --git a/vendor/libc/src/new/vita/mod.rs b/vendor/libc/src/new/vita/mod.rs new file mode 100644 index 0000000..21205eb --- /dev/null +++ b/vendor/libc/src/new/vita/mod.rs @@ -0,0 +1,2 @@ +//! VITASDK system library. +// FIXME(vita): link to headers or manpages needed. diff --git a/vendor/libc/src/new/vxworks/mod.rs b/vendor/libc/src/new/vxworks/mod.rs new file mode 100644 index 0000000..3160012 --- /dev/null +++ b/vendor/libc/src/new/vxworks/mod.rs @@ -0,0 +1,7 @@ +//! VxWorks libc. +//! +//! VxWorks allows compiling different types of programs. The `libc` crate only +//! supports RTPs. Refer to the RTP definitions in case of discrepancy. +// FIXME(vxworks): link to headers needed. + +pub(crate) mod unistd; diff --git a/vendor/libc/src/new/vxworks/unistd.rs b/vendor/libc/src/new/vxworks/unistd.rs new file mode 100644 index 0000000..8d55ee5 --- /dev/null +++ b/vendor/libc/src/new/vxworks/unistd.rs @@ -0,0 +1,7 @@ +//! Header: `unistd.h` + +pub use crate::new::common::posix::unistd::{ + STDERR_FILENO, + STDIN_FILENO, + STDOUT_FILENO, +}; diff --git a/vendor/libc/src/new/wasi/mod.rs b/vendor/libc/src/new/wasi/mod.rs new file mode 100644 index 0000000..341e6d5 --- /dev/null +++ b/vendor/libc/src/new/wasi/mod.rs @@ -0,0 +1,3 @@ +//! WASI libc. +//! +//! * Headers: diff --git a/vendor/libc/src/new/xous/mod.rs b/vendor/libc/src/new/xous/mod.rs new file mode 100644 index 0000000..8a9a285 --- /dev/null +++ b/vendor/libc/src/new/xous/mod.rs @@ -0,0 +1,2 @@ +//! Xous libc. +// FIXME(xous): link to headers needed. diff --git a/vendor/libc/src/primitives.rs b/vendor/libc/src/primitives.rs new file mode 100644 index 0000000..228dbc2 --- /dev/null +++ b/vendor/libc/src/primitives.rs @@ -0,0 +1,58 @@ +//! This module contains type aliases for C's platform-specific types +//! and fixed-width integer types. +//! +//! The platform-specific types definitions were taken from rust-lang/rust in +//! library/core/src/ffi/primitives.rs +//! +//! The fixed-width integer aliases are deprecated: use the Rust types instead. + +// FIXME(1.0): Deprecate these aliases in a few releases, remove in 1.0. +pub use core::ffi::{ + c_char, + c_double, + c_float, + c_int, + c_long, + c_longlong, + c_schar, + c_short, + c_uchar, + c_uint, + c_ulong, + c_ulonglong, + c_ushort, +}; + +#[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(target_arch = "aarch64", not(target_os = "windows")))] { + /// C `__int128` (a GCC extension that's part of many ABIs) + #[deprecated(since = "0.2.184", note = "Use i128 instead.")] + pub type __int128 = i128; + /// C `unsigned __int128` (a GCC extension that's part of many ABIs) + #[deprecated(since = "0.2.184", note = "Use u128 instead.")] + pub type __uint128 = u128; + /// C __int128_t (alternate name for [__int128][]) + #[deprecated(since = "0.2.184", note = "Use i128 instead.")] + pub type __int128_t = i128; + /// C __uint128_t (alternate name for [__uint128][]) + #[deprecated(since = "0.2.184", note = "Use u128 instead.")] + pub type __uint128_t = u128; + } +} diff --git a/vendor/libc/src/psp.rs b/vendor/libc/src/psp.rs new file mode 100644 index 0000000..99a72b7 --- /dev/null +++ b/vendor/libc/src/psp.rs @@ -0,0 +1,4131 @@ +//! 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. + +use crate::prelude::*; + +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 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], + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + 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, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + 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, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + 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, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + 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, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + 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, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + 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, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + 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! { + pub struct GeContext { + pub context: [u32; 512], + } + + pub struct SceKernelUtilsSha1Context { + pub h: [u32; 5usize], + pub us_remains: u16, + pub us_computed: u16, + pub ull_total_len: u64, + pub buf: [u8; 64usize], + } + + pub struct SceKernelUtilsMt19937Context { + pub count: u32, + pub state: [u32; 624usize], + } + + 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], + } + + pub struct SceIoDirent { + pub d_stat: SceIoStat, + pub d_name: [u8; 256usize], + pub d_private: *mut c_void, + pub dummy: i32, + } + + pub struct ScePspFRect { + pub x: f32, + pub y: f32, + pub w: f32, + pub h: f32, + } + + #[repr(align(16))] + pub struct ScePspFVector3 { + pub x: f32, + pub y: f32, + pub z: f32, + } + + #[repr(align(16))] + pub struct ScePspFVector4 { + pub x: f32, + pub y: f32, + pub z: f32, + pub w: f32, + } + + pub struct ScePspFVector4Unaligned { + pub x: f32, + pub y: f32, + pub z: f32, + pub w: f32, + } + + pub struct ScePspFVector2 { + pub x: f32, + pub y: f32, + } + + pub struct ScePspFMatrix2 { + pub x: ScePspFVector2, + pub y: ScePspFVector2, + } + + pub struct ScePspFMatrix3 { + pub x: ScePspFVector3, + pub y: ScePspFVector3, + pub z: ScePspFVector3, + } + + #[repr(align(16))] + pub struct ScePspFMatrix4 { + pub x: ScePspFVector4, + pub y: ScePspFVector4, + pub z: ScePspFVector4, + pub w: ScePspFVector4, + } + + pub struct ScePspFMatrix4Unaligned { + pub x: ScePspFVector4, + pub y: ScePspFVector4, + pub z: ScePspFVector4, + pub w: ScePspFVector4, + } + + pub union ScePspVector3 { + pub fv: ScePspFVector3, + pub iv: ScePspIVector3, + pub f: [f32; 3usize], + pub i: [i32; 3usize], + } + + pub union ScePspVector4 { + pub fv: ScePspFVector4, + pub iv: ScePspIVector4, + pub qw: u128, + pub f: [f32; 4usize], + pub i: [i32; 4usize], + } + + 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], + } + + 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], + } + + pub union ScePspVector2 { + pub fv: ScePspFVector2, + pub iv: ScePspIVector2, + pub f: [f32; 2usize], + pub i: [i32; 2usize], + } + + 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], + } + + pub struct Key { + pub key_type: KeyType, + pub name: [u8; 256usize], + pub name_len: u32, + pub unk2: u32, + pub unk3: u32, + } + + 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, + } + + pub union UtilityNetData { + pub as_uint: u32, + pub as_string: [u8; 128usize], + } + + pub struct UtilitySavedataSFOParam { + pub title: [u8; 128usize], + pub savedata_title: [u8; 128usize], + pub detail: [u8; 1024usize], + pub parental_level: u8, + pub unknown: [u8; 3usize], + } + + 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], + } + + pub struct SceNetAdhocctlPeerInfo { + pub next: *mut SceNetAdhocctlPeerInfo, + pub nickname: [u8; 128usize], + pub mac: [u8; 6usize], + pub unknown: [u8; 6usize], + pub timestamp: u32, + } + + pub struct SceNetAdhocctlParams { + pub channel: i32, + pub name: [u8; 8usize], + pub bssid: [u8; 6usize], + pub nickname: [u8; 128usize], + } + + 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 = u32_cast_int(0x80000000); +pub const THREAD_ATTR_USBWLAN: i32 = u32_cast_int(0xa0000000); +pub const THREAD_ATTR_VSH: i32 = u32_cast_int(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 = u32_cast_int(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 c_char, + p_utc: *const u64, + time_zone_minutes: i32, + ) -> i32; + pub fn sceRtcFormatRFC3339LocalTime(psz_date_time: *mut c_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 c_char, + p_utc: *const u64, + time_zone_minutes: i32, + ) -> i32; + pub fn sceRtcFormatRFC2822LocalTime(psz_date_time: *mut c_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/qurt/mod.rs b/vendor/libc/src/qurt/mod.rs new file mode 100644 index 0000000..b5e01f9 --- /dev/null +++ b/vendor/libc/src/qurt/mod.rs @@ -0,0 +1,18 @@ +//! Interface to QuRT (Qualcomm Real-Time OS) C library +//! +//! This module re-exports items from the new module structure. +//! QuRT was introduced after the `src/new/` module structure was established, +//! so all definitions live in `src/new/qurt/` and are re-exported here +//! for compatibility with the existing libc structure. + +// Re-export everything from the new qurt module +pub use crate::new::qurt::*; + +// Architecture-specific modules (if any are needed in the future) +cfg_if! { + if #[cfg(target_arch = "hexagon")] { + // Currently no hexagon-specific items needed beyond what's in new/qurt + } else { + // Add other architectures as needed + } +} diff --git a/vendor/libc/src/sgx.rs b/vendor/libc/src/sgx.rs new file mode 100644 index 0000000..9cf9c6d --- /dev/null +++ b/vendor/libc/src/sgx.rs @@ -0,0 +1,15 @@ +//! SGX C types definition + +use crate::prelude::*; + +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 const INT_MIN: c_int = -2147483648; +pub const INT_MAX: c_int = 2147483647; diff --git a/vendor/libc/src/solid/aarch64.rs b/vendor/libc/src/solid/aarch64.rs new file mode 100644 index 0000000..376783c --- /dev/null +++ b/vendor/libc/src/solid/aarch64.rs @@ -0,0 +1 @@ +pub type wchar_t = u32; diff --git a/vendor/libc/src/solid/arm.rs b/vendor/libc/src/solid/arm.rs new file mode 100644 index 0000000..376783c --- /dev/null +++ b/vendor/libc/src/solid/arm.rs @@ -0,0 +1 @@ +pub type wchar_t = u32; diff --git a/vendor/libc/src/solid/mod.rs b/vendor/libc/src/solid/mod.rs new file mode 100644 index 0000000..d14dcf8 --- /dev/null +++ b/vendor/libc/src/solid/mod.rs @@ -0,0 +1,868 @@ +//! Interface to the [SOLID] C library +//! +//! [SOLID]: https://solid.kmckk.com/ + +use crate::prelude::*; + +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 = crate::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, + } + + #[derive(Default)] + 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 = 0o0100; +pub const S_IWRITE: c_short = 0o0200; +pub const S_IREAD: c_short = 0o0400; +pub const S_IFCHR: c_short = 0o2_0000; +pub const S_IFDIR: c_short = 0o4_0000; +pub const S_IFMT: c_short = u16_cast_short(0o16_0000); +pub const S_IFIFO: c_short = 0o1_0000; +pub const S_IFBLK: c_short = 0o6_0000; +pub const S_IFREG: c_short = u16_cast_short(0o10_0000); + +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +extern_ty! { + pub type FILE; + pub type fpos_t; +} + +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: crate::nl_item) -> *mut c_char; + pub fn nl_langinfo_l(item: crate::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(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..2d202dd --- /dev/null +++ b/vendor/libc/src/switch.rs @@ -0,0 +1,17 @@ +//! Switch C type definitions +use crate::prelude::*; + +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 wchar_t = u32; + +pub const INT_MIN: c_int = -2147483648; +pub const INT_MAX: c_int = 2147483647; diff --git a/vendor/libc/src/teeos/mod.rs b/vendor/libc/src/teeos/mod.rs new file mode 100644 index 0000000..daf4cf3 --- /dev/null +++ b/vendor/libc/src/teeos/mod.rs @@ -0,0 +1,1349 @@ +//! 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)] + +use crate::prelude::*; + +pub type c_bool = i32; + +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; + +pub type wchar_t = u32; + +// long double in C means A float point value, which has 128bit length. +// but some bit maybe not used, so the real 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 cause 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 = i64; + +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(); + +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; + +s_paren! { + #[repr(align(16))] + pub struct _CLongDouble(pub u128); +} + +s! { + #[repr(align(8))] + pub struct pthread_cond_t { + #[doc(hidden)] + size: [u8; __SIZEOF_PTHREAD_COND_T], + } + + #[repr(align(8))] + pub struct pthread_mutex_t { + #[doc(hidden)] + size: [u8; __SIZEOF_PTHREAD_MUTEX_T], + } + + #[repr(align(4))] + pub struct pthread_mutexattr_t { + #[doc(hidden)] + size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + #[doc(hidden)] + size: [u8; __SIZEOF_PTHREAD_CONDATTR_T], + } + + pub struct pthread_attr_t { + __size: [u64; 7], + } + + pub struct cpu_set_t { + bits: [c_ulong; 128 / size_of::()], + } + + #[derive(Default)] + pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: c_long, + } + + #[derive(Default)] + pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: suseconds_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 mbstate_t { + pub __opaque1: c_uint, + pub __opaque2: c_uint, + } + + pub struct sem_t { + pub __val: [c_int; 4 * size_of::() / size_of::()], + } + + 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 = 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(size_of::(), cpuset) +} diff --git a/vendor/libc/src/trusty.rs b/vendor/libc/src/trusty.rs new file mode 100644 index 0000000..2cb2d5e --- /dev/null +++ b/vendor/libc/src/trusty.rs @@ -0,0 +1,73 @@ +use crate::prelude::*; +pub type size_t = usize; +pub type ssize_t = isize; + +pub type off_t = i64; + +pub type c_uint8_t = u8; +pub type c_uint16_t = u16; +pub type c_uint32_t = u32; +pub type c_uint64_t = u64; + +pub type c_int8_t = i8; +pub type c_int16_t = i16; +pub type c_int32_t = i32; +pub type c_int64_t = i64; + +pub type intptr_t = isize; +pub type uintptr_t = usize; + +pub type time_t = c_long; + +pub type clockid_t = c_int; + +s! { + pub struct iovec { + pub iov_base: *mut c_void, + pub iov_len: size_t, + } + + #[derive(Default)] + pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: c_long, + } +} + +pub const PROT_READ: i32 = 1; +pub const PROT_WRITE: i32 = 2; + +// Trusty only supports `CLOCK_BOOTTIME`. +pub const CLOCK_BOOTTIME: clockid_t = 7; + +pub const STDOUT_FILENO: c_int = 1; +pub const STDERR_FILENO: c_int = 2; + +pub const AT_PAGESZ: c_ulong = 6; + +pub const MAP_FAILED: *mut c_void = !0 as *mut c_void; + +extern "C" { + 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 memalign(align: size_t, size: size_t) -> *mut c_void; + pub fn posix_memalign(memptr: *mut *mut c_void, align: size_t, size: size_t) -> c_int; + pub fn write(fd: c_int, buf: *const c_void, count: size_t) -> ssize_t; + pub fn writev(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + pub fn close(fd: c_int) -> c_int; + pub fn strlen(cs: *const c_char) -> size_t; + pub fn getauxval(type_: c_ulong) -> c_ulong; + 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 clock_gettime(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn nanosleep(rqtp: *const crate::timespec, rmtp: *mut crate::timespec) -> c_int; +} diff --git a/vendor/libc/src/types.rs b/vendor/libc/src/types.rs new file mode 100644 index 0000000..7be6e78 --- /dev/null +++ b/vendor/libc/src/types.rs @@ -0,0 +1,140 @@ +//! Platform-agnostic support types. + +#[cfg(feature = "extra_traits")] +use core::hash::Hash; +use core::mem::MaybeUninit; + +use crate::prelude::*; + +/// A transparent wrapper over `MaybeUninit` to represent uninitialized padding +/// while providing `Default`. +// This is restricted to `Copy` types since that's a loose indicator that zeros is actually +// a valid bitpattern. There is no technical reason this is required, though, so it could be +// lifted in the future if it becomes a problem. +#[allow(dead_code)] +#[repr(transparent)] +#[derive(Clone, Copy)] +pub(crate) struct Padding(MaybeUninit); + +impl Default for Padding { + fn default() -> Self { + Self(MaybeUninit::zeroed()) + } +} + +impl Padding { + /// Create a `Padding` initialized with the given value. + #[allow(dead_code)] + pub(crate) const fn new(val: T) -> Self { + Self(MaybeUninit::new(val)) + } +} + +impl fmt::Debug for Padding { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Taken from `MaybeUninit`'s debug implementation + // NB: there is no `.pad_fmt` so we can't use a simpler `format_args!("Padding<{..}>"). + let full_name = core::any::type_name::(); + let prefix_len = full_name.find("Padding").unwrap(); + f.pad(&full_name[prefix_len..]) + } +} + +/// Do nothing when hashing to ignore the existence of padding fields. +#[cfg(feature = "extra_traits")] +impl Hash for Padding { + fn hash(&self, _state: &mut H) {} +} + +/// Padding fields are all equal, regardless of what is inside them, so they do not affect anything. +#[cfg(feature = "extra_traits")] +impl PartialEq for Padding { + fn eq(&self, _other: &Self) -> bool { + true + } +} + +/// Mark that `Padding` implements `Eq` so that it can be used in types that implement it. +#[cfg(feature = "extra_traits")] +impl Eq for Padding {} + +/// The default repr type used for C style enums in Rust. +#[cfg(target_env = "msvc")] +#[allow(unused)] +pub(crate) type CEnumRepr = c_int; +#[cfg(not(target_env = "msvc"))] +#[allow(unused)] +pub(crate) type CEnumRepr = c_uint; + +/// Used to avoid `overflowing_literals` when the value is in-range for the unsigned number but +/// out-of-range for signed. +#[allow(unused)] +pub(crate) const fn u16_cast_short(x: u16) -> c_short { + assert!(size_of::() <= size_of::()); // Should always be true + x as i16 +} + +/// Used to avoid `overflowing_literals` when the value is in-range for the unsigned number but +/// out-of-range for signed. +#[allow(unused)] +pub(crate) const fn u32_cast_int(x: u32) -> c_int { + // May not be true on 16-bit platforms, but should be everywhere this is used. + assert!(size_of::() <= size_of::()); + x as i32 +} + +/// Used to avoid `overflowing_literals` when the value is in-range for the unsigned number but +/// out-of-range for signed. +#[allow(unused)] +pub(crate) const fn u32_cast_long(x: u32) -> c_long { + assert!(size_of::() <= size_of::()); // Should always be true + x as c_long +} + +/// Checked casting from `unsigned long` to `int`. +#[allow(unused)] +pub(crate) const fn ulong_cast_int(x: c_ulong) -> c_int { + assert!(x <= (c_int::MAX as c_ulong)); + x as c_int +} + +/// Checked casting from `unsigned long` to `unsigned int`. +#[allow(unused)] +pub(crate) const fn ulong_cast_uint(x: c_ulong) -> c_uint { + assert!(x <= (c_uint::MAX as c_ulong)); + x as c_uint +} + +/// Used to avoid `overflowing_literals` when the value is in-range for the unsigned number but +/// out-of-range for signed. +#[allow(unused)] +#[cfg(any(target_os = "linux", target_os = "android", target_os = "l4re"))] +pub(crate) const fn u32_cast_ioctl(x: u32) -> crate::Ioctl { + assert!(size_of::() <= size_of::()); // Should always be true + x as crate::Ioctl +} + +#[allow(unused)] +pub(crate) const fn u8_slice_cast_char_slice(x: &[u8]) -> &[c_char] { + assert!(size_of::() == size_of::()); + // SAFETY: same repr, possibly just a sign cast + unsafe { mem::transmute::<&[u8], &[c_char]>(x) } +} + +/// Replace bytes in an array with those from a slice. This is a polyfill for `[T]::copy_from_slice` +/// in `const`. +// FIXME(msrv): we can switch to `copy_from_slice` in 1.87. +#[must_use] +#[allow(dead_code)] +pub const fn replace_array_items( + mut dst: [T; N], + src: &[T], + start: usize, +) -> [T; N] { + let mut i = 0; + while i < src.len() { + dst[i + start] = src[i]; + i += 1; + } + dst +} diff --git a/vendor/libc/src/unix/aix/mod.rs b/vendor/libc/src/unix/aix/mod.rs new file mode 100644 index 0000000..6f5a02a --- /dev/null +++ b/vendor/libc/src/unix/aix/mod.rs @@ -0,0 +1,3408 @@ +use crate::prelude::*; +use crate::{ + in_addr_t, + in_port_t, +}; + +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 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 = i64; +pub type timer_t = c_long; +pub type wchar_t = c_uint; +pub type nfds_t = c_uint; +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 suseconds_t = c_int; +pub type useconds_t = c_uint; +pub type off_t = c_long; +pub type offset_t = c_longlong; +pub type off64_t = c_longlong; +pub type idtype_t = c_uint; + +pub type socklen_t = c_uint; +pub type sa_family_t = c_uchar; + +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 sctp_assoc_t = c_uint; + +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! { + #[repr(u32)] + pub enum uio_rw { + UIO_READ = 0, + UIO_WRITE, + UIO_READ_NO_MOVE, + UIO_WRITE_NO_MOVE, + UIO_PWRITE, + } + #[repr(u32)] + pub enum ACTION { + FIND = 0, + ENTER, + } +} + +s! { + pub struct fsid_t { + pub val: [c_uint; 2], + } + + pub struct fsid64_t { + pub val: [crate::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: crate::ino_t, + pub d_reclen: c_ushort, + pub d_namlen: c_ushort, + pub d_name: [c_char; 256], + } + + pub struct termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_cc: [crate::cc_t; crate::NCCS], + } + + pub struct flock64 { + pub l_type: c_short, + pub l_whence: c_short, + pub l_sysid: c_uint, + pub l_pid: crate::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: crate::socklen_t, + pub msg_iov: *mut crate::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: crate::blksize64_t, + pub f_frsize: crate::blksize64_t, + pub f_blocks: crate::blkcnt64_t, + pub f_bfree: crate::blkcnt64_t, + pub f_bavail: crate::blkcnt64_t, + pub f_files: crate::blkcnt64_t, + pub f_ffree: crate::blkcnt64_t, + pub f_favail: crate::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 crate::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_uchar; 8], + } + + pub struct sockaddr_in6 { + pub sin6_len: c_uchar, + pub sin6_family: c_uchar, + pub sin6_port: crate::uint16_t, + pub sin6_flowinfo: crate::uint32_t, + pub sin6_addr: crate::in6_addr, + pub sin6_scope_id: crate::uint32_t, + } + + pub struct sockaddr_storage { + pub __ss_len: c_uchar, + pub ss_family: sa_family_t, + __ss_pad1: Padding<[c_char; 6]>, + __ss_align: crate::int64_t, + __ss_pad2: Padding<[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: crate::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: crate::uint64_t, + pub f_ffree: crate::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: crate::uid_t, + pub pw_gid: crate::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, + reserved: Padding, + pub longnid: c_ulonglong, + } + + pub struct cmsghdr { + pub cmsg_len: crate::socklen_t, + pub cmsg_level: c_int, + pub cmsg_type: c_int, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigevent { + pub sigev_value: crate::sigval, + pub sigev_signo: c_int, + pub sigev_notify: c_int, + pub sigev_notify_function: extern "C" fn(val: crate::sigval), + pub sigev_notify_attributes: *mut pthread_attr_t, + } + + 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: crate::uint64_t, + pub file_offset: crate::uint64_t, + pub file_bytes: crate::int64_t, + pub trailer_data: *mut c_void, + pub trailer_length: c_uint, + pub bytes_sent: crate::uint64_t, + } + + pub struct mmsghdr { + pub msg_hdr: crate::msghdr, + pub msg_len: c_uint, + } + + pub struct sched_param { + pub sched_priority: c_int, + pub sched_policy: c_int, + sched_reserved: Padding<[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: crate::pid_t, + pub posix_attr_sigmask: crate::sigset_t, + pub posix_attr_sigdefault: crate::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 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: crate::pid_t, + pub ut_type: c_short, + pub ut_time: time64_t, + pub ut_exit: 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: [crate::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, + __unused: Padding<[*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: crate::pid_t, + pub shm_cpid: crate::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: crate::uint32_t, + pub shm_extshm: c_int, + pub shm_pagesize: crate::int64_t, + pub shm_lba: crate::uint64_t, + shm_reserved0: Padding, + shm_reserved1: Padding, + } + + 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: crate::uid_t, + pub st_gid: crate::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, + st_reserved: Padding<[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: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: mode_t, + pub seq: c_ushort, + __reserved: Padding, + 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: crate::timespec, + pub it_value: crate::timespec, + } + + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, // FIXME(union): this field is actually a union + pub sa_mask: sigset_t, + pub sa_flags: c_int, + } + + pub struct poll_ctl_ext { + pub version: u8, + pub command: u8, + pub events: c_short, + pub fd: c_int, + pub u: __poll_ctl_ext_u, + reserved64: Padding<[u64; 6]>, + } +} + +s_no_extra_traits! { + pub union __poll_ctl_ext_u { + pub addr: *mut c_void, + pub data32: u32, + pub data: u64, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + 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 + } + } + } + impl Eq for __poll_ctl_ext_u {} + 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); + } + } + } + } +} + +// 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_MEMBER: c_int = 0x40000; +pub const RTLD_NOAUTODEFER: c_int = 0x20000; +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 | O_EXEC | O_SEARCH; +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_DUPFD: c_int = 0; +pub const F_DUPFD_CLOEXEC: c_int = 16; +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_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 F_CLOSEM: c_int = 10; +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 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 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: crate::nl_item = 13; +pub const DAY_2: crate::nl_item = 14; +pub const DAY_3: crate::nl_item = 15; +pub const DAY_4: crate::nl_item = 16; +pub const DAY_5: crate::nl_item = 17; +pub const DAY_6: crate::nl_item = 18; +pub const DAY_7: crate::nl_item = 19; +pub const ABDAY_1: crate::nl_item = 6; +pub const ABDAY_2: crate::nl_item = 7; +pub const ABDAY_3: crate::nl_item = 8; +pub const ABDAY_4: crate::nl_item = 9; +pub const ABDAY_5: crate::nl_item = 10; +pub const ABDAY_6: crate::nl_item = 11; +pub const ABDAY_7: crate::nl_item = 12; +pub const MON_1: crate::nl_item = 32; +pub const MON_2: crate::nl_item = 33; +pub const MON_3: crate::nl_item = 34; +pub const MON_4: crate::nl_item = 35; +pub const MON_5: crate::nl_item = 36; +pub const MON_6: crate::nl_item = 37; +pub const MON_7: crate::nl_item = 38; +pub const MON_8: crate::nl_item = 39; +pub const MON_9: crate::nl_item = 40; +pub const MON_10: crate::nl_item = 41; +pub const MON_11: crate::nl_item = 42; +pub const MON_12: crate::nl_item = 43; +pub const ABMON_1: crate::nl_item = 20; +pub const ABMON_2: crate::nl_item = 21; +pub const ABMON_3: crate::nl_item = 22; +pub const ABMON_4: crate::nl_item = 23; +pub const ABMON_5: crate::nl_item = 24; +pub const ABMON_6: crate::nl_item = 25; +pub const ABMON_7: crate::nl_item = 26; +pub const ABMON_8: crate::nl_item = 27; +pub const ABMON_9: crate::nl_item = 28; +pub const ABMON_10: crate::nl_item = 29; +pub const ABMON_11: crate::nl_item = 30; +pub const ABMON_12: crate::nl_item = 31; +pub const RADIXCHAR: crate::nl_item = 44; +pub const THOUSEP: crate::nl_item = 45; +pub const YESSTR: crate::nl_item = 46; +pub const NOSTR: crate::nl_item = 47; +pub const CRNCYSTR: crate::nl_item = 48; +pub const D_T_FMT: crate::nl_item = 1; +pub const D_FMT: crate::nl_item = 2; +pub const T_FMT: crate::nl_item = 3; +pub const AM_STR: crate::nl_item = 4; +pub const PM_STR: crate::nl_item = 5; +pub const CODESET: crate::nl_item = 49; +pub const T_FMT_AMPM: crate::nl_item = 55; +pub const ERA: crate::nl_item = 56; +pub const ERA_D_FMT: crate::nl_item = 57; +pub const ERA_D_T_FMT: crate::nl_item = 58; +pub const ERA_T_FMT: crate::nl_item = 59; +pub const ALT_DIGITS: crate::nl_item = 60; +pub const YESEXPR: crate::nl_item = 61; +pub const NOEXPR: crate::nl_item = 62; + +// locale.h +pub const LC_GLOBAL_LOCALE: crate::locale_t = -1isize as crate::locale_t; +pub const LC_COLLATE: c_int = 0; +pub const LC_CTYPE: c_int = 1; +pub const LC_MONETARY: c_int = 2; +pub const LC_NUMERIC: c_int = 3; +pub const LC_TIME: c_int = 4; +pub const LC_MESSAGES: c_int = 5; +pub const LC_ALL: c_int = -1; +pub const LC_COLLATE_MASK: c_int = 1; +pub const LC_CTYPE_MASK: c_int = 2; +pub const LC_MESSAGES_MASK: c_int = 4; +pub const LC_MONETARY_MASK: c_int = 8; +pub const LC_NUMERIC_MASK: c_int = 16; +pub const LC_TIME_MASK: c_int = 32; +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; + +// netdb.h +pub const NI_MAXHOST: crate::socklen_t = 1025; +pub const NI_MAXSERV: crate::socklen_t = 32; +pub const NI_NOFQDN: crate::socklen_t = 0x1; +pub const NI_NUMERICHOST: crate::socklen_t = 0x2; +pub const NI_NAMEREQD: crate::socklen_t = 0x4; +pub const NI_NUMERICSERV: crate::socklen_t = 0x8; +pub const NI_DGRAM: crate::socklen_t = 0x10; +pub const NI_NUMERICSCOPE: crate::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 = 0x00ffffff; +pub const IPV6_FLOWINFO_PRIORITY: c_int = 0x0f000000; +pub const IPV6_FLOWINFO_PRIFLOW: c_int = 0x0fffffff; +pub const IPV6_FLOWINFO_SRFLAG: c_int = 0x10000000; +pub const IPV6_FLOWINFO_VERSION: c_int = u32_cast_int(0xf0000000); +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_int = u32_cast_int(0x80104267); +pub const BIOCGRTIMEOUT: c_int = 0x4010426e; +pub const BIOCGBLEN: c_int = 0x40044266; +pub const BIOCSBLEN: c_int = u32_cast_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 = u32_cast_int(0x8010426d); +pub const BIOCGSTATS: c_int = 0x4008426f; +pub const BIOCIMMEDIATE: c_int = u32_cast_int(0x80044270); +pub const BIOCVERSION: c_int = 0x40044271; +pub const BIOCSDEVNO: c_int = 0x20004272; +pub const BIOCGETIF: c_int = 0x4020426b; +pub const BIOCSETIF: c_int = u32_cast_int(0x8020426c); +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 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; + +// 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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 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 = 2; +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_SOFT: c_int = 0x001; +pub const NFSMNT_WSIZE: c_int = 0x002; +pub const NFSMNT_RSIZE: c_int = 0x004; +pub const NFSMNT_TIMEO: c_int = 0x008; +pub const NFSMNT_RETRANS: c_int = 0x010; +pub const NFSMNT_HOSTNAME: c_int = 0x020; +pub const NFSMNT_INT: c_int = 0x040; +pub const NFSMNT_NOAC: c_int = 0x080; +pub const NFSMNT_ACREGMIN: c_int = 0x0100; +pub const NFSMNT_ACREGMAX: c_int = 0x0200; +pub const NFSMNT_ACDIRMIN: c_int = 0x0400; +pub const NFSMNT_ACDIRMAX: c_int = 0x0800; + +// rpcsvc/rstat.h +pub const CPUSTATES: c_int = 4; + +// semaphore.h +pub const SEM_FAILED: *mut sem_t = -1isize as *mut crate::sem_t; + +// spawn.h +// DIFF(main): changed to `c_short` in f62eb023ab +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 ENOTREADY: c_int = 46; +pub const EWRPROTECT: c_int = 47; +pub const EFORMAT: c_int = 48; +pub const ENOLCK: c_int = 49; +pub const ENOCONNECT: c_int = 50; +pub const ESTALE: c_int = 52; +pub const EDIST: c_int = 53; +// POSIX allows EWOULDBLOCK to be the same value as EAGAIN. +pub const EWOULDBLOCK: c_int = EAGAIN; +pub const EINPROGRESS: c_int = 55; +pub const EALREADY: c_int = 56; +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 ETIMEDOUT: c_int = 78; +pub const ECONNREFUSED: c_int = 79; +pub const EHOSTDOWN: c_int = 80; +pub const EHOSTUNREACH: c_int = 81; +pub const ERESTART: c_int = 82; +pub const EPROCLIM: c_int = 83; +pub const EUSERS: c_int = 84; +pub const ELOOP: c_int = 85; +pub const ENAMETOOLONG: c_int = 86; +pub const ENOTEMPTY: c_int = 87; +pub const EDQUOT: c_int = 88; +pub const ECORRUPT: c_int = 89; +pub const ESYSERROR: c_int = 90; +pub const EREMOTE: c_int = 93; +pub const ENOTRECOVERABLE: c_int = 94; +pub const EOWNERDEAD: c_int = 95; +// errnos 96-108 reserved for future use compatible with AIX PS/2 +pub const ENOSYS: c_int = 109; +pub const EMEDIA: c_int = 110; +pub const ESOFT: c_int = 111; +pub const ENOATTR: c_int = 112; +pub const ESAD: c_int = 113; +pub const ENOTRUST: c_int = 114; +pub const ETOOMANYREFS: c_int = 115; +pub const EILSEQ: c_int = 116; +pub const ECANCELED: c_int = 117; +pub const ENOSR: c_int = 118; +pub const ETIME: c_int = 119; +pub const EBADMSG: c_int = 120; +pub const EPROTO: c_int = 121; +pub const ENODATA: c_int = 122; +pub const ENOSTR: c_int = 123; +pub const ENOTSUP: c_int = 124; +pub const EMULTIHOP: c_int = 125; +pub const ENOLINK: c_int = 126; +pub const EOVERFLOW: c_int = 127; + +// 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 = 0x20006601; +pub const FIONCLEX: c_int = 0x20006602; +pub const FIONREAD: c_int = 0x4004667f; +pub const FIONBIO: c_int = u32_cast_int(0x8004667e); +pub const FIOASYNC: c_int = u32_cast_int(0x8004667d); +pub const FIOSETOWN: c_int = u32_cast_int(0x8004667c); +pub const FIOGETOWN: c_int = 0x4004667b; +pub const TIOCGETD: c_int = 0x40047400; +pub const TIOCSETD: c_int = u32_cast_int(0x80047401); +pub const TIOCHPCL: c_int = 0x20007402; +pub const TIOCMODG: c_int = 0x40047403; +pub const TIOCMODS: c_int = u32_cast_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 = u32_cast_int(0x80067409); +pub const TIOCSETN: c_int = u32_cast_int(0x8006740a); +pub const TIOCEXCL: c_int = 0x2000740d; +pub const TIOCNXCL: c_int = 0x2000740e; +pub const TIOCFLUSH: c_int = u32_cast_int(0x80047410); +pub const TIOCSETC: c_int = u32_cast_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 = u32_cast_int(0x80206931); +pub const SIOCADDRT: c_int = u32_cast_int(0x8038720a); +pub const SIOCDARP: c_int = u32_cast_int(0x804c6920); +pub const SIOCDELMULTI: c_int = u32_cast_int(0x80206932); +pub const SIOCDELRT: c_int = u32_cast_int(0x8038720b); +pub const SIOCDIFADDR: c_int = u32_cast_int(0x80286919); +pub const SIOCGARP: c_int = u32_cast_int(0xc04c6926); +pub const SIOCGIFADDR: c_int = u32_cast_int(0xc0286921); +pub const SIOCGIFBRDADDR: c_int = u32_cast_int(0xc0286923); +pub const SIOCGIFCONF: c_int = u32_cast_int(0xc0106945); +pub const SIOCGIFDSTADDR: c_int = u32_cast_int(0xc0286922); +pub const SIOCGIFFLAGS: c_int = u32_cast_int(0xc0286911); +pub const SIOCGIFHWADDR: c_int = u32_cast_int(0xc0546995); +pub const SIOCGIFMETRIC: c_int = u32_cast_int(0xc0286917); +pub const SIOCGIFMTU: c_int = u32_cast_int(0xc0286956); +pub const SIOCGIFNETMASK: c_int = u32_cast_int(0xc0286925); +pub const SIOCSARP: c_int = u32_cast_int(0x804c691e); +pub const SIOCSIFADDR: c_int = u32_cast_int(0x8028690c); +pub const SIOCSIFBRDADDR: c_int = u32_cast_int(0x80286913); +pub const SIOCSIFDSTADDR: c_int = u32_cast_int(0x8028690e); +pub const SIOCSIFFLAGS: c_int = u32_cast_int(0x80286910); +pub const SIOCSIFMETRIC: c_int = u32_cast_int(0x80286918); +pub const SIOCSIFMTU: c_int = u32_cast_int(0x80286958); +pub const SIOCSIFNETMASK: c_int = u32_cast_int(0x80286916); +pub const TIOCUCNTL: c_int = u32_cast_int(0x80047466); +pub const TIOCCONS: c_int = u32_cast_int(0x80047462); +pub const TIOCPKT: c_int = u32_cast_int(0x80047470); +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: crate::key_t = -1; +pub const SHM_LOCK: c_int = 201; +pub const SHM_UNLOCK: c_int = 202; + +// sys/ldr.h +pub const L_GETMESSAGES: c_int = 1; +pub const L_GETINFO: c_int = 2; +pub const L_GETLIBPATH: c_int = 3; +pub const L_GETKERNINFO: c_int = 4; +pub const L_GETLIB32INFO: c_int = 5; +pub const L_GETLIB64INFO: c_int = 6; +pub const L_GETPROCINFO: c_int = 7; +pub const L_GETXINFO: c_int = 8; + +// sys/limits.h + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const BC_BASE_MAX: c_int = 99; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const BC_DIM_MAX: c_int = 0x800; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const BC_SCALE_MAX: c_int = 99; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const BC_STRING_MAX: c_int = 0x800; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const CHARCLASS_NAME_MAX: c_int = 14; + +pub const CHILD_MAX: c_int = 128; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const COLL_WEIGHTS_MAX: c_int = 4; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 = 0o17_0000; +pub const S_IFREG: mode_t = 0o10_0000; +pub const S_IFDIR: mode_t = 0o4_0000; +pub const S_IFBLK: mode_t = 0o6_0000; +pub const S_IFCHR: mode_t = 0o2_0000; +pub const S_IFIFO: mode_t = 0o1_0000; +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_IFLNK: mode_t = 0o12_0000; +pub const S_IFSOCK: mode_t = 0o14_0000; +pub const S_IEXEC: mode_t = 0o0100; +pub const S_IWRITE: mode_t = 0o0200; +pub const S_IREAD: mode_t = 0o0400; + +// 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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 = u16_cast_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 = u32_cast_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 = u32_cast_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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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: crate::clockid_t = TIMEOFDAY as clockid_t; +pub const CLOCK_MONOTONIC: crate::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: crate::tcflag_t = 0o21; +pub const CSTOP: crate::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 = u32_cast_int(0x80087467); +pub const TIOCLBIS: c_int = u32_cast_int(0x8004747f); +pub const TIOCLBIC: c_int = u32_cast_int(0x8004747e); +pub const TIOCLSET: c_int = u32_cast_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 = u32_cast_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 = u32_cast_int(0x80047476); +pub const TIOCGSID: c_int = 0x40047448; +pub const TIOCSTI: c_int = u32_cast_int(0x80017472); +pub const TIOCMSET: c_int = u32_cast_int(0x8004746d); +pub const TIOCMBIS: c_int = u32_cast_int(0x8004746c); +pub const TIOCMBIC: c_int = u32_cast_int(0x8004746b); +pub const TIOCMGET: c_int = 0x4004746a; +pub const TIOCREMOTE: c_int = u32_cast_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: idtype_t = 0; +pub const P_PID: idtype_t = 1; +pub const P_PGID: idtype_t = 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: crate::tcflag_t = 2; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS5: crate::tcflag_t = 0x00000000; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const ECHO: crate::tcflag_t = 0x00000008; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOCTL: crate::tcflag_t = 0x00020000; +pub const ECHOPRT: crate::tcflag_t = 0x00040000; +pub const ECHOKE: crate::tcflag_t = 0x00080000; +pub const IGNBRK: crate::tcflag_t = 0x00000001; +pub const BRKINT: crate::tcflag_t = 0x00000002; +pub const IGNPAR: crate::tcflag_t = 0x00000004; +pub const PARMRK: crate::tcflag_t = 0x00000008; +pub const INPCK: crate::tcflag_t = 0x00000010; +pub const ISTRIP: crate::tcflag_t = 0x00000020; +pub const INLCR: crate::tcflag_t = 0x00000040; +pub const IGNCR: crate::tcflag_t = 0x00000080; +pub const ICRNL: crate::tcflag_t = 0x00000100; +pub const IXON: crate::tcflag_t = 0x00000200; +pub const IXOFF: crate::tcflag_t = 0x00000400; +pub const IXANY: crate::tcflag_t = 0x00001000; +pub const IMAXBEL: crate::tcflag_t = 0x00010000; +pub const OPOST: crate::tcflag_t = 0x00000001; +pub const ONLCR: crate::tcflag_t = 0x00000004; +pub const OCRNL: crate::tcflag_t = 0x00000008; +pub const ONOCR: crate::tcflag_t = 0x00000010; +pub const ONLRET: crate::tcflag_t = 0x00000020; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const IEXTEN: crate::tcflag_t = 0x00200000; +pub const TOSTOP: crate::tcflag_t = 0x00010000; +pub const FLUSHO: crate::tcflag_t = 0x00100000; +pub const PENDIN: crate::tcflag_t = 0x20000000; +pub const NOFLSH: crate::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: crate::speed_t = 0x0; +pub const B50: crate::speed_t = 0x1; +pub const B75: crate::speed_t = 0x2; +pub const B110: crate::speed_t = 0x3; +pub const B134: crate::speed_t = 0x4; +pub const B150: crate::speed_t = 0x5; +pub const B200: crate::speed_t = 0x6; +pub const B300: crate::speed_t = 0x7; +pub const B600: crate::speed_t = 0x8; +pub const B1200: crate::speed_t = 0x9; +pub const B1800: crate::speed_t = 0xa; +pub const B2400: crate::speed_t = 0xb; +pub const B4800: crate::speed_t = 0xc; +pub const B9600: crate::speed_t = 0xd; +pub const B19200: crate::speed_t = 0xe; +pub const B38400: crate::speed_t = 0xf; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const IUCLC: crate::tcflag_t = 0x00000800; +pub const OFILL: crate::tcflag_t = 0x00000040; +pub const OFDEL: crate::tcflag_t = 0x00000080; +pub const CRDLY: crate::tcflag_t = 0x00000300; +pub const CR0: crate::tcflag_t = 0x00000000; +pub const CR1: crate::tcflag_t = 0x00000100; +pub const CR2: crate::tcflag_t = 0x00000200; +pub const CR3: crate::tcflag_t = 0x00000300; +pub const TABDLY: crate::tcflag_t = 0x00000c00; +pub const TAB0: crate::tcflag_t = 0x00000000; +pub const TAB1: crate::tcflag_t = 0x00000400; +pub const TAB2: crate::tcflag_t = 0x00000800; +pub const TAB3: crate::tcflag_t = 0x00000c00; +pub const BSDLY: crate::tcflag_t = 0x00001000; +pub const BS0: crate::tcflag_t = 0x00000000; +pub const BS1: crate::tcflag_t = 0x00001000; +pub const FFDLY: crate::tcflag_t = 0x00002000; +pub const FF0: crate::tcflag_t = 0x00000000; +pub const FF1: crate::tcflag_t = 0x00002000; +pub const NLDLY: crate::tcflag_t = 0x00004000; +pub const NL0: crate::tcflag_t = 0x00000000; +pub const NL1: crate::tcflag_t = 0x00004000; +pub const VTDLY: crate::tcflag_t = 0x00008000; +pub const VT0: crate::tcflag_t = 0x00000000; +pub const VT1: crate::tcflag_t = 0x00008000; +pub const OXTABS: crate::tcflag_t = 0x00040000; +pub const ONOEOT: crate::tcflag_t = 0x00080000; +pub const CBAUD: crate::tcflag_t = 0x0000000f; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const CIBAUD: crate::tcflag_t = 0x000f0000; +pub const IBSHIFT: crate::tcflag_t = 16; +pub const PAREXT: crate::tcflag_t = 0x00100000; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const XCASE: crate::tcflag_t = 0x00000004; +pub const ALTWERASE: crate::tcflag_t = 0x00400000; + +// time.h +pub const CLOCK_PROCESS_CPUTIME_ID: crate::clockid_t = 11; +pub const CLOCK_THREAD_CPUTIME_ID: crate::clockid_t = 12; + +// unistd.h +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 = 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; + +f! { + pub unsafe fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize >= size_of::() { + (*mhdr).msg_control as *mut cmsghdr + } else { + ptr::null_mut() + } + } + + pub unsafe 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 + size_of::()) + > ((*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize) + { + ptr::null_mut() + } 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 unsafe fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + (cmsg as *mut c_uchar).offset(size_of::() as isize) + } + + pub const unsafe fn CMSG_LEN(length: c_uint) -> c_uint { + size_of::() as c_uint + length + } + + pub const unsafe fn CMSG_SPACE(length: c_uint) -> c_uint { + size_of::() as c_uint + length + } + + pub unsafe fn FD_ZERO(set: *mut fd_set) -> () { + (*set).fds_bits.fill(0); + } + + pub unsafe fn FD_SET(fd: c_int, set: *mut fd_set) -> () { + let bits = size_of::() * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] |= 1 << (fd % bits); + return; + } + + pub unsafe fn FD_CLR(fd: c_int, set: *mut fd_set) -> () { + let bits = size_of::() * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); + return; + } + + pub unsafe fn FD_ISSET(fd: c_int, set: *const fd_set) -> bool { + let bits = size_of::() * 8; + let fd = fd as usize; + return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0; + } +} + +safe_f! { + pub const safe fn WIFSTOPPED(status: c_int) -> bool { + (status & _W_STOPPED) != 0 + } + + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + if WIFSTOPPED(status) { + (((status as c_uint) >> 8) & 0xff) as c_int + } else { + -1 + } + } + + pub const safe fn WIFEXITED(status: c_int) -> bool { + (status & 0xFF) == 0 + } + + pub const safe fn WEXITSTATUS(status: c_int) -> c_int { + if WIFEXITED(status) { + (((status as c_uint) >> 8) & 0xff) as c_int + } else { + -1 + } + } + + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + !WIFEXITED(status) && !WIFSTOPPED(status) + } + + pub const safe fn WTERMSIG(status: c_int) -> c_int { + if WIFSIGNALED(status) { + (((status as c_uint) >> 16) & 0xff) as c_int + } else { + -1 + } + } + + pub const safe fn WIFCONTINUED(status: c_int) -> bool { + (status & WCONTINUED) != 0 + } + + // AIX doesn't have native WCOREDUMP. + pub const safe fn WCOREDUMP(_status: c_int) -> bool { + false + } + + pub const safe fn major(dev: crate::dev_t) -> c_uint { + let x = dev >> 16; + x as c_uint + } + + pub const safe fn minor(dev: crate::dev_t) -> c_uint { + let y = dev & 0xFFFF; + y as c_uint + } + + pub const safe fn makedev(major: c_uint, minor: c_uint) -> crate::dev_t { + let major = major as crate::dev_t; + let minor = minor as crate::dev_t; + let mut dev = 0; + dev |= major << 16; + dev |= minor; + dev + } +} + +#[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_getdetachstate( + attr: *const crate::pthread_attr_t, + detachstate: *mut c_int, + ) -> c_int; + + pub fn pthread_attr_getguardsize( + attr: *const crate::pthread_attr_t, + guardsize: *mut size_t, + ) -> c_int; + + pub fn pthread_attr_getinheritsched( + attr: *const crate::pthread_attr_t, + inheritsched: *mut c_int, + ) -> c_int; + + pub fn pthread_attr_getschedparam( + attr: *const crate::pthread_attr_t, + param: *mut sched_param, + ) -> c_int; + + pub fn pthread_attr_getstackaddr( + attr: *const crate::pthread_attr_t, + stackaddr: *mut *mut c_void, + ) -> c_int; + + pub fn pthread_attr_getschedpolicy( + attr: *const crate::pthread_attr_t, + policy: *mut c_int, + ) -> c_int; + + pub fn pthread_attr_getscope( + attr: *const crate::pthread_attr_t, + contentionscope: *mut c_int, + ) -> c_int; + + pub fn pthread_attr_getstack( + attr: *const crate::pthread_attr_t, + stackaddr: *mut *mut c_void, + stacksize: *mut size_t, + ) -> c_int; + + pub fn pthread_attr_setguardsize(attr: *mut crate::pthread_attr_t, guardsize: size_t) -> c_int; + + pub fn pthread_attr_setinheritsched( + attr: *mut crate::pthread_attr_t, + inheritsched: c_int, + ) -> c_int; + + pub fn pthread_attr_setschedparam( + attr: *mut crate::pthread_attr_t, + param: *const sched_param, + ) -> c_int; + + pub fn pthread_attr_setschedpolicy(attr: *mut crate::pthread_attr_t, policy: c_int) -> c_int; + + pub fn pthread_attr_setscope(attr: *mut crate::pthread_attr_t, contentionscope: c_int) + -> c_int; + + pub fn pthread_attr_setstack( + attr: *mut crate::pthread_attr_t, + stackaddr: *mut c_void, + stacksize: size_t, + ) -> c_int; + + pub fn pthread_attr_setstackaddr( + attr: *mut crate::pthread_attr_t, + stackaddr: *mut c_void, + ) -> c_int; + + pub fn pthread_barrierattr_destroy(attr: *mut crate::pthread_barrierattr_t) -> c_int; + + pub fn pthread_barrierattr_getpshared( + attr: *const crate::pthread_barrierattr_t, + pshared: *mut c_int, + ) -> c_int; + + pub fn pthread_barrierattr_init(attr: *mut crate::pthread_barrierattr_t) -> c_int; + + pub fn pthread_barrierattr_setpshared( + attr: *mut crate::pthread_barrierattr_t, + pshared: c_int, + ) -> 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 crate::pthread_barrierattr_t, + count: c_uint, + ) -> c_int; + + pub fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -> c_int; + + pub fn pthread_cancel(thread: crate::pthread_t) -> c_int; + + pub fn pthread_cleanup_pop(execute: c_int); + + pub fn pthread_cleanup_push( + routine: Option, + arg: *mut c_void, + ); + + 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: crate::clockid_t, + ) -> c_int; + + pub fn pthread_condattr_setpshared(attr: *mut pthread_condattr_t, pshared: c_int) -> c_int; + + pub fn pthread_create( + thread: *mut crate::pthread_t, + attr: *const crate::pthread_attr_t, + start_routine: extern "C" fn(*mut c_void) -> *mut c_void, + arg: *mut c_void, + ) -> c_int; + + pub fn pthread_getconcurrency() -> c_int; + + pub fn pthread_getcpuclockid( + thread_id: crate::pthread_t, + clock_id: *mut crate::clockid_t, + ) -> c_int; + + pub fn pthread_getschedparam( + thread: crate::pthread_t, + policy: *mut c_int, + param: *mut sched_param, + ) -> c_int; + + pub fn pthread_kill(thread: crate::pthread_t, sig: c_int) -> c_int; + + pub fn pthread_mutexattr_getprioceiling( + attr: *const crate::pthread_mutexattr_t, + prioceiling: *mut c_int, + ) -> 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: *const crate::pthread_mutexattr_t, + robust: *mut c_int, + ) -> c_int; + + pub fn pthread_mutexattr_gettype( + attr: *const crate::pthread_mutexattr_t, + _type: *mut c_int, + ) -> c_int; + + pub fn pthread_mutexattr_setprioceiling( + attr: *mut crate::pthread_mutexattr_t, + prioceiling: 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 crate::pthread_mutexattr_t, + robust: c_int, + ) -> c_int; + + pub fn pthread_mutex_consistent(mutex: *mut crate::pthread_mutex_t) -> c_int; + + pub fn pthread_mutex_getprioceiling( + mutex: *const crate::pthread_mutex_t, + prioceiling: *mut c_int, + ) -> c_int; + + pub fn pthread_mutex_setprioceiling( + mutex: *mut crate::pthread_mutex_t, + prioceiling: c_int, + old_ceiling: *mut c_int, + ) -> c_int; + + pub fn pthread_mutex_timedlock( + mutex: *mut pthread_mutex_t, + abstime: *const crate::timespec, + ) -> c_int; + + pub fn pthread_once( + once_control: *mut crate::pthread_once_t, + init_routine: Option, + ) -> c_int; + + pub fn pthread_rwlockattr_getpshared( + attr: *const pthread_rwlockattr_t, + pshared: *mut c_int, + ) -> c_int; + + pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t, pshared: c_int) -> c_int; + + pub fn pthread_rwlock_timedrdlock( + rwlock: *mut crate::pthread_rwlock_t, + abstime: *const crate::timespec, + ) -> c_int; + + pub fn pthread_rwlock_timedwrlock( + rwlock: *mut crate::pthread_rwlock_t, + abstime: *const crate::timespec, + ) -> c_int; + + pub fn pthread_setcancelstate(state: c_int, oldstate: *mut c_int) -> c_int; + pub fn pthread_setcanceltype(_type: c_int, oldtype: *mut c_int) -> c_int; + + pub fn pthread_setconcurrency(new_level: c_int) -> c_int; + + pub fn pthread_setschedparam( + thread: crate::pthread_t, + policy: c_int, + param: *const sched_param, + ) -> c_int; + + pub fn pthread_setschedprio(thread: crate::pthread_t, prio: c_int) -> c_int; + + pub fn pthread_sigmask(how: c_int, set: *const sigset_t, oset: *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; + + pub fn pthread_testcancel(); +} + +#[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: *mut c_char) -> c_int; + #[link_name = "_posix_aio_cancel"] + pub fn aio_cancel(fildes: c_int, aiocbp: *mut crate::aiocb) -> c_int; + #[link_name = "_posix_aio_error"] + pub fn aio_error(aiocbp: *const crate::aiocb) -> c_int; + #[link_name = "_posix_aio_fsync"] + pub fn aio_fsync(op: c_int, aiocbp: *mut crate::aiocb) -> c_int; + #[link_name = "_posix_aio_read"] + pub fn aio_read(aiocbp: *mut crate::aiocb) -> c_int; + #[link_name = "_posix_aio_return"] + pub fn aio_return(aiocbp: *mut crate::aiocb) -> ssize_t; + #[link_name = "_posix_aio_suspend"] + pub fn aio_suspend( + list: *const *const crate::aiocb, + nent: c_int, + timeout: *const crate::timespec, + ) -> c_int; + #[link_name = "_posix_aio_write"] + pub fn aio_write(aiocbp: *mut crate::aiocb) -> c_int; + pub fn basename(path: *mut c_char) -> *mut c_char; + pub fn bind( + socket: c_int, + address: *const crate::sockaddr, + address_len: crate::socklen_t, + ) -> c_int; + pub fn brk(addr: *mut c_void) -> c_int; + pub fn clearenv() -> c_int; + pub fn clock_getcpuclockid(pid: crate::pid_t, clk_id: *mut crate::clockid_t) -> c_int; + pub fn clock_getres(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_gettime(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_nanosleep( + clk_id: crate::clockid_t, + flags: c_int, + rqtp: *const crate::timespec, + rmtp: *mut crate::timespec, + ) -> c_int; + pub fn clock_settime(clock_id: crate::clockid_t, tp: *const crate::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 crate::DIR) -> c_int; + pub fn dirname(path: *mut c_char) -> *mut c_char; + pub fn drand48() -> c_double; + pub fn duplocale(arg1: crate::locale_t) -> crate::locale_t; + pub fn endgrent(); + pub fn endmntent(streamp: *mut crate::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; + + // DIFF(main): changed to `*const *mut` in e77f551de9 + 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 crate::FILE) -> *mut crate::group; + pub fn fgetpos64(stream: *mut crate::FILE, ptr: *mut fpos64_t) -> c_int; + pub fn fgetpwent(file: *mut crate::FILE) -> *mut crate::passwd; + pub fn fopen64(filename: *const c_char, mode: *const c_char) -> *mut crate::FILE; + pub fn freelocale(loc: crate::locale_t); + pub fn freopen64( + filename: *const c_char, + mode: *const c_char, + file: *mut crate::FILE, + ) -> *mut crate::FILE; + pub fn fseeko64(stream: *mut crate::FILE, offset: off64_t, whence: c_int) -> c_int; + pub fn fsetpos64(stream: *mut crate::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 crate::FILE) -> off64_t; + pub fn ftok(path: *const c_char, id: c_int) -> crate::key_t; + pub fn ftruncate64(fd: c_int, length: off64_t) -> c_int; + pub fn futimens(fd: c_int, times: *const crate::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 crate::group; + pub fn getgrgid(gid: crate::gid_t) -> *mut crate::group; + #[link_name = "_posix_getgrgid_r"] + pub fn getgrgid_r( + gid: crate::gid_t, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn getgrnam(name: *const c_char) -> *mut crate::group; + #[link_name = "_posix_getgrnam_r"] + pub fn getgrnam_r( + name: *const c_char, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn getgrset(user: *const c_char) -> *mut c_char; + pub fn gethostid() -> c_long; + pub fn getmntent(stream: *mut crate::FILE) -> *mut crate::mntent; + pub fn getnameinfo( + sa: *const crate::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 crate::uid_t, egid: *mut crate::gid_t) -> c_int; + pub fn getpriority(which: c_int, who: crate::id_t) -> c_int; + pub fn getpwent() -> *mut crate::passwd; + #[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; + #[link_name = "_posix_getpwuid_r"] + pub fn getpwuid_r( + uid: crate::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 crate::rlimit) -> c_int; + pub fn getrlimit64(resource: c_int, rlim: *mut rlimit64) -> c_int; + pub fn gettimeofday(tp: *mut crate::timeval, tz: *mut c_void) -> c_int; + pub fn getitimer(which: c_int, curr_value: *mut crate::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 crate::glob_t, + ) -> c_int; + pub fn globfree(pglob: *mut crate::glob_t); + pub fn hasmntopt(mnt: *const crate::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: ACTION) -> *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: crate::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; + #[link_name = "_posix_lio_listio"] + pub fn lio_listio( + mode: c_int, + aiocb_list: *const *mut aiocb, + nent: c_int, + sevp: *mut sigevent, + ) -> c_int; + pub fn loadquery(flags: c_int, buf: *mut c_void, 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: caddr_t, len: size_t, advice: c_int) -> c_int; + pub fn makecontext(ucp: *mut crate::ucontext_t, func: extern "C" fn(), argc: c_int, ...); + pub fn mallinfo() -> crate::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: caddr_t, 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: crate::mqd_t) -> c_int; + pub fn mq_getattr(mqd: crate::mqd_t, attr: *mut crate::mq_attr) -> c_int; + pub fn mq_notify(mqd: crate::mqd_t, notification: *const crate::sigevent) -> c_int; + pub fn mq_open(name: *const c_char, oflag: c_int, ...) -> crate::mqd_t; + pub fn mq_receive( + mqd: crate::mqd_t, + msg_ptr: *mut c_char, + msg_len: size_t, + msg_prio: *mut c_uint, + ) -> ssize_t; + pub fn mq_send( + mqd: crate::mqd_t, + msg_ptr: *const c_char, + msg_len: size_t, + msg_prio: c_uint, + ) -> c_int; + pub fn mq_setattr( + mqd: crate::mqd_t, + newattr: *const crate::mq_attr, + oldattr: *mut crate::mq_attr, + ) -> c_int; + pub fn mq_timedreceive( + mqd: crate::mqd_t, + msg_ptr: *mut c_char, + msg_len: size_t, + msg_prio: *mut c_uint, + abs_timeout: *const crate::timespec, + ) -> ssize_t; + pub fn mq_timedsend( + mqd: crate::mqd_t, + msg_ptr: *const c_char, + msg_len: size_t, + msg_prio: c_uint, + abs_timeout: *const crate::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: crate::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: crate::locale_t) -> crate::locale_t; + pub fn nl_langinfo(item: crate::nl_item) -> *mut c_char; + pub fn nl_langinfo_l(item: crate::nl_item, loc: crate::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 crate::pollfd, + array_length: c_int, + timeout: c_int, + ) -> c_int; + pub fn pollset_query(ps: pollset_t, pollfd_query: *mut crate::pollfd) -> c_int; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut crate::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 crate::pid_t, + path: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::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 crate::pid_t, + ) -> c_int; + pub fn posix_spawnattr_getschedparam( + attr: *const posix_spawnattr_t, + param: *mut crate::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: crate::pid_t) -> c_int; + pub fn posix_spawnattr_setschedparam( + attr: *mut posix_spawnattr_t, + param: *const crate::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 crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + default: *const crate::sigset_t, + ) -> c_int; + pub fn posix_spawnp( + pid: *mut crate::pid_t, + file: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::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 crate::iovec, iovcnt: c_int, offset: offset_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 crate::iovec, iovcnt: c_int, offset: offset_t) + -> ssize_t; + pub fn quotactl(cmd: *mut c_char, special: c_int, id: c_int, data: caddr_t) -> c_int; + pub fn rand() -> c_int; + pub fn readv(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + // AIX header socket.h maps recvfrom() to nrecvfrom() + #[link_name = "nrecvfrom"] + pub fn recvfrom( + socket: c_int, + buf: *mut c_void, + len: size_t, + flags: c_int, + addr: *mut crate::sockaddr, + addrlen: *mut crate::socklen_t, + ) -> ssize_t; + pub fn recvmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: c_uint, + flags: c_int, + timeout: *mut crate::timespec, + ) -> c_int; + // AIX header socket.h maps recvmsg() to nrecvmsg(). + #[link_name = "nrecvmsg"] + 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 crate::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: crate::pid_t, param: *mut sched_param) -> c_int; + pub fn sched_getscheduler(pid: crate::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: crate::pid_t, tp: *mut crate::timespec) -> c_int; + pub fn sched_setparam(pid: crate::pid_t, param: *const crate::sched_param) -> c_int; + pub fn sched_setscheduler( + pid: crate::pid_t, + policy: c_int, + param: *const crate::sched_param, + ) -> c_int; + pub fn sctp_opt_info( + sd: c_int, + id: crate::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: *mut c_uint) -> c_int; + pub fn seed48(xseed: *mut c_ushort) -> *mut c_ushort; + pub fn seekdir(dirp: *mut crate::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 crate::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: crate::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; + // AIX header socket.h maps sendmsg() to nsendmsg(). + #[link_name = "nsendmsg"] + 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 crate::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 crate::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 crate::rlimit) -> c_int; + pub fn setrlimit64(resource: c_int, rlim: *const rlimit64) -> c_int; + pub fn settimeofday(tv: *const crate::timeval, tz: *const crate::timezone) -> c_int; + pub fn setitimer( + which: c_int, + new_value: *const crate::itimerval, + old_value: *mut crate::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 crate::sigset_t) -> c_int; + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const crate::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 crate::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: crate::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: crate::locale_t, + ) -> c_int; + pub fn strptime(s: *const c_char, format: *const c_char, tm: *mut crate::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(path: *const c_char) -> c_int; + pub fn swapon(path: *const c_char) -> c_int; + pub fn sync(); + pub fn telldir(dirp: *mut crate::DIR) -> c_long; + pub fn timer_create( + clockid: crate::clockid_t, + sevp: *mut crate::sigevent, + timerid: *mut crate::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: crate::timer_t, + flags: c_int, + new_value: *const crate::itimerspec, + old_value: *mut crate::itimerspec, + ) -> c_int; + pub fn truncate64(path: *const c_char, length: off64_t) -> c_int; + pub fn uname(buf: *mut crate::utsname) -> c_int; + pub fn updwtmp(file: *const c_char, u: *const utmp); + pub fn uselocale(loc: crate::locale_t) -> crate::locale_t; + pub fn utmpname(file: *const c_char) -> c_int; + pub fn utimensat( + dirfd: c_int, + path: *const c_char, + times: *const crate::timespec, + flag: c_int, + ) -> c_int; + pub fn wait4( + pid: crate::pid_t, + status: *mut c_int, + options: c_int, + rusage: *mut crate::rusage, + ) -> crate::pid_t; + pub fn waitid( + idtype: idtype_t, + id: id_t, + infop: *mut crate::siginfo_t, + options: c_int, + ) -> c_int; + pub fn writev(fd: c_int, iov: *const crate::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..cd43904 --- /dev/null +++ b/vendor/libc/src/unix/aix/powerpc64.rs @@ -0,0 +1,427 @@ +use crate::off_t; +use crate::prelude::*; + +// Define lock_data_instrumented as an empty enum +extern_ty! { + pub type lock_data_instrumented; +} + +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: crate::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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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 pthread_once_t { + __on_word: [c_long; 9], + } + + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_flag: c_ushort, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub st_ssize: c_int, + pub st_atim: crate::st_timespec, + pub st_mtim: crate::st_timespec, + pub st_ctim: crate::st_timespec, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_vfstype: c_int, + pub st_vfs: c_uint, + pub st_type: c_uint, + pub st_gen: c_uint, + st_reserved: Padding<[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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsblkcnt_t, + pub f_ffree: crate::fsblkcnt_t, + pub f_fsid: crate::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: crate::sigevent, + pub aio_word2: c_int, + pub aio_fp: c_int, + pub aio_handle: *mut aiocb, + aio_reserved: Padding<[c_uint; 2]>, + pub aio_sigev_tid: c_long, + } + + pub struct __vmxreg_t { + __v: [c_uint; 4], + } + + pub struct __vmx_context_t { + pub __vr: [crate::__vmxreg_t; 32], + pub __pad1: [c_uint; 3], + pub __vscr: c_uint, + pub __vrsave: c_uint, + pub __pad2: [c_uint; 3], + } + + pub struct __vsx_context_t { + pub __vsr_dw1: [c_ulonglong; 32], + } + + pub struct __tm_context_t { + pub vmx: crate::__vmx_context_t, + pub vsx: crate::__vsx_context_t, + pub gpr: [c_ulonglong; 32], + pub lr: c_ulonglong, + pub ctr: c_ulonglong, + pub cr: c_uint, + pub xer: c_uint, + pub amr: c_ulonglong, + pub texasr: c_ulonglong, + pub tfiar: c_ulonglong, + pub tfhar: c_ulonglong, + pub ppr: c_ulonglong, + pub dscr: c_ulonglong, + pub tar: c_ulonglong, + pub fpscr: c_uint, + pub fpscrx: c_uint, + pub fpr: [fpreg_t; 32], + pub tmcontext: c_char, + pub tmstate: c_char, + pub prevowner: c_char, + pub pad: [c_char; 5], + } + + pub struct __context64 { + 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], + pub fpr: [fpreg_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 mcontext_t { + pub jmp_context: __context64, + } + + pub struct __extctx_t { + pub __flags: c_uint, + pub __rsvd1: [c_uint; 3], + pub __vmx: crate::__vmx_context_t, + pub __ukeys: [c_uint; 2], + pub __vsx: crate::__vsx_context_t, + pub __tm: crate::__tm_context_t, + __reserved: Padding<[c_char; 1860]>, + pub __extctx_magic: c_int, + } + + pub struct ucontext_t { + pub __sc_onstack: c_int, + pub uc_sigmask: crate::sigset_t, + pub __sc_uerror: c_int, + pub uc_mcontext: crate::mcontext_t, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub __extctx: *mut crate::__extctx_t, + pub __extctx_magic: c_int, + pub __pad: [c_int; 1], + } + + pub struct utmpx { + pub ut_user: [c_char; 256], + pub ut_id: [c_char; 14], + pub ut_line: [c_char; 64], + pub ut_pid: crate::pid_t, + pub ut_type: c_short, + pub ut_tv: crate::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: crate::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: crate::pid_t, + pub msg_lrpid: crate::pid_t, + pub msg_stime: crate::time_t, + pub msg_rtime: crate::time_t, + pub msg_ctime: crate::time_t, + pub msg_rwait: c_int, + pub msg_wwait: c_int, + pub msg_reqevents: c_ushort, + } + + pub struct siginfo_t { + pub si_signo: c_int, + pub si_errno: c_int, + pub si_code: c_int, + pub si_pid: crate::pid_t, + pub si_uid: crate::uid_t, + pub si_status: c_int, + pub si_addr: *mut c_void, + pub si_band: c_long, + pub si_value: crate::sigval, + pub __si_flags: c_int, + pub __pad: [c_int; 3], + } + + pub struct pollfd_ext { + pub fd: c_int, + pub events: c_short, + pub revents: c_short, + pub data: __pollfd_ext_u, + } +} + +s_no_extra_traits! { + pub union _kernel_simple_lock { + pub _slock: c_long, + pub _slockp: *mut lock_data_instrumented, + } + + pub struct fileops_t { + pub fo_rw: Option< + extern "C" fn( + file: *mut file, + rw: crate::uio_rw, + io: *mut c_void, + ext: c_long, + secattr: *mut c_void, + ) -> c_int, + >, + pub fo_ioctl: Option< + extern "C" fn( + file: *mut file, + a: c_long, + b: crate::caddr_t, + c: c_long, + d: c_long, + ) -> c_int, + >, + pub fo_select: Option< + extern "C" fn(file: *mut file, a: c_int, b: *mut c_ushort, c: extern "C" fn()) -> c_int, + >, + pub fo_close: Option c_int>, + pub fo_fstat: Option 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, + pub f_lock: _kernel_simple_lock, + pub f_offset_lock: _kernel_simple_lock, + pub f_vinfo: crate::caddr_t, + pub f_ops: *mut fileops_t, + pub f_parentp: crate::caddr_t, + pub f_fnamep: crate::caddr_t, + pub f_fdata: [c_char; 160], + } + + 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, + 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], + } + + pub union __pollfd_ext_u { + pub addr: *mut c_void, + pub data32: u32, + pub data: u64, + } + + pub struct fpreg_t { + pub d: c_double, + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut c_void { + self.si_addr + } + + pub unsafe fn si_value(&self) -> crate::sigval { + self.si_value + } + + pub unsafe fn si_pid(&self) -> crate::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> crate::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 __pollfd_ext_u { + fn eq(&self, other: &__pollfd_ext_u) -> bool { + unsafe { + self.addr == other.addr + && self.data32 == other.data32 + && self.data == other.data + } + } + } + impl Eq for __pollfd_ext_u {} + 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 fpreg_t { + fn eq(&self, other: &fpreg_t) -> bool { + self.d == other.d + } + } + impl Eq for fpreg_t {} + impl hash::Hash for fpreg_t { + fn hash(&self, state: &mut H) { + let d: u64 = self.d.to_bits(); + d.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 PTHREAD_ONCE_INIT: pthread_once_t = pthread_once_t { + __on_word: [0, 0, 0, 0, 0, 2, 0, 0, 0], +}; + +pub const RLIM_INFINITY: c_ulong = 0x7fffffffffffffff; + +extern "C" { + pub fn getsystemcfg(label: c_int) -> c_ulong; +} diff --git a/vendor/libc/src/unix/bsd/apple/b32/mod.rs b/vendor/libc/src/unix/bsd/apple/b32/mod.rs new file mode 100644 index 0000000..e71378c --- /dev/null +++ b/vendor/libc/src/unix/bsd/apple/b32/mod.rs @@ -0,0 +1,70 @@ +//! 32-bit specific Apple (ios/darwin) definitions + +use crate::prelude::*; + +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: crate::timeval, + pub ifi_unused2: u32, + pub ifi_hwassist: u32, + pub ifi_reserved1: u32, + pub ifi_reserved2: u32, + } + + pub struct bpf_hdr { + pub bh_tstamp: crate::timeval, + pub bh_caplen: u32, + pub bh_datalen: u32, + pub bh_hdrlen: c_ushort, + } + + pub struct malloc_zone_t { + __private: [crate::uintptr_t; 18], // FIXME(macos): keeping private for now + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 2], + } +} + +#[doc(hidden)] +#[deprecated(since = "0.2.55")] +pub const NET_RT_MAXID: c_int = 10; + +pub const BIOCSETF: c_ulong = 0x80084267; +pub const BIOCSRTIMEOUT: c_ulong = 0x8008426d; +pub const BIOCGRTIMEOUT: c_ulong = 0x4008426e; +pub const BIOCSETFNR: c_ulong = 0x8008427e; + +extern "C" { + pub fn exchangedata(path1: *const c_char, path2: *const c_char, options: c_ulong) -> c_int; +} 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..b5cbe8f --- /dev/null +++ b/vendor/libc/src/unix/bsd/apple/b64/aarch64/mod.rs @@ -0,0 +1,15 @@ +use crate::prelude::*; + +pub type boolean_t = c_int; + +s! { + pub struct malloc_zone_t { + __private: [crate::uintptr_t; 18], // FIXME(macos): needs arm64 auth pointers support + } +} + +s_no_extra_traits! { + pub struct max_align_t { + priv_: f64, + } +} 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..359aa79 --- /dev/null +++ b/vendor/libc/src/unix/bsd/apple/b64/mod.rs @@ -0,0 +1,75 @@ +//! 64-bit specific Apple (ios/darwin) definitions + +use crate::prelude::*; + +s! { + #[derive(Default)] + 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: crate::timeval32, + pub bh_caplen: u32, + pub bh_datalen: u32, + pub bh_hdrlen: c_ushort, + } +} + +#[doc(hidden)] +#[deprecated(since = "0.2.55")] +pub const NET_RT_MAXID: c_int = 11; + +pub const BIOCSETF: c_ulong = 0x80104267; +pub const BIOCSRTIMEOUT: c_ulong = 0x8010426d; +pub const BIOCGRTIMEOUT: c_ulong = 0x4010426e; +pub const BIOCSETFNR: c_ulong = 0x8010427e; + +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/mod.rs b/vendor/libc/src/unix/bsd/apple/b64/x86_64/mod.rs new file mode 100644 index 0000000..dac8c9e --- /dev/null +++ b/vendor/libc/src/unix/bsd/apple/b64/x86_64/mod.rs @@ -0,0 +1,77 @@ +use crate::prelude::*; + +pub type boolean_t = c_uint; + +s! { + pub struct malloc_introspection_t { + _private: [crate::uintptr_t; 16], // FIXME(macos): keeping private for now + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct malloc_zone_t { + _reserved1: Padding<*mut c_void>, + _reserved2: Padding<*mut c_void>, + pub size: + Option size_t>, + pub malloc: + Option *mut c_void>, + pub calloc: Option< + unsafe extern "C" fn( + zone: *mut malloc_zone_t, + num_items: size_t, + size: size_t, + ) -> *mut c_void, + >, + pub valloc: + Option *mut c_void>, + pub free: Option, + pub realloc: Option< + unsafe extern "C" fn( + zone: *mut malloc_zone_t, + ptr: *mut c_void, + size: size_t, + ) -> *mut c_void, + >, + pub destroy: Option, + pub zone_name: *const c_char, + pub batch_malloc: Option< + unsafe extern "C" fn( + zone: *mut malloc_zone_t, + size: size_t, + results: *mut *mut c_void, + num_requested: c_uint, + ) -> c_uint, + >, + pub batch_free: Option< + unsafe extern "C" fn( + zone: *mut malloc_zone_t, + to_be_freed: *mut *mut c_void, + num_to_be_freed: c_uint, + ), + >, + pub introspect: *mut malloc_introspection_t, + pub version: c_uint, + pub memalign: Option< + unsafe extern "C" fn( + zone: *mut malloc_zone_t, + alignment: size_t, + size: size_t, + ) -> *mut c_void, + >, + pub free_definite_size: + Option, + pub pressure_relief: + Option size_t>, + pub claimed_address: Option< + unsafe extern "C" fn(zone: *mut malloc_zone_t, ptr: *mut c_void) -> crate::boolean_t, + >, + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 2], + } +} 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..ab6736a --- /dev/null +++ b/vendor/libc/src/unix/bsd/apple/mod.rs @@ -0,0 +1,5280 @@ +//! Apple (ios/darwin)-specific definitions +//! +//! This covers *-apple-* triples currently + +use crate::prelude::*; +use crate::{ + cmsghdr, + off_t, +}; + +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 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 = crate::uintptr_t; +pub type vm_size_t = crate::uintptr_t; +pub type vm_address_t = vm_offset_t; +pub type quad_t = i64; +pub type u_quad_t = u64; + +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 = crate::mach_port_t; +pub type thread_act_t = crate::mach_port_t; +pub type thread_act_array_t = *mut crate::thread_act_t; +pub type policy_t = c_int; +pub type mach_error_t = crate::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 = crate::mach_port_t; +pub type mem_entry_name_port_t = crate::mach_port_t; +pub type memory_object_t = crate::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 = crate::mach_port_t; +pub type ledger_array_t = *mut crate::ledger_t; + +pub type iconv_t = *mut c_void; + +// mach/host_info.h +pub type host_cpu_load_info_t = *mut host_cpu_load_info; +pub type host_cpu_load_info_data_t = host_cpu_load_info; + +// mach/processor_info.h +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 = crate::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_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 = crate::mach_port_t; +pub type task_inspect_t = crate::mach_port_t; + +pub type sysdir_search_path_enumeration_state = c_uint; + +pub type CCStatus = i32; +pub type CCCryptorStatus = i32; +pub type CCRNGStatus = crate::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; +} + +extern_ty! { + pub type timezone; +} + +#[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 + } +} + +#[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: Padding, + pub gl_offs: size_t, + __unused2: Padding, + pub gl_pathv: *mut *mut c_char, + + __unused3: Padding<*mut c_void>, + + __unused4: Padding<*mut c_void>, + __unused5: Padding<*mut c_void>, + __unused6: Padding<*mut c_void>, + __unused7: Padding<*mut c_void>, + __unused8: Padding<*mut c_void>, + } + + 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 addrinfo { + pub ai_flags: c_int, + pub ai_family: c_int, + pub ai_socktype: c_int, + pub ai_protocol: c_int, + pub ai_addrlen: crate::socklen_t, + pub ai_canonname: *mut c_char, + pub ai_addr: *mut crate::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: crate::uid_t, + pub st_gid: crate::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: crate::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 siginfo_t { + pub si_signo: c_int, + pub si_errno: c_int, + pub si_code: c_int, + pub si_pid: crate::pid_t, + pub si_uid: crate::uid_t, + pub si_status: c_int, + pub si_addr: *mut c_void, + //Requires it to be union for tests + //pub si_value: crate::sigval, + _pad: Padding<[usize; 9]>, + } + + pub struct sigaction { + // FIXME(union): this field is actually a union + pub sa_sigaction: crate::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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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: crate::sa_family_t, + pub sin_port: crate::in_port_t, + pub sin_addr: crate::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: crate::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: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_cc: [crate::cc_t; crate::NCCS], + pub c_ispeed: crate::speed_t, + pub c_ospeed: crate::speed_t, + } + + pub struct flock { + pub l_start: off_t, + pub l_len: off_t, + pub l_pid: crate::pid_t, + pub l_type: c_short, + pub l_whence: c_short, + } + + pub struct sf_hdtr { + pub headers: *mut crate::iovec, + pub hdr_cnt: c_int, + pub trailers: *mut crate::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: crate::uid_t, + pub pbi_gid: crate::gid_t, + pub pbi_ruid: crate::uid_t, + pub pbi_rgid: crate::gid_t, + pub pbi_svuid: crate::uid_t, + pub pbi_svgid: crate::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_bsdshortinfo { + /// Process ID. + pub pbsi_pid: u32, + /// Process parent ID. + pub pbsi_ppid: u32, + /// Process perp ID. + pub pbsi_pgid: u32, + /// `p_stat` value: `SZOMB`, `SRUN`, etc. + pub pbsi_status: u32, + /// Up to 16 characters of process name. + pub pbsi_comm: [c_char; MAXCOMLEN], + /// 64bit, emulated, etc. + pub pbsi_flags: u32, + /// Current UID on process. + pub pbsi_uid: crate::uid_t, + /// Current GID on process. + pub pbsi_gid: crate::gid_t, + /// Current RUID on process. + pub pbsi_ruid: crate::uid_t, + /// Current RGID on process. + pub pbsi_rgid: crate::gid_t, + /// Current SVUID on process. + pub pbsi_svuid: crate::uid_t, + /// Current SVGID on process. + pub pbsi_svgid: crate::gid_t, + /// Reserved for future use. + pbsi_rfu: u32, + } + + 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: crate::boolean_t, + } + + pub struct xucred { + pub cr_version: c_uint, + pub cr_uid: crate::uid_t, + pub cr_ngroups: c_short, + pub cr_groups: [crate::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: crate::in_addr, + pub sin_srcaddr: crate::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: crate::in_addr, + pub ipi_addr: crate::in_addr, + } + + pub struct in6_pktinfo { + pub ipi6_addr: crate::in6_addr, + pub ipi6_ifindex: c_uint, + } + + // sys/ipc.h: + + pub struct ipc_perm { + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: mode_t, + pub _seq: c_ushort, + pub _key: crate::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: crate::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; crate::IFNAMSIZ], + } + + // sys/socket.h + + pub struct sa_endpoints_t { + pub sae_srcif: c_uint, // optional source interface + pub sae_srcaddr: *const crate::sockaddr, // optional source address + pub sae_srcaddrlen: crate::socklen_t, // size of source address + pub sae_dstaddr: *const crate::sockaddr, // destination address + pub sae_dstaddrlen: crate::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: crate::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: crate::vm_address_t, + pub size: crate::vm_size_t, + } + + pub struct vinfo_stat { + pub vst_dev: u32, + pub vst_mode: u16, + pub vst_nlink: u16, + pub vst_ino: u64, + pub vst_uid: crate::uid_t, + pub vst_gid: crate::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: crate::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: crate::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, + } + + #[repr(align(8))] + pub struct tcp_connection_info { + pub tcpi_state: u8, + pub tcpi_snd_wscale: u8, + pub tcpi_rcv_wscale: u8, + __pad1: Padding, + 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: Padding, + 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, + } + + pub struct in6_addrlifetime { + pub ia6t_expire: time_t, + pub ia6t_preferred: time_t, + pub ia6t_vltime: u32, + pub ia6t_pltime: u32, + } + + pub struct in6_ifstat { + pub ifs6_in_receive: crate::u_quad_t, + pub ifs6_in_hdrerr: crate::u_quad_t, + pub ifs6_in_toobig: crate::u_quad_t, + pub ifs6_in_noroute: crate::u_quad_t, + pub ifs6_in_addrerr: crate::u_quad_t, + pub ifs6_in_protounknown: crate::u_quad_t, + pub ifs6_in_truncated: crate::u_quad_t, + pub ifs6_in_discard: crate::u_quad_t, + pub ifs6_in_deliver: crate::u_quad_t, + pub ifs6_out_forward: crate::u_quad_t, + pub ifs6_out_request: crate::u_quad_t, + pub ifs6_out_discard: crate::u_quad_t, + pub ifs6_out_fragok: crate::u_quad_t, + pub ifs6_out_fragfail: crate::u_quad_t, + pub ifs6_out_fragcreat: crate::u_quad_t, + pub ifs6_reass_reqd: crate::u_quad_t, + pub ifs6_reass_ok: crate::u_quad_t, + pub ifs6_atmfrag_rcvd: crate::u_quad_t, + pub ifs6_reass_fail: crate::u_quad_t, + pub ifs6_in_mcast: crate::u_quad_t, + pub ifs6_out_mcast: crate::u_quad_t, + pub ifs6_cantfoward_icmp6: crate::u_quad_t, + pub ifs6_addr_expiry_cnt: crate::u_quad_t, + pub ifs6_pfx_expiry_cnt: crate::u_quad_t, + pub ifs6_defrtr_expiry_cnt: crate::u_quad_t, + } + + pub struct icmp6_ifstat { + pub ifs6_in_msg: crate::u_quad_t, + pub ifs6_in_error: crate::u_quad_t, + pub ifs6_in_dstunreach: crate::u_quad_t, + pub ifs6_in_adminprohib: crate::u_quad_t, + pub ifs6_in_timeexceed: crate::u_quad_t, + pub ifs6_in_paramprob: crate::u_quad_t, + pub ifs6_in_pkttoobig: crate::u_quad_t, + pub ifs6_in_echo: crate::u_quad_t, + pub ifs6_in_echoreply: crate::u_quad_t, + pub ifs6_in_routersolicit: crate::u_quad_t, + pub ifs6_in_routeradvert: crate::u_quad_t, + pub ifs6_in_neighborsolicit: crate::u_quad_t, + pub ifs6_in_neighboradvert: crate::u_quad_t, + pub ifs6_in_redirect: crate::u_quad_t, + pub ifs6_in_mldquery: crate::u_quad_t, + pub ifs6_in_mldreport: crate::u_quad_t, + pub ifs6_in_mlddone: crate::u_quad_t, + pub ifs6_out_msg: crate::u_quad_t, + pub ifs6_out_error: crate::u_quad_t, + pub ifs6_out_dstunreach: crate::u_quad_t, + pub ifs6_out_adminprohib: crate::u_quad_t, + pub ifs6_out_timeexceed: crate::u_quad_t, + pub ifs6_out_paramprob: crate::u_quad_t, + pub ifs6_out_pkttoobig: crate::u_quad_t, + pub ifs6_out_echo: crate::u_quad_t, + pub ifs6_out_echoreply: crate::u_quad_t, + pub ifs6_out_routersolicit: crate::u_quad_t, + pub ifs6_out_routeradvert: crate::u_quad_t, + pub ifs6_out_neighborsolicit: crate::u_quad_t, + pub ifs6_out_neighboradvert: crate::u_quad_t, + pub ifs6_out_redirect: crate::u_quad_t, + pub ifs6_out_mldquery: crate::u_quad_t, + pub ifs6_out_mldreport: crate::u_quad_t, + pub ifs6_out_mlddone: crate::u_quad_t, + } + + // mach/host_info.h + pub struct host_cpu_load_info { + pub cpu_ticks: [crate::natural_t; CPU_STATE_MAX as usize], + } + + // net/if_mib.h + pub struct ifmibdata { + /// Name of interface + pub ifmd_name: [c_char; crate::IFNAMSIZ], + /// Number of promiscuous listeners + pub ifmd_pcount: c_uint, + /// Interface flags + pub ifmd_flags: c_uint, + /// Instantaneous length of send queue + pub ifmd_snd_len: c_uint, + /// Maximum length of send queue + pub ifmd_snd_maxlen: c_uint, + /// Number of drops in send queue + pub ifmd_snd_drops: c_uint, + /// For future expansion + pub ifmd_filler: [c_uint; 4], + /// Generic information and statistics + pub ifmd_data: if_data64, + } + + pub struct ifs_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, + } + + // kern_control.h + pub struct ctl_info { + pub ctl_id: u32, + pub ctl_name: [c_char; MAX_KCTL_NAME], + } + + // sys/proc_info.h + pub struct proc_fdinfo { + pub proc_fd: i32, + pub proc_fdtype: u32, + } + + #[repr(packed(4))] + pub struct kevent { + pub ident: crate::uintptr_t, + pub filter: i16, + pub flags: u16, + pub fflags: u32, + pub data: intptr_t, + pub udata: *mut c_void, + } + + #[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: crate::time_t, + pub sem_pad1: i32, + pub sem_ctime: crate::time_t, + pub sem_pad2: i32, + pub sem_pad3: [i32; 4], + } + + #[repr(packed(4))] + pub struct shmid_ds { + pub shm_perm: ipc_perm, + pub shm_segsz: size_t, + pub shm_lpid: crate::pid_t, + pub shm_cpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + pub shm_atime: crate::time_t, // FIXME(macos): 64-bit wrong align => wrong offset + pub shm_dtime: crate::time_t, // FIXME(macos): 64-bit wrong align => wrong offset + pub shm_ctime: crate::time_t, // FIXME(macos): 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: crate::fsid_t, + pub f_owner: crate::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 sockaddr_storage { + pub ss_len: u8, + pub ss_family: crate::sa_family_t, + __ss_pad1: Padding<[u8; 6]>, + __ss_align: i64, + __ss_pad2: Padding<[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: crate::pid_t, + pub ut_type: c_short, + pub ut_tv: crate::timeval, + pub ut_host: [c_char; _UTX_HOSTSIZE], + ut_pad: Padding<[u32; 16]>, + } + + pub struct sigevent { + pub sigev_notify: c_int, + pub sigev_signo: c_int, + pub sigev_value: crate::sigval, + __unused1: Padding<*mut c_void>, //actually a function pointer + pub sigev_notify_attributes: *mut crate::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: crate::boolean_t, + pub slot_num: c_int, + pub is_master: crate::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: crate::integer_t, + pub policy: crate::policy_t, + pub run_state: crate::integer_t, + pub flags: crate::integer_t, + pub suspend_count: crate::integer_t, + pub sleep_time: crate::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], + } + + #[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: crate::timeval, + #[cfg(not(target_pointer_width = "32"))] + pub ifi_lastchange: timeval32, + } + + #[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, + } + + #[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, + pub swapped_count: u64, + pub total_tag_storage_pages: u64, + pub nontag_pageable_tag_storage_pages: u64, + pub nontag_wired_tag_storage_pages: u64, + pub free_tag_storage_pages: u64, + pub tag_storing_tag_storage_pages: u64, + pub total_tagged_pages: u64, + pub resident_tagged_pages: u64, + pub compressed_tagged_pages: u64, + pub tagged_compressions: u64, + pub tagged_decompressions: u64, + pub compressed_tag_storage_bytes: u64, + pub speculative_pages_created: u64, + pub speculative_pages_activated: u64, + pub swap_count: u64, + pub empty_tag_storing_tag_storage_pages: u64, + pub executable_count: u64, + pub shared_region_count: u64, + pub boot_stolen_count: u64, + pub secluded_count: u64, + pub active_internal_count: u64, + pub inactive_internal_count: u64, + pub active_external_count: u64, + pub inactive_external_count: u64, + pub purgeable_pageable_count: u64, + pub purgeable_wired_count: u64, + pub background_internal_count: u64, + pub background_external_count: u64, + pub donated_count: u64, + pub realtime_count: u64, + pub max_mem_count: u64, + pub phantom_ghosts_found: u64, + pub phantom_ghosts_added: u64, + } + + #[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: crate::policy_t, + pub suspend_count: integer_t, + } + + #[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, + } + + #[repr(packed(1))] + pub struct sockaddr_vm { + pub svm_len: c_uchar, + pub svm_family: crate::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, + } + + #[repr(packed(4))] + pub struct ifkpi { + pub ifk_module_id: c_uint, + pub ifk_type: c_uint, + pub ifk_data: __c_anonymous_ifk_data, + } + + pub struct ifreq { + pub ifr_name: [c_char; crate::IFNAMSIZ], + pub ifr_ifru: __c_anonymous_ifr_ifru, + } + + pub struct in6_ifreq { + pub ifr_name: [c_char; crate::IFNAMSIZ], + pub ifr_ifru: __c_anonymous_ifr_ifru6, + } +} + +s_no_extra_traits! { + #[repr(packed(4))] + pub struct ifconf { + pub ifc_len: c_int, + pub ifc_ifcu: __c_anonymous_ifc_ifcu, + } + pub union __c_anonymous_ifk_data { + pub ifk_ptr: *mut c_void, + pub ifk_value: c_int, + } + + pub union __c_anonymous_ifr_ifru { + pub ifru_addr: crate::sockaddr, + pub ifru_dstaddr: crate::sockaddr, + pub ifru_broadaddr: crate::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 union __c_anonymous_ifc_ifcu { + pub ifcu_buf: *mut c_char, + pub ifcu_req: *mut ifreq, + } + + pub union __c_anonymous_ifr_ifru6 { + pub ifru_addr: crate::sockaddr_in6, + pub ifru_dstaddr: crate::sockaddr_in6, + pub ifru_flags: c_int, + pub ifru_flags6: c_int, + pub ifru_metrics: c_int, + pub ifru_intval: c_int, + pub ifru_data: *mut c_char, + pub ifru_lifetime: in6_addrlifetime, + pub ifru_stat: in6_ifstat, + pub ifru_icmp6stat: icmp6_ifstat, + pub ifru_scope_id: [u32; SCOPE6_ID_MAX], + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut c_void { + self.si_addr + } + + pub unsafe fn si_value(&self) -> crate::sigval { + #[repr(C)] + struct siginfo_timer { + _si_signo: c_int, + _si_errno: c_int, + _si_code: c_int, + _si_pid: crate::pid_t, + _si_uid: crate::uid_t, + _si_status: c_int, + _si_addr: *mut c_void, + si_value: crate::sigval, + } + + (*(self as *const siginfo_t).cast::()).si_value + } + + pub unsafe fn si_pid(&self) -> crate::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> crate::uid_t { + self.si_uid + } + + pub unsafe fn si_status(&self) -> c_int { + self.si_status + } +} + +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 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 ifconf + where + Self: Copy, + { + fn eq(&self, other: &Self) -> bool { + let len_ptr1 = core::ptr::addr_of!(self.ifc_len); + let len_ptr2 = core::ptr::addr_of!(other.ifc_len); + let ifcu_ptr1 = core::ptr::addr_of!(self.ifc_ifcu); + let ifcu_ptr2 = core::ptr::addr_of!(other.ifc_ifcu); + + // SAFETY: `ifconf` implements `Copy` so the reads are valid + let len1 = unsafe { len_ptr1.read_unaligned() }; + let len2 = unsafe { len_ptr2.read_unaligned() }; + let ifcu1 = unsafe { ifcu_ptr1.read_unaligned() }; + let ifcu2 = unsafe { ifcu_ptr2.read_unaligned() }; + + len1 == len2 && ifcu1 == ifcu2 + } + } + impl Eq for ifconf {} + + 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 } + } + } + + impl Eq for __c_anonymous_ifk_data {} + 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 __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 + } + } + } + + impl Eq for __c_anonymous_ifr_ifru {} + + 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 Eq for __c_anonymous_ifc_ifcu {} + + 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 } + } + } + + 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 __c_anonymous_ifr_ifru6 { + fn eq(&self, other: &__c_anonymous_ifr_ifru6) -> bool { + unsafe { + self.ifru_addr == other.ifru_addr + && self.ifru_dstaddr == other.ifru_dstaddr + && self.ifru_flags == other.ifru_flags + && self.ifru_flags6 == other.ifru_flags6 + && self.ifru_metrics == other.ifru_metrics + && self.ifru_intval == other.ifru_intval + && self.ifru_data == other.ifru_data + && self + .ifru_scope_id + .iter() + .zip(other.ifru_scope_id.iter()) + .all(|(a, b)| a == b) + } + } + } + + impl Eq for __c_anonymous_ifr_ifru6 {} + + impl hash::Hash for __c_anonymous_ifr_ifru6 { + fn hash(&self, state: &mut H) { + unsafe { + self.ifru_addr.hash(state); + self.ifru_dstaddr.hash(state); + self.ifru_flags.hash(state); + self.ifru_flags6.hash(state); + self.ifru_metrics.hash(state); + self.ifru_intval.hash(state); + self.ifru_data.hash(state); + self.ifru_scope_id.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: crate::nl_item = 0; +pub const D_T_FMT: crate::nl_item = 1; +pub const D_FMT: crate::nl_item = 2; +pub const T_FMT: crate::nl_item = 3; +pub const T_FMT_AMPM: crate::nl_item = 4; +pub const AM_STR: crate::nl_item = 5; +pub const PM_STR: crate::nl_item = 6; + +pub const DAY_1: crate::nl_item = 7; +pub const DAY_2: crate::nl_item = 8; +pub const DAY_3: crate::nl_item = 9; +pub const DAY_4: crate::nl_item = 10; +pub const DAY_5: crate::nl_item = 11; +pub const DAY_6: crate::nl_item = 12; +pub const DAY_7: crate::nl_item = 13; + +pub const ABDAY_1: crate::nl_item = 14; +pub const ABDAY_2: crate::nl_item = 15; +pub const ABDAY_3: crate::nl_item = 16; +pub const ABDAY_4: crate::nl_item = 17; +pub const ABDAY_5: crate::nl_item = 18; +pub const ABDAY_6: crate::nl_item = 19; +pub const ABDAY_7: crate::nl_item = 20; + +pub const MON_1: crate::nl_item = 21; +pub const MON_2: crate::nl_item = 22; +pub const MON_3: crate::nl_item = 23; +pub const MON_4: crate::nl_item = 24; +pub const MON_5: crate::nl_item = 25; +pub const MON_6: crate::nl_item = 26; +pub const MON_7: crate::nl_item = 27; +pub const MON_8: crate::nl_item = 28; +pub const MON_9: crate::nl_item = 29; +pub const MON_10: crate::nl_item = 30; +pub const MON_11: crate::nl_item = 31; +pub const MON_12: crate::nl_item = 32; + +pub const ABMON_1: crate::nl_item = 33; +pub const ABMON_2: crate::nl_item = 34; +pub const ABMON_3: crate::nl_item = 35; +pub const ABMON_4: crate::nl_item = 36; +pub const ABMON_5: crate::nl_item = 37; +pub const ABMON_6: crate::nl_item = 38; +pub const ABMON_7: crate::nl_item = 39; +pub const ABMON_8: crate::nl_item = 40; +pub const ABMON_9: crate::nl_item = 41; +pub const ABMON_10: crate::nl_item = 42; +pub const ABMON_11: crate::nl_item = 43; +pub const ABMON_12: crate::nl_item = 44; + +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 CLOCK_REALTIME: crate::clockid_t = 0; +pub const CLOCK_MONOTONIC_RAW: crate::clockid_t = 4; +pub const CLOCK_MONOTONIC_RAW_APPROX: crate::clockid_t = 5; +pub const CLOCK_MONOTONIC: crate::clockid_t = 6; +pub const CLOCK_UPTIME_RAW: crate::clockid_t = 8; +pub const CLOCK_UPTIME_RAW_APPROX: crate::clockid_t = 9; +pub const CLOCK_PROCESS_CPUTIME_ID: crate::clockid_t = 12; +pub const CLOCK_THREAD_CPUTIME_ID: crate::clockid_t = 16; + +pub const ERA: crate::nl_item = 45; +pub const ERA_D_FMT: crate::nl_item = 46; +pub const ERA_D_T_FMT: crate::nl_item = 47; +pub const ERA_T_FMT: crate::nl_item = 48; +pub const ALT_DIGITS: crate::nl_item = 49; + +pub const RADIXCHAR: crate::nl_item = 50; +pub const THOUSEP: crate::nl_item = 51; + +pub const YESEXPR: crate::nl_item = 52; +pub const NOEXPR: crate::nl_item = 53; + +pub const YESSTR: crate::nl_item = 54; +pub const NOSTR: crate::nl_item = 55; + +pub const CRNCYSTR: crate::nl_item = 56; + +pub const D_MD_ORDER: crate::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 = 0o1_0000; +pub const S_IFCHR: mode_t = 0o2_0000; +pub const S_IFBLK: mode_t = 0o6_0000; +pub const S_IFDIR: mode_t = 0o4_0000; +pub const S_IFREG: mode_t = 0o10_0000; +pub const S_IFLNK: mode_t = 0o12_0000; +pub const S_IFSOCK: mode_t = 0o14_0000; +pub const S_IFMT: mode_t = 0o17_0000; +pub const S_IEXEC: mode_t = 0o0100; +pub const S_IWRITE: mode_t = 0o0200; +pub const S_IREAD: mode_t = 0o0400; +pub const S_IRWXU: mode_t = 0o0700; +pub const S_IXUSR: mode_t = 0o0100; +pub const S_IWUSR: mode_t = 0o0200; +pub const S_IRUSR: mode_t = 0o0400; +pub const S_IRWXG: mode_t = 0o0070; +pub const S_IXGRP: mode_t = 0o0010; +pub const S_IWGRP: mode_t = 0o0020; +pub const S_IRGRP: mode_t = 0o0040; +pub const S_IRWXO: mode_t = 0o0007; +pub const S_IXOTH: mode_t = 0o0001; +pub const S_IWOTH: mode_t = 0o0002; +pub const S_IROTH: mode_t = 0o0004; +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 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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 = u32_cast_int(0xFF000000); + pub const VM_FLAGS_USER_ALLOCATE: c_int = u32_cast_int(0xff07401f); + pub const VM_FLAGS_USER_MAP: c_int = u32_cast_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 ENOTCAPABLE: c_int = 107; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details.and use. +pub const ELAST: c_int = 107; + +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 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; + +#[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 MADV_ZERO: c_int = 11; + +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 SCOPE6_ID_MAX: size_t = 16; + +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: crate::sae_associd_t = 0; +/// ((sae_associd_t)(-1ULL)) +pub const SAE_ASSOCID_ALL: crate::sae_associd_t = 0xffffffff; + +pub const SAE_CONNID_ANY: crate::sae_connid_t = 0; +/// ((sae_connid_t)(-1ULL)) +pub const SAE_CONNID_ALL: crate::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 OS_UNFAIR_LOCK_INIT: os_unfair_lock = os_unfair_lock { + _os_unfair_lock_opaque: 0, +}; + +pub const OS_LOG_TYPE_DEFAULT: crate::os_log_type_t = 0x00; +pub const OS_LOG_TYPE_INFO: crate::os_log_type_t = 0x01; +pub const OS_LOG_TYPE_DEBUG: crate::os_log_type_t = 0x02; +pub const OS_LOG_TYPE_ERROR: crate::os_log_type_t = 0x10; +pub const OS_LOG_TYPE_FAULT: crate::os_log_type_t = 0x11; + +pub const OS_SIGNPOST_EVENT: crate::os_signpost_type_t = 0x00; +pub const OS_SIGNPOST_INTERVAL_BEGIN: crate::os_signpost_type_t = 0x01; +pub const OS_SIGNPOST_INTERVAL_END: crate::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 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 EVFILT_EXCEPT: i16 = -15; + +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_UDATA_SPECIFIC: u16 = 0x0100; +pub const EV_DISPATCH2: u16 = EV_DISPATCH | EV_UDATA_SPECIFIC; +pub const EV_VANISHED: u16 = 0x0200; +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 KEVENT_FLAG_NONE: c_uint = 0x000000; +pub const KEVENT_FLAG_IMMEDIATE: c_uint = 0x000001; +pub const KEVENT_FLAG_ERROR_EVENTS: c_uint = 0x000002; + +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_NONE: u32 = 0x00000080; +pub const NOTE_FUNLOCK: u32 = 0x00000100; +pub const NOTE_LEASE_DOWNGRADE: u32 = 0x00000200; +pub const NOTE_LEASE_RELEASE: u32 = 0x00000400; +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: crate::tcflag_t = 0x00000010; +pub const ONOCR: crate::tcflag_t = 0x00000020; +pub const ONLRET: crate::tcflag_t = 0x00000040; +pub const OFILL: crate::tcflag_t = 0x00000080; +pub const NLDLY: crate::tcflag_t = 0x00000300; +pub const TABDLY: crate::tcflag_t = 0x00000c04; +pub const CRDLY: crate::tcflag_t = 0x00003000; +pub const FFDLY: crate::tcflag_t = 0x00004000; +pub const BSDLY: crate::tcflag_t = 0x00008000; +pub const VTDLY: crate::tcflag_t = 0x00010000; +pub const OFDEL: crate::tcflag_t = 0x00020000; + +pub const NL0: crate::tcflag_t = 0x00000000; +pub const NL1: crate::tcflag_t = 0x00000100; +pub const TAB0: crate::tcflag_t = 0x00000000; +pub const TAB1: crate::tcflag_t = 0x00000400; +pub const TAB2: crate::tcflag_t = 0x00000800; +pub const CR0: crate::tcflag_t = 0x00000000; +pub const CR1: crate::tcflag_t = 0x00001000; +pub const CR2: crate::tcflag_t = 0x00002000; +pub const CR3: crate::tcflag_t = 0x00003000; +pub const FF0: crate::tcflag_t = 0x00000000; +pub const FF1: crate::tcflag_t = 0x00004000; +pub const BS0: crate::tcflag_t = 0x00000000; +pub const BS1: crate::tcflag_t = 0x00008000; +pub const TAB3: crate::tcflag_t = 0x00000004; +pub const VT0: crate::tcflag_t = 0x00000000; +pub const VT1: crate::tcflag_t = 0x00010000; +pub const IUTF8: crate::tcflag_t = 0x00004000; +pub const CRTSCTS: crate::tcflag_t = 0x00030000; + +pub const NI_MAXHOST: crate::socklen_t = 1025; +pub const NI_MAXSERV: crate::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 = u32_cast_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: crate::vm_prot_t = 0x00; +pub const VM_PROT_READ: crate::vm_prot_t = 0x01; +pub const VM_PROT_WRITE: crate::vm_prot_t = 0x02; +pub const VM_PROT_EXECUTE: crate::vm_prot_t = 0x04; +pub const MEMORY_OBJECT_NULL: crate::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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_BASE_MAX: c_int = 2; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_DIM_MAX: c_int = 3; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_SCALE_MAX: c_int = 4; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_STRING_MAX: c_int = 5; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_COLL_WEIGHTS_MAX: c_int = 6; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_EXPR_NEST_MAX: c_int = 7; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_LINE_MAX: c_int = 8; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 crate::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; +pub const AIO_LISTIO_MAX: c_int = 32; +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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_PIDT_SHORTBSDINFO: c_int = 13; +pub const PROC_PIDPATHINFO_MAXSIZE: c_int = 4096; + +pub const PROC_PIDLISTFDS: c_int = 1; +pub const PROC_PIDLISTFD_SIZE: c_int = size_of::() as c_int; +pub const PROX_FDTYPE_ATALK: c_int = 0; +pub const PROX_FDTYPE_VNODE: c_int = 1; +pub const PROX_FDTYPE_SOCKET: c_int = 2; +pub const PROX_FDTYPE_PSHM: c_int = 3; +pub const PROX_FDTYPE_PSEM: c_int = 4; +pub const PROX_FDTYPE_KQUEUE: c_int = 5; +pub const PROX_FDTYPE_PIPE: c_int = 6; +pub const PROX_FDTYPE_FSEVENTS: c_int = 7; +pub const PROX_FDTYPE_NETPOLICY: c_int = 9; +pub const PROX_FDTYPE_CHANNEL: c_int = 10; +pub const PROX_FDTYPE_NEXUS: c_int = 11; + +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; + +// 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: +// DIFF(main): changed to `c_short` in f62eb023ab +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 = 0x3fff0000; +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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: crate::copyfile_flags_t = 1 << 0; +pub const COPYFILE_STAT: crate::copyfile_flags_t = 1 << 1; +pub const COPYFILE_XATTR: crate::copyfile_flags_t = 1 << 2; +pub const COPYFILE_DATA: crate::copyfile_flags_t = 1 << 3; +pub const COPYFILE_SECURITY: crate::copyfile_flags_t = COPYFILE_STAT | COPYFILE_ACL; +pub const COPYFILE_METADATA: crate::copyfile_flags_t = COPYFILE_SECURITY | COPYFILE_XATTR; +pub const COPYFILE_RECURSIVE: crate::copyfile_flags_t = 1 << 15; +pub const COPYFILE_CHECK: crate::copyfile_flags_t = 1 << 16; +pub const COPYFILE_EXCL: crate::copyfile_flags_t = 1 << 17; +pub const COPYFILE_NOFOLLOW_SRC: crate::copyfile_flags_t = 1 << 18; +pub const COPYFILE_NOFOLLOW_DST: crate::copyfile_flags_t = 1 << 19; +pub const COPYFILE_MOVE: crate::copyfile_flags_t = 1 << 20; +pub const COPYFILE_UNLINK: crate::copyfile_flags_t = 1 << 21; +pub const COPYFILE_NOFOLLOW: crate::copyfile_flags_t = + COPYFILE_NOFOLLOW_SRC | COPYFILE_NOFOLLOW_DST; +pub const COPYFILE_PACK: crate::copyfile_flags_t = 1 << 22; +pub const COPYFILE_UNPACK: crate::copyfile_flags_t = 1 << 23; +pub const COPYFILE_CLONE: crate::copyfile_flags_t = 1 << 24; +pub const COPYFILE_CLONE_FORCE: crate::copyfile_flags_t = 1 << 25; +pub const COPYFILE_RUN_IN_PLACE: crate::copyfile_flags_t = 1 << 26; +pub const COPYFILE_DATA_SPARSE: crate::copyfile_flags_t = 1 << 27; +pub const COPYFILE_PRESERVE_DST_TRACKED: crate::copyfile_flags_t = 1 << 28; +pub const COPYFILE_VERBOSE: crate::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; + +// +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +const fn __DARWIN_ALIGN32(p: usize) -> usize { + const __DARWIN_ALIGNBYTES32: usize = size_of::() - 1; + (p + __DARWIN_ALIGNBYTES32) & !__DARWIN_ALIGNBYTES32 +} + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const THREAD_EXTENDED_POLICY_COUNT: mach_msg_type_number_t = + (size_of::() / size_of::()) as mach_msg_type_number_t; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const THREAD_TIME_CONSTRAINT_POLICY_COUNT: mach_msg_type_number_t = + (size_of::() / size_of::()) + as mach_msg_type_number_t; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const THREAD_PRECEDENCE_POLICY_COUNT: mach_msg_type_number_t = + (size_of::() / size_of::()) + as mach_msg_type_number_t; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const THREAD_AFFINITY_POLICY_COUNT: mach_msg_type_number_t = + (size_of::() / size_of::()) as mach_msg_type_number_t; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const THREAD_BACKGROUND_POLICY_COUNT: mach_msg_type_number_t = + (size_of::() / size_of::()) + as mach_msg_type_number_t; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const THREAD_LATENCY_QOS_POLICY_COUNT: mach_msg_type_number_t = + (size_of::() / size_of::()) + as mach_msg_type_number_t; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const THREAD_THROUGHPUT_QOS_POLICY_COUNT: mach_msg_type_number_t = + (size_of::() / size_of::()) + as mach_msg_type_number_t; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const THREAD_BASIC_INFO_COUNT: mach_msg_type_number_t = + (size_of::() / size_of::()) as mach_msg_type_number_t; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const THREAD_IDENTIFIER_INFO_COUNT: mach_msg_type_number_t = + (size_of::() / size_of::()) as mach_msg_type_number_t; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const THREAD_EXTENDED_INFO_COUNT: mach_msg_type_number_t = + (size_of::() / size_of::()) as mach_msg_type_number_t; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const TASK_THREAD_TIMES_INFO_COUNT: u32 = + (size_of::() / size_of::()) as u32; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const MACH_TASK_BASIC_INFO_COUNT: u32 = + (size_of::() / size_of::()) as u32; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const HOST_VM_INFO64_COUNT: mach_msg_type_number_t = + (size_of::() / size_of::()) as mach_msg_type_number_t; + +// bsd/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; +/// All interfaces data at once +pub const IFMIB_IFALLDATA: c_int = 3; + +/// 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; +/// Addresses assigned to interface +pub const IFDATA_ADDRS: c_int = 3; +/// Multicast addresses assigned to interface +pub const IFDATA_MULTIADDRS: c_int = 4; + +/// 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; + +// kern_control.h +pub const MAX_KCTL_NAME: usize = 96; + +f! { + pub unsafe fn CMSG_NXTHDR(mhdr: *const crate::msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { + if cmsg.is_null() { + return crate::CMSG_FIRSTHDR(mhdr); + } + let cmsg_len = (*cmsg).cmsg_len as usize; + let next = cmsg as usize + __DARWIN_ALIGN32(cmsg_len); + let max = (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize; + if next + __DARWIN_ALIGN32(size_of::()) > max { + ptr::null_mut() + } else { + next as *mut cmsghdr + } + } + + pub unsafe fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + (cmsg as *mut c_uchar).add(__DARWIN_ALIGN32(size_of::())) + } + + pub const unsafe fn CMSG_SPACE(length: c_uint) -> c_uint { + (__DARWIN_ALIGN32(size_of::()) + __DARWIN_ALIGN32(length as usize)) as c_uint + } + + pub const unsafe fn CMSG_LEN(length: c_uint) -> c_uint { + (__DARWIN_ALIGN32(size_of::()) + length as usize) as c_uint + } + + pub const unsafe fn VM_MAKE_TAG(id: u8) -> u32 { + (id as u32) << 24u32 + } +} + +safe_f! { + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + status >> 8 + } + + pub const safe fn _WSTATUS(status: c_int) -> c_int { + status & 0x7f + } + + pub const safe fn WIFCONTINUED(status: c_int) -> bool { + _WSTATUS(status) == _WSTOPPED && WSTOPSIG(status) == 0x13 + } + + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + _WSTATUS(status) != _WSTOPPED && _WSTATUS(status) != 0 + } + + pub const safe fn WIFSTOPPED(status: c_int) -> bool { + _WSTATUS(status) == _WSTOPPED && WSTOPSIG(status) != 0x13 + } + + pub const safe fn makedev(major: i32, minor: i32) -> dev_t { + (major << 24) | minor + } + + pub const safe fn major(dev: dev_t) -> i32 { + (dev >> 24) & 0xff + } + + pub const safe fn minor(dev: dev_t) -> i32 { + dev & 0xffffff + } +} + +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 crate::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: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_gettime(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + 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 crate::DIR) -> c_int; + + pub fn lutimes(file: *const c_char, times: *const crate::timeval) -> c_int; + + pub fn gettimeofday(tp: *mut crate::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 crate::tm) -> *mut c_char; + pub fn ctime(clock: *const time_t) -> *mut c_char; + pub fn getdate(datestr: *const c_char) -> *mut crate::tm; + pub fn strptime( + buf: *const c_char, + format: *const c_char, + timeptr: *mut crate::tm, + ) -> *mut c_char; + pub fn asctime_r(tm: *const crate::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 crate::sockaddr, + salen: crate::socklen_t, + host: *mut c_char, + hostlen: crate::socklen_t, + serv: *mut c_char, + servlen: crate::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 crate::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 crate::mach_timebase_info) -> c_int; + #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + pub fn mach_host_self() -> mach_port_t; + #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + pub fn mach_thread_self() -> mach_port_t; + pub fn pthread_cond_timedwait_relative_np( + cond: *mut crate::pthread_cond_t, + lock: *mut crate::pthread_mutex_t, + timeout: *const crate::timespec, + ) -> c_int; + pub fn pthread_attr_getscope( + attr: *const crate::pthread_attr_t, + contentionscope: *mut c_int, + ) -> c_int; + pub fn pthread_attr_getstackaddr( + attr: *const crate::pthread_attr_t, + stackaddr: *mut *mut c_void, + ) -> c_int; + pub fn pthread_attr_getdetachstate( + attr: *const crate::pthread_attr_t, + detachstate: *mut c_int, + ) -> c_int; + pub fn pthread_attr_setscope(attr: *mut crate::pthread_attr_t, contentionscope: c_int) + -> c_int; + pub fn pthread_attr_setstackaddr( + attr: *mut crate::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: crate::pthread_t, name: *mut c_char, len: size_t) -> c_int; + pub fn pthread_mach_thread_np(thread: crate::pthread_t) -> crate::mach_port_t; + pub fn pthread_from_mach_thread_np(port: crate::mach_port_t) -> crate::pthread_t; + pub fn pthread_get_stackaddr_np(thread: crate::pthread_t) -> *mut c_void; + pub fn pthread_get_stacksize_np(thread: crate::pthread_t) -> size_t; + pub fn pthread_main_np() -> c_int; + pub fn pthread_threadid_np(thread: crate::pthread_t, thread_id: *mut u64) -> c_int; + + 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: crate::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) -> crate::os_log_t; + pub fn os_log_type_enabled(oslog: crate::os_log_t, tpe: crate::os_log_type_t) -> bool; + pub fn os_signpost_id_make_with_pointer( + log: crate::os_log_t, + ptr: *const c_void, + ) -> crate::os_signpost_id_t; + pub fn os_signpost_id_generate(log: crate::os_log_t) -> crate::os_signpost_id_t; + pub fn os_signpost_enabled(log: crate::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 crate::kevent, + nchanges: c_int, + eventlist: *mut crate::kevent, + nevents: c_int, + timeout: *const crate::timespec, + ) -> c_int; + pub fn kevent64( + kq: c_int, + changelist: *const crate::kevent64_s, + nchanges: c_int, + eventlist: *mut crate::kevent64_s, + nevents: c_int, + flags: c_uint, + timeout: *const crate::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: crate::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 crate::sf_hdtr, + flags: c_int, + ) -> c_int; + pub fn futimens(fd: c_int, times: *const crate::timespec) -> c_int; + pub fn utimensat( + dirfd: c_int, + path: *const c_char, + times: *const crate::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 crate::winsize, + ) -> c_int; + pub fn forkpty( + amaster: *mut c_int, + name: *mut c_char, + termp: *mut termios, + winp: *mut crate::winsize, + ) -> crate::pid_t; + pub fn login_tty(fd: c_int) -> c_int; + pub fn duplocale(base: crate::locale_t) -> crate::locale_t; + pub fn freelocale(loc: crate::locale_t) -> c_int; + pub fn localeconv_l(loc: crate::locale_t) -> *mut lconv; + pub fn newlocale(mask: c_int, locale: *const c_char, base: crate::locale_t) -> crate::locale_t; + pub fn uselocale(loc: crate::locale_t) -> crate::locale_t; + pub fn querylocale(mask: c_int, loc: crate::locale_t) -> *const c_char; + pub fn getpriority(which: c_int, who: crate::id_t) -> c_int; + pub fn setpriority(which: c_int, who: crate::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 crate::iovec, iovcnt: c_int, offset: off_t) -> ssize_t; + pub fn pwritev(fd: c_int, iov: *const crate::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 crate::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 crate::timeval, tz: *const crate::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 crate::pid_t, + path: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::posix_spawnattr_t, + argv: *const *mut c_char, + envp: *const *mut c_char, + ) -> c_int; + pub fn posix_spawnp( + pid: *mut crate::pid_t, + file: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::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 crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + default: *const crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + default: *mut crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + default: *const crate::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 crate::pid_t, + ) -> c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: crate::pid_t) -> c_int; + pub fn posix_spawnattr_setarchpref_np( + attr: *mut posix_spawnattr_t, + count: size_t, + pref: *mut crate::cpu_type_t, + subpref: *mut crate::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 crate::cpu_type_t, + subpref: *mut crate::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 crate::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 crate::cpu_type_t, + ocount: *mut size_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 crate::utsname) -> c_int; + + pub fn connectx( + socket: c_int, + endpoints: *const sa_endpoints_t, + associd: sae_associd_t, + flags: c_uint, + iov: *const crate::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: crate::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 crate::malloc_zone_t) -> crate::boolean_t; + pub fn malloc_zone_print(zone: *mut crate::malloc_zone_t, verbose: crate::boolean_t); + pub fn malloc_zone_statistics(zone: *mut crate::malloc_zone_t, stats: *mut malloc_statistics_t); + pub fn malloc_zone_log(zone: *mut crate::malloc_zone_t, address: *mut c_void); + pub fn malloc_zone_print_ptr_info(ptr: *mut c_void); + pub fn malloc_default_zone() -> *mut crate::malloc_zone_t; + pub fn malloc_zone_from_ptr(ptr: *const c_void) -> *mut crate::malloc_zone_t; + pub fn malloc_zone_malloc(zone: *mut crate::malloc_zone_t, size: size_t) -> *mut c_void; + pub fn malloc_zone_valloc(zone: *mut crate::malloc_zone_t, size: size_t) -> *mut c_void; + pub fn malloc_zone_calloc( + zone: *mut crate::malloc_zone_t, + num_items: size_t, + size: size_t, + ) -> *mut c_void; + pub fn malloc_zone_realloc( + zone: *mut crate::malloc_zone_t, + ptr: *mut c_void, + size: size_t, + ) -> *mut c_void; + pub fn malloc_zone_free(zone: *mut crate::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: crate::pid_t, buffer: *mut c_void, buffersize: c_int) + -> c_int; + pub fn proc_listchildpids(ppid: crate::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 crate::timespec) -> c_int; + + pub fn gethostid() -> c_long; + pub fn sethostid(hostid: c_long); + + pub fn CCRandomGenerateBytes(bytes: *mut c_void, size: size_t) -> crate::CCRNGStatus; + pub fn getentropy(buf: *mut c_void, buflen: size_t) -> c_int; + + // FIXME(1.0): should this actually be deprecated? + #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + 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; + + #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + pub fn mach_vm_map( + target_task: crate::vm_map_t, + address: *mut crate::mach_vm_address_t, + size: crate::mach_vm_size_t, + mask: crate::mach_vm_offset_t, + flags: c_int, + object: crate::mem_entry_name_port_t, + offset: crate::memory_object_offset_t, + copy: crate::boolean_t, + cur_protection: crate::vm_prot_t, + max_protection: crate::vm_prot_t, + inheritance: crate::vm_inherit_t, + ) -> crate::kern_return_t; + + pub fn vm_allocate( + target_task: vm_map_t, + address: *mut vm_address_t, + size: vm_size_t, + flags: c_int, + ) -> crate::kern_return_t; + + pub fn vm_deallocate( + target_task: vm_map_t, + address: vm_address_t, + size: vm_size_t, + ) -> crate::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, + ) -> crate::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, + ) -> crate::kern_return_t; + + #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + pub static mut mach_task_self_: crate::mach_port_t; + pub fn task_for_pid( + host: crate::mach_port_t, + pid: crate::pid_t, + task: *mut crate::mach_port_t, + ) -> crate::kern_return_t; + pub fn task_info( + host: crate::mach_port_t, + flavor: task_flavor_t, + task_info_out: task_info_t, + task_info_count: *mut mach_msg_type_number_t, + ) -> crate::kern_return_t; + pub fn task_create( + target_task: crate::task_t, + ledgers: crate::ledger_array_t, + ledgersCnt: crate::mach_msg_type_number_t, + inherit_memory: crate::boolean_t, + child_task: *mut crate::task_t, + ) -> crate::kern_return_t; + pub fn task_terminate(target_task: crate::task_t) -> crate::kern_return_t; + pub fn task_threads( + target_task: crate::task_inspect_t, + act_list: *mut crate::thread_act_array_t, + act_listCnt: *mut crate::mach_msg_type_number_t, + ) -> crate::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, + ) -> crate::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, + ) -> crate::sysdir_search_path_enumeration_state; + pub fn sysdir_get_next_search_path_enumeration( + state: crate::sysdir_search_path_enumeration_state, + path: *mut c_char, + ) -> crate::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 fn qsort_r( + base: *mut c_void, + num: size_t, + size: size_t, + arg: *mut c_void, + compar: Option c_int>, + ); +} + +#[allow(deprecated)] +#[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] +pub unsafe fn mach_task_self() -> crate::mach_port_t { + mach_task_self_ +} + +cfg_if! { + if #[cfg(target_os = "macos")] { + extern "C" { + pub fn clock_settime(clock_id: crate::clockid_t, tp: *const crate::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: crate::task_t, + flavor: crate::task_flavor_t, + task_info_in: crate::task_info_t, + task_info_inCnt: crate::mach_msg_type_number_t, + ) -> crate::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" { + #[deprecated(note = "Will be removed in 1.0 to avoid the `iconv` dependency")] + pub fn iconv_open(tocode: *const c_char, fromcode: *const c_char) -> iconv_t; + #[deprecated(note = "Will be removed in 1.0 to avoid the `iconv` dependency")] + 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; + #[deprecated(note = "Will be removed in 1.0 to avoid the `iconv` dependency")] + 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 + } +} 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..773acc6 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs @@ -0,0 +1,1481 @@ +use crate::prelude::*; +use crate::{ + cmsghdr, + off_t, +}; + +pub type dev_t = u32; +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 time_t = i64; +pub type suseconds_t = i64; + +pub type uuid_t = crate::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 pthread_barrierattr_t = *mut __c_anonymous_pthread_barrierattr; +pub type pthread_barrier_t = *mut __c_anonymous_pthread_barrier; +pub type pthread_spinlock_t = crate::uintptr_t; + +pub type segsz_t = isize; + +pub type vm_prot_t = u8; +pub type vm_maptype_t = u8; +pub type vm_inherit_t = i8; + +pub type vm_map_t = *mut c_void; +pub type vm_map_entry_t = *mut c_void; + +extern_ty! { + pub type sem; + pub type __c_anonymous_pthread_barrier; + pub type __c_anonymous_pthread_barrierattr; +} + +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: crate::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, + clock_seq_hi_and_reserved: Padding, + 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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::fsfilcnt_t, + pub f_fsid: c_ulong, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + pub f_owner: crate::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: crate::uuid_t, + pub f_uid_uuid: crate::uuid_t, + } + + pub struct stat { + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_dev: crate::dev_t, + pub st_mode: crate::mode_t, + st_padding1: Padding, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::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: crate::timeval, + } + + pub struct if_msghdr { + pub ifm_msglen: c_ushort, + pub ifm_version: c_uchar, + pub ifm_type: c_uchar, + pub ifm_index: c_ushort, + pub ifm_flags: c_int, + pub ifm_addrs: 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; 12], + pub sdl_rcf: c_ushort, + pub sdl_route: [c_ushort; 16], + } + + pub struct xucred { + pub cr_version: c_uint, + pub cr_uid: crate::uid_t, + pub cr_ngroups: c_short, + pub cr_groups: [crate::gid_t; 16], + __cr_unused1: Padding<*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: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_lpid: crate::pid_t, + pub shm_cpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + shm_internal: *mut c_void, + } + + pub struct kinfo_file { + pub f_size: size_t, + pub f_pid: crate::pid_t, + pub f_uid: crate::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_idle: u64, + cp_unused01: Padding, + cp_unused02: Padding, + pub cp_sample_pc: u64, + pub cp_sample_sp: u64, + pub cp_msg: [c_char; 32], + } + + pub struct kinfo_lwp { + pub kl_pid: crate::pid_t, + pub kl_tid: crate::lwpid_t, + pub kl_flags: c_int, + pub kl_stat: crate::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: crate::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: crate::rusage, + pub kl_siglist: crate::sigset_t, + pub kl_sigmask: crate::sigset_t, + pub kl_wchan: crate::uintptr_t, + pub kl_wmesg: [c_char; 9], + pub kl_comm: [c_char; MAXCOMLEN + 1], + } + + pub struct kinfo_proc { + pub kp_paddr: crate::uintptr_t, + pub kp_flags: c_int, + pub kp_stat: crate::procstat, + pub kp_lock: c_int, + pub kp_acflag: c_int, + pub kp_traceflag: c_int, + pub kp_fd: crate::uintptr_t, + pub kp_siglist: crate::sigset_t, + pub kp_sigignore: crate::sigset_t, + pub kp_sigcatch: crate::sigset_t, + pub kp_sigflag: c_int, + pub kp_start: crate::timeval, + pub kp_comm: [c_char; MAXCOMLEN + 1], + pub kp_uid: crate::uid_t, + pub kp_ngroups: c_short, + pub kp_groups: [crate::gid_t; NGROUPS], + pub kp_ruid: crate::uid_t, + pub kp_svuid: crate::uid_t, + pub kp_rgid: crate::gid_t, + pub kp_svgid: crate::gid_t, + pub kp_pid: crate::pid_t, + pub kp_ppid: crate::pid_t, + pub kp_pgid: crate::pid_t, + pub kp_jobc: c_int, + pub kp_sid: crate::pid_t, + pub kp_login: [c_char; 40], // MAXNAMELEN rounded up to the nearest sizeof(long) + pub kp_tdev: crate::dev_t, + pub kp_tpgid: crate::pid_t, + pub kp_tsid: crate::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: crate::segsz_t, + pub kp_vm_swrss: crate::segsz_t, + pub kp_vm_tsize: crate::segsz_t, + pub kp_vm_dsize: crate::segsz_t, + pub kp_vm_ssize: crate::segsz_t, + pub kp_vm_prssize: c_uint, + pub kp_jailid: c_int, + pub kp_ru: crate::rusage, + pub kp_cru: crate::rusage, + pub kp_auxflags: c_int, + pub kp_lwp: crate::kinfo_lwp, + pub kp_ktaddr: crate::uintptr_t, + kp_spare: [c_int; 2], + } + + 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, + } + + 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], + + ut_unused: Padding<[u8; 16]>, + pub ut_session: u16, + pub ut_type: u16, + pub ut_pid: crate::pid_t, + ut_exit: exit_status, + ut_ss: crate::sockaddr_storage, + pub ut_tv: crate::timeval, + ut_unused2: Padding<[u8; 16]>, + } + + pub struct lastlogx { + pub ll_tv: crate::timeval, + pub ll_line: [c_char; _UTX_LINESIZE], + pub ll_host: [c_char; _UTX_HOSTSIZE], + pub ll_ss: crate::sockaddr_storage, + } + + pub struct dirent { + pub d_fileno: crate::ino_t, + pub d_namlen: u16, + pub d_type: u8, + __unused1: Padding, + __unused2: Padding, + 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: crate::fsid_t, + pub f_owner: crate::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: Padding, + pub sigev_signo: c_int, //actually a union + // pad the union + #[cfg(target_pointer_width = "64")] + __unused2: Padding, + pub sigev_value: crate::sigval, + __unused3: Padding<*mut c_void>, //actually a function pointer + } + + #[repr(align(64))] + 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: Padding, + __unused: Padding<[c_uint; 8]>, + pub mc_fpregs: [c_uint; 256], + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct ucontext_t { + pub uc_sigmask: crate::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: Padding<[c_int; 4]>, + } +} + +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 O_FBLOCKING: c_int = 0x00040000; +pub const O_FNONBLOCKING: c_int = 0x00080000; +pub const O_FAPPEND: c_int = 0x00100000; +pub const O_FOFFSET: c_int = 0x00200000; +pub const O_FSYNCWRITE: c_int = 0x00400000; +pub const O_FASYNCWRITE: c_int = 0x00800000; +pub const O_FMASK: c_int = + O_FBLOCKING | O_FNONBLOCKING | O_FAPPEND | O_FOFFSET | O_FSYNCWRITE | O_FASYNCWRITE; +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 POSIX_FADV_NORMAL: c_int = 0; +pub const POSIX_FADV_SEQUENTIAL: c_int = 1; +pub const POSIX_FADV_RANDOM: 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 ENOMEDIUM: c_int = 93; +pub const ENOTRECOVERABLE: c_int = 94; +pub const EOWNERDEAD: c_int = 95; +pub const EASYNC: c_int = 99; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details.and use. +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: crate::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_STATIC_TLS_EXTRA: c_int = 37; +pub const KERN_MAXID: 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_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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_BASE_MAX: c_int = 2; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_DIM_MAX: c_int = 3; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_SCALE_MAX: c_int = 4; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_STRING_MAX: c_int = 5; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_COLL_WEIGHTS_MAX: c_int = 6; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_EXPR_NEST_MAX: c_int = 7; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_LINE_MAX: c_int = 8; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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_RDMSR: c_int = u32_cast_int(0xc0106301); +#[deprecated(since = "0.2.187", note = "Replaced on DragonFly by CPUCTL_RDMSR")] +pub const CPUCTL_RSMSR: c_int = CPUCTL_RDMSR; +pub const CPUCTL_WRMSR: c_int = u32_cast_int(0xc0106302); +pub const CPUCTL_CPUID: c_int = u32_cast_int(0xc0146303); +pub const CPUCTL_UPDATE: c_int = u32_cast_int(0xc0106304); +pub const CPUCTL_MSRSBIT: c_int = u32_cast_int(0xc0106305); +pub const CPUCTL_MSRCBIT: c_int = u32_cast_int(0xc0106306); +pub const CPUCTL_CPUID_COUNT: c_int = u32_cast_int(0xc0186307); + +pub const CPU_SETSIZE: size_t = size_of::() * 8; + +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 = 0x8; +pub const REG_NEWLINE: c_int = 0x4; +pub const REG_NOSPEC: c_int = 0o0020; +pub const REG_PEND: c_int = 0x80; +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 = 15; +pub const REG_ILLSEQ: 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 = 0x8; + +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 = 0x0800; +pub const EV_SYSFLAGS: u16 = 0xF800; + +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_OACTIVE: c_int = IFF_OACTIVE_COMPAT; +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 AF_ARP: c_int = 36; + +pub const PF_BLUETOOTH: c_int = AF_BLUETOOTH; +pub const PF_ARP: c_int = AF_ARP; + +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 = u32_cast_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_LASTLOGX: c_uint = 2; +#[deprecated(since = "0.2.187", note = "Replaced on DragonFly by UTX_DB_LASTLOGX")] +pub const UTX_DB_LASTLOG: c_uint = UTX_DB_LASTLOGX; +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 EXTATTR_NAMESPACE_EMPTY: c_int = 0; +pub const EXTATTR_NAMESPACE_USER: c_int = 1; +pub const EXTATTR_NAMESPACE_SYSTEM: c_int = 2; + +pub const GRND_NONBLOCK: c_uint = 0x2; +pub const GRND_RANDOM: c_uint = 0x1; +pub const GRND_INSECURE: c_uint = 0x4; + +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 = 0x00000040; + +pub const B460800: crate::speed_t = 460800; +pub const B921600: crate::speed_t = 921600; + +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; +pub const TIOCTIMESTAMP: c_ulong = 0x40107459; +pub const BIOCSRTIMEOUT: c_ulong = 0x8010426d; +pub const BIOCGRTIMEOUT: c_ulong = 0x4010426e; + +// Constants used by "at" family of system calls. +pub const AT_FDCWD: c_int = u32_cast_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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const RTAX_MAX: c_int = 11; + +const fn _CMSG_ALIGN(n: usize) -> usize { + (n + (size_of::() - 1)) & !(size_of::() - 1) +} + +f! { + pub unsafe fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + (cmsg as *mut c_uchar).offset(_CMSG_ALIGN(size_of::()) as isize) + } + + pub const unsafe fn CMSG_LEN(length: c_uint) -> c_uint { + (_CMSG_ALIGN(size_of::()) + length as usize) as c_uint + } + + pub unsafe fn CMSG_NXTHDR(mhdr: *const crate::msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { + let next = cmsg as usize + + _CMSG_ALIGN((*cmsg).cmsg_len as usize) + + _CMSG_ALIGN(size_of::()); + 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 { + ptr::null_mut() + } + } + + pub const unsafe fn CMSG_SPACE(length: c_uint) -> c_uint { + (_CMSG_ALIGN(size_of::()) + _CMSG_ALIGN(length as usize)) as c_uint + } + + pub unsafe fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + cpuset.ary.fill(0); + } + + pub unsafe fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let (idx, offset) = ((cpu >> 6) & 3, cpu & 63); + cpuset.ary[idx] |= 1 << offset; + () + } + + pub unsafe fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let (idx, offset) = ((cpu >> 6) & 3, cpu & 63); + cpuset.ary[idx] &= !(1 << offset); + () + } + + pub unsafe fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let (idx, offset) = ((cpu >> 6) & 3, cpu & 63); + 0 != cpuset.ary[idx] & (1 << offset) + } +} + +safe_f! { + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 + } + + pub const safe fn makedev(major: c_uint, minor: c_uint) -> crate::dev_t { + let major = major as crate::dev_t; + let minor = minor as crate::dev_t; + let mut dev = 0; + dev |= major << 8; + dev |= minor; + dev + } + + pub const safe fn major(dev: crate::dev_t) -> c_int { + ((dev >> 8) & 0xff) as c_int + } + + pub const safe fn minor(dev: crate::dev_t) -> c_int { + (dev & 0xffff00ff) as c_int + } +} + +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 crate::timespec) -> c_int; + + pub fn devname_r( + dev: crate::dev_t, + mode: crate::mode_t, + buf: *mut c_char, + len: size_t, + ) -> *mut c_char; + + pub fn waitid( + idtype: idtype_t, + id: crate::id_t, + infop: *mut crate::siginfo_t, + options: c_int, + ) -> c_int; + + pub fn freelocale(loc: crate::locale_t); + + pub fn lwp_rtprio( + function: c_int, + pid: crate::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 fdatasync(fd: c_int) -> c_int; + pub fn uname(buf: *mut crate::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 dlvsym( + handle: *mut c_void, + symbol: *const c_char, + version: *const c_char, + ) -> *mut c_void; + pub fn reallocarray(ptr: *mut c_void, nmemb: size_t, size: size_t) -> *mut c_void; + pub fn qsort_r( + base: *mut c_void, + num: size_t, + size: size_t, + arg: *mut c_void, + compar: Option 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_getaffinity_np( + td: crate::pthread_t, + cpusetsize: size_t, + cpusetp: *mut cpuset_t, + ) -> c_int; + pub fn pthread_setaffinity_np( + td: crate::pthread_t, + cpusetsize: size_t, + cpusetp: *const cpuset_t, + ) -> c_int; + + pub fn sched_getaffinity(pid: crate::pid_t, cpusetsize: size_t, mask: *mut cpu_set_t) -> c_int; + pub fn sched_setaffinity( + pid: crate::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 ftok(path: *const c_char, id: c_int) -> crate::key_t; + pub fn shmget(key: crate::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 crate::shmid_ds) -> c_int; + pub fn procctl( + idtype: crate::idtype_t, + id: crate::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: crate::uid_t, ll: *mut lastlogx) + -> *mut lastlogx; + pub fn updlastlogx(fname: *const c_char, uid: crate::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: crate::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 crate::statfs, flags: c_int) -> c_int; + pub fn getmntvinfo( + mntbufp: *mut *mut crate::statfs, + mntvbufp: *mut *mut crate::statvfs, + flags: c_int, + ) -> c_int; + + pub fn extattr_delete_file( + path: *const c_char, + attrnamespace: c_int, + attrname: *const c_char, + ) -> c_int; + 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_set_file( + path: *const c_char, + attrnamespace: c_int, + attrname: *const c_char, + data: *const c_void, + nbytes: size_t, + ) -> c_int; + + pub fn dup3(src: c_int, dst: c_int, flags: c_int) -> c_int; + pub fn closefrom(lowfd: 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 crate::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 crate::kvm_t, + map: vm_map_t, + entry: vm_map_entry_t, + ) -> vm_map_entry_t; + pub fn kvm_vm_map_entry_next( + kvm: *mut crate::kvm_t, + map: vm_map_entry_t, + entry: vm_map_entry_t, + ) -> vm_map_entry_t; +} 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..232770f --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs @@ -0,0 +1,42 @@ +use crate::prelude::*; + +pub type clock_t = i32; +pub type wchar_t = u32; +pub type time_t = i64; +pub type suseconds_t = i64; +pub type register_t = i64; + +s! { + pub struct gpregs { + pub gp_x: [crate::register_t; 30], + pub gp_lr: crate::register_t, + pub gp_sp: crate::register_t, + pub gp_elr: crate::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], + } +} + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 1; + +pub const BIOCSRTIMEOUT: c_ulong = 0x8010426d; +pub const BIOCGRTIMEOUT: c_ulong = 0x4010426e; +pub const MAP_32BIT: c_int = 0x00080000; +pub const MINSIGSTKSZ: size_t = 4096; // 1024 * 4 +pub const TIOCTIMESTAMP: c_ulong = 0x40107459; 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..a0f5183 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/arm.rs @@ -0,0 +1,27 @@ +use crate::prelude::*; + +pub type clock_t = u32; +pub type wchar_t = u32; +pub type time_t = i64; +pub type suseconds_t = i32; +pub type register_t = i32; +pub type __greg_t = c_uint; +pub type __gregset_t = [crate::__greg_t; 17]; + +s! { + pub struct mcontext_t { + pub __gregs: crate::__gregset_t, + pub mc_vfp_size: usize, + pub mc_vfp_ptr: *mut c_void, + pub mc_spare: [c_uint; 33], + } +} + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 1; + +pub const BIOCSRTIMEOUT: c_ulong = 0x8010426d; +pub const BIOCGRTIMEOUT: c_ulong = 0x4010426e; + +pub const MAP_32BIT: c_int = 0x00080000; +pub const MINSIGSTKSZ: size_t = 4096; // 1024 * 4 +pub const TIOCTIMESTAMP: c_ulong = 0x40107459; 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..cd0c3e0 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/b32.rs @@ -0,0 +1,29 @@ +use crate::off_t; +use crate::prelude::*; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_size: off_t, + pub st_blocks: crate::blkcnt_t, + pub st_blksize: crate::blksize_t, + pub st_flags: crate::fflags_t, + pub st_gen: u32, + pub st_lspare: i32, + pub st_birthtime: crate::time_t, + pub st_birthtime_nsec: c_long, + __unused: Padding<[u8; 8]>, + } +} 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..9e80a79 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs @@ -0,0 +1,28 @@ +use crate::off_t; +use crate::prelude::*; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_size: off_t, + pub st_blocks: crate::blkcnt_t, + pub st_blksize: crate::blksize_t, + pub st_flags: crate::fflags_t, + pub st_gen: u32, + pub st_lspare: i32, + pub st_birthtime: crate::time_t, + pub st_birthtime_nsec: c_long, + } +} 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..1bf913b --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs @@ -0,0 +1,336 @@ +use crate::prelude::*; + +// 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: crate::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: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_lpid: crate::pid_t, + pub shm_cpid: crate::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: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::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 crate::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, + /// Pointer to open file info. + pub ki_fd: *mut crate::filedesc, + // 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: crate::pid_t, + /// Parent process ID. + pub ki_ppid: crate::pid_t, + /// Process group ID. + pub ki_pgid: crate::pid_t, + /// tty process group ID. + pub ki_tpgid: crate::pid_t, + /// Process session ID. + pub ki_sid: crate::pid_t, + /// Terminal session ID. + pub ki_tsid: crate::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: crate::dev_t, + /// Signals arrived but not delivered. + pub ki_siglist: crate::sigset_t, + /// Current signal mask. + pub ki_sigmask: crate::sigset_t, + /// Signals being ignored. + pub ki_sigignore: crate::sigset_t, + /// Signals being caught by user. + pub ki_sigcatch: crate::sigset_t, + /// Effective user ID. + pub ki_uid: crate::uid_t, + /// Real user ID. + pub ki_ruid: crate::uid_t, + /// Saved effective user ID. + pub ki_svuid: crate::uid_t, + /// Real group ID. + pub ki_rgid: crate::gid_t, + /// Saved effective group ID. + pub ki_svgid: crate::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: [crate::gid_t; crate::KI_NGROUPS], + /// Virtual size. + pub ki_size: crate::vm_size_t, + /// Current resident set size in pages. + pub ki_rssize: crate::segsz_t, + /// Resident set size before last swap. + pub ki_swrss: crate::segsz_t, + /// Text size (pages) XXX. + pub ki_tsize: crate::segsz_t, + /// Data size (pages) XXX. + pub ki_dsize: crate::segsz_t, + /// Stack size (pages). + pub ki_ssize: crate::segsz_t, + /// Exit status for wait & stop signal. + pub ki_xstat: crate::u_short, + /// Accounting flags. + pub ki_acflag: crate::u_short, + /// %cpu for process during `ki_swtime`. + pub ki_pctcpu: crate::fixpt_t, + /// Time averaged value of `ki_cpticks`. + pub ki_estcpu: crate::u_int, + /// Time since last blocked. + pub ki_slptime: crate::u_int, + /// Time swapped in or out. + pub ki_swtime: crate::u_int, + /// Number of copy-on-write faults. + pub ki_cow: crate::u_int, + /// Real time in microsec. + pub ki_runtime: u64, + /// Starting time. + pub ki_start: crate::timeval, + /// Time used by process children. + pub ki_childtime: crate::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; crate::TDNAMLEN + 1], + /// Wchan message. + pub ki_wmesg: [c_char; crate::WMESGLEN + 1], + /// Setlogin name. + pub ki_login: [c_char; crate::LOGNAMELEN + 1], + /// Lock name. + pub ki_lockname: [c_char; crate::LOCKNAMELEN + 1], + /// Command name. + pub ki_comm: [c_char; crate::COMMLEN + 1], + /// Emulation name. + pub ki_emul: [c_char; crate::KI_EMULNAMELEN + 1], + /// Login class. + pub ki_loginclass: [c_char; crate::LOGINCLASSLEN + 1], + /// More thread name. + pub ki_moretdname: [c_char; crate::MAXCOMLEN - crate::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; crate::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: crate::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: crate::lwpid_t, + /// Process priority. + pub ki_pri: crate::priority, + /// Process rusage statistics. + pub ki_rusage: crate::rusage, + /// rusage of children processes. + pub ki_rusage_ch: crate::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; crate::KI_NSPARE_PTR], + pub ki_sparelongs: [c_long; crate::KI_NSPARE_LONG], + /// PS_* flags. + pub ki_sflag: c_long, + /// kthread flag. + pub ki_tdflags: c_long, + } + pub struct dirent { + pub d_fileno: crate::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: crate::uid_t, + pub f_fsid: crate::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; crate::SPECNAMELEN as usize + 1], + } +} + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const ELAST: c_int = 96; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 safe fn makedev(major: c_uint, minor: c_uint) -> crate::dev_t { + let major = major as crate::dev_t; + let minor = minor as crate::dev_t; + (major << 8) | minor + } + + pub const safe fn major(dev: crate::dev_t) -> c_int { + ((dev >> 8) & 0xff) as c_int + } + + pub const safe fn minor(dev: crate::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: crate::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; + + // Argument order of the function pointer changed in FreeBSD 14. From 14 onwards the signature + // matches the POSIX specification by having the third argument be a mutable pointer, on + // earlier versions the first argument is the mutable pointer. + #[link_name = "qsort_r@FBSD_1.0"] + pub fn qsort_r( + base: *mut c_void, + num: size_t, + size: size_t, + arg: *mut c_void, + compar: Option c_int>, + ); +} + +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..8fd4961 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs @@ -0,0 +1,371 @@ +use crate::off_t; +use crate::prelude::*; + +// 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: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_lpid: crate::pid_t, + pub shm_cpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + } + + pub struct kevent { + pub ident: crate::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: crate::vm_prot_t, + pub offset: crate::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 crate::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, + /// Pointer to open file info. + pub ki_fd: *mut crate::filedesc, + // 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: crate::pid_t, + /// Parent process ID. + pub ki_ppid: crate::pid_t, + /// Process group ID. + pub ki_pgid: crate::pid_t, + /// tty process group ID. + pub ki_tpgid: crate::pid_t, + /// Process session ID. + pub ki_sid: crate::pid_t, + /// Terminal session ID. + pub ki_tsid: crate::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: crate::sigset_t, + /// Current signal mask. + pub ki_sigmask: crate::sigset_t, + /// Signals being ignored. + pub ki_sigignore: crate::sigset_t, + /// Signals being caught by user. + pub ki_sigcatch: crate::sigset_t, + /// Effective user ID. + pub ki_uid: crate::uid_t, + /// Real user ID. + pub ki_ruid: crate::uid_t, + /// Saved effective user ID. + pub ki_svuid: crate::uid_t, + /// Real group ID. + pub ki_rgid: crate::gid_t, + /// Saved effective group ID. + pub ki_svgid: crate::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: [crate::gid_t; crate::KI_NGROUPS], + /// Virtual size. + pub ki_size: crate::vm_size_t, + /// Current resident set size in pages. + pub ki_rssize: crate::segsz_t, + /// Resident set size before last swap. + pub ki_swrss: crate::segsz_t, + /// Text size (pages) XXX. + pub ki_tsize: crate::segsz_t, + /// Data size (pages) XXX. + pub ki_dsize: crate::segsz_t, + /// Stack size (pages). + pub ki_ssize: crate::segsz_t, + /// Exit status for wait & stop signal. + pub ki_xstat: crate::u_short, + /// Accounting flags. + pub ki_acflag: crate::u_short, + /// %cpu for process during `ki_swtime`. + pub ki_pctcpu: crate::fixpt_t, + /// Time averaged value of `ki_cpticks`. + pub ki_estcpu: crate::u_int, + /// Time since last blocked. + pub ki_slptime: crate::u_int, + /// Time swapped in or out. + pub ki_swtime: crate::u_int, + /// Number of copy-on-write faults. + pub ki_cow: crate::u_int, + /// Real time in microsec. + pub ki_runtime: u64, + /// Starting time. + pub ki_start: crate::timeval, + /// Time used by process children. + pub ki_childtime: crate::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; crate::TDNAMLEN + 1], + /// Wchan message. + pub ki_wmesg: [c_char; crate::WMESGLEN + 1], + /// Setlogin name. + pub ki_login: [c_char; crate::LOGNAMELEN + 1], + /// Lock name. + pub ki_lockname: [c_char; crate::LOCKNAMELEN + 1], + /// Command name. + pub ki_comm: [c_char; crate::COMMLEN + 1], + /// Emulation name. + pub ki_emul: [c_char; crate::KI_EMULNAMELEN + 1], + /// Login class. + pub ki_loginclass: [c_char; crate::LOGINCLASSLEN + 1], + /// More thread name. + pub ki_moretdname: [c_char; crate::MAXCOMLEN - crate::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; crate::KI_NSPARE_INT], + /// Controlling tty dev. + pub ki_tdev: crate::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: crate::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: crate::lwpid_t, + /// Process priority. + pub ki_pri: crate::priority, + /// Process rusage statistics. + pub ki_rusage: crate::rusage, + /// rusage of children processes. + pub ki_rusage_ch: crate::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; crate::KI_NSPARE_PTR], + pub ki_sparelongs: [c_long; crate::KI_NSPARE_LONG], + /// PS_* flags. + pub ki_sflag: c_long, + /// kthread flag. + pub ki_tdflags: c_long, + } + + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + st_padding0: Padding, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + st_padding1: Padding, + pub st_rdev: crate::dev_t, + #[cfg(target_arch = "x86")] + st_atim_ext: i32, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + #[cfg(target_arch = "x86")] + st_mtim_ext: i32, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + #[cfg(target_arch = "x86")] + st_ctim_ext: i32, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + #[cfg(target_arch = "x86")] + st_btim_ext: i32, + pub st_birthtime: crate::time_t, + pub st_birthtime_nsec: c_long, + pub st_size: off_t, + pub st_blocks: crate::blkcnt_t, + pub st_blksize: crate::blksize_t, + pub st_flags: crate::fflags_t, + pub st_gen: u64, + pub st_spare: [u64; 10], + } + + pub struct dirent { + pub d_fileno: crate::ino_t, + pub d_off: off_t, + pub d_reclen: u16, + pub d_type: u8, + d_pad0: Padding, + pub d_namlen: u16, + d_pad1: Padding, + 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: crate::uid_t, + pub f_fsid: crate::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; crate::SPECNAMELEN as usize + 1], + } +} + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const RAND_MAX: c_int = 0x7fff_fffd; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 safe fn makedev(major: c_uint, minor: c_uint) -> crate::dev_t { + let major = major as crate::dev_t; + let minor = minor as crate::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 + } + + pub const safe fn major(dev: crate::dev_t) -> c_int { + (((dev >> 32) & 0xffffff00) | ((dev >> 8) & 0xff)) as c_int + } + + pub const safe fn minor(dev: crate::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: crate::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; + + #[link_name = "qsort_r@FBSD_1.0"] + pub fn qsort_r( + base: *mut c_void, + num: size_t, + size: size_t, + arg: *mut c_void, + compar: Option c_int>, + ); +} + +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..cf720eb --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs @@ -0,0 +1,7 @@ +use crate::prelude::*; + +pub const PROC_KPTI_CTL: c_int = crate::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 = crate::PROC_PROCCTL_MD_MIN + 1; +pub const PROC_KPTI_STATUS_ACTIVE: c_int = u32_cast_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..2858cbf --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs @@ -0,0 +1,415 @@ +use crate::off_t; +use crate::prelude::*; + +// 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: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_lpid: crate::pid_t, + pub shm_cpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + } + + pub struct kevent { + pub ident: crate::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: crate::u_int, + pub kp_paddr: crate::kpaddr_t, + pub kp_kmap_vaddr: crate::kvaddr_t, + pub kp_dmap_vaddr: crate::kvaddr_t, + pub kp_prot: crate::vm_prot_t, + pub kp_offset: off_t, + pub kp_len: size_t, + } + + pub struct __c_anonymous_domainset { + #[cfg(target_pointer_width = "64")] + _priv: [c_ulong; 4], + #[cfg(target_pointer_width = "32")] + _priv: [c_ulong; 8], + } + + 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 crate::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, + /// Pointer to open file info. + pub ki_fd: *mut crate::filedesc, + // 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: crate::pid_t, + /// Parent process ID. + pub ki_ppid: crate::pid_t, + /// Process group ID. + pub ki_pgid: crate::pid_t, + /// tty process group ID. + pub ki_tpgid: crate::pid_t, + /// Process session ID. + pub ki_sid: crate::pid_t, + /// Terminal session ID. + pub ki_tsid: crate::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: crate::sigset_t, + /// Current signal mask. + pub ki_sigmask: crate::sigset_t, + /// Signals being ignored. + pub ki_sigignore: crate::sigset_t, + /// Signals being caught by user. + pub ki_sigcatch: crate::sigset_t, + /// Effective user ID. + pub ki_uid: crate::uid_t, + /// Real user ID. + pub ki_ruid: crate::uid_t, + /// Saved effective user ID. + pub ki_svuid: crate::uid_t, + /// Real group ID. + pub ki_rgid: crate::gid_t, + /// Saved effective group ID. + pub ki_svgid: crate::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: [crate::gid_t; crate::KI_NGROUPS], + /// Virtual size. + pub ki_size: crate::vm_size_t, + /// Current resident set size in pages. + pub ki_rssize: crate::segsz_t, + /// Resident set size before last swap. + pub ki_swrss: crate::segsz_t, + /// Text size (pages) XXX. + pub ki_tsize: crate::segsz_t, + /// Data size (pages) XXX. + pub ki_dsize: crate::segsz_t, + /// Stack size (pages). + pub ki_ssize: crate::segsz_t, + /// Exit status for wait & stop signal. + pub ki_xstat: crate::u_short, + /// Accounting flags. + pub ki_acflag: crate::u_short, + /// %cpu for process during `ki_swtime`. + pub ki_pctcpu: crate::fixpt_t, + /// Time averaged value of `ki_cpticks`. + pub ki_estcpu: crate::u_int, + /// Time since last blocked. + pub ki_slptime: crate::u_int, + /// Time swapped in or out. + pub ki_swtime: crate::u_int, + /// Number of copy-on-write faults. + pub ki_cow: crate::u_int, + /// Real time in microsec. + pub ki_runtime: u64, + /// Starting time. + pub ki_start: crate::timeval, + /// Time used by process children. + pub ki_childtime: crate::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; crate::TDNAMLEN + 1], + /// Wchan message. + pub ki_wmesg: [c_char; crate::WMESGLEN + 1], + /// Setlogin name. + pub ki_login: [c_char; crate::LOGNAMELEN + 1], + /// Lock name. + pub ki_lockname: [c_char; crate::LOCKNAMELEN + 1], + /// Command name. + pub ki_comm: [c_char; crate::COMMLEN + 1], + /// Emulation name. + pub ki_emul: [c_char; crate::KI_EMULNAMELEN + 1], + /// Login class. + pub ki_loginclass: [c_char; crate::LOGINCLASSLEN + 1], + /// More thread name. + pub ki_moretdname: [c_char; crate::MAXCOMLEN - crate::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; crate::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: crate::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: crate::lwpid_t, + /// Process priority. + pub ki_pri: crate::priority, + /// Process rusage statistics. + pub ki_rusage: crate::rusage, + /// rusage of children processes. + pub ki_rusage_ch: crate::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; crate::KI_NSPARE_PTR], + pub ki_sparelongs: [c_long; crate::KI_NSPARE_LONG], + /// PS_* flags. + pub ki_sflag: c_long, + /// kthread flag. + pub ki_tdflags: c_long, + } + + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + st_padding0: Padding, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + st_padding1: Padding, + pub st_rdev: crate::dev_t, + #[cfg(target_arch = "x86")] + st_atim_ext: i32, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + #[cfg(target_arch = "x86")] + st_mtim_ext: i32, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + #[cfg(target_arch = "x86")] + st_ctim_ext: i32, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + #[cfg(target_arch = "x86")] + st_btim_ext: i32, + pub st_birthtime: crate::time_t, + pub st_birthtime_nsec: c_long, + pub st_size: off_t, + pub st_blocks: crate::blkcnt_t, + pub st_blksize: crate::blksize_t, + pub st_flags: crate::fflags_t, + pub st_gen: u64, + pub st_spare: [u64; 10], + } + + pub struct dirent { + pub d_fileno: crate::ino_t, + pub d_off: off_t, + pub d_reclen: u16, + pub d_type: u8, + d_pad0: Padding, + pub d_namlen: u16, + d_pad1: Padding, + 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: crate::uid_t, + pub f_fsid: crate::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; crate::SPECNAMELEN as usize + 1], + } +} + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const RAND_MAX: c_int = 0x7fff_ffff; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 safe fn makedev(major: c_uint, minor: c_uint) -> crate::dev_t { + let major = major as crate::dev_t; + let minor = minor as crate::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 + } + + pub const safe fn major(dev: crate::dev_t) -> c_int { + (((dev >> 32) & 0xffffff00) | ((dev >> 8) & 0xff)) as c_int + } + + pub const safe fn minor(dev: crate::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: crate::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: crate::cpulevel_t, + which: crate::cpuwhich_t, + id: crate::id_t, + setsize: size_t, + mask: *mut crate::domainset_t, + policy: *mut c_int, + ) -> c_int; + pub fn cpuset_setdomain( + level: crate::cpulevel_t, + which: crate::cpuwhich_t, + id: crate::id_t, + setsize: size_t, + mask: *const crate::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 = "qsort_r@FBSD_1.0"] + pub fn qsort_r( + base: *mut c_void, + num: size_t, + size: size_t, + arg: *mut c_void, + compar: Option c_int>, + ); +} + +#[link(name = "kvm")] +extern "C" { + pub fn kvm_kerndisp(kd: *mut crate::kvm_t) -> crate::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..cf720eb --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs @@ -0,0 +1,7 @@ +use crate::prelude::*; + +pub const PROC_KPTI_CTL: c_int = crate::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 = crate::PROC_PROCCTL_MD_MIN + 1; +pub const PROC_KPTI_STATUS_ACTIVE: c_int = u32_cast_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..12beb34 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs @@ -0,0 +1,416 @@ +use crate::off_t; +use crate::prelude::*; + +// 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: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_lpid: crate::pid_t, + pub shm_cpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + } + + pub struct kevent { + pub ident: crate::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: crate::u_int, + pub kp_paddr: crate::kpaddr_t, + pub kp_kmap_vaddr: crate::kvaddr_t, + pub kp_dmap_vaddr: crate::kvaddr_t, + pub kp_prot: crate::vm_prot_t, + pub kp_offset: off_t, + pub kp_len: size_t, + } + + pub struct __c_anonymous_domainset { + #[cfg(target_pointer_width = "64")] + _priv: [c_ulong; 4], + #[cfg(target_pointer_width = "32")] + _priv: [c_ulong; 8], + } + + 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 crate::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, + /// Pointer to open file info. + pub ki_fd: *mut crate::filedesc, + // 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: crate::pid_t, + /// Parent process ID. + pub ki_ppid: crate::pid_t, + /// Process group ID. + pub ki_pgid: crate::pid_t, + /// tty process group ID. + pub ki_tpgid: crate::pid_t, + /// Process session ID. + pub ki_sid: crate::pid_t, + /// Terminal session ID. + pub ki_tsid: crate::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: crate::sigset_t, + /// Current signal mask. + pub ki_sigmask: crate::sigset_t, + /// Signals being ignored. + pub ki_sigignore: crate::sigset_t, + /// Signals being caught by user. + pub ki_sigcatch: crate::sigset_t, + /// Effective user ID. + pub ki_uid: crate::uid_t, + /// Real user ID. + pub ki_ruid: crate::uid_t, + /// Saved effective user ID. + pub ki_svuid: crate::uid_t, + /// Real group ID. + pub ki_rgid: crate::gid_t, + /// Saved effective group ID. + pub ki_svgid: crate::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: [crate::gid_t; crate::KI_NGROUPS], + /// Virtual size. + pub ki_size: crate::vm_size_t, + /// Current resident set size in pages. + pub ki_rssize: crate::segsz_t, + /// Resident set size before last swap. + pub ki_swrss: crate::segsz_t, + /// Text size (pages) XXX. + pub ki_tsize: crate::segsz_t, + /// Data size (pages) XXX. + pub ki_dsize: crate::segsz_t, + /// Stack size (pages). + pub ki_ssize: crate::segsz_t, + /// Exit status for wait & stop signal. + pub ki_xstat: crate::u_short, + /// Accounting flags. + pub ki_acflag: crate::u_short, + /// %cpu for process during `ki_swtime`. + pub ki_pctcpu: crate::fixpt_t, + /// Time averaged value of `ki_cpticks`. + pub ki_estcpu: crate::u_int, + /// Time since last blocked. + pub ki_slptime: crate::u_int, + /// Time swapped in or out. + pub ki_swtime: crate::u_int, + /// Number of copy-on-write faults. + pub ki_cow: crate::u_int, + /// Real time in microsec. + pub ki_runtime: u64, + /// Starting time. + pub ki_start: crate::timeval, + /// Time used by process children. + pub ki_childtime: crate::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; crate::TDNAMLEN + 1], + /// Wchan message. + pub ki_wmesg: [c_char; crate::WMESGLEN + 1], + /// Setlogin name. + pub ki_login: [c_char; crate::LOGNAMELEN + 1], + /// Lock name. + pub ki_lockname: [c_char; crate::LOCKNAMELEN + 1], + /// Command name. + pub ki_comm: [c_char; crate::COMMLEN + 1], + /// Emulation name. + pub ki_emul: [c_char; crate::KI_EMULNAMELEN + 1], + /// Login class. + pub ki_loginclass: [c_char; crate::LOGINCLASSLEN + 1], + /// More thread name. + pub ki_moretdname: [c_char; crate::MAXCOMLEN - crate::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; crate::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: crate::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: crate::lwpid_t, + /// Process priority. + pub ki_pri: crate::priority, + /// Process rusage statistics. + pub ki_rusage: crate::rusage, + /// rusage of children processes. + pub ki_rusage_ch: crate::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; crate::KI_NSPARE_PTR], + pub ki_sparelongs: [c_long; crate::KI_NSPARE_LONG], + /// PS_* flags. + pub ki_sflag: c_long, + /// kthread flag. + pub ki_tdflags: c_long, + } + + #[non_exhaustive] + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + st_padding0: Padding, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + st_padding1: Padding, + pub st_rdev: crate::dev_t, + #[cfg(target_arch = "x86")] + st_atim_ext: i32, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + #[cfg(target_arch = "x86")] + st_mtim_ext: i32, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + #[cfg(target_arch = "x86")] + st_ctim_ext: i32, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + #[cfg(target_arch = "x86")] + st_btim_ext: i32, + pub st_birthtime: crate::time_t, + pub st_birthtime_nsec: c_long, + pub st_size: off_t, + pub st_blocks: crate::blkcnt_t, + pub st_blksize: crate::blksize_t, + pub st_flags: crate::fflags_t, + pub st_gen: u64, + pub st_filerev: u64, + pub st_spare: [u64; 9], + } + + pub struct dirent { + pub d_fileno: crate::ino_t, + pub d_off: off_t, + pub d_reclen: u16, + pub d_type: u8, + d_pad0: Padding, + pub d_namlen: u16, + d_pad1: Padding, + 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: crate::uid_t, + pub f_fsid: crate::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; crate::SPECNAMELEN as usize + 1], + } +} + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const RAND_MAX: c_int = 0x7fff_ffff; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 safe fn makedev(major: c_uint, minor: c_uint) -> crate::dev_t { + let major = major as crate::dev_t; + let minor = minor as crate::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 + } + + pub const safe fn major(dev: crate::dev_t) -> c_int { + (((dev >> 32) & 0xffffff00) | ((dev >> 8) & 0xff)) as c_int + } + + pub const safe fn minor(dev: crate::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: crate::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: crate::cpulevel_t, + which: crate::cpuwhich_t, + id: crate::id_t, + setsize: size_t, + mask: *mut crate::domainset_t, + policy: *mut c_int, + ) -> c_int; + pub fn cpuset_setdomain( + level: crate::cpulevel_t, + which: crate::cpuwhich_t, + id: crate::id_t, + setsize: size_t, + mask: *const crate::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; + + pub fn qsort_r( + base: *mut c_void, + num: size_t, + size: size_t, + compar: Option c_int>, + arg: *mut c_void, + ); +} + +#[link(name = "kvm")] +extern "C" { + pub fn kvm_kerndisp(kd: *mut crate::kvm_t) -> crate::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..b490c6e --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs @@ -0,0 +1,14 @@ +use crate::prelude::*; + +pub const PROC_KPTI_CTL: c_int = crate::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 = crate::PROC_PROCCTL_MD_MIN + 1; +pub const PROC_KPTI_STATUS_ACTIVE: c_int = u32_cast_int(0x80000000); +pub const PROC_LA_CTL: c_int = crate::PROC_PROCCTL_MD_MIN + 2; +pub const PROC_LA_STATUS: c_int = crate::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..92c263f --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/mod.rs @@ -0,0 +1,418 @@ +use crate::off_t; +use crate::prelude::*; + +// 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: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_lpid: crate::pid_t, + pub shm_cpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + } + + pub struct kevent { + pub ident: crate::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: crate::u_int, + pub kp_paddr: crate::kpaddr_t, + pub kp_kmap_vaddr: crate::kvaddr_t, + pub kp_dmap_vaddr: crate::kvaddr_t, + pub kp_prot: crate::vm_prot_t, + pub kp_offset: off_t, + pub kp_len: size_t, + } + + pub struct __c_anonymous_domainset { + #[cfg(target_pointer_width = "64")] + _priv: [c_ulong; 4], + #[cfg(target_pointer_width = "32")] + _priv: [c_ulong; 8], + } + + #[non_exhaustive] + 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 crate::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, + /// Pointer to open file info. + pub ki_fd: *mut crate::filedesc, + // 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: crate::pid_t, + /// Parent process ID. + pub ki_ppid: crate::pid_t, + /// Process group ID. + pub ki_pgid: crate::pid_t, + /// tty process group ID. + pub ki_tpgid: crate::pid_t, + /// Process session ID. + pub ki_sid: crate::pid_t, + /// Terminal session ID. + pub ki_tsid: crate::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: crate::sigset_t, + /// Current signal mask. + pub ki_sigmask: crate::sigset_t, + /// Signals being ignored. + pub ki_sigignore: crate::sigset_t, + /// Signals being caught by user. + pub ki_sigcatch: crate::sigset_t, + /// Effective user ID. + pub ki_uid: crate::uid_t, + /// Real user ID. + pub ki_ruid: crate::uid_t, + /// Saved effective user ID. + pub ki_svuid: crate::uid_t, + /// Real group ID. + pub ki_rgid: crate::gid_t, + /// Saved effective group ID. + pub ki_svgid: crate::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: [crate::gid_t; crate::KI_NGROUPS], + /// Virtual size. + pub ki_size: crate::vm_size_t, + /// Current resident set size in pages. + pub ki_rssize: crate::segsz_t, + /// Resident set size before last swap. + pub ki_swrss: crate::segsz_t, + /// Text size (pages) XXX. + pub ki_tsize: crate::segsz_t, + /// Data size (pages) XXX. + pub ki_dsize: crate::segsz_t, + /// Stack size (pages). + pub ki_ssize: crate::segsz_t, + /// Exit status for wait & stop signal. + pub ki_xstat: crate::u_short, + /// Accounting flags. + pub ki_acflag: crate::u_short, + /// %cpu for process during `ki_swtime`. + pub ki_pctcpu: crate::fixpt_t, + /// Time averaged value of `ki_cpticks`. + pub ki_estcpu: crate::u_int, + /// Time since last blocked. + pub ki_slptime: crate::u_int, + /// Time swapped in or out. + pub ki_swtime: crate::u_int, + /// Number of copy-on-write faults. + pub ki_cow: crate::u_int, + /// Real time in microsec. + pub ki_runtime: u64, + /// Starting time. + pub ki_start: crate::timeval, + /// Time used by process children. + pub ki_childtime: crate::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; crate::TDNAMLEN + 1], + /// Wchan message. + pub ki_wmesg: [c_char; crate::WMESGLEN + 1], + /// Setlogin name. + pub ki_login: [c_char; crate::LOGNAMELEN + 1], + /// Lock name. + pub ki_lockname: [c_char; crate::LOCKNAMELEN + 1], + /// Command name. + pub ki_comm: [c_char; crate::COMMLEN + 1], + /// Emulation name. + pub ki_emul: [c_char; crate::KI_EMULNAMELEN + 1], + /// Login class. + pub ki_loginclass: [c_char; crate::LOGINCLASSLEN + 1], + /// More thread name. + pub ki_moretdname: [c_char; crate::MAXCOMLEN - crate::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; crate::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: crate::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: crate::lwpid_t, + /// Process priority. + pub ki_pri: crate::priority, + /// Process rusage statistics. + pub ki_rusage: crate::rusage, + /// rusage of children processes. + pub ki_rusage_ch: crate::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, + /// Address of the ext err msg place + pub ki_uerrmsg: *mut c_void, + pub ki_spareptrs: [*mut c_void; crate::KI_NSPARE_PTR], + pub ki_sparelongs: [c_long; crate::KI_NSPARE_LONG], + /// PS_* flags. + pub ki_sflag: c_long, + /// kthread flag. + pub ki_tdflags: c_long, + } + + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + st_padding0: Padding, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + st_padding1: Padding, + pub st_rdev: crate::dev_t, + #[cfg(target_arch = "x86")] + st_atim_ext: i32, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + #[cfg(target_arch = "x86")] + st_mtim_ext: i32, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + #[cfg(target_arch = "x86")] + st_ctim_ext: i32, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + #[cfg(target_arch = "x86")] + st_btim_ext: i32, + pub st_birthtime: crate::time_t, + pub st_birthtime_nsec: c_long, + pub st_size: off_t, + pub st_blocks: crate::blkcnt_t, + pub st_blksize: crate::blksize_t, + pub st_flags: crate::fflags_t, + pub st_gen: u64, + pub st_filerev: u64, + pub st_spare: [u64; 9], + } + + pub struct dirent { + pub d_fileno: crate::ino_t, + pub d_off: off_t, + pub d_reclen: u16, + pub d_type: u8, + d_pad0: Padding, + pub d_namlen: u16, + d_pad1: Padding, + 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: crate::uid_t, + pub f_fsid: crate::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; crate::SPECNAMELEN as usize + 1], + } +} + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const RAND_MAX: c_int = 0x7fff_ffff; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 = 4; + +/// 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 safe fn makedev(major: c_uint, minor: c_uint) -> crate::dev_t { + let major = major as crate::dev_t; + let minor = minor as crate::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 + } + + pub const safe fn major(dev: crate::dev_t) -> c_int { + (((dev >> 32) & 0xffffff00) | ((dev >> 8) & 0xff)) as c_int + } + + pub const safe fn minor(dev: crate::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: crate::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: crate::cpulevel_t, + which: crate::cpuwhich_t, + id: crate::id_t, + setsize: size_t, + mask: *mut crate::domainset_t, + policy: *mut c_int, + ) -> c_int; + pub fn cpuset_setdomain( + level: crate::cpulevel_t, + which: crate::cpuwhich_t, + id: crate::id_t, + setsize: size_t, + mask: *const crate::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; + + pub fn qsort_r( + base: *mut c_void, + num: size_t, + size: size_t, + compar: Option c_int>, + arg: *mut c_void, + ); +} + +#[link(name = "kvm")] +extern "C" { + pub fn kvm_kerndisp(kd: *mut crate::kvm_t) -> crate::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..b490c6e --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/x86_64.rs @@ -0,0 +1,14 @@ +use crate::prelude::*; + +pub const PROC_KPTI_CTL: c_int = crate::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 = crate::PROC_PROCCTL_MD_MIN + 1; +pub const PROC_KPTI_STATUS_ACTIVE: c_int = u32_cast_int(0x80000000); +pub const PROC_LA_CTL: c_int = crate::PROC_PROCCTL_MD_MIN + 2; +pub const PROC_LA_STATUS: c_int = crate::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..0d1491b --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs @@ -0,0 +1,5377 @@ +use crate::prelude::*; +use crate::{ + cmsghdr, + off_t, +}; + +pub type fflags_t = u32; + +pub type Elf32_Lword = u64; + +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 ksize_t = u64; +pub type inp_gen_t = u64; +pub type so_gen_t = u64; +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 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 = crate::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 = crate::uid_t; +pub type au_asid_t = crate::pid_t; + +pub type cpusetid_t = c_int; + +pub type sctp_assoc_t = u32; + +pub type eventfd_t = u64; + +#[derive(Debug)] +#[cfg_attr(feature = "extra_traits", derive(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 + } +} + +#[derive(Debug)] +#[cfg_attr(feature = "extra_traits", derive(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 + } +} + +#[derive(Debug)] +#[cfg_attr(feature = "extra_traits", derive(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 + } +} + +#[derive(Debug)] +#[cfg_attr(feature = "extra_traits", derive(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 + } +} + +#[derive(Debug)] +#[cfg_attr(feature = "extra_traits", derive(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 + } +} + +#[derive(Debug)] +#[cfg_attr(feature = "extra_traits", derive(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 + } +} + +#[derive(Debug)] +#[cfg_attr(feature = "extra_traits", derive(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 + } +} + +#[derive(Debug)] +#[cfg_attr(feature = "extra_traits", derive(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 crate::in_addr, + pub ip6: *mut crate::in6_addr, + } + + pub struct ip_mreq_source { + pub imr_multiaddr: crate::in_addr, + pub imr_sourceaddr: crate::in_addr, + pub imr_interface: crate::in_addr, + } + + pub struct statvfs { + pub f_bavail: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_blocks: crate::fsblkcnt_t, + pub f_favail: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_files: crate::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 input_event { + pub time: crate::timeval, + pub type_: crate::u_short, + pub code: crate::u_short, + pub value: i32, + } + + pub struct input_absinfo { + pub value: i32, + pub minimum: i32, + pub maximum: i32, + pub fuzz: i32, + pub flat: i32, + pub resolution: i32, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + __unused1: Padding<*mut c_void>, + __unused2: Padding<*mut c_void>, + pub msg_cbytes: crate::msglen_t, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + pub msg_stime: crate::time_t, + pub msg_rtime: crate::time_t, + pub msg_ctime: crate::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: crate::msghdr, + pub msg_len: ssize_t, + } + + pub struct sockcred { + pub sc_uid: crate::uid_t, + pub sc_euid: crate::uid_t, + pub sc_gid: crate::gid_t, + pub sc_egid: crate::gid_t, + pub sc_ngroups: c_int, + pub sc_groups: [crate::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: crate::sigset_t, + pub pl_siglist: crate::sigset_t, + pub pl_siginfo: crate::siginfo_t, + pub pl_tdname: [c_char; crate::MAXCOMLEN as usize + 1], + pub pl_child_pid: crate::pid_t, + pub pl_syscall_code: c_uint, + pub pl_syscall_narg: c_uint, + } + + pub struct ptrace_sc_ret { + pub sr_retval: [crate::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 crate::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: crate::lwpid_t, + m_flags: u32, + m_ceilings: [u32; 2], + m_rb_link: crate::uintptr_t, + #[cfg(target_pointer_width = "32")] + m_pad: Padding, + 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, + clock_seq_hi_and_reserved: Padding, + 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: crate::uintptr_t, + pub vmentries: *mut c_void, + pub files: *mut c_void, + pub argv: *mut c_void, + pub envv: *mut c_void, + pub core: crate::uintptr_t, + } + + pub struct itimerspec { + pub it_interval: crate::timespec, + pub it_value: crate::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, + ksw_reserved1: Padding, + ksw_reserved2: Padding, + } + + 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: crate::kvaddr_t, + } + + pub struct __c_anonymous_sem { + _priv: crate::uintptr_t, + } + + pub struct semid_ds { + pub sem_perm: crate::ipc_perm, + pub __sem_base: *mut __c_anonymous_sem, + pub sem_nsems: c_ushort, + pub sem_otime: crate::time_t, + pub sem_ctime: crate::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: crate::sockaddr_storage, + /// Peer address. + pub sa_peer: crate::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; crate::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; crate::IFNAMSIZ as usize], + pub ifra_addr: crate::sockaddr, + pub ifra_broadaddr: crate::sockaddr, + pub ifra_mask: crate::sockaddr, + pub ifra_vhid: c_int, + } + + /// 9.x compat + pub struct oifaliasreq { + /// if name, e.g. "en0" + pub ifra_name: [c_char; crate::IFNAMSIZ as usize], + pub ifra_addr: crate::sockaddr, + pub ifra_broadaddr: crate::sockaddr, + pub ifra_mask: crate::sockaddr, + } + + pub struct ifmediareq { + /// if name, e.g. "en0" + pub ifm_name: [c_char; crate::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; crate::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; crate::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; crate::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; crate::MAXFIDSZ as usize], + } + + pub struct fhandle { + pub fh_fsid: crate::fsid_t, + pub fh_fid: fid, + } + + pub struct bintime { + pub sec: crate::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: crate::u_int, + /// Allocated entry + pub allocated: c_int, + /// started ops + pub start_count: crate::u_int, + /// completed ops + pub end_count: crate::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: crate::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: crate::pid_t, + pub sc_uid: crate::uid_t, + pub sc_euid: crate::uid_t, + pub sc_gid: crate::gid_t, + pub sc_egid: crate::gid_t, + pub sc_ngroups: c_int, + pub sc_groups: [crate::gid_t; 1], + } + + pub struct ifconf { + pub ifc_len: c_int, + pub ifc_ifcu: __c_anonymous_ifc_ifcu, + } + + pub struct au_mask_t { + pub am_success: c_uint, + pub am_failure: c_uint, + } + + pub struct au_tid_t { + pub port: u32, + pub machine: u32, + } + + pub struct auditinfo_t { + pub ai_auid: crate::au_id_t, + pub ai_mask: crate::au_mask_t, + pub ai_termid: au_tid_t, + pub ai_asid: crate::au_asid_t, + } + + pub struct tcp_fastopen { + pub enable: c_int, + pub psk: [u8; crate::TCP_FASTOPEN_PSK_LEN as usize], + } + + pub struct tcp_function_set { + pub function_set_name: [c_char; crate::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: crate::timespec, + pub _flags: u32, + pub _clockid: u32, + } + + pub struct shm_largepage_conf { + pub psind: c_int, + pub alloc_policy: c_int, + __pad: Padding<[c_int; 10]>, + } + + pub struct memory_type { + __priva: [crate::uintptr_t; 32], + __privb: [crate::uintptr_t; 26], + } + + pub struct memory_type_list { + __priv: [crate::uintptr_t; 2], + } + + pub struct pidfh { + __priva: [[crate::uintptr_t; 32]; 8], + __privb: [crate::uintptr_t; 2], + } + + pub struct sctp_event { + pub se_assoc_id: crate::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: crate::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: crate::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: crate::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: crate::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: crate::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: crate::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: crate::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: crate::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: crate::sockaddr_storage, + pub spc_state: u32, + pub spc_error: u32, + pub spc_assoc_id: crate::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: crate::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: crate::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: crate::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: crate::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: crate::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: crate::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: crate::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: crate::sctp_assoc_t, + pub strchange_instrms: u16, + pub strchange_outstrms: u16, + } + + pub struct filedesc { + pub fd_files: *mut fdescenttbl, + pub fd_map: *mut c_ulong, + pub fd_freefile: c_int, + pub fd_refcnt: c_int, + pub fd_holdcnt: c_int, + fd_sx: sx, + fd_kqlist: kqlist, + pub fd_holdleaderscount: c_int, + pub fd_holdleaderswakeup: c_int, + } + + pub struct fdescenttbl { + pub fdt_nfiles: c_int, + fdt_ofiles: [*mut c_void; 0], + } + + // FIXME: Should be private. + #[doc(hidden)] + pub struct sx { + lock_object: lock_object, + sx_lock: crate::uintptr_t, + } + + // FIXME: Should be private. + #[doc(hidden)] + pub struct lock_object { + lo_name: *const c_char, + lo_flags: c_uint, + lo_data: c_uint, + // This is normally `struct witness`. + lo_witness: *mut c_void, + } + + // FIXME: Should be private. + #[doc(hidden)] + pub struct kqlist { + tqh_first: *mut c_void, + tqh_last: *mut *mut c_void, + } + + pub struct splice { + pub sp_fd: c_int, + pub sp_max: off_t, + pub sp_idle: crate::timeval, + } + + pub struct utmpx { + pub ut_type: c_short, + pub ut_tv: crate::timeval, + pub ut_id: [c_char; 8], + pub ut_pid: crate::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], + } + + pub struct xucred { + pub cr_version: c_uint, + pub cr_uid: crate::uid_t, + pub cr_ngroups: c_short, + pub cr_groups: [crate::gid_t; 16], + pub cr_pid__c_anonymous_union: __c_anonymous_cr_pid, + } + + 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: Padding<[c_long; 4]>, + } + + 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], + } + + pub struct Elf32_Auxinfo { + pub a_type: c_int, + pub a_un: __c_anonymous_elf32_auxv_union, + } + + pub struct ifreq { + /// if name, e.g. "en0" + pub ifr_name: [c_char; crate::IFNAMSIZ], + pub ifr_ifru: __c_anonymous_ifr_ifru, + } + + 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 + pub __ifi_epoch: __c_anonymous_ifi_epoch, + /// time of last administrative change + pub __ifi_lastchange: __c_anonymous_ifi_lastchange, + } + + pub struct ifstat { + /// if name, e.g. "en0" + pub ifs_name: [c_char; crate::IFNAMSIZ as usize], + pub ascii: [c_char; crate::IFSTATMAX as usize + 1], + } + + pub struct ifrsskey { + /// if name, e.g. "en0" + pub ifrk_name: [c_char; crate::IFNAMSIZ as usize], + /// RSS_FUNC_ + pub ifrk_func: u8, + pub ifrk_spare0: u8, + pub ifrk_keylen: u16, + pub ifrk_key: [u8; crate::RSS_KEYLEN as usize], + } + + pub struct ifdownreason { + pub ifdr_name: [c_char; crate::IFNAMSIZ as usize], + pub ifdr_reason: u32, + pub ifdr_vendor: u32, + pub ifdr_msg: [c_char; crate::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: Padding, + } + + #[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: Padding, + pub kf_offset: i64, + _priv: [u8; 304], // FIXME(freebsd): this is really a giant union + pub kf_status: u16, + _kf_pad1: Padding, + _kf_ispare0: c_int, + pub kf_cap_rights: crate::cap_rights_t, + _kf_cap_spare: u64, + pub kf_path: [c_char; crate::PATH_MAX as usize], + } +} + +s_no_extra_traits! { + pub union __c_anonymous_cr_pid { + __cr_unused: Padding<*mut c_void>, + pub cr_pid: crate::pid_t, + } + + pub struct sigevent { + pub sigev_notify: c_int, + pub sigev_signo: c_int, + pub sigev_value: crate::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: crate::lwpid_t, + #[cfg(target_pointer_width = "64")] + __unused1: c_int, + __unused2: [c_long; 7], + } + + pub union __c_anonymous_elf32_auxv_union { + pub a_val: c_int, + } + + pub union __c_anonymous_ifi_epoch { + pub tt: crate::time_t, + pub ph: u64, + } + + pub union __c_anonymous_ifi_lastchange { + pub tv: crate::timeval, + pub ph: __c_anonymous_ph, + } + + pub union __c_anonymous_ifr_ifru { + pub ifru_addr: crate::sockaddr, + pub ifru_dstaddr: crate::sockaddr, + pub ifru_broadaddr: crate::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: crate::caddr_t, + pub ifru_cap: [c_int; 2], + pub ifru_fib: c_uint, + pub ifru_vlan_pcp: c_uchar, + } + + pub union __c_anonymous_ifc_ifcu { + pub ifcu_buf: crate::caddr_t, + pub ifcu_req: *mut ifreq, + } + + pub struct ucontext_t { + pub uc_sigmask: crate::sigset_t, + pub uc_mcontext: crate::mcontext_t, + pub uc_link: *mut crate::ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_flags: c_int, + __spare__: [c_int; 4], + } + + #[repr(align(8))] + pub struct xinpgen { + pub xig_len: ksize_t, + pub xig_count: u32, + _xig_spare32: u32, + pub xig_gen: inp_gen_t, + pub xig_sogen: so_gen_t, + _xig_spare64: [u64; 4], + } + + pub struct in_addr_4in6 { + _ia46_pad32: Padding<[u32; 3]>, + pub ia46_addr4: crate::in_addr, + } + + pub union in_dependaddr { + pub id46_addr: crate::in_addr_4in6, + pub id6_addr: crate::in6_addr, + } + + pub struct in_endpoints { + pub ie_fport: u16, + pub ie_lport: u16, + pub ie_dependfaddr: crate::in_dependaddr, + pub ie_dependladdr: crate::in_dependaddr, + pub ie6_zoneid: u32, + } + + pub struct in_conninfo { + pub inc_flags: u8, + pub inc_len: u8, + pub inc_fibnum: u16, + pub inc_ie: crate::in_endpoints, + } + + pub struct xktls_session_onedir { + // Note: this field is called `gen` in upstream FreeBSD, but `gen` is + // reserved keyword in Rust since the 2024 Edition, hence `gennum`. + pub gennum: u64, + _rsrv1: [u64; 8], + _rsrv2: [u32; 8], + pub iv: [u8; 32], + pub cipher_algorithm: i32, + pub auth_algorithm: i32, + pub cipher_key_len: u16, + pub iv_len: u16, + pub auth_key_len: u16, + pub max_frame_len: u16, + pub tls_vmajor: u8, + pub tls_vminor: u8, + pub tls_hlen: u8, + pub tls_tlen: u8, + pub tls_bs: u8, + pub flags: u8, + pub drv_st_len: u16, + pub ifnet: [c_char; 16], + } + + pub struct xktls_session { + pub tsz: u32, + pub fsz: u32, + pub inp_gencnt: u64, + pub so_pcb: kvaddr_t, + pub coninf: crate::in_conninfo, + pub rx_vlan_id: c_ushort, + pub rcv: crate::xktls_session_onedir, + pub snd: crate::xktls_session_onedir, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for __c_anonymous_cr_pid { + fn eq(&self, other: &__c_anonymous_cr_pid) -> bool { + unsafe { self.cr_pid == other.cr_pid } + } + } + impl Eq for __c_anonymous_cr_pid {} + impl hash::Hash for __c_anonymous_cr_pid { + fn hash(&self, state: &mut H) { + unsafe { self.cr_pid.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 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 __c_anonymous_elf32_auxv_union { + fn eq(&self, other: &__c_anonymous_elf32_auxv_union) -> bool { + unsafe { self.a_val == other.a_val } + } + } + impl Eq for __c_anonymous_elf32_auxv_union {} + impl hash::Hash for __c_anonymous_elf32_auxv_union { + fn hash(&self, _state: &mut H) { + unimplemented!("traits"); + } + } + + 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 + } + } + } + impl Eq for __c_anonymous_ifr_ifru {} + 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 __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 } + } + } + impl Eq for __c_anonymous_ifc_ifcu {} + 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 __c_anonymous_ifi_epoch { + fn eq(&self, other: &__c_anonymous_ifi_epoch) -> bool { + unsafe { self.tt == other.tt && self.ph == other.ph } + } + } + impl Eq for __c_anonymous_ifi_epoch {} + impl hash::Hash for __c_anonymous_ifi_epoch { + fn hash(&self, state: &mut H) { + unsafe { + self.tt.hash(state); + self.ph.hash(state); + } + } + } + + 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 } + } + } + impl Eq for __c_anonymous_ifi_lastchange {} + impl hash::Hash for __c_anonymous_ifi_lastchange { + fn hash(&self, state: &mut H) { + unsafe { + self.tv.hash(state); + self.ph.hash(state); + } + } + } + } +} + +#[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; +#[deprecated(since = "0.2.165", note = "Not stable across OS versions")] +pub const CAP_ALL0: u64 = cap_right!(0, 0x000007FFFFFFFFFFu64); +#[deprecated(since = "0.2.165", note = "Not stable across OS versions")] +pub const CAP_UNUSED0_44: u64 = cap_right!(0, 0x0000080000000000u64); +#[deprecated(since = "0.2.165", note = "Not stable across OS versions")] +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; +#[deprecated(since = "0.2.165", note = "Not stable across OS versions")] +pub const CAP_ALL1: u64 = cap_right!(1, 0x00000000001FFFFFu64); +#[deprecated(since = "0.2.165", note = "Not stable across OS versions")] +pub const CAP_UNUSED1_22: u64 = cap_right!(1, 0x0000000000200000u64); +#[deprecated(since = "0.2.165", note = "Not stable across OS versions")] +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: crate::rlim_t = 15; +pub const RLIM_SAVED_MAX: crate::rlim_t = crate::RLIM_INFINITY; +pub const RLIM_SAVED_CUR: crate::rlim_t = crate::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 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_ILLSEQ: c_int = 17; +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; + +// For getrandom() +pub const GRND_NONBLOCK: c_uint = 0x1; +pub const GRND_RANDOM: c_uint = 0x2; +pub const GRND_INSECURE: c_uint = 0x4; + +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 = u32_cast_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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_BASE_MAX: c_int = 2; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_DIM_MAX: c_int = 3; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_SCALE_MAX: c_int = 4; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_STRING_MAX: c_int = 5; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_COLL_WEIGHTS_MAX: c_int = 6; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_EXPR_NEST_MAX: c_int = 7; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_LINE_MAX: c_int = 8; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + pub const BIOCSETFNR: c_ulong = 0x80104282; + } else { + pub const BIOCSETFNR: c_ulong = 0x80084282; + } +} + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + pub const FIODGNAME: c_ulong = 0x80106678; + } else { + pub const FIODGNAME: c_ulong = 0x80086678; + } +} + +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_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_SPLICE: c_int = 0x1023; +pub const SO_VENDOR: c_int = u32_cast_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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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_LOGSIGEXIT_CTL: c_int = 23; +pub const PROC_LOGSIGEXIT_STATUS: c_int = 24; +pub const PROC_LOGSIGEXIT_CTL_NOFORCE: c_int = 1; +pub const PROC_LOGSIGEXIT_CTL_FORCE_ENABLE: c_int = 2; +pub const PROC_LOGSIGEXIT_CTL_FORCE_DISABLE: c_int = 3; +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 = u32_cast_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 = u32_cast_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 = u32_cast_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 = u32_cast_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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; +#[deprecated(since = "0.2.171", note = "removed in FreeBSD 15")] +pub const TCP_PCAP_OUT: c_int = 2048; +#[deprecated(since = "0.2.171", note = "removed in FreeBSD 15")] +pub const TCP_PCAP_IN: c_int = 4096; +pub const TCP_FUNCTION_BLK: c_int = 8192; +pub const TCP_FUNCTION_ALIAS: c_int = 8193; +pub const TCP_FASTOPEN_PSK_LEN: c_int = 16; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const TCP_FUNCTION_NAME_LEN_MAX: c_int = 32; + +pub const TCP_REUSPORT_LB_NUMA: c_int = 1026; +pub const TCP_RACK_MBUF_QUEUE: c_int = 1050; +pub const TCP_RACK_TLP_REDUCE: c_int = 1052; +pub const TCP_RACK_PACE_MAX_SEG: c_int = 1054; +pub const TCP_RACK_PACE_ALWAYS: c_int = 1055; +pub const TCP_RACK_PRR_SENDALOT: c_int = 1057; +pub const TCP_RACK_MIN_TO: c_int = 1058; +pub const TCP_RACK_EARLY_SEG: c_int = 1060; +pub const TCP_RACK_REORD_THRESH: c_int = 1061; +pub const TCP_RACK_REORD_FADE: c_int = 1062; +pub const TCP_RACK_TLP_THRESH: c_int = 1063; +pub const TCP_RACK_PKT_DELAY: c_int = 1064; +pub const TCP_BBR_IWINTSO: c_int = 1067; +pub const TCP_BBR_STARTUP_PG: c_int = 1069; +pub const TCP_BBR_DRAIN_PG: c_int = 1070; +pub const TCP_BBR_PROBE_RTT_INT: c_int = 1072; +pub const TCP_BBR_STARTUP_LOSS_EXIT: c_int = 1074; +pub const TCP_BBR_TSLIMITS: c_int = 1076; +pub const TCP_BBR_PACE_OH: c_int = 1077; +pub const TCP_BBR_USEDEL_RATE: c_int = 1079; +pub const TCP_BBR_MIN_RTO: c_int = 1080; +pub const TCP_BBR_MAX_RTO: c_int = 1081; +pub const TCP_BBR_ALGORITHM: c_int = 1083; +pub const TCP_BBR_PACE_PER_SEC: c_int = 1086; +pub const TCP_BBR_PACE_DEL_TAR: c_int = 1087; +pub const TCP_BBR_PACE_SEG_MAX: c_int = 1088; +pub const TCP_BBR_PACE_SEG_MIN: c_int = 1089; +pub const TCP_BBR_PACE_CROSS: c_int = 1090; +pub const TCP_BBR_TMR_PACE_OH: c_int = 1096; +pub const TCP_BBR_RACK_RTT_USE: c_int = 1098; +pub const TCP_BBR_RETRAN_WTSO: c_int = 1099; +pub const TCP_BBR_PROBE_RTT_GAIN: c_int = 1101; +pub const TCP_BBR_PROBE_RTT_LEN: c_int = 1102; +pub const TCP_BBR_SEND_IWND_IN_TSO: c_int = 1103; +pub const TCP_BBR_USE_RACK_RR: c_int = 1104; +pub const TCP_BBR_HDWR_PACE: c_int = 1105; +pub const TCP_BBR_UTTER_MAX_TSO: c_int = 1106; +pub const TCP_BBR_EXTRA_STATE: c_int = 1107; +pub const TCP_BBR_FLOOR_MIN_TSO: c_int = 1108; +pub const TCP_BBR_MIN_TOPACEOUT: c_int = 1109; +pub const TCP_BBR_TSTMP_RAISES: c_int = 1110; +pub const TCP_BBR_POLICER_DETECT: c_int = 1111; +pub const TCP_BBR_RACK_INIT_RATE: c_int = 1112; + +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 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_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: crate::speed_t = 460800; +pub const B921600: crate::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 AT_HWCAP3: c_int = 38; +pub const AT_HWCAP4: c_int = 39; + +pub const TABDLY: crate::tcflag_t = 0x00000004; +pub const TAB0: crate::tcflag_t = 0x00000000; +pub const TAB3: crate::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; + +// 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 = u32_cast_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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PRI_MAX: c_int = 255; + +pub const PRI_MIN_ITHD: c_int = PRI_MIN; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PRI_MAX_ITHD: c_int = PRI_MIN_REALTIME - 1; + +pub const PI_REALTIME: c_int = PRI_MIN_ITHD + 0; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PI_AV: c_int = PRI_MIN_ITHD + 4; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PI_NET: c_int = PRI_MIN_ITHD + 8; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PI_DISK: c_int = PRI_MIN_ITHD + 12; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PI_TTY: c_int = PRI_MIN_ITHD + 16; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PI_DULL: c_int = PRI_MIN_ITHD + 20; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PI_SOFT: c_int = PRI_MIN_ITHD + 24; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PRI_MIN_REALTIME: c_int = 48; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PRI_MAX_REALTIME: c_int = PRI_MIN_KERN - 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PRI_MIN_KERN: c_int = 80; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PRI_MAX_KERN: c_int = PRI_MIN_TIMESHARE - 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PSWP: c_int = PRI_MIN_KERN + 0; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PVM: c_int = PRI_MIN_KERN + 4; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PINOD: c_int = PRI_MIN_KERN + 8; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PRIBIO: c_int = PRI_MIN_KERN + 12; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PVFS: c_int = PRI_MIN_KERN + 16; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PZERO: c_int = PRI_MIN_KERN + 20; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PSOCK: c_int = PRI_MIN_KERN + 24; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PWAIT: c_int = PRI_MIN_KERN + 28; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PLOCK: c_int = PRI_MIN_KERN + 32; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PPAUSE: c_int = PRI_MIN_KERN + 36; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PRI_MIN_TIMESHARE: c_int = 120; + +pub const PRI_MAX_TIMESHARE: c_int = PRI_MIN_IDLE - 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 = crate::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. +/// +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const NAME_MAX: c_int = 255; +pub const MAXSYMLINKS: c_int = 32; +/// Max supplemental group IDs. +/// +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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). +/// +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const BC_BASE_MAX: c_int = 99; + +/// Max array elements in bc(1). +/// +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const BC_DIM_MAX: c_int = 2048; + +/// Max scale value in bc(1). +/// +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const BC_SCALE_MAX: c_int = 99; + +/// Max const string length in bc(1). +/// +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const BC_STRING_MAX: c_int = 1000; + +/// Max character class name size. +/// +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const CHARCLASS_NAME_MAX: c_int = 14; + +/// Max weights for order keyword. +/// +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const COLL_WEIGHTS_MAX: c_int = 10; + +/// Max expressions nested in expr(1). +/// +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const EXPR_NEST_MAX: c_int = 32; + +/// Max bytes in an input line. +/// +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const LINE_MAX: c_int = 2048; + +/// Max RE's in interval notation. +/// +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; +#[deprecated(since = "1.0", note = "Replaced in FreeBSD 15 by P_IDLEPROC")] +pub const P_UNUSED3: c_int = 0x00000008; +#[cfg(freebsd15)] +pub const P_IDLEPROC: 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 = u32_cast_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 = u32_cast_int(0xbeefface); + +pub const TDP_SIGFASTBLOCK: c_int = 0x00000100; +pub const TDP_UIOHELD: c_int = 0x10000000; +pub const TDP_SIGFASTPENDING: c_int = u32_cast_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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +// netinet/in_pcb.h +pub const INC_ISIPV6: c_uchar = 0x01; +pub const INC_IPV6MINMTU: c_uchar = 0x02; + +// sys/time.h +pub const CLOCK_BOOTTIME: crate::clockid_t = crate::CLOCK_UPTIME; +pub const CLOCK_REALTIME_COARSE: crate::clockid_t = crate::CLOCK_REALTIME_FAST; +pub const CLOCK_MONOTONIC_COARSE: crate::clockid_t = crate::CLOCK_MONOTONIC_FAST; + +// sys/timerfd.h + +pub const TFD_NONBLOCK: c_int = crate::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; + +// sys/unistd.h + +pub const CLOSE_RANGE_CLOEXEC: c_uint = 1 << 2; + +pub const KCMP_FILE: c_int = 100; +pub const KCMP_FILEOBJ: c_int = 101; +pub const KCMP_FILES: c_int = 102; +pub const KCMP_SIGHAND: c_int = 103; +pub const KCMP_VM: c_int = 104; + +pub const SOL_LOCAL: c_int = 0; + +pub const fn MAP_ALIGNED(a: c_int) -> c_int { + a << 24 +} + +const fn _ALIGN(p: usize) -> usize { + (p + _ALIGNBYTES) & !_ALIGNBYTES +} + +f! { + pub unsafe fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + (cmsg as *mut c_uchar).add(_ALIGN(size_of::())) + } + + pub const unsafe fn CMSG_LEN(length: c_uint) -> c_uint { + _ALIGN(size_of::()) as c_uint + length + } + + pub unsafe fn CMSG_NXTHDR(mhdr: *const crate::msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { + if cmsg.is_null() { + return crate::CMSG_FIRSTHDR(mhdr); + } + let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize) + _ALIGN(size_of::()); + let max = (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize; + if next > max { + ptr::null_mut() + } else { + (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)) as *mut cmsghdr + } + } + + pub const unsafe fn CMSG_SPACE(length: c_uint) -> c_uint { + (_ALIGN(size_of::()) + _ALIGN(length as usize)) as c_uint + } + + pub unsafe fn MALLOCX_ALIGN(lg: c_uint) -> c_int { + ffsl(lg as c_long - 1) + } + + pub const unsafe fn MALLOCX_TCACHE(tc: c_int) -> c_int { + (tc + 2) << 8 as c_int + } + + pub const unsafe fn MALLOCX_ARENA(a: c_int) -> c_int { + (a + 1) << 20 as c_int + } + + pub unsafe fn SOCKCREDSIZE(ngrps: usize) -> usize { + let ngrps = if ngrps > 0 { ngrps - 1 } else { 0 }; + size_of::() + size_of::() * ngrps + } + + pub unsafe fn uname(buf: *mut crate::utsname) -> c_int { + __xuname(256, buf.cast()) + } + + pub unsafe fn CPU_ZERO(cpuset: &mut cpuset_t) -> () { + cpuset.__bits.fill(0); + } + + pub unsafe fn CPU_FILL(cpuset: &mut cpuset_t) -> () { + cpuset.__bits.fill(!0); + } + + pub unsafe fn CPU_SET(cpu: usize, cpuset: &mut cpuset_t) -> () { + let bitset_bits = 8 * size_of::(); + let (idx, offset) = (cpu / bitset_bits, cpu % bitset_bits); + cpuset.__bits[idx] |= 1 << offset; + } + + pub unsafe fn CPU_CLR(cpu: usize, cpuset: &mut cpuset_t) -> () { + let bitset_bits = 8 * size_of::(); + let (idx, offset) = (cpu / bitset_bits, cpu % bitset_bits); + cpuset.__bits[idx] &= !(1 << offset); + } + + pub unsafe fn CPU_ISSET(cpu: usize, cpuset: &cpuset_t) -> bool { + let bitset_bits = 8 * size_of::(); + let (idx, offset) = (cpu / bitset_bits, cpu % bitset_bits); + 0 != cpuset.__bits[idx] & (1 << offset) + } + + pub unsafe fn CPU_COUNT(cpuset: &cpuset_t) -> c_int { + let mut s: u32 = 0; + let cpuset_size = size_of::(); + let bitset_size = size_of::(); + + for i in cpuset.__bits[..(cpuset_size / bitset_size)].iter() { + s += i.count_ones(); + } + s as c_int + } + + pub unsafe fn SOCKCRED2SIZE(ngrps: usize) -> usize { + let ngrps = if ngrps > 0 { ngrps - 1 } else { 0 }; + size_of::() + size_of::() * ngrps + } + + pub unsafe fn PROT_MAX(x: c_int) -> c_int { + x << 16 + } + + pub unsafe fn PROT_MAX_EXTRACT(x: c_int) -> c_int { + (x >> 16) & (crate::PROT_READ | crate::PROT_WRITE | crate::PROT_EXEC) + } +} + +safe_f! { + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 && status != 0x13 + } + + pub const safe fn INVALID_SINFO_FLAG(x: c_int) -> bool { + (x) & u32_cast_int(0xfffffff0) + & !(SCTP_EOF + | SCTP_ABORT + | SCTP_UNORDERED + | SCTP_ADDR_OVER + | SCTP_SENDALL + | SCTP_EOR + | SCTP_SACK_IMMEDIATELY) + != 0 + } + + pub const safe fn PR_SCTP_POLICY(x: c_int) -> c_int { + x & 0x0f + } + + pub const safe 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 safe fn PR_SCTP_TTL_ENABLED(x: c_int) -> bool { + PR_SCTP_POLICY(x) == SCTP_PR_SCTP_TTL + } + + pub const safe fn PR_SCTP_BUF_ENABLED(x: c_int) -> bool { + PR_SCTP_POLICY(x) == SCTP_PR_SCTP_BUF + } + + pub const safe fn PR_SCTP_RTX_ENABLED(x: c_int) -> bool { + PR_SCTP_POLICY(x) == SCTP_PR_SCTP_RTX + } + + pub const safe fn PR_SCTP_INVALID_POLICY(x: c_int) -> bool { + PR_SCTP_POLICY(x) > SCTP_PR_SCTP_MAX + } + + pub const safe fn PR_SCTP_VALID_POLICY(x: c_int) -> bool { + PR_SCTP_POLICY(x) <= SCTP_PR_SCTP_MAX + } + + pub const safe fn PPROT_OP(o: c_int) -> c_int { + o & 0xf + } + + pub const safe fn PPROT_FLAGS(o: c_int) -> c_int { + o & !0xf + } +} + +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 crate::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 crate::timespec, + ) -> c_int; + pub fn aio_write(aiocbp: *mut aiocb) -> c_int; + pub fn aio_writev(aiocbp: *mut crate::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: crate::dev_t, + mode: crate::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 crate::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 crate::iovec, niov: c_uint, flags: c_int) -> c_int; + pub fn jail_set(iov: *mut crate::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 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 crate::timespec) -> ssize_t; + pub fn mq_getfd_np(mqd: crate::mqd_t) -> c_int; + + pub fn waitid( + idtype: idtype_t, + id: crate::id_t, + infop: *mut crate::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) -> crate::key_t; + pub fn shmget(key: crate::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 crate::shmid_ds) -> c_int; + pub fn semget(key: crate::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 crate::msqid_ds) -> c_int; + pub fn msgget(key: crate::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 crate::termios); + + pub fn pdfork(fdp: *mut c_int, flags: c_int) -> crate::pid_t; + pub fn pdgetpid(fd: c_int, pidp: *mut crate::pid_t) -> c_int; + pub fn pdkill(fd: c_int, signum: c_int) -> c_int; + + pub fn rtprio_thread(function: c_int, lwpid: crate::lwpid_t, rtp: *mut super::rtprio) -> 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: crate::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: crate::pthread_t, + cpusetsize: size_t, + cpusetp: *mut cpuset_t, + ) -> c_int; + pub fn pthread_setaffinity_np( + td: crate::pthread_t, + cpusetsize: size_t, + cpusetp: *const cpuset_t, + ) -> c_int; + + // sched.h linux compatibility api + pub fn sched_getaffinity( + pid: crate::pid_t, + cpusetsz: size_t, + cpuset: *mut crate::cpuset_t, + ) -> c_int; + pub fn sched_setaffinity( + pid: crate::pid_t, + cpusetsz: size_t, + cpuset: *const crate::cpuset_t, + ) -> c_int; + pub fn sched_getcpu() -> c_int; + + pub fn pthread_mutex_consistent(mutex: *mut crate::pthread_mutex_t) -> c_int; + + pub fn pthread_mutexattr_getrobust( + attr: *mut crate::pthread_mutexattr_t, + robust: *mut c_int, + ) -> c_int; + pub fn pthread_mutexattr_setrobust( + attr: *mut crate::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; + + pub fn pthread_timedjoin_np( + thread: crate::pthread_t, + retval: *mut *mut c_void, + abstime: *const crate::timespec, + ) -> 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 crate::mmsghdr, + vlen: size_t, + flags: c_int, + ) -> ssize_t; + pub fn recvmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: size_t, + flags: c_int, + timeout: *const crate::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 crate::stat) -> c_int; + pub fn fhstatfs(fhp: *const fhandle_t, buf: *mut crate::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 crate::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 crate::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 crate::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: crate::id_t, + setsize: size_t, + mask: *mut cpuset_t, + ) -> c_int; + pub fn cpuset_setaffinity( + level: cpulevel_t, + which: cpuwhich_t, + id: crate::id_t, + setsize: size_t, + mask: *const cpuset_t, + ) -> c_int; + pub fn cpuset(setid: *mut crate::cpusetid_t) -> c_int; + pub fn cpuset_getid( + level: cpulevel_t, + which: cpuwhich_t, + id: crate::id_t, + setid: *mut crate::cpusetid_t, + ) -> c_int; + pub fn cpuset_setid(which: cpuwhich_t, id: crate::id_t, setid: crate::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: crate::idtype_t, + id: crate::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: crate::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: crate::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(initval: 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: crate::sctp_assoc_t) -> c_int; + pub fn sctp_bindx(s: c_int, addrs: *mut crate::sockaddr, num: c_int, tpe: c_int) -> c_int; + pub fn sctp_connectx( + s: c_int, + addrs: *const crate::sockaddr, + addrcnt: c_int, + id: *mut crate::sctp_assoc_t, + ) -> c_int; + pub fn sctp_getaddrlen(family: crate::sa_family_t) -> c_int; + pub fn sctp_getpaddrs( + s: c_int, + asocid: crate::sctp_assoc_t, + addrs: *mut *mut crate::sockaddr, + ) -> c_int; + pub fn sctp_freepaddrs(addrs: *mut crate::sockaddr); + pub fn sctp_getladdrs( + s: c_int, + asocid: crate::sctp_assoc_t, + addrs: *mut *mut crate::sockaddr, + ) -> c_int; + pub fn sctp_freeladdrs(addrs: *mut crate::sockaddr); + pub fn sctp_opt_info( + s: c_int, + id: crate::sctp_assoc_t, + opt: c_int, + arg: *mut c_void, + size: *mut crate::socklen_t, + ) -> c_int; + pub fn sctp_sendv( + sd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + addrs: *mut crate::sockaddr, + addrcnt: c_int, + info: *mut c_void, + infolen: crate::socklen_t, + infotype: c_uint, + flags: c_int, + ) -> ssize_t; + pub fn sctp_recvv( + sd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + from: *mut crate::sockaddr, + fromlen: *mut crate::socklen_t, + info: *mut c_void, + infolen: *mut crate::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; + + pub fn kcmp( + pid1: crate::pid_t, + pid2: crate::pid_t, + type_: c_int, + idx1: c_ulong, + idx2: c_ulong, + ) -> c_int; + pub fn dlvsym( + handle: *mut c_void, + symbol: *const c_char, + version: *const c_char, + ) -> *mut c_void; +} + +#[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 crate::kvm_t, cpu: c_uint) -> c_int; + pub fn kvm_getargv( + kd: *mut crate::kvm_t, + p: *const kinfo_proc, + nchr: c_int, + ) -> *mut *mut c_char; + pub fn kvm_getcptime(kd: *mut crate::kvm_t, cp_time: *mut c_long) -> c_int; + pub fn kvm_getenvv( + kd: *mut crate::kvm_t, + p: *const kinfo_proc, + nchr: c_int, + ) -> *mut *mut c_char; + pub fn kvm_geterr(kd: *mut crate::kvm_t) -> *mut c_char; + pub fn kvm_getmaxcpu(kd: *mut crate::kvm_t) -> c_int; + pub fn kvm_getncpus(kd: *mut crate::kvm_t) -> c_int; + pub fn kvm_getpcpu(kd: *mut crate::kvm_t, cpu: c_int) -> *mut c_void; + pub fn kvm_counter_u64_fetch(kd: *mut crate::kvm_t, base: c_ulong) -> u64; + pub fn kvm_getswapinfo( + kd: *mut crate::kvm_t, + info: *mut kvm_swap, + maxswap: c_int, + flags: c_int, + ) -> c_int; + pub fn kvm_native(kd: *mut crate::kvm_t) -> c_int; + pub fn kvm_nlist(kd: *mut crate::kvm_t, nl: *mut nlist) -> c_int; + pub fn kvm_nlist2(kd: *mut crate::kvm_t, nl: *mut kvm_nlist) -> c_int; + pub fn kvm_read_zpcpu( + kd: *mut crate::kvm_t, + base: c_ulong, + buf: *mut c_void, + size: size_t, + cpu: c_int, + ) -> ssize_t; + pub fn kvm_read2( + kd: *mut crate::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 crate::in_addr) -> c_int; + pub fn realhostname_sa( + host: *mut c_char, + hsize: size_t, + addr: *mut crate::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: crate::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: crate::mode_t, + pidptr: *mut crate::pid_t, + ) -> *mut crate::pidfh; + pub fn pidfile_write(path: *mut crate::pidfh) -> c_int; + pub fn pidfile_close(path: *mut crate::pidfh) -> c_int; + pub fn pidfile_remove(path: *mut crate::pidfh) -> c_int; + pub fn pidfile_fileno(path: *const crate::pidfh) -> c_int; + // FIXME(freebsd): 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 crate::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 crate::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 crate::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 crate::kvm_t) -> c_int; + pub fn devstat_getgeneration(kd: *mut crate::kvm_t) -> c_long; + pub fn devstat_getversion(kd: *mut crate::kvm_t) -> c_int; + pub fn devstat_checkversion(kd: *mut crate::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..4c0e165 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc.rs @@ -0,0 +1,30 @@ +use crate::prelude::*; + +pub type clock_t = u32; +pub type wchar_t = i32; +pub type time_t = i64; +pub type suseconds_t = i32; +pub type register_t = i32; + +s! { + #[repr(align(16))] + pub struct mcontext_t { + pub mc_vers: c_int, + pub mc_flags: c_int, + pub mc_onstack: c_int, + pub mc_len: c_int, + pub mc_avec: [u64; 64], + pub mc_av: [u32; 2], + pub mc_frame: [crate::register_t; 42], + pub mc_fpreg: [u64; 33], + pub mc_vsxfpreg: [u64; 32], + } +} + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 1; + +pub const BIOCSRTIMEOUT: c_ulong = 0x8010426d; +pub const BIOCGRTIMEOUT: c_ulong = 0x4010426e; +pub const MAP_32BIT: c_int = 0x00080000; +pub const MINSIGSTKSZ: size_t = 2048; // 512 * 4 +pub const TIOCTIMESTAMP: c_ulong = 0x40107459; 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..bfc6d5c --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs @@ -0,0 +1,31 @@ +use crate::prelude::*; + +pub type clock_t = u32; +pub type wchar_t = i32; +pub type time_t = i64; +pub type suseconds_t = i64; +pub type register_t = i64; + +s! { + #[repr(align(16))] + pub struct mcontext_t { + pub mc_vers: c_int, + pub mc_flags: c_int, + pub mc_onstack: c_int, + pub mc_len: c_int, + pub mc_avec: [u64; 64], + pub mc_av: [u32; 2], + pub mc_frame: [crate::register_t; 42], + pub mc_fpreg: [u64; 33], + pub mc_vsxfpreg: [u64; 32], + } +} + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 1; + +pub const BIOCSRTIMEOUT: c_ulong = 0x8010426d; +pub const BIOCGRTIMEOUT: c_ulong = 0x4010426e; + +pub const MAP_32BIT: c_int = 0x00080000; +pub const MINSIGSTKSZ: size_t = 2048; // 512 * 4 +pub const TIOCTIMESTAMP: c_ulong = 0x40107459; 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..e2d7920 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/riscv64.rs @@ -0,0 +1,44 @@ +use crate::prelude::*; + +pub type clock_t = i32; +pub type wchar_t = c_int; +pub type time_t = i64; +pub type suseconds_t = c_long; +pub type register_t = i64; + +s! { + pub struct gpregs { + pub gp_ra: crate::register_t, + pub gp_sp: crate::register_t, + pub gp_gp: crate::register_t, + pub gp_tp: crate::register_t, + pub gp_t: [crate::register_t; 7], + pub gp_s: [crate::register_t; 12], + pub gp_a: [crate::register_t; 8], + pub gp_sepc: crate::register_t, + pub gp_sstatus: crate::register_t, + } + + pub struct fpregs { + pub fp_x: [[u64; 2]; 32], + pub fp_fcsr: u64, + pub fp_flags: c_int, + pub 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], + } +} + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 1; + +pub const BIOCSRTIMEOUT: c_ulong = 0x8010426d; +pub const BIOCGRTIMEOUT: c_ulong = 0x4010426e; +pub const MAP_32BIT: c_int = 0x00080000; +pub const MINSIGSTKSZ: size_t = 4096; // 1024 * 4 +pub const TIOCTIMESTAMP: c_ulong = 0x40107459; 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..a95914d --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs @@ -0,0 +1,52 @@ +use crate::prelude::*; + +pub type clock_t = c_ulong; +pub type wchar_t = i32; +pub type time_t = i32; +pub type suseconds_t = i32; +pub type register_t = i32; + +s! { + #[repr(align(16))] + 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; 128], + 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], + } +} + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 1; + +pub const MINSIGSTKSZ: size_t = 2048; // 512 * 4 + +pub const BIOCSRTIMEOUT: c_ulong = 0x8008426d; +pub const BIOCGRTIMEOUT: c_ulong = 0x4008426e; +pub const KINFO_FILE_SIZE: c_int = 1392; +pub const TIOCTIMESTAMP: c_ulong = 0x40087459; 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..9848542 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs @@ -0,0 +1,187 @@ +use crate::prelude::*; + +pub type clock_t = i32; +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, + } + + 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], + } + #[repr(align(16))] + #[cfg_attr(not(any(freebsd11, freebsd12, freebsd13, freebsd14)), non_exhaustive)] + 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, + // freebsd < 15 + #[cfg(any(freebsd11, freebsd12, freebsd13))] + pub mc_spare: [c_long; 4], + // freebsd >= 15 + #[cfg(not(any(freebsd11, freebsd12, freebsd13)))] + pub mc_tlsbase: register_t, + #[cfg(not(any(freebsd11, freebsd12, freebsd13)))] + pub mc_spare: [c_long; 3], + } +} + +s_no_extra_traits! { + 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, + pub a_un: __c_anonymous_elf64_auxv_union, + } + + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + // FIXME(msrv): suggested method was added in 1.85 + #[allow(unpredictable_function_pointer_comparisons)] + 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 + } + } + } + impl Eq for __c_anonymous_elf64_auxv_union {} + } +} + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 1; + +pub const BIOCSRTIMEOUT: c_ulong = 0x8010426d; +pub const BIOCGRTIMEOUT: c_ulong = 0x4010426e; + +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_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; + +pub const TIOCTIMESTAMP: c_ulong = 0x40107459; 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..5c9bccf --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/mod.rs @@ -0,0 +1,1965 @@ +use crate::off_t; +use crate::prelude::*; + +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 = crate::uintptr_t; +pub type key_t = c_long; + +// elf.h + +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_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; + +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; + } +} + +// link.h + +extern_ty! { + pub type timezone; +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut c_void { + self.si_addr + } + + pub unsafe fn si_value(&self) -> crate::sigval { + self.si_value + } + + pub unsafe fn si_pid(&self) -> crate::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> crate::uid_t { + self.si_uid + } + + pub unsafe fn si_status(&self) -> c_int { + self.si_status + } +} + +s! { + pub struct in_addr { + pub s_addr: crate::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 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: Padding<*mut c_void>, + __unused4: Padding<*mut c_void>, + __unused5: Padding<*mut c_void>, + __unused6: Padding<*mut c_void>, + __unused7: Padding<*mut c_void>, + __unused8: Padding<*mut c_void>, + } + + 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 addrinfo { + pub ai_flags: c_int, + pub ai_family: c_int, + pub ai_socktype: c_int, + pub ai_protocol: c_int, + pub ai_addrlen: crate::socklen_t, + pub ai_canonname: *mut c_char, + pub ai_addr: *mut crate::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: crate::pid_t, + pub si_uid: crate::uid_t, + pub si_status: c_int, + pub si_addr: *mut c_void, + pub si_value: crate::sigval, + _pad1: Padding, + _pad2: Padding<[c_int; 7]>, + } + + pub struct sigaction { + pub sa_sigaction: crate::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: crate::sa_family_t, + pub sin_port: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_zero: [c_char; 8], + } + + pub struct termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_cc: [crate::cc_t; crate::NCCS], + pub c_ispeed: crate::speed_t, + pub c_ospeed: crate::speed_t, + } + + pub struct flock { + pub l_start: off_t, + pub l_len: off_t, + pub l_pid: crate::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 crate::iovec, + pub hdr_cnt: c_int, + pub trailers: *mut crate::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: crate::pid_t, + pub cmcred_uid: crate::uid_t, + pub cmcred_euid: crate::uid_t, + pub cmcred_gid: crate::gid_t, + pub cmcred_ngroups: c_short, + pub cmcred_groups: [crate::gid_t; CMGROUP_MAX], + } + + pub struct rtprio { + pub type_: c_ushort, + pub prio: c_ushort, + } + + pub struct in6_pktinfo { + pub ipi6_addr: crate::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: crate::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; 256 - 16], + } + + 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: crate::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: crate::uid_t, + pub cgid: crate::gid_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub mode: mode_t, + pub seq: c_ushort, + pub key: crate::key_t, + } + + pub struct eui64 { + pub octet: [u8; EUI64_LEN], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: crate::sa_family_t, + __ss_pad1: Padding<[u8; 6]>, + __ss_align: i64, + __ss_pad2: Padding<[u8; 112]>, + } +} + +// Non-public helper constant +const SIZEOF_LONG: usize = size_of::(); + +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: crate::nl_item = 0; +pub const D_T_FMT: crate::nl_item = 1; +pub const D_FMT: crate::nl_item = 2; +pub const T_FMT: crate::nl_item = 3; +pub const T_FMT_AMPM: crate::nl_item = 4; +pub const AM_STR: crate::nl_item = 5; +pub const PM_STR: crate::nl_item = 6; + +pub const DAY_1: crate::nl_item = 7; +pub const DAY_2: crate::nl_item = 8; +pub const DAY_3: crate::nl_item = 9; +pub const DAY_4: crate::nl_item = 10; +pub const DAY_5: crate::nl_item = 11; +pub const DAY_6: crate::nl_item = 12; +pub const DAY_7: crate::nl_item = 13; + +pub const ABDAY_1: crate::nl_item = 14; +pub const ABDAY_2: crate::nl_item = 15; +pub const ABDAY_3: crate::nl_item = 16; +pub const ABDAY_4: crate::nl_item = 17; +pub const ABDAY_5: crate::nl_item = 18; +pub const ABDAY_6: crate::nl_item = 19; +pub const ABDAY_7: crate::nl_item = 20; + +pub const MON_1: crate::nl_item = 21; +pub const MON_2: crate::nl_item = 22; +pub const MON_3: crate::nl_item = 23; +pub const MON_4: crate::nl_item = 24; +pub const MON_5: crate::nl_item = 25; +pub const MON_6: crate::nl_item = 26; +pub const MON_7: crate::nl_item = 27; +pub const MON_8: crate::nl_item = 28; +pub const MON_9: crate::nl_item = 29; +pub const MON_10: crate::nl_item = 30; +pub const MON_11: crate::nl_item = 31; +pub const MON_12: crate::nl_item = 32; + +pub const ABMON_1: crate::nl_item = 33; +pub const ABMON_2: crate::nl_item = 34; +pub const ABMON_3: crate::nl_item = 35; +pub const ABMON_4: crate::nl_item = 36; +pub const ABMON_5: crate::nl_item = 37; +pub const ABMON_6: crate::nl_item = 38; +pub const ABMON_7: crate::nl_item = 39; +pub const ABMON_8: crate::nl_item = 40; +pub const ABMON_9: crate::nl_item = 41; +pub const ABMON_10: crate::nl_item = 42; +pub const ABMON_11: crate::nl_item = 43; +pub const ABMON_12: crate::nl_item = 44; + +pub const ERA: crate::nl_item = 45; +pub const ERA_D_FMT: crate::nl_item = 46; +pub const ERA_D_T_FMT: crate::nl_item = 47; +pub const ERA_T_FMT: crate::nl_item = 48; +pub const ALT_DIGITS: crate::nl_item = 49; + +pub const RADIXCHAR: crate::nl_item = 50; +pub const THOUSEP: crate::nl_item = 51; + +pub const YESEXPR: crate::nl_item = 52; +pub const NOEXPR: crate::nl_item = 53; + +pub const YESSTR: crate::nl_item = 54; +pub const NOSTR: crate::nl_item = 55; + +pub const CRNCYSTR: crate::nl_item = 56; + +pub const D_MD_ORDER: crate::nl_item = 57; + +pub const ALTMON_1: crate::nl_item = 58; +pub const ALTMON_2: crate::nl_item = 59; +pub const ALTMON_3: crate::nl_item = 60; +pub const ALTMON_4: crate::nl_item = 61; +pub const ALTMON_5: crate::nl_item = 62; +pub const ALTMON_6: crate::nl_item = 63; +pub const ALTMON_7: crate::nl_item = 64; +pub const ALTMON_8: crate::nl_item = 65; +pub const ALTMON_9: crate::nl_item = 66; +pub const ALTMON_10: crate::nl_item = 67; +pub const ALTMON_11: crate::nl_item = 68; +pub const ALTMON_12: crate::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 = 0o1_0000; +pub const S_IFCHR: mode_t = 0o2_0000; +pub const S_IFBLK: mode_t = 0o6_0000; +pub const S_IFDIR: mode_t = 0o4_0000; +pub const S_IFREG: mode_t = 0o10_0000; +pub const S_IFLNK: mode_t = 0o12_0000; +pub const S_IFSOCK: mode_t = 0o14_0000; +pub const S_IFMT: mode_t = 0o17_0000; +pub const S_IEXEC: mode_t = 0o0100; +pub const S_IWRITE: mode_t = 0o0200; +pub const S_IREAD: mode_t = 0o0400; +pub const S_IRWXU: mode_t = 0o0700; +pub const S_IXUSR: mode_t = 0o0100; +pub const S_IWUSR: mode_t = 0o0200; +pub const S_IRUSR: mode_t = 0o0400; +pub const S_IRWXG: mode_t = 0o0070; +pub const S_IXGRP: mode_t = 0o0010; +pub const S_IWGRP: mode_t = 0o0020; +pub const S_IRGRP: mode_t = 0o0040; +pub const S_IRWXO: mode_t = 0o0007; +pub const S_IXOTH: mode_t = 0o0001; +pub const S_IWOTH: mode_t = 0o0002; +pub const S_IROTH: mode_t = 0o0004; +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 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 = u32_cast_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 = crate::POLLIN + | crate::POLLPRI + | crate::POLLOUT + | crate::POLLRDNORM + | crate::POLLRDBAND + | crate::POLLWRBAND + | crate::POLLERR + | crate::POLLHUP + | crate::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: crate::clockid_t = 0; +pub const CLOCK_VIRTUAL: crate::clockid_t = 1; +pub const CLOCK_PROF: crate::clockid_t = 2; +pub const CLOCK_MONOTONIC: crate::clockid_t = 4; +pub const CLOCK_UPTIME: crate::clockid_t = 5; +pub const CLOCK_UPTIME_PRECISE: crate::clockid_t = 7; +pub const CLOCK_UPTIME_FAST: crate::clockid_t = 8; +pub const CLOCK_REALTIME_PRECISE: crate::clockid_t = 9; +pub const CLOCK_REALTIME_FAST: crate::clockid_t = 10; +pub const CLOCK_MONOTONIC_PRECISE: crate::clockid_t = 11; +pub const CLOCK_MONOTONIC_FAST: crate::clockid_t = 12; +pub const CLOCK_SECOND: crate::clockid_t = 13; +pub const CLOCK_THREAD_CPUTIME_ID: crate::clockid_t = 14; +pub const CLOCK_PROCESS_CPUTIME_ID: crate::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 IP_MINTTL: c_int = 66; +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 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 _CS_PATH: c_int = 1; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = ptr::null_mut(); +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = ptr::null_mut(); +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = ptr::null_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; +#[cfg_attr( + not(target_os = "dragonfly"), + deprecated = "unused since FreeBSD 8, removed in FreeBSD 15" +)] +pub const TIOCMGDTRWAIT: c_ulong = 0x4004745a; +#[cfg_attr( + not(target_os = "dragonfly"), + deprecated = "unused since FreeBSD 8, removed in FreeBSD 15" +)] +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; +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + pub const BIOCGDLTLIST: c_ulong = 0xc0104279; + pub const BIOCSETF: c_ulong = 0x80104267; + } else if #[cfg(target_pointer_width = "32")] { + pub const BIOCGDLTLIST: c_ulong = 0xc0084279; + pub const BIOCSETF: c_ulong = 0x80084267; + } +} + +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 = ptr::null_mut(); + +pub const CRTSCTS: crate::tcflag_t = 0x00030000; +pub const CCTS_OFLOW: crate::tcflag_t = 0x00010000; +pub const CRTS_IFLOW: crate::tcflag_t = 0x00020000; +pub const CDTR_IFLOW: crate::tcflag_t = 0x00040000; +pub const CDSR_OFLOW: crate::tcflag_t = 0x00080000; +pub const CCAR_OFLOW: crate::tcflag_t = 0x00100000; +pub const VERASE2: usize = 7; +pub const OCRNL: crate::tcflag_t = 0x10; +pub const ONOCR: crate::tcflag_t = 0x20; +pub const ONLRET: crate::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 IPC_PRIVATE: crate::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; + +// DIFF(main): changed to `c_short` in f62eb023ab +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; + +safe_f! { + pub const safe fn WIFCONTINUED(status: c_int) -> bool { + status == 0x13 + } + + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + status >> 8 + } + + pub const safe 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 crate::timeval, tz: *mut crate::timezone) -> c_int; + pub fn accept4( + s: c_int, + addr: *mut crate::sockaddr, + addrlen: *mut crate::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: crate::clockid_t, + flags: c_int, + rqtp: *const crate::timespec, + rmtp: *mut crate::timespec, + ) -> c_int; + + pub fn clock_getres(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_gettime(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_settime(clk_id: crate::clockid_t, tp: *const crate::timespec) -> c_int; + pub fn clock_getcpuclockid(pid: crate::pid_t, clk_id: *mut crate::clockid_t) -> c_int; + + pub fn pthread_getcpuclockid(thread: crate::pthread_t, clk_id: *mut crate::clockid_t) -> c_int; + + pub fn dirfd(dirp: *mut crate::DIR) -> c_int; + pub fn duplocale(base: crate::locale_t) -> crate::locale_t; + pub fn endutxent(); + pub fn fchflags(fd: c_int, flags: c_ulong) -> c_int; + + // DIFF(main): changed to `*const *mut` in e77f551de9 + 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 crate::timespec) -> c_int; + pub fn getdomainname(name: *mut c_char, len: c_int) -> c_int; + pub fn getgrent_r( + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn getpwent_r( + pwd: *mut crate::passwd, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::passwd, + ) -> c_int; + pub fn getgrouplist( + name: *const c_char, + basegid: crate::gid_t, + groups: *mut crate::gid_t, + ngroups: *mut c_int, + ) -> c_int; + pub fn getnameinfo( + sa: *const crate::sockaddr, + salen: crate::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 crate::gid_t, + egid: *mut crate::gid_t, + sgid: *mut crate::gid_t, + ) -> c_int; + pub fn getresuid( + ruid: *mut crate::uid_t, + euid: *mut crate::uid_t, + suid: *mut crate::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: crate::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 crate::kevent, + nchanges: c_int, + eventlist: *mut crate::kevent, + nevents: c_int, + timeout: *const crate::timespec, + ) -> c_int; + pub fn lchflags(path: *const c_char, flags: c_ulong) -> c_int; + pub fn lutimes(file: *const c_char, times: *const crate::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: crate::locale_t) -> crate::locale_t; + pub fn nl_langinfo_l(item: crate::nl_item, locale: crate::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 crate::pollfd, + nfds: crate::nfds_t, + timeout: *const crate::timespec, + sigmask: *const sigset_t, + ) -> c_int; + pub fn preadv(fd: c_int, iov: *const crate::iovec, iovcnt: c_int, offset: off_t) -> ssize_t; + pub fn pthread_attr_get_np(tid: crate::pthread_t, attr: *mut crate::pthread_attr_t) -> c_int; + pub fn pthread_attr_getguardsize( + attr: *const crate::pthread_attr_t, + guardsize: *mut size_t, + ) -> c_int; + pub fn pthread_attr_setguardsize(attr: *mut crate::pthread_attr_t, guardsize: size_t) -> c_int; + pub fn pthread_attr_getstack( + attr: *const crate::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: crate::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 crate::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 crate::pthread_barrierattr_t) -> c_int; + pub fn pthread_barrierattr_destroy(attr: *mut crate::pthread_barrierattr_t) -> c_int; + pub fn pthread_barrierattr_getpshared( + attr: *const crate::pthread_barrierattr_t, + shared: *mut c_int, + ) -> c_int; + pub fn pthread_barrierattr_setpshared( + attr: *mut crate::pthread_barrierattr_t, + shared: c_int, + ) -> c_int; + pub fn pthread_barrier_init( + barrier: *mut pthread_barrier_t, + attr: *const crate::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: crate::pthread_t, name: *mut c_char, len: size_t); + pub fn pthread_set_name_np(tid: crate::pthread_t, name: *const c_char); + pub fn pthread_getname_np( + thread: crate::pthread_t, + buffer: *mut c_char, + length: size_t, + ) -> c_int; + pub fn pthread_setname_np(thread: crate::pthread_t, name: *const c_char) -> c_int; + pub fn pthread_setschedparam( + native: crate::pthread_t, + policy: c_int, + param: *const sched_param, + ) -> c_int; + pub fn pthread_getschedparam( + native: crate::pthread_t, + policy: *mut c_int, + param: *mut sched_param, + ) -> c_int; + pub fn ptrace(request: c_int, pid: crate::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 crate::iovec, iovcnt: c_int, offset: off_t) -> ssize_t; + pub fn querylocale(mask: c_int, loc: crate::locale_t) -> *const c_char; + pub fn rtprio(function: c_int, pid: crate::pid_t, rtp: *mut rtprio) -> c_int; + pub fn sched_rr_get_interval(pid: crate::pid_t, t: *mut crate::timespec) -> c_int; + pub fn sched_getparam(pid: crate::pid_t, param: *mut sched_param) -> c_int; + pub fn sched_setparam(pid: crate::pid_t, param: *const sched_param) -> c_int; + pub fn sched_getscheduler(pid: crate::pid_t) -> c_int; + pub fn sched_setscheduler( + pid: crate::pid_t, + policy: c_int, + param: *const crate::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 crate::timespec) -> c_int; + pub fn sendfile( + fd: c_int, + s: c_int, + offset: off_t, + nbytes: size_t, + hdtr: *mut crate::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: crate::gid_t, egid: crate::gid_t, sgid: crate::gid_t) -> c_int; + pub fn setresuid(ruid: crate::uid_t, euid: crate::uid_t, suid: crate::uid_t) -> c_int; + pub fn settimeofday(tv: *const crate::timeval, tz: *const crate::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 crate::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: crate::locale_t) -> crate::locale_t; + pub fn utimensat( + dirfd: c_int, + path: *const c_char, + times: *const crate::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; + + 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 posix_spawn( + pid: *mut crate::pid_t, + path: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::posix_spawnattr_t, + argv: *const *mut c_char, + envp: *const *mut c_char, + ) -> c_int; + pub fn posix_spawnp( + pid: *mut crate::pid_t, + file: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::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 crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + default: *const crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + default: *mut crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + default: *const crate::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 crate::pid_t, + ) -> c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: crate::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 crate::sched_param, + ) -> c_int; + pub fn posix_spawnattr_setschedparam( + attr: *mut posix_spawnattr_t, + param: *const crate::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; +} + +#[link(name = "rt")] +extern "C" { + pub fn mq_close(mqd: crate::mqd_t) -> c_int; + pub fn mq_getattr(mqd: crate::mqd_t, attr: *mut crate::mq_attr) -> c_int; + pub fn mq_notify(mqd: crate::mqd_t, notification: *const crate::sigevent) -> c_int; + pub fn mq_open(name: *const c_char, oflag: c_int, ...) -> crate::mqd_t; + pub fn mq_receive( + mqd: crate::mqd_t, + msg_ptr: *mut c_char, + msg_len: size_t, + msg_prio: *mut c_uint, + ) -> ssize_t; + pub fn mq_send( + mqd: crate::mqd_t, + msg_ptr: *const c_char, + msg_len: size_t, + msg_prio: c_uint, + ) -> c_int; + pub fn mq_setattr( + mqd: crate::mqd_t, + newattr: *const crate::mq_attr, + oldattr: *mut crate::mq_attr, + ) -> c_int; + pub fn mq_timedreceive( + mqd: crate::mqd_t, + msg_ptr: *mut c_char, + msg_len: size_t, + msg_prio: *mut c_uint, + abs_timeout: *const crate::timespec, + ) -> ssize_t; + pub fn mq_timedsend( + mqd: crate::mqd_t, + msg_ptr: *const c_char, + msg_len: size_t, + msg_prio: c_uint, + abs_timeout: *const crate::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 crate::winsize, + ) -> c_int; + pub fn forkpty( + amaster: *mut c_int, + name: *mut c_char, + termp: *mut termios, + winp: *mut crate::winsize, + ) -> crate::pid_t; + pub fn login_tty(fd: c_int) -> c_int; + pub fn fparseln( + stream: *mut crate::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 crate::kvm_t; + pub fn kvm_close(kd: *mut crate::kvm_t) -> c_int; + pub fn kvm_getprocs( + kd: *mut crate::kvm_t, + op: c_int, + arg: c_int, + cnt: *mut c_int, + ) -> *mut crate::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 crate::kvm_t; + pub fn kvm_read( + kd: *mut crate::kvm_t, + addr: c_ulong, + buf: *mut c_void, + nbytes: size_t, + ) -> ssize_t; + pub fn kvm_write( + kd: *mut crate::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..e0a39f2 --- /dev/null +++ b/vendor/libc/src/unix/bsd/mod.rs @@ -0,0 +1,871 @@ +use crate::prelude::*; + +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 = crate::uintptr_t; +pub type nfds_t = c_uint; +#[cfg(target_os = "dragonfly")] +pub type regoff_t = c_int; +#[cfg(not(target_os = "dragonfly"))] +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: crate::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: crate::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: crate::uid_t, + pub pw_gid: crate::gid_t, + pub pw_change: crate::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: crate::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 crate::sockaddr, + pub ifa_netmask: *mut crate::sockaddr, + pub ifa_dstaddr: *mut crate::sockaddr, + pub ifa_data: *mut c_void, + #[cfg(any(target_os = "dragonfly", 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 as usize / 64], + #[cfg(not(all( + target_pointer_width = "64", + any(target_os = "freebsd", target_os = "dragonfly") + )))] + fds_bits: [i32; FD_SETSIZE as usize / 32], + } + + pub struct msghdr { + pub msg_name: *mut c_void, + pub msg_namelen: crate::socklen_t, + pub msg_iov: *mut crate::iovec, + pub msg_iovlen: c_int, + pub msg_control: *mut c_void, + pub msg_controllen: crate::socklen_t, + pub msg_flags: c_int, + } + + pub struct cmsghdr { + pub cmsg_len: crate::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, + } + 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], + } +} + +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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: crate::cc_t = 0xff; +pub const IGNBRK: crate::tcflag_t = 0x00000001; +pub const BRKINT: crate::tcflag_t = 0x00000002; +pub const IGNPAR: crate::tcflag_t = 0x00000004; +pub const PARMRK: crate::tcflag_t = 0x00000008; +pub const INPCK: crate::tcflag_t = 0x00000010; +pub const ISTRIP: crate::tcflag_t = 0x00000020; +pub const INLCR: crate::tcflag_t = 0x00000040; +pub const IGNCR: crate::tcflag_t = 0x00000080; +pub const ICRNL: crate::tcflag_t = 0x00000100; +pub const IXON: crate::tcflag_t = 0x00000200; +pub const IXOFF: crate::tcflag_t = 0x00000400; +pub const IXANY: crate::tcflag_t = 0x00000800; +pub const IMAXBEL: crate::tcflag_t = 0x00002000; +pub const OPOST: crate::tcflag_t = 0x1; +pub const ONLCR: crate::tcflag_t = 0x2; +pub const OXTABS: crate::tcflag_t = 0x4; +pub const ONOEOT: crate::tcflag_t = 0x8; +pub const CIGNORE: crate::tcflag_t = 0x00000001; +pub const CSIZE: crate::tcflag_t = 0x00000300; +pub const CS5: crate::tcflag_t = 0x00000000; +pub const CS6: crate::tcflag_t = 0x00000100; +pub const CS7: crate::tcflag_t = 0x00000200; +pub const CS8: crate::tcflag_t = 0x00000300; +pub const CSTOPB: crate::tcflag_t = 0x00000400; +pub const CREAD: crate::tcflag_t = 0x00000800; +pub const PARENB: crate::tcflag_t = 0x00001000; +pub const PARODD: crate::tcflag_t = 0x00002000; +pub const HUPCL: crate::tcflag_t = 0x00004000; +pub const CLOCAL: crate::tcflag_t = 0x00008000; +pub const ECHOKE: crate::tcflag_t = 0x00000001; +pub const ECHOE: crate::tcflag_t = 0x00000002; +pub const ECHOK: crate::tcflag_t = 0x00000004; +pub const ECHO: crate::tcflag_t = 0x00000008; +pub const ECHONL: crate::tcflag_t = 0x00000010; +pub const ECHOPRT: crate::tcflag_t = 0x00000020; +pub const ECHOCTL: crate::tcflag_t = 0x00000040; +pub const ISIG: crate::tcflag_t = 0x00000080; +pub const ICANON: crate::tcflag_t = 0x00000100; +pub const ALTWERASE: crate::tcflag_t = 0x00000200; +pub const IEXTEN: crate::tcflag_t = 0x00000400; +pub const EXTPROC: crate::tcflag_t = 0x00000800; +pub const TOSTOP: crate::tcflag_t = 0x00400000; +pub const FLUSHO: crate::tcflag_t = 0x00800000; +pub const NOKERNINFO: crate::tcflag_t = 0x02000000; +pub const PENDIN: crate::tcflag_t = 0x20000000; +pub const NOFLSH: crate::tcflag_t = 0x80000000; +pub const MDMBUF: crate::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; + +cfg_if! { + // Not yet implemented on NetBSD + if #[cfg(not(any(target_os = "netbsd")))] { + 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; + } +} + +cfg_if! { + // Redefined in `new/apple` + if #[cfg(not(target_vendor = "apple"))] { + 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 unsafe fn CMSG_FIRSTHDR(mhdr: *const crate::msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize >= size_of::() { + (*mhdr).msg_control.cast() + } else { + ptr::null_mut() + } + } + + pub unsafe fn FD_CLR(fd: c_int, set: *mut fd_set) -> () { + let bits = size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); + return; + } + + pub unsafe fn FD_ISSET(fd: c_int, set: *const fd_set) -> bool { + let bits = size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0; + } + + pub unsafe fn FD_SET(fd: c_int, set: *mut fd_set) -> () { + let bits = size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] |= 1 << (fd % bits); + return; + } + + pub unsafe fn FD_ZERO(set: *mut fd_set) -> () { + (*set).fds_bits.fill(0); + } +} + +safe_f! { + pub const safe fn WTERMSIG(status: c_int) -> c_int { + status & 0o177 + } + + pub const safe fn WIFEXITED(status: c_int) -> bool { + (status & 0o177) == 0 + } + + pub const safe fn WEXITSTATUS(status: c_int) -> c_int { + (status >> 8) & 0x00ff + } + + pub const safe fn WCOREDUMP(status: c_int) -> bool { + (status & 0o200) != 0 + } + + pub const safe 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 crate::rlimit) -> c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "setrlimit$UNIX2003" + )] + pub fn setrlimit(resource: c_int, rlim: *const crate::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 crate::ifaddrs) -> c_int; + pub fn freeifaddrs(ifa: *mut crate::ifaddrs); + pub fn setgroups(ngroups: c_int, ptr: *const crate::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 crate::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 crate::uid_t, egid: *mut crate::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 crate::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 crate::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 crate::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 crate::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 crate::sockaddr, + addrlen: *mut crate::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 crate::timeval) -> c_int; + pub fn nl_langinfo(item: crate::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 crate::sockaddr, + address_len: crate::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 crate::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 crate::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 crate::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 crate::msghdr, flags: c_int) -> ssize_t; + + pub fn sync(); + pub fn getgrgid_r( + gid: crate::gid_t, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::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; + #[cfg_attr(target_os = "netbsd", link_name = "__sigsuspend14")] + pub fn sigsuspend(mask: *const crate::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 crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::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 crate::group; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_cancel$UNIX2003" + )] + pub fn pthread_cancel(thread: crate::pthread_t) -> c_int; + pub fn pthread_kill(thread: crate::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: crate::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: crate::gid_t) -> *mut crate::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 crate::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 crate::pthread_t, + attr: *const crate::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" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__wait450")] + pub fn wait4( + pid: crate::pid_t, + status: *mut c_int, + options: c_int, + rusage: *mut crate::rusage, + ) -> crate::pid_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "getitimer$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__getitimer50")] + pub fn getitimer(which: c_int, curr_value: *mut crate::itimerval) -> c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "setitimer$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__setitimer50")] + pub fn setitimer( + which: c_int, + new_value: *const crate::itimerval, + old_value: *mut crate::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 crate::tm, + ) -> size_t; + pub fn strftime_l( + buf: *mut c_char, + maxsize: size_t, + format: *const c_char, + timeptr: *const crate::tm, + locale: crate::locale_t, + ) -> size_t; + + #[cfg_attr(target_os = "netbsd", link_name = "__devname50")] + pub fn devname(dev: crate::dev_t, mode_t: crate::mode_t) -> *mut c_char; + + pub fn issetugid() -> c_int; +} + +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..c46a955 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/mod.rs @@ -0,0 +1,917 @@ +use crate::off_t; +use crate::prelude::*; + +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; + +extern_ty! { + pub type timezone; + pub type sem; +} + +s! { + pub struct sched_param { + pub sched_priority: c_int, + } + + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::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: crate::in6_addr, + pub ipi6_ifindex: c_uint, + } + + pub struct termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_cc: [crate::cc_t; crate::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: crate::pid_t, + pub l_type: c_short, + pub l_whence: c_short, + } + + 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: crate::msghdr, + pub msg_len: c_uint, + } +} + +pub const D_T_FMT: crate::nl_item = 0; +pub const D_FMT: crate::nl_item = 1; +pub const T_FMT: crate::nl_item = 2; +pub const T_FMT_AMPM: crate::nl_item = 3; +pub const AM_STR: crate::nl_item = 4; +pub const PM_STR: crate::nl_item = 5; + +pub const DAY_1: crate::nl_item = 6; +pub const DAY_2: crate::nl_item = 7; +pub const DAY_3: crate::nl_item = 8; +pub const DAY_4: crate::nl_item = 9; +pub const DAY_5: crate::nl_item = 10; +pub const DAY_6: crate::nl_item = 11; +pub const DAY_7: crate::nl_item = 12; + +pub const ABDAY_1: crate::nl_item = 13; +pub const ABDAY_2: crate::nl_item = 14; +pub const ABDAY_3: crate::nl_item = 15; +pub const ABDAY_4: crate::nl_item = 16; +pub const ABDAY_5: crate::nl_item = 17; +pub const ABDAY_6: crate::nl_item = 18; +pub const ABDAY_7: crate::nl_item = 19; + +pub const MON_1: crate::nl_item = 20; +pub const MON_2: crate::nl_item = 21; +pub const MON_3: crate::nl_item = 22; +pub const MON_4: crate::nl_item = 23; +pub const MON_5: crate::nl_item = 24; +pub const MON_6: crate::nl_item = 25; +pub const MON_7: crate::nl_item = 26; +pub const MON_8: crate::nl_item = 27; +pub const MON_9: crate::nl_item = 28; +pub const MON_10: crate::nl_item = 29; +pub const MON_11: crate::nl_item = 30; +pub const MON_12: crate::nl_item = 31; + +pub const ABMON_1: crate::nl_item = 32; +pub const ABMON_2: crate::nl_item = 33; +pub const ABMON_3: crate::nl_item = 34; +pub const ABMON_4: crate::nl_item = 35; +pub const ABMON_5: crate::nl_item = 36; +pub const ABMON_6: crate::nl_item = 37; +pub const ABMON_7: crate::nl_item = 38; +pub const ABMON_8: crate::nl_item = 39; +pub const ABMON_9: crate::nl_item = 40; +pub const ABMON_10: crate::nl_item = 41; +pub const ABMON_11: crate::nl_item = 42; +pub const ABMON_12: crate::nl_item = 43; + +pub const RADIXCHAR: crate::nl_item = 44; +pub const THOUSEP: crate::nl_item = 45; +pub const YESSTR: crate::nl_item = 46; +pub const YESEXPR: crate::nl_item = 47; +pub const NOSTR: crate::nl_item = 48; +pub const NOEXPR: crate::nl_item = 49; +pub const CRNCYSTR: crate::nl_item = 50; + +pub const CODESET: crate::nl_item = 51; + +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 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 = 0o1_0000; +pub const S_IFCHR: mode_t = 0o2_0000; +pub const S_IFBLK: mode_t = 0o6_0000; +pub const S_IFDIR: mode_t = 0o4_0000; +pub const S_IFREG: mode_t = 0o10_0000; +pub const S_IFLNK: mode_t = 0o12_0000; +pub const S_IFSOCK: mode_t = 0o14_0000; +pub const S_IFMT: mode_t = 0o17_0000; +pub const S_IEXEC: mode_t = 0o0100; +pub const S_IWRITE: mode_t = 0o0200; +pub const S_IREAD: mode_t = 0o0400; +pub const S_IRWXU: mode_t = 0o0700; +pub const S_IXUSR: mode_t = 0o0100; +pub const S_IWUSR: mode_t = 0o0200; +pub const S_IRUSR: mode_t = 0o0400; +pub const S_IRWXG: mode_t = 0o0070; +pub const S_IXGRP: mode_t = 0o0010; +pub const S_IWGRP: mode_t = 0o0020; +pub const S_IRGRP: mode_t = 0o0040; +pub const S_IRWXO: mode_t = 0o0007; +pub const S_IXOTH: mode_t = 0o0001; +pub const S_IWOTH: mode_t = 0o0002; +pub const S_IROTH: mode_t = 0o0004; +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 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: crate::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; + +// DIFF(main): changed to `c_short` in f62eb023ab +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: crate::clockid_t = 0; +pub const CLOCK_MONOTONIC: crate::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; + +// sys/ioccom.h in NetBSD and OpenBSD +pub const IOCPARM_MASK: u32 = 0x1fff; + +pub const IOC_VOID: c_ulong = 0x20000000; +pub const IOC_OUT: c_ulong = 0x40000000; +pub const IOC_IN: c_ulong = 0x80000000; +pub const IOC_INOUT: c_ulong = IOC_IN | IOC_OUT; +pub const IOC_DIRMASK: c_ulong = 0xe0000000; + +pub const fn _IO(g: c_ulong, n: c_ulong) -> c_ulong { + _IOC(IOC_VOID, g, n, 0) +} + +/// Build an ioctl number for an read-only ioctl. +pub const fn _IOR(g: c_ulong, n: c_ulong) -> c_ulong { + _IOC(IOC_OUT, g, n, mem::size_of::() as c_ulong) +} + +/// Build an ioctl number for an write-only ioctl. +pub const fn _IOW(g: c_ulong, n: c_ulong) -> c_ulong { + _IOC(IOC_IN, g, n, mem::size_of::() as c_ulong) +} + +/// Build an ioctl number for a read-write ioctl. +pub const fn _IOWR(g: c_ulong, n: c_ulong) -> c_ulong { + _IOC(IOC_INOUT, g, n, mem::size_of::() as c_ulong) +} + +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 = ptr::null_mut(); + +pub const CRTSCTS: crate::tcflag_t = 0x00010000; +pub const CRTS_IFLOW: crate::tcflag_t = CRTSCTS; +pub const CCTS_OFLOW: crate::tcflag_t = CRTSCTS; +pub const OCRNL: crate::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 crate::sockaddr, + addrlen: *mut crate::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: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__clock_gettime50")] + pub fn clock_gettime(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__clock_settime50")] + pub fn clock_settime(clk_id: crate::clockid_t, tp: *const crate::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 crate::iovec, iovcnt: c_int, offset: off_t) -> ssize_t; + pub fn preadv(fd: c_int, iov: *const crate::iovec, iovcnt: c_int, offset: off_t) -> ssize_t; + pub fn futimens(fd: c_int, times: *const crate::timespec) -> c_int; + pub fn utimensat( + dirfd: c_int, + path: *const c_char, + times: *const crate::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: crate::id_t) -> c_int; + pub fn setpriority(which: c_int, who: crate::id_t, prio: c_int) -> c_int; + + pub fn mknodat(dirfd: c_int, pathname: *const c_char, mode: mode_t, dev: crate::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 crate::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: crate::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 crate::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: crate::pthread_t, + policy: c_int, + param: *const sched_param, + ) -> c_int; + pub fn pthread_getschedparam( + native: crate::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 ppoll( + fds: *mut crate::pollfd, + nfds: crate::nfds_t, + ts: *const crate::timespec, + sigmask: *const crate::sigset_t, + ) -> c_int; + + pub fn getgrouplist( + name: *const c_char, + basegid: crate::gid_t, + groups: *mut crate::gid_t, + ngroups: *mut c_int, + ) -> c_int; + pub fn initgroups(name: *const c_char, basegid: crate::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 crate::utsname) -> c_int; + + pub fn shmget(key: crate::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; + #[cfg_attr(target_os = "netbsd", link_name = "__shmctl50")] + pub fn shmctl(shmid: c_int, cmd: c_int, buf: *mut crate::shmid_ds) -> c_int; + + // DIFF(main): changed to `*const *mut` in e77f551de9 + 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: crate::id_t, + infop: *mut crate::siginfo_t, + options: c_int, + ) -> c_int; + + pub fn posix_spawn( + pid: *mut crate::pid_t, + path: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::posix_spawnattr_t, + argv: *const *mut c_char, + envp: *const *mut c_char, + ) -> c_int; + pub fn posix_spawnp( + pid: *mut crate::pid_t, + file: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::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 crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + default: *const crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + default: *mut crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + default: *const crate::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 crate::pid_t, + ) -> c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: crate::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 crate::sched_param, + ) -> c_int; + pub fn posix_spawnattr_setschedparam( + attr: *mut posix_spawnattr_t, + param: *const crate::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) -> crate::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 crate::mmsghdr, vlen: c_uint, flags: c_int) -> c_int; + pub fn recvmmsg( + sockfd: c_int, + mmsg: *mut crate::mmsghdr, + vlen: c_uint, + flags: c_int, + timeout: *mut crate::timespec, + ) -> c_int; + + pub fn closefrom(lowfd: c_int) -> 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..e0206af --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs @@ -0,0 +1,132 @@ +use crate::prelude::*; +use crate::PT_FIRSTMACH; + +pub type greg_t = u64; +pub type __cpu_simple_lock_nv_t = c_uchar; + +s! { + pub struct __fregset { + pub __qregs: [__c_anonymous__freg; 32], + pub __fpcr: u32, + pub __fpsr: u32, + } + + pub struct mcontext_t { + pub __gregs: [crate::greg_t; 32], + pub __fregs: __fregset, + __spare: [crate::greg_t; 8], + } + + pub struct ucontext_t { + pub uc_flags: c_uint, + pub uc_link: *mut ucontext_t, + pub uc_sigmask: crate::sigset_t, + pub uc_stack: crate::stack_t, + pub uc_mcontext: mcontext_t, + } +} + +s_no_extra_traits! { + #[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")] { + 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 + } + } + } + impl Eq for __c_anonymous__freg {} + 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); + } + } + } + } +} + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 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..1af255e --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/arm.rs @@ -0,0 +1,70 @@ +use crate::prelude::*; +use crate::PT_FIRSTMACH; + +pub type __cpu_simple_lock_nv_t = c_int; + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 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 + 5; +pub const PT_SETFPREGS: c_int = PT_FIRSTMACH + 6; + +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_TPIDR: c_int = 34; + +pub const _REG_RV: c_int = _REG_R0; +pub const _REG_FP: c_int = _REG_R11; +pub const _REG_SP: c_int = _REG_R13; +pub const _REG_LR: 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..1b24b4f --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mips.rs @@ -0,0 +1,11 @@ +use crate::prelude::*; +use crate::PT_FIRSTMACH; + +pub type __cpu_simple_lock_nv_t = c_int; + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 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..43572ce --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs @@ -0,0 +1,2493 @@ +use crate::prelude::*; +use crate::{ + cmsghdr, + cpuid_t, + lwpid_t, + off_t, +}; + +pub type blksize_t = i32; +pub type eventfd_t = u64; +pub type fsblkcnt_t = u64; +pub type fsfilcnt_t = u64; +pub type idtype_t = c_int; +type __pthread_spin_t = __cpu_simple_lock_nv_t; +pub type shmatt_t = c_uint; +pub type cpuset_t = _cpuset; +pub type pthread_spin_t = __pthread_spin_t; + +// 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! { + #[repr(C)] + pub enum fae_action { + FAE_OPEN, + FAE_DUP2, + FAE_CLOSE, + } +} + +extern_ty! { + pub type _cpuset; +} + +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) -> crate::pid_t { + #[repr(C)] + struct siginfo_timer { + _si_signo: c_int, + _si_errno: c_int, + _si_code: c_int, + #[cfg(target_pointer_width = "64")] + __pad1: Padding, + _pid: crate::pid_t, + } + (*(self as *const siginfo_t).cast::())._pid + } + + pub unsafe fn si_uid(&self) -> crate::uid_t { + #[repr(C)] + struct siginfo_timer { + _si_signo: c_int, + _si_errno: c_int, + _si_code: c_int, + #[cfg(target_pointer_width = "64")] + __pad1: Padding, + _pid: crate::pid_t, + _uid: crate::uid_t, + } + (*(self as *const siginfo_t).cast::())._uid + } + + pub unsafe fn si_value(&self) -> crate::sigval { + #[repr(C)] + struct siginfo_timer { + _si_signo: c_int, + _si_errno: c_int, + _si_code: c_int, + #[cfg(target_pointer_width = "64")] + __pad1: Padding, + _pid: crate::pid_t, + _uid: crate::uid_t, + value: crate::sigval, + } + (*(self as *const siginfo_t).cast::()).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, + #[cfg(target_pointer_width = "64")] + __pad1: Padding, + _pid: crate::pid_t, + _uid: crate::uid_t, + status: c_int, + } + (*(self as *const siginfo_t).cast::()).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: crate::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: Padding<*mut c_void>, + + __unused4: Padding<*mut c_void>, + __unused5: Padding<*mut c_void>, + __unused6: Padding<*mut c_void>, + __unused7: Padding<*mut c_void>, + __unused8: Padding<*mut c_void>, + } + + 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 mq_attr { + pub mq_flags: c_long, + pub mq_maxmsg: c_long, + pub mq_msgsize: c_long, + pub mq_curmsgs: c_long, + } + + pub struct sigset_t { + __bits: [u32; 4], + } + + pub struct stat { + pub st_dev: crate::dev_t, + pub st_mode: crate::mode_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub st_atime: crate::time_t, + pub st_atimensec: c_long, + pub st_mtime: crate::time_t, + pub st_mtimensec: c_long, + pub st_ctime: crate::time_t, + pub st_ctimensec: c_long, + pub st_birthtime: crate::time_t, + pub st_birthtimensec: c_long, + pub st_size: off_t, + pub st_blocks: crate::blkcnt_t, + pub st_blksize: crate::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: crate::socklen_t, + pub ai_canonname: *mut c_char, + pub ai_addr: *mut crate::sockaddr, + pub ai_next: *mut crate::addrinfo, + } + + pub struct siginfo_t { + pub si_signo: c_int, + pub si_code: c_int, + pub si_errno: c_int, + #[cfg(target_pointer_width = "64")] + __pad1: Padding, + pub si_addr: *mut c_void, + #[cfg(target_pointer_width = "64")] + __pad2: Padding<[u64; 13]>, + #[cfg(target_pointer_width = "32")] + __pad2: Padding<[u64; 14]>, + } + + 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: Padding<[u8; 3]>, + // actually a union with a non-unused, 0-initialized field + ptm_unused: Padding<__pthread_spin_t>, + #[cfg(any( + target_arch = "sparc", + target_arch = "sparc64", + target_arch = "x86", + target_arch = "x86_64" + ))] + ptm_pad2: Padding<[u8; 3]>, + ptm_owner: crate::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 crate::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: crate::pthread_t, + ptr_private: *mut c_void, + } + + pub struct pthread_spinlock_t { + pts_magic: c_uint, + pts_spin: crate::pthread_spin_t, + pts_flags: c_int, + } + + pub struct kevent { + pub ident: crate::uintptr_t, + pub filter: u32, + pub flags: u32, + pub fflags: u32, + pub data: i64, + pub udata: *mut c_void, + } + + 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 sockcred { + pub sc_pid: crate::pid_t, + pub sc_uid: crate::uid_t, + pub sc_euid: crate::uid_t, + pub sc_gid: crate::gid_t, + pub sc_egid: crate::gid_t, + pub sc_ngroups: c_int, + pub sc_groups: [crate::gid_t; 1], + } + + pub struct uucred { + cr_unused: Padding, + pub cr_uid: crate::uid_t, + pub cr_gid: crate::gid_t, + pub cr_ngroups: c_short, + pub cr_groups: [crate::gid_t; NGROUPS_MAX as usize], + } + + pub struct unpcbid { + pub unp_pid: crate::pid_t, + pub unp_euid: crate::uid_t, + pub unp_egid: crate::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; 24], + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_lpid: crate::pid_t, + pub shm_cpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + _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, + } + + 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, + } + + // sys/sysctl.h + + pub struct kinfo_file { + pub ki_fileaddr: u64, + pub ki_flag: u32, + pub ki_iflags: u32, + pub ki_ftype: u32, + pub ki_count: u32, + pub ki_msgcount: u32, + pub ki_usecount: u32, + pub ki_fucred: u64, + pub ki_fuid: u32, + pub ki_fgid: u32, + pub ki_fops: u64, + pub ki_foffset: u64, + pub ki_fdata: u64, + pub ki_vun: u64, + pub ki_vsize: u64, + pub ki_vtype: u32, + pub ki_vtag: u32, + pub ki_vdata: u64, + pub ki_pid: u32, + pub ki_fd: i32, + pub ki_ofileflags: u32, + _ki_padto64bits: Padding, + } + + // 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 accept_filter_arg { + pub af_name: [c_char; 16], + af_arg: [c_char; 256 - 16], + } + + 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: Padding, + l_pad2: Padding, + 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; crate::PATH_MAX as usize], + } + + pub struct __c_anonymous_posix_spawn_fae_open { + pub path: *mut c_char, + pub oflag: c_int, + pub mode: crate::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: crate::pid_t, + pub sa_schedparam: crate::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, + pub fae_data: __c_anonymous_posix_spawn_fae, + } + + pub struct posix_spawn_file_actions_t { + pub size: c_uint, + pub len: c_uint, + pub fae: *mut posix_spawn_file_actions_entry_t, + } + + #[deprecated(since = "0.2.178", note = "obsolete upstream")] + 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 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], + } + + pub struct in_pktinfo { + pub ipi_addr: crate::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: crate::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: crate::sa_family_t, + pub sin_port: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_zero: [i8; 8], + } + + pub struct dirent { + pub d_fileno: crate::ino_t, + pub d_reclen: u16, + pub d_namlen: u16, + pub d_type: u8, + pub d_name: [c_char; 512], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: crate::sa_family_t, + __ss_pad1: Padding<[u8; 6]>, + __ss_pad2: Padding, + __ss_pad3: Padding<[u8; 112]>, + } + + pub struct sigevent { + pub sigev_notify: c_int, + pub sigev_signo: c_int, + pub sigev_value: crate::sigval, + __unused1: Padding<*mut c_void>, //actually a function pointer + pub sigev_notify_attributes: *mut c_void, + } +} + +s_no_extra_traits! { + pub union __c_anonymous_posix_spawn_fae { + pub open: __c_anonymous_posix_spawn_fae_open, + pub dup2: __c_anonymous_posix_spawn_fae_dup2, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl Eq for __c_anonymous_posix_spawn_fae {} + 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 } + } + } + impl hash::Hash for __c_anonymous_posix_spawn_fae { + fn hash(&self, state: &mut H) { + unsafe { + self.open.hash(state); + self.dup2.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_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 << crate::LC_COLLATE; +pub const LC_CTYPE_MASK: c_int = 1 << crate::LC_CTYPE; +pub const LC_MONETARY_MASK: c_int = 1 << crate::LC_MONETARY; +pub const LC_NUMERIC_MASK: c_int = 1 << crate::LC_NUMERIC; +pub const LC_TIME_MASK: c_int = 1 << crate::LC_TIME; +pub const LC_MESSAGES_MASK: c_int = 1 << crate::LC_MESSAGES; +pub const LC_ALL_MASK: c_int = !0; + +pub const ERA: crate::nl_item = 52; +pub const ERA_D_FMT: crate::nl_item = 53; +pub const ERA_D_T_FMT: crate::nl_item = 54; +pub const ERA_T_FMT: crate::nl_item = 55; +pub const ALT_DIGITS: crate::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 = u32_cast_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 + +// 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 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 _CS_PATH: c_int = 1; + +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 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 = u32_cast_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; + +// sys/ioccom.h +pub const IOCPARM_SHIFT: u32 = 16; +pub const IOCGROUP_SHIFT: u32 = 8; + +pub const fn IOCPARM_LEN(x: u32) -> u32 { + (x >> IOCPARM_SHIFT) & crate::IOCPARM_MASK +} + +pub const fn IOCBASECMD(x: u32) -> u32 { + x & (!(crate::IOCPARM_MASK << IOCPARM_SHIFT)) +} + +pub const fn IOCGROUP(x: u32) -> u32 { + (x >> IOCGROUP_SHIFT) & 0xff +} + +pub const fn _IOC(inout: c_ulong, group: c_ulong, num: c_ulong, len: c_ulong) -> c_ulong { + (inout) + | (((len) & crate::IOCPARM_MASK as c_ulong) << IOCPARM_SHIFT) + | ((group) << IOCGROUP_SHIFT) + | (num) +} + +pub const NTP_API: c_int = 4; + +pub const LITTLE_ENDIAN: c_int = 1234; +pub const BIG_ENDIAN: c_int = 4321; + +#[deprecated(since = "0.2.178", note = "obsolete upstream")] +pub const PL_EVENT_NONE: c_int = 0; +#[deprecated(since = "0.2.178", note = "obsolete upstream")] +pub const PL_EVENT_SIGNAL: c_int = 1; +#[deprecated(since = "0.2.178", note = "obsolete upstream")] +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: Padding::new([0; 3]), + ptm_unused: Padding::new(0), + ptm_pad2: Padding::new([0; 3]), + ptm_waiters: ptr::null_mut(), + ptm_owner: 0, + ptm_recursed: 0, + ptm_spare2: ptr::null_mut(), + }; + } else { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + ptm_magic: 0x33330003, + ptm_errorcheck: 0, + ptm_unused: Padding::new(0), + ptm_waiters: ptr::null_mut(), + ptm_owner: 0, + ptm_recursed: 0, + ptm_spare2: ptr::null_mut(), + }; + } +} + +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + ptc_magic: 0x55550005, + ptc_lock: 0, + ptc_waiters_first: ptr::null_mut(), + ptc_waiters_last: ptr::null_mut(), + ptc_mutex: ptr::null_mut(), + ptc_private: ptr::null_mut(), +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + ptr_magic: 0x99990009, + ptr_interlock: 0, + ptr_rblocked_first: ptr::null_mut(), + ptr_rblocked_last: ptr::null_mut(), + ptr_wblocked_first: ptr::null_mut(), + ptr_wblocked_last: ptr::null_mut(), + ptr_nreaders: 0, + ptr_owner: 0, + ptr_private: ptr::null_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: crate::socklen_t = 1025; +pub const NI_MAXSERV: crate::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 = u32_cast_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 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_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: crate::speed_t = 460800; +pub const B921600: crate::speed_t = 921600; + +pub const ONOCR: crate::tcflag_t = 0x20; +pub const ONLRET: crate::tcflag_t = 0x40; +pub const CDTRCTS: crate::tcflag_t = 0x00020000; +pub const CHWFLOW: crate::tcflag_t = crate::MDMBUF | crate::CRTSCTS | crate::CDTRCTS; + +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_ILLSEQ: c_int = 17; + +pub const PT_DUMPCORE: c_int = 12; +#[deprecated(note = "obsolete operation")] +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 = 22; +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +pub const KERN_FILE_BYFILE: c_int = 1; +pub const KERN_FILE_BYPID: c_int = 2; +pub const KERN_FILESLOP: c_int = 10; + +// 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; + +pub const 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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const RTAX_MAX: c_int = 9; + +// For eventfd +pub const EFD_SEMAPHORE: c_int = crate::O_RDWR; +pub const EFD_NONBLOCK: c_int = crate::O_NONBLOCK; +pub const EFD_CLOEXEC: c_int = crate::O_CLOEXEC; + +// sys/timerfd.h +pub const TFD_CLOEXEC: i32 = crate::O_CLOEXEC; +pub const TFD_NONBLOCK: i32 = crate::O_NONBLOCK; +pub const TFD_TIMER_ABSTIME: i32 = crate::O_WRONLY; +pub const TFD_TIMER_CANCEL_ON_SET: i32 = crate::O_RDWR; + +const fn _ALIGN(p: usize) -> usize { + (p + _ALIGNBYTES) & !_ALIGNBYTES +} + +f! { + pub unsafe fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + (cmsg as *mut c_uchar).add(_ALIGN(size_of::())) + } + + pub const unsafe fn CMSG_LEN(length: c_uint) -> c_uint { + _ALIGN(size_of::()) as c_uint + length + } + + pub unsafe fn CMSG_NXTHDR(mhdr: *const crate::msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { + if cmsg.is_null() { + return crate::CMSG_FIRSTHDR(mhdr); + } + let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize) + _ALIGN(size_of::()); + let max = (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize; + if next > max { + ptr::null_mut() + } else { + (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)) as *mut cmsghdr + } + } + + pub const unsafe fn CMSG_SPACE(length: c_uint) -> c_uint { + (_ALIGN(size_of::()) + _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 unsafe fn dirfd(dirp: *mut crate::DIR) -> c_int { + *(dirp as *const c_int) + } + + pub unsafe fn SOCKCREDSIZE(ngrps: usize) -> usize { + let ngrps = if ngrps > 0 { ngrps - 1 } else { 0 }; + size_of::() + size_of::() * ngrps + } + + pub unsafe fn PROT_MPROTECT(x: c_int) -> c_int { + x << 3 + } + + pub unsafe fn PROT_MPROTECT_EXTRACT(x: c_int) -> c_int { + (x >> 3) & 0x7 + } +} + +safe_f! { + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + status >> 8 + } + + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 + } + + pub const safe fn WIFSTOPPED(status: c_int) -> bool { + (status & 0o177) == 0o177 + } + + pub const safe fn WIFCONTINUED(status: c_int) -> bool { + status == 0xffff + } + + pub const safe fn makedev(major: c_uint, minor: c_uint) -> crate::dev_t { + let major = major as crate::dev_t; + let minor = minor as crate::dev_t; + let mut dev = 0; + dev |= (major << 8) & 0x000ff00; + dev |= (minor << 12) & 0xfff00000; + dev |= minor & 0xff; + dev + } + + pub const safe fn major(dev: crate::dev_t) -> c_int { + (((dev as u32) & 0x000fff00) >> 8) as c_int + } + + pub const safe fn minor(dev: crate::dev_t) -> c_int { + let mut res = 0; + res |= ((dev as u32) & 0xfff00000) >> 12; + res |= (dev as u32) & 0x000000ff; + res as c_int + } +} + +extern "C" { + pub fn clock_nanosleep( + clk_id: crate::clockid_t, + flags: c_int, + rqtp: *const crate::timespec, + rmtp: *mut crate::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 crate::termios, + winp: *mut crate::winsize, + ) -> c_int; + pub fn forkpty( + amaster: *mut c_int, + name: *mut c_char, + termp: *mut crate::termios, + winp: *mut crate::winsize, + ) -> crate::pid_t; + + pub fn ptsname_r(fd: c_int, buf: *mut c_char, buflen: size_t) -> c_int; + + #[link_name = "__lutimes50"] + pub fn lutimes(file: *const c_char, times: *const crate::timeval) -> c_int; + #[link_name = "__gettimeofday50"] + pub fn gettimeofday(tp: *mut crate::timeval, tz: *mut c_void) -> c_int; + pub fn getnameinfo( + sa: *const crate::sockaddr, + salen: crate::socklen_t, + host: *mut c_char, + hostlen: crate::socklen_t, + serv: *mut c_char, + servlen: crate::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 crate::kevent, + nchanges: size_t, + eventlist: *mut crate::kevent, + nevents: size_t, + timeout: *const crate::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, ...) -> crate::mqd_t; + pub fn mq_close(mqd: crate::mqd_t) -> c_int; + pub fn mq_getattr(mqd: crate::mqd_t, attr: *mut crate::mq_attr) -> c_int; + pub fn mq_notify(mqd: crate::mqd_t, notification: *const crate::sigevent) -> c_int; + pub fn mq_receive( + mqd: crate::mqd_t, + msg_ptr: *mut c_char, + msg_len: size_t, + msg_prio: *mut c_uint, + ) -> ssize_t; + pub fn mq_send( + mqd: crate::mqd_t, + msg_ptr: *const c_char, + msg_len: size_t, + msg_prio: c_uint, + ) -> c_int; + pub fn mq_setattr( + mqd: crate::mqd_t, + newattr: *const crate::mq_attr, + oldattr: *mut crate::mq_attr, + ) -> c_int; + #[link_name = "__mq_timedreceive50"] + pub fn mq_timedreceive( + mqd: crate::mqd_t, + msg_ptr: *mut c_char, + msg_len: size_t, + msg_prio: *mut c_uint, + abs_timeout: *const crate::timespec, + ) -> ssize_t; + #[link_name = "__mq_timedsend50"] + pub fn mq_timedsend( + mqd: crate::mqd_t, + msg_ptr: *const c_char, + msg_len: size_t, + msg_prio: c_uint, + abs_timeout: *const crate::timespec, + ) -> c_int; + pub fn mq_unlink(name: *const c_char) -> c_int; + pub fn ptrace(request: c_int, pid: crate::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: crate::pthread_t, name: *mut c_char, len: size_t) -> c_int; + pub fn pthread_setname_np( + t: crate::pthread_t, + name: *const c_char, + arg: *const c_void, + ) -> c_int; + pub fn pthread_attr_get_np(thread: crate::pthread_t, attr: *mut crate::pthread_attr_t) + -> c_int; + pub fn pthread_getattr_np(native: crate::pthread_t, attr: *mut crate::pthread_attr_t) -> c_int; + pub fn pthread_attr_getguardsize( + attr: *const crate::pthread_attr_t, + guardsize: *mut size_t, + ) -> c_int; + pub fn pthread_attr_setguardsize(attr: *mut crate::pthread_attr_t, guardsize: size_t) -> c_int; + pub fn pthread_attr_getstack( + attr: *const crate::pthread_attr_t, + stackaddr: *mut *mut c_void, + stacksize: *mut size_t, + ) -> c_int; + pub fn pthread_getaffinity_np( + thread: crate::pthread_t, + size: size_t, + set: *mut cpuset_t, + ) -> c_int; + pub fn pthread_setaffinity_np( + thread: crate::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 crate::timespec, + ) -> c_int; + pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> c_int; + + pub fn duplocale(base: crate::locale_t) -> crate::locale_t; + pub fn freelocale(loc: crate::locale_t); + pub fn localeconv_l(loc: crate::locale_t) -> *mut lconv; + pub fn newlocale(mask: c_int, locale: *const c_char, base: crate::locale_t) -> crate::locale_t; + #[link_name = "__settimeofday50"] + pub fn settimeofday(tv: *const crate::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: crate::clockid_t, + sevp: *mut crate::sigevent, + timerid: *mut crate::timer_t, + ) -> c_int; + pub fn timer_delete(timerid: crate::timer_t) -> c_int; + pub fn timer_getoverrun(timerid: crate::timer_t) -> c_int; + #[link_name = "__timer_gettime50"] + pub fn timer_gettime(timerid: crate::timer_t, curr_value: *mut crate::itimerspec) -> c_int; + #[link_name = "__timer_settime50"] + pub fn timer_settime( + timerid: crate::timer_t, + flags: c_int, + new_value: *const crate::itimerspec, + old_value: *mut crate::itimerspec, + ) -> c_int; + pub fn dlvsym( + handle: *mut c_void, + symbol: *const c_char, + version: *const c_char, + ) -> *mut c_void; + + // 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; + + #[link_name = "__sched_rr_get_interval50"] + pub fn sched_rr_get_interval(pid: crate::pid_t, t: *mut crate::timespec) -> c_int; + pub fn sched_setparam(pid: crate::pid_t, param: *const crate::sched_param) -> c_int; + pub fn sched_getparam(pid: crate::pid_t, param: *mut crate::sched_param) -> c_int; + pub fn sched_getscheduler(pid: crate::pid_t) -> c_int; + pub fn sched_setscheduler( + pid: crate::pid_t, + policy: c_int, + param: *const crate::sched_param, + ) -> c_int; + + #[link_name = "__pollts50"] + pub fn pollts( + fds: *mut crate::pollfd, + nfds: crate::nfds_t, + ts: *const crate::timespec, + sigmask: *const crate::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: crate::clockid_t, + flags: c_int, + ts: *mut crate::timespec, + unpark: crate::lwpid_t, + hint: *const c_void, + unparkhint: *mut c_void, + ) -> c_int; + pub fn _lwp_unpark(lwp: crate::lwpid_t, hint: *const c_void) -> c_int; + pub fn _lwp_unpark_all( + targets: *const crate::lwpid_t, + ntargets: size_t, + hint: *const c_void, + ) -> c_int; + #[link_name = "__getmntinfo13"] + pub fn getmntinfo(mntbufp: *mut *mut crate::statvfs, flags: c_int) -> c_int; + pub fn getvfsstat(buf: *mut crate::statvfs, bufsize: size_t, flags: c_int) -> c_int; + + pub fn eventfd(val: c_uint, flags: c_int) -> c_int; + pub fn eventfd_read(efd: c_int, valp: *mut eventfd_t) -> c_int; + pub fn eventfd_write(efd: c_int, val: eventfd_t) -> c_int; + + // Added in `NetBSD` 10.0 + pub fn timerfd_create(clockid: crate::clockid_t, flags: c_int) -> c_int; + pub fn timerfd_gettime(fd: c_int, curr_value: *mut crate::itimerspec) -> c_int; + pub fn timerfd_settime( + fd: c_int, + flags: c_int, + new_value: *const crate::itimerspec, + old_value: *mut crate::itimerspec, + ) -> c_int; + + pub fn qsort_r( + base: *mut c_void, + num: size_t, + size: size_t, + compar: Option c_int>, + arg: *mut c_void, + ); +} + +#[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 crate::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" { + #[link_name = "__getpwent_r50"] + pub fn getpwent_r( + pwd: *mut crate::passwd, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::passwd, + ) -> c_int; + pub fn getgrent_r( + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + + pub fn efopen(p: *const c_char, m: *const c_char) -> crate::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: crate::intmax_t, + hi: crate::intmax_t, + ) -> crate::intmax_t; + pub fn estrtou( + nptr: *const c_char, + base: c_int, + lo: crate::uintmax_t, + hi: crate::uintmax_t, + ) -> crate::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: crate::uintmax_t, + denominator: crate::uintmax_t, + precision: size_t, + ) -> *mut c_char; + pub fn strspct( + buf: *mut c_char, + bufsiz: size_t, + numerator: crate::intmax_t, + denominator: crate::intmax_t, + precision: size_t, + ) -> *mut c_char; + #[link_name = "__login50"] + pub fn login(ut: *const crate::utmp); + #[link_name = "__loginx50"] + pub fn loginx(ut: *const crate::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: crate::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(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..f8f2d56 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/powerpc.rs @@ -0,0 +1,10 @@ +use crate::prelude::*; +use crate::PT_FIRSTMACH; + +pub type __cpu_simple_lock_nv_t = c_int; + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 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..05c0cd5 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/riscv64.rs @@ -0,0 +1,97 @@ +use crate::prelude::*; +use crate::PT_FIRSTMACH; + +pub type __greg_t = u64; +pub type __cpu_simple_lock_nv_t = c_uint; +pub type __gregset_t = [__greg_t; _NGREG]; +pub type __fregset_t = [__fpreg; _NFREG]; + +s_no_extra_traits! { + pub union __fpreg { + pub u_u64: u64, + pub u_d: c_double, + } +} + +s! { + pub struct mcontext_t { + pub __gregs: __gregset_t, + pub __fregs: __fregset_t, + __spare: [crate::__greg_t; 7], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for __fpreg { + fn eq(&self, other: &__fpreg) -> bool { + unsafe { self.u_u64 == other.u_u64 || self.u_d == other.u_d } + } + } + impl Eq for __fpreg {} + impl hash::Hash for __fpreg { + fn hash(&self, state: &mut H) { + unsafe { + self.u_u64.hash(state); + } + } + } + } +} + +// gcc for riscv64 defines `BIGGEST_ALIGNMENT`, but it's mesured in bits. +pub(crate) const __BIGGEST_ALIGNMENT_IN_BITS__: usize = 128; +// `_ALIGNBYTES` is measured in, well, bytes. +pub(crate) const _ALIGNBYTES: usize = (__BIGGEST_ALIGNMENT_IN_BITS__ / 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; + +pub const _NGREG: usize = 32; +pub const _NFREG: usize = 33; + +pub const _REG_X1: c_int = 0; +pub const _REG_X2: c_int = 1; +pub const _REG_X3: c_int = 2; +pub const _REG_X4: c_int = 3; +pub const _REG_X5: c_int = 4; +pub const _REG_X6: c_int = 5; +pub const _REG_X7: c_int = 6; +pub const _REG_X8: c_int = 7; +pub const _REG_X9: c_int = 8; +pub const _REG_X10: c_int = 9; +pub const _REG_X11: c_int = 10; +pub const _REG_X12: c_int = 11; +pub const _REG_X13: c_int = 12; +pub const _REG_X14: c_int = 13; +pub const _REG_X15: c_int = 14; +pub const _REG_X16: c_int = 15; +pub const _REG_X17: c_int = 16; +pub const _REG_X18: c_int = 17; +pub const _REG_X19: c_int = 18; +pub const _REG_X20: c_int = 19; +pub const _REG_X21: c_int = 20; +pub const _REG_X22: c_int = 21; +pub const _REG_X23: c_int = 22; +pub const _REG_X24: c_int = 23; +pub const _REG_X25: c_int = 24; +pub const _REG_X26: c_int = 25; +pub const _REG_X27: c_int = 26; +pub const _REG_X28: c_int = 27; +pub const _REG_X29: c_int = 28; +pub const _REG_X30: c_int = 29; +pub const _REG_X31: c_int = 30; +pub const _REG_PC: c_int = 31; + +pub const _REG_RA: c_int = _REG_X1; +pub const _REG_SP: c_int = _REG_X2; +pub const _REG_GP: c_int = _REG_X3; +pub const _REG_TP: c_int = _REG_X4; +pub const _REG_S0: c_int = _REG_X8; +pub const _REG_RV: c_int = _REG_X10; +pub const _REG_A0: c_int = _REG_X10; + +pub const _REG_F0: c_int = 0; +pub const _REG_FPCSR: c_int = 32; 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..91622f7 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/sparc64.rs @@ -0,0 +1,7 @@ +use crate::prelude::*; + +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..95f5576 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86.rs @@ -0,0 +1,5 @@ +use crate::prelude::*; + +pub type __cpu_simple_lock_nv_t = c_uchar; + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 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..801b326 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86_64.rs @@ -0,0 +1,59 @@ +use crate::prelude::*; +use crate::PT_FIRSTMACH; + +pub type c___greg_t = u64; +pub type __cpu_simple_lock_nv_t = c_uchar; + +// FIXME(alignment): Type is `__aligned(8)` +type __fpregset_t = [c_char; 512]; + +s! { + pub struct mcontext_t { + pub __gregs: [c___greg_t; 26], + pub _mc_tlsbase: c___greg_t, + pub __fpregs: __fpregset_t, + } + + pub struct ucontext_t { + pub uc_flags: c_uint, + pub uc_link: *mut crate::ucontext_t, + pub uc_sigmask: crate::sigset_t, + pub uc_stack: crate::stack_t, + pub uc_mcontext: crate::mcontext_t, + } +} + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 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..13142ea --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/aarch64.rs @@ -0,0 +1,20 @@ +use crate::prelude::*; + +pub type ucontext_t = sigcontext; + +s! { + pub struct sigcontext { + __sc_unused: Padding, + 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, + } +} + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 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..8b3f721 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/arm.rs @@ -0,0 +1,5 @@ +use crate::prelude::*; + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 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..162ceda --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mips64.rs @@ -0,0 +1,4 @@ +#[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..5a69b0e --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs @@ -0,0 +1,2116 @@ +use crate::prelude::*; +use crate::unix::bsd::O_SYNC; +use crate::{ + cmsghdr, + off_t, +}; + +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 = crate::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: Padding<*mut c_void>, + __unused2: Padding<*mut c_void>, + __unused3: Padding<*mut c_void>, + __unused4: Padding<*mut c_void>, + __unused5: Padding<*mut c_void>, + __unused6: Padding<*mut c_void>, + __unused7: Padding<*mut c_void>, + } + + 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 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 crate::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: crate::uid_t, + pub gid: crate::gid_t, + pub mask: crate::mode_t, + pub flags: c_int, + } + + pub struct ntfs_args { + pub fspec: *mut c_char, + pub export_info: export_args, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub mode: crate::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: crate::ino_t, + pub ta_size_max: off_t, + pub ta_root_uid: crate::uid_t, + pub ta_root_gid: crate::gid_t, + pub ta_root_mode: crate::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: crate::uid_t, + pub cr_gid: crate::gid_t, + pub cr_ngroups: c_short, + //https://github.com/openbsd/src/blob/HEAD/sys/sys/syslimits.h#L44 + pub cr_groups: [crate::gid_t; 16], + } + + pub struct export_args { + pub ex_flags: c_int, + pub ex_root: crate::uid_t, + pub ex_anon: xucred, + pub ex_addr: *mut crate::sockaddr, + pub ex_addrlen: c_int, + pub ex_mask: *mut crate::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: crate::in_addr_t, + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: crate::sa_family_t, + pub sin_port: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_zero: [i8; 8], + } + + pub struct splice { + pub sp_fd: c_int, + pub sp_max: off_t, + pub sp_idle: crate::timeval, + } + + pub struct kevent { + pub ident: crate::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: crate::mode_t, + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_size: off_t, + pub st_blocks: crate::blkcnt_t, + pub st_blksize: crate::blksize_t, + pub st_flags: u32, + pub st_gen: u32, + pub st_birthtime: crate::time_t, + pub st_birthtime_nsec: c_long, + } + + pub struct statvfs { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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: crate::socklen_t, + pub ai_addr: *mut crate::sockaddr, + pub ai_canonname: *mut c_char, + pub ai_next: *mut crate::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: crate::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: crate::uid_t, + pub gid: crate::gid_t, + pub pid: crate::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: crate::ipc_perm, + pub shm_segsz: c_int, + pub shm_lpid: crate::pid_t, + pub shm_cpid: crate::pid_t, + pub shm_nattch: c_short, + pub shm_atime: crate::time_t, + __shm_atimensec: c_long, + pub shm_dtime: crate::time_t, + __shm_dtimensec: c_long, + pub shm_ctime: crate::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_file { + pub f_fileaddr: u64, + pub f_flag: u32, + pub f_iflags: u32, + pub f_type: u32, + pub f_count: u32, + pub f_msgcount: u32, + pub f_usecount: u32, + pub f_ucred: u64, + pub f_uid: u32, + pub f_gid: u32, + pub f_ops: u64, + pub f_offset: u64, + pub f_data: u64, + pub f_rxfer: u64, + pub f_rwfer: u64, + pub f_seek: u64, + pub f_rbytes: u64, + pub f_wbytes: u64, + pub v_un: u64, + pub v_type: u32, + pub v_tag: u32, + pub v_flag: u32, + pub va_rdev: u32, + pub v_data: u64, + pub v_mount: u64, + pub va_fileid: u64, + pub va_size: u64, + pub va_mode: u32, + pub va_fsid: u32, + pub f_mntonname: [c_char; KI_MNAMELEN as usize], + pub so_type: u32, + pub so_state: u32, + pub so_pcb: u64, + pub so_protocol: u32, + pub so_family: u32, + pub inp_ppcb: u64, + pub inp_lport: u32, + pub inp_laddru: [u32; 4], + pub inp_fport: u32, + pub inp_faddru: [u32; 4], + pub unp_conn: u64, + pub pipe_peer: u64, + pub pipe_state: u32, + pub kq_count: u32, + pub kq_state: u32, + __unused1: Padding, + pub p_pid: u32, + pub fd_fd: i32, + pub fd_ofileflags: u32, + pub p_uid: u32, + pub p_gid: u32, + pub p_tid: u32, + pub p_comm: [c_char; KI_MAXCOMLEN as usize], + pub inp_rtableid: u32, + pub so_splice: u64, + pub so_splicelen: i64, + pub so_rcv_cc: u64, + pub so_snd_cc: u64, + pub unp_refs: u64, + pub unp_nextref: u64, + pub unp_addr: u64, + pub unp_path: [c_char; KI_UNPPATHLEN as usize], + pub inp_proto: u32, + pub t_state: u32, + pub t_rcv_wnd: u64, + pub t_snd_wnd: u64, + pub t_snd_cwnd: u64, + pub va_nlink: u32, + } + + 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: crate::pid_t, + pub pe_tid: crate::pid_t, + } + + pub struct ptrace_thread_state { + pub pts_tid: crate::pid_t, + pub pts_name: [c_char; PT_PTS_NAMELEN as usize], + } + + // search.h + pub struct entry { + pub key: *mut c_char, + pub data: *mut c_void, + } + + pub struct ifreq { + pub ifr_name: [c_char; crate::IFNAMSIZ], + pub ifr_ifru: __c_anonymous_ifr_ifru, + } + + 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, + } + + pub struct dirent { + pub d_fileno: crate::ino_t, + pub d_off: off_t, + pub d_reclen: u16, + pub d_type: u8, + pub d_namlen: u8, + __d_padding: Padding<[u8; 4]>, + pub d_name: [c_char; 256], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: crate::sa_family_t, + __ss_pad1: Padding<[u8; 6]>, + __ss_pad2: Padding, + __ss_pad3: Padding<[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: Padding<[u8; 112]>, + #[cfg(target_pointer_width = "64")] + __pad: Padding<[u8; 108]>, + } + + pub struct lastlog { + ll_time: crate::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: crate::time_t, + } + + 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: crate::fsid_t, + pub f_namemax: u32, + pub f_owner: crate::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, + } +} + +s_no_extra_traits! { + 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_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for mount_info { + fn eq(&self, other: &mount_info) -> bool { + unsafe { + self.align + .iter() + .zip(other.align.iter()) + .all(|(a, b)| a == b) + } + } + } + + impl Eq for mount_info {} + + impl hash::Hash for mount_info { + fn hash(&self, state: &mut H) { + unsafe { self.align.hash(state) }; + } + } + } +} + +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) -> crate::pid_t { + #[repr(C)] + struct siginfo_timer { + _si_signo: c_int, + _si_code: c_int, + _si_errno: c_int, + _pad: Padding<[c_int; SI_PAD]>, + _pid: crate::pid_t, + } + (*(self as *const siginfo_t).cast::())._pid + } + + pub unsafe fn si_uid(&self) -> crate::uid_t { + #[repr(C)] + struct siginfo_timer { + _si_signo: c_int, + _si_code: c_int, + _si_errno: c_int, + _pad: Padding<[c_int; SI_PAD]>, + _pid: crate::pid_t, + _uid: crate::uid_t, + } + (*(self as *const siginfo_t).cast::())._uid + } + + pub unsafe fn si_value(&self) -> crate::sigval { + #[repr(C)] + struct siginfo_timer { + _si_signo: c_int, + _si_code: c_int, + _si_errno: c_int, + _pad: Padding<[c_int; SI_PAD]>, + _pid: crate::pid_t, + _uid: crate::uid_t, + value: crate::sigval, + } + (*(self as *const siginfo_t).cast::()).value + } + + pub unsafe fn si_status(&self) -> c_int { + #[repr(C)] + struct siginfo_proc { + _si_signo: c_int, + _si_code: c_int, + _si_errno: c_int, + _pad: Padding<[c_int; SI_PAD]>, + _pid: crate::pid_t, + _uid: crate::uid_t, + _utime: crate::clock_t, + _stime: crate::clock_t, + _status: crate::c_int, + } + (*(self as *const siginfo_t).cast::())._status + } +} + +s_no_extra_traits! { + pub union __c_anonymous_ifr_ifru { + pub ifru_addr: crate::sockaddr, + pub ifru_dstaddr: crate::sockaddr, + pub ifru_broadaddr: crate::sockaddr, + pub ifru_flags: c_short, + pub ifru_metric: c_int, + pub ifru_vnetid: i64, + pub ifru_media: u64, + pub ifru_data: crate::caddr_t, + pub ifru_index: c_uint, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + 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 + } + } + } + + impl Eq for __c_anonymous_ifr_ifru {} + + 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); + } + } + } + } +} + +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 = crate::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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +pub const AT_NULL: c_int = 0; +pub const AT_IGNORE: c_int = 1; +pub const AT_PAGESZ: c_int = 6; +pub const AT_HWCAP: c_int = 25; +pub const AT_HWCAP2: c_int = 26; + +#[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 _CS_PATH: c_int = 1; + +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 = ptr::null_mut(); +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = ptr::null_mut(); +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = ptr::null_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 EVFILT_USER: 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_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_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_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 KERN_FILE_BYFILE: c_int = 1; +pub const KERN_FILE_BYPID: c_int = 2; +pub const KERN_FILE_BYUID: c_int = 3; +pub const KERN_FILESLOP: c_int = 10; + +pub const KERN_FILE_TEXT: c_int = -1; +pub const KERN_FILE_CDIR: c_int = -2; +pub const KERN_FILE_RDIR: c_int = -3; +pub const KERN_FILE_TRACE: c_int = -4; + +pub const KI_MNAMELEN: c_int = 96; +pub const KI_UNPPATHLEN: c_int = 104; + +pub const CHWFLOW: crate::tcflag_t = crate::MDMBUF | crate::CRTSCTS; +pub const OLCUC: crate::tcflag_t = 0x20; +pub const ONOCR: crate::tcflag_t = 0x40; +pub const ONLRET: crate::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 + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 = u32_cast_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 = u32_cast_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 / size_of::()) - 3; + +pub const MAP_STACK: c_int = 0x4000; +pub const MAP_CONCEAL: c_int = 0x8000; + +// https://github.com/openbsd/src/blob/f8a2f73b6503213f5eb24ca315ac7e1f9421c0c9/sys/net/if.h#L135 +pub const LINK_STATE_UNKNOWN: c_int = 0; // link unknown +pub const LINK_STATE_INVALID: c_int = 1; // link invalid +pub const LINK_STATE_DOWN: c_int = 2; // link is down +pub const LINK_STATE_KALIVE_DOWN: c_int = 3; // keepalive reports down +pub const LINK_STATE_UP: c_int = 4; // link is up +pub const LINK_STATE_HALF_DUPLEX: c_int = 5; // link is up and half duplex +pub const LINK_STATE_FULL_DUPLEX: c_int = 6; // link is up and full duplex + +// 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 PT_PTS_NAMELEN: 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: crate::idtype_t = 0; +pub const P_PGID: crate::idtype_t = 1; +pub const P_PID: crate::idtype_t = 2; + +// search.h +pub const FIND: crate::ACTION = 0; +pub const ENTER: crate::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; + +// sys/file.h +pub const DTYPE_VNODE: c_int = 1; +pub const DTYPE_SOCKET: c_int = 2; +pub const DTYPE_PIPE: c_int = 3; +pub const DTYPE_KQUEUE: c_int = 4; +pub const DTYPE_DMABUF: c_int = 5; +pub const DTYPE_SYNC: c_int = 6; + +// 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/ioccom.h +pub const fn IOCPARM_LEN(x: u32) -> u32 { + (x >> 16) & crate::IOCPARM_MASK +} + +pub const fn IOCBASECMD(x: u32) -> u32 { + x & (!(crate::IOCPARM_MASK << 16)) +} + +pub const fn IOCGROUP(x: u32) -> u32 { + (x >> 8) & 0xff +} + +pub const fn _IOC(inout: c_ulong, group: c_ulong, num: c_ulong, len: c_ulong) -> c_ulong { + (inout) | (((len) & crate::IOCPARM_MASK as c_ulong) << 16) | ((group) << 8) | (num) +} + +// 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: crate::clockid_t = 2; +pub const CLOCK_THREAD_CPUTIME_ID: crate::clockid_t = 4; +pub const CLOCK_UPTIME: crate::clockid_t = 5; +pub const CLOCK_BOOTTIME: crate::clockid_t = 6; + +pub const LC_COLLATE_MASK: c_int = 1 << crate::LC_COLLATE; +pub const LC_CTYPE_MASK: c_int = 1 << crate::LC_CTYPE; +pub const LC_MONETARY_MASK: c_int = 1 << crate::LC_MONETARY; +pub const LC_NUMERIC_MASK: c_int = 1 << crate::LC_NUMERIC; +pub const LC_TIME_MASK: c_int = 1 << crate::LC_TIME; +pub const LC_MESSAGES_MASK: c_int = 1 << crate::LC_MESSAGES; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +const _LC_LAST: c_int = 7; + +pub const LC_ALL_MASK: c_int = (1 << _LC_LAST) - 2; + +pub const LC_GLOBAL_LOCALE: crate::locale_t = -1isize as crate::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 = crate::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 = crate::RTF_LLINFO + | crate::RTF_PROTO1 + | crate::RTF_PROTO2 + | crate::RTF_PROTO3 + | crate::RTF_BLACKHOLE + | crate::RTF_REJECT + | crate::RTF_STATIC + | crate::RTF_MPLS + | crate::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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const RTAX_MAX: c_int = 15; + +const fn _ALIGN(p: usize) -> usize { + (p + _ALIGNBYTES) & !_ALIGNBYTES +} + +f! { + pub unsafe fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + (cmsg as *mut c_uchar).offset(_ALIGN(size_of::()) as isize) + } + + pub const unsafe fn CMSG_LEN(length: c_uint) -> c_uint { + _ALIGN(size_of::()) as c_uint + length + } + + pub unsafe fn CMSG_NXTHDR(mhdr: *const crate::msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { + if cmsg.is_null() { + return crate::CMSG_FIRSTHDR(mhdr); + } + let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize) + _ALIGN(size_of::()); + let max = (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize; + if next > max { + ptr::null_mut() + } else { + (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)) as *mut cmsghdr + } + } + + pub const unsafe fn CMSG_SPACE(length: c_uint) -> c_uint { + (_ALIGN(size_of::()) + _ALIGN(length as usize)) as c_uint + } +} + +safe_f! { + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + status >> 8 + } + + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 + } + + pub const safe fn WIFSTOPPED(status: c_int) -> bool { + (status & 0xff) == 0o177 + } + + pub const safe fn WIFCONTINUED(status: c_int) -> bool { + (status & 0o177777) == 0o177777 + } + + pub const safe fn makedev(major: c_uint, minor: c_uint) -> crate::dev_t { + let major = major as crate::dev_t; + let minor = minor as crate::dev_t; + let mut dev = 0; + dev |= (major & 0xff) << 8; + dev |= minor & 0xff; + dev |= (minor & 0xffff00) << 8; + dev + } + + pub const safe fn major(dev: crate::dev_t) -> c_uint { + ((dev as c_uint) >> 8) & 0xff + } + + pub const safe fn minor(dev: crate::dev_t) -> c_uint { + let dev = dev as c_uint; + let mut res = 0; + res |= (dev) & 0xff; + res |= ((dev) & 0xffff0000) >> 8; + res + } +} + +extern "C" { + pub fn gettimeofday(tp: *mut crate::timeval, tz: *mut crate::timezone) -> c_int; + pub fn settimeofday(tp: *const crate::timeval, tz: *const crate::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 crate::DIR) -> c_int; + pub fn getnameinfo( + sa: *const crate::sockaddr, + salen: crate::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 crate::gid_t, + egid: *mut crate::gid_t, + sgid: *mut crate::gid_t, + ) -> c_int; + pub fn getresuid( + ruid: *mut crate::uid_t, + euid: *mut crate::uid_t, + suid: *mut crate::uid_t, + ) -> c_int; + pub fn kevent( + kq: c_int, + changelist: *const crate::kevent, + nchanges: c_int, + eventlist: *mut crate::kevent, + nevents: c_int, + timeout: *const crate::timespec, + ) -> c_int; + pub fn mprotect(addr: *mut c_void, len: size_t, prot: c_int) -> c_int; + pub fn getthrid() -> crate::pid_t; + pub fn pthread_attr_getguardsize( + attr: *const crate::pthread_attr_t, + guardsize: *mut size_t, + ) -> c_int; + pub fn pthread_attr_setguardsize(attr: *mut crate::pthread_attr_t, guardsize: size_t) -> c_int; + pub fn pthread_attr_getstack( + attr: *const crate::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: crate::pthread_t, name: *mut c_char, len: size_t); + pub fn pthread_set_name_np(tid: crate::pthread_t, name: *const c_char); + pub fn pthread_stackseg_np(thread: crate::pthread_t, sinfo: *mut crate::stack_t) -> c_int; + + pub fn openpty( + amaster: *mut c_int, + aslave: *mut c_int, + name: *mut c_char, + termp: *const crate::termios, + winp: *const crate::winsize, + ) -> c_int; + pub fn forkpty( + amaster: *mut c_int, + name: *mut c_char, + termp: *const crate::termios, + winp: *const crate::winsize, + ) -> crate::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: crate::gid_t, egid: crate::gid_t, sgid: crate::gid_t) -> c_int; + pub fn setresuid(ruid: crate::uid_t, euid: crate::uid_t, suid: crate::uid_t) -> c_int; + pub fn ptrace(request: c_int, pid: crate::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: crate::locale_t) -> crate::locale_t; + pub fn freelocale(loc: crate::locale_t); + pub fn newlocale(mask: c_int, locale: *const c_char, base: crate::locale_t) -> crate::locale_t; + pub fn duplocale(base: crate::locale_t) -> crate::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: crate::ENTRY, action: crate::ACTION) -> *mut crate::ENTRY; + + // futex.h + pub fn futex( + uaddr: *mut u32, + op: c_int, + val: c_int, + timeout: *const crate::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; + + 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 crate::statfs, flags: c_int) -> c_int; + pub fn getfsstat(buf: *mut statfs, bufsize: size_t, flags: c_int) -> c_int; + + pub fn elf_aux_info(aux: c_int, buf: *mut c_void, buflen: 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(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..8b3f721 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc.rs @@ -0,0 +1,5 @@ +use crate::prelude::*; + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 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..5ebe857 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc64.rs @@ -0,0 +1,5 @@ +use crate::prelude::*; + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 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..e0ecf2a --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/riscv64.rs @@ -0,0 +1,25 @@ +use crate::prelude::*; + +pub type ucontext_t = sigcontext; + +s! { + pub struct sigcontext { + __sc_unused: Padding, + 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, + } +} + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 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..88481f4 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/sparc64.rs @@ -0,0 +1,4 @@ +#[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..97dc583 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86.rs @@ -0,0 +1,5 @@ +use crate::prelude::*; + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 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..74889a7 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86_64.rs @@ -0,0 +1,65 @@ +use crate::prelude::*; +use crate::PT_FIRSTMACH; + +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: Padding, + pub sc_mask: c_int, + pub sc_cookie: c_long, + } + + #[repr(packed)] + pub struct fxsave64 { + pub fx_fcw: u16, + pub fx_fsw: u16, + pub fx_ftw: u8, + __fx_unused1: Padding, + 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: Padding<[u8; 96]>, + } +} + +pub(crate) const _ALIGNBYTES: usize = size_of::() - 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/cygwin/mod.rs b/vendor/libc/src/unix/cygwin/mod.rs new file mode 100644 index 0000000..bfe1d8f --- /dev/null +++ b/vendor/libc/src/unix/cygwin/mod.rs @@ -0,0 +1,2393 @@ +use crate::prelude::*; +use crate::*; + +pub type wchar_t = c_ushort; + +pub type blkcnt_t = i64; +pub type blksize_t = i32; +pub type dev_t = u32; +pub type fsblkcnt_t = c_ulong; +pub type fsfilcnt_t = c_ulong; +pub type ino_t = u64; +pub type key_t = c_longlong; +pub type sa_family_t = u16; +pub type socklen_t = c_int; + +pub type off_t = c_long; +pub type id_t = u32; +pub type mode_t = u32; +pub type _off64_t = c_longlong; +pub type loff_t = _off64_t; +pub type iconv_t = *mut c_void; +pub type clock_t = c_ulong; +pub type time_t = c_long; +pub type clockid_t = c_ulong; +pub type timer_t = c_ulong; +pub type nl_item = c_int; +pub type nlink_t = c_ushort; +pub type suseconds_t = c_long; +pub type useconds_t = c_ulong; + +extern_ty! { + pub type timezone; +} + +pub type sigset_t = c_ulong; + +pub type fd_mask = c_ulong; + +pub type pthread_t = *mut c_void; +pub type pthread_mutex_t = *mut c_void; + +// Must be usize due to libstd/sys_common/thread_local.rs, +// should technically be *mut c_void +pub type pthread_key_t = usize; + +pub type pthread_attr_t = *mut c_void; +pub type pthread_mutexattr_t = *mut c_void; +pub type pthread_condattr_t = *mut c_void; +pub type pthread_cond_t = *mut c_void; + +// The following ones should be *mut c_void +pub type pthread_barrierattr_t = usize; +pub type pthread_barrier_t = usize; +pub type pthread_spinlock_t = usize; + +pub type pthread_rwlock_t = *mut c_void; +pub type pthread_rwlockattr_t = *mut c_void; + +pub type register_t = intptr_t; +pub type u_char = c_uchar; +pub type u_short = c_ushort; +pub type u_long = c_ulong; +pub type u_int = c_uint; +pub type caddr_t = *mut c_char; +pub type vm_size_t = c_ulong; + +pub type rlim_t = c_ulong; + +pub type nfds_t = c_uint; + +pub type sem_t = *mut sem; + +extern_ty! { + pub type sem; +} + +pub type tcflag_t = c_uint; +pub type speed_t = c_uint; + +pub type vm_offset_t = c_ulong; + +pub type posix_spawn_file_actions_t = *mut c_void; +pub type posix_spawnattr_t = *mut c_void; + +s! { + pub struct itimerspec { + pub it_interval: timespec, + pub it_value: timespec, + } + + pub struct cpu_set_t { + bits: [u64; 16], + } + + 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_flags: c_int, + pub ss_size: size_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 bintime { + pub sec: time_t, + pub frac: u64, + } + + 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_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 ucred { + pub pid: pid_t, + pub uid: uid_t, + pub gid: gid_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: size_t, + pub cmsg_level: c_int, + pub cmsg_type: c_int, + } + + pub struct Dl_info { + pub dli_fname: [c_char; PATH_MAX as usize], + pub dli_fbase: *mut c_void, + pub dli_sname: *const c_char, + pub dli_saddr: *mut c_void, + } + + pub struct in6_pktinfo { + pub ipi6_addr: in6_addr, + pub ipi6_ifindex: u32, + } + + 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 ip_mreq_source { + pub imr_multiaddr: in_addr, + pub imr_sourceaddr: in_addr, + pub imr_interface: in_addr, + } + + 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 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 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_cc: [cc_t; NCCS], + pub c_ispeed: speed_t, + pub c_ospeed: speed_t, + } + + pub struct sched_param { + pub sched_priority: c_int, + } + + 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 hostent { + pub h_name: *const c_char, + pub h_aliases: *mut *mut c_char, + pub h_addrtype: c_short, + pub h_length: c_short, + pub h_addr_list: *mut *mut c_char, + } + + pub struct linger { + pub l_onoff: c_ushort, + pub l_linger: c_ushort, + } + + pub struct fd_set { + fds_bits: [fd_mask; FD_SETSIZE / size_of::() / 8], + } + + pub struct _uc_fpxreg { + pub significand: [u16; 4], + pub exponent: u16, + padding: Padding<[u16; 3]>, + } + + pub struct _uc_xmmreg { + pub element: [u32; 4], + } + + pub struct _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: [_uc_fpxreg; 8], + pub xmm: [_uc_xmmreg; 16], + padding: Padding<[u32; 24]>, + } + + #[repr(align(16))] + pub struct mcontext_t { + pub p1home: u64, + pub p2home: u64, + pub p3home: u64, + pub p4home: u64, + pub p5home: u64, + pub p6home: u64, + pub ctxflags: u32, + pub mxcsr: u32, + pub cs: u16, + pub ds: u16, + pub es: u16, + pub fs: u16, + pub gs: u16, + pub ss: u16, + pub eflags: u32, + pub dr0: u64, + pub dr1: u64, + pub dr2: u64, + pub dr3: u64, + pub dr6: u64, + pub dr7: u64, + pub rax: u64, + pub rcx: u64, + pub rdx: u64, + pub rbx: u64, + pub rsp: u64, + pub rbp: u64, + pub rsi: u64, + pub rdi: 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 fpregs: _fpstate, + pub vregs: [u64; 52], + pub vcx: u64, + pub dbc: u64, + pub btr: u64, + pub bfr: u64, + pub etr: u64, + pub efr: u64, + pub oldmask: u64, + pub cr2: u64, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigevent { + pub sigev_value: sigval, + pub sigev_signo: c_int, + pub sigev_notify: c_int, + pub sigev_notify_function: Option, + pub sigev_notify_attributes: *mut pthread_attr_t, + } + + #[repr(align(8))] + pub struct ucontext_t { + pub uc_mcontext: mcontext_t, + pub uc_link: *mut ucontext_t, + pub uc_sigmask: sigset_t, + pub uc_stack: stack_t, + pub uc_flags: c_ulong, + } + + pub struct sockaddr { + pub sa_family: sa_family_t, + pub sa_data: [c_char; 14], + } + + pub struct sockaddr_storage { + pub ss_family: sa_family_t, + __ss_pad1: Padding<[c_char; 6]>, + __ss_align: i64, + __ss_pad2: Padding<[c_char; 112]>, + } + + 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, + pub st_birthtime: time_t, + pub st_birthtime_nsec: c_long, + } + + 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 in_pktinfo { + pub ipi_addr: in_addr, + pub ipi_ifindex: 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 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 statfs { + pub f_type: c_long, + pub f_bsize: 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: c_long, + pub f_namelen: c_long, + pub f_spare: [c_long; 6], + } + + pub struct sockaddr_un { + pub sun_family: sa_family_t, + pub sun_path: [c_char; 108], + } + + pub struct utsname { + pub sysname: [c_char; 66], + 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 siginfo_t { + pub si_signo: c_int, + pub si_code: c_int, + pub si_pid: pid_t, + pub si_uid: uid_t, + pub si_errno: c_int, + __pad: Padding<[u32; 32]>, + } + + pub struct dirent { + __d_version: u32, + pub d_ino: ino_t, + pub d_type: c_uchar, + __d_unused1: Padding<[c_uchar; 3]>, + __d_internal1: u32, + pub d_name: [c_char; 256], + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4], + } + + pub union __c_anonymous_ifr_ifru { + pub ifru_addr: sockaddr, + pub ifru_broadaddr: sockaddr, + pub ifru_dstaddr: sockaddr, + pub ifru_netmask: sockaddr, + pub ifru_hwaddr: sockaddr, + pub ifru_flags: c_int, + pub ifru_metric: c_int, + pub ifru_mtu: c_int, + pub ifru_ifindex: c_int, + pub ifru_data: *mut c_char, + __ifru_pad: Padding<[c_char; 28]>, + } + + pub struct ifreq { + /// if name, e.g. "en0" + pub ifr_name: [c_char; IFNAMSIZ], + pub ifr_ifru: __c_anonymous_ifr_ifru, + } + + pub union __c_anonymous_ifc_ifcu { + pub ifcu_buf: caddr_t, + pub ifcu_req: *mut ifreq, + } + + pub struct ifconf { + pub ifc_len: c_int, + pub ifc_ifcu: __c_anonymous_ifc_ifcu, + } + + 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; UT_IDLEN], + pub ut_time: time_t, + pub ut_user: [c_char; UT_NAMESIZE], + pub ut_host: [c_char; UT_HOSTSIZE], + pub ut_addr: c_long, + pub ut_tv: timeval, + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut c_void { + #[repr(C)] + struct siginfo_si_addr { + _si_signo: c_int, + _si_code: c_int, + _si_pid: pid_t, + _si_uid: uid_t, + _si_errno: c_int, + si_addr: *mut c_void, + } + (*(self as *const siginfo_t).cast::()).si_addr + } + + pub unsafe fn si_status(&self) -> c_int { + #[repr(C)] + struct siginfo_sigchld { + _si_signo: c_int, + _si_code: c_int, + _si_pid: pid_t, + _si_uid: uid_t, + _si_errno: c_int, + si_status: c_int, + } + (*(self as *const siginfo_t).cast::()).si_status + } + + 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_value(&self) -> sigval { + #[repr(C)] + struct siginfo_si_value { + _si_signo: c_int, + _si_code: c_int, + _si_pid: pid_t, + _si_uid: uid_t, + _si_errno: c_int, + si_value: sigval, + } + (*(self as *const siginfo_t).cast::()).si_value + } +} + +pub const FD_SETSIZE: usize = 1024; + +pub const CPU_SETSIZE: c_int = 0x400; + +// si_code values for SIGBUS signal +pub const BUS_ADRALN: c_int = 25; +pub const BUS_ADRERR: c_int = 26; +pub const BUS_OBJERR: c_int = 27; + +// si_code values for SIGCHLD signal +pub const CLD_EXITED: c_int = 28; +pub const CLD_KILLED: c_int = 29; +pub const CLD_DUMPED: c_int = 30; +pub const CLD_TRAPPED: c_int = 31; +pub const CLD_STOPPED: c_int = 32; +pub const CLD_CONTINUED: c_int = 33; + +pub const SIGEV_SIGNAL: c_int = 0; +pub const SIGEV_NONE: c_int = 1; +pub const SIGEV_THREAD: c_int = 2; + +pub const SA_NOCLDSTOP: c_int = 0x00000001; +pub const SA_NOCLDWAIT: c_int = 0; // FIXME: does not exist on Cygwin! +pub const SA_SIGINFO: c_int = 0x00000002; +pub const SA_RESTART: c_int = 0x10000000; +pub const SA_ONSTACK: c_int = 0x20000000; +pub const SA_NODEFER: c_int = 0x40000000; +pub const SA_RESETHAND: c_int = u32_cast_int(0x80000000); +pub const MINSIGSTKSZ: size_t = 8192; +pub const SIGSTKSZ: size_t = 32768; +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 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 SIGPWR: c_int = 29; +pub const SIGUSR1: c_int = 30; +pub const SIGUSR2: c_int = 31; + +pub const SS_ONSTACK: c_int = 0x1; +pub const SS_DISABLE: c_int = 0x2; + +pub const SIG_SETMASK: c_int = 0; +pub const SIG_BLOCK: c_int = 1; +pub const SIG_UNBLOCK: c_int = 2; + +pub const TIMER_ABSTIME: c_int = 4; +pub const CLOCK_REALTIME_COARSE: clockid_t = 0; +pub const CLOCK_REALTIME: 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: clockid_t = 4; +pub const CLOCK_MONOTONIC_RAW: 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 ITIMER_REAL: c_int = 0; +pub const ITIMER_VIRTUAL: c_int = 1; +pub const ITIMER_PROF: c_int = 2; + +pub const PRIO_PROCESS: c_int = 0; +pub const PRIO_PGRP: c_int = 1; +pub const PRIO_USER: c_int = 2; +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 RLIM_NLIMITS: c_int = 7; +pub const RLIMIT_NLIMITS: c_int = RLIM_NLIMITS; +pub const RLIM_INFINITY: rlim_t = !0; +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 IFF_UP: c_int = 0x1; // interface is up +pub const IFF_BROADCAST: c_int = 0x2; // broadcast address valid +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_MULTICAST: c_int = 0x1000; // supports multicast +pub const IFF_LOWER_UP: c_int = 0x10000; // driver signals L1 up +pub const IFF_DORMANT: c_int = 0x20000; // driver signals dormant + +pub const IF_NAMESIZE: size_t = 44; +pub const IFNAMSIZ: size_t = IF_NAMESIZE; + +pub const FIONREAD: c_int = 0x4008667f; +pub const FIONBIO: c_int = u32_cast_int(0x8004667e); +pub const FIOASYNC: c_int = u32_cast_int(0x8008667d); +pub const FIOCLEX: c_int = 0; // FIXME: does not exist on Cygwin! +pub const SIOCGIFCONF: c_ulong = 0x80107364; +pub const SIOCGIFFLAGS: c_ulong = 0x80507365; +pub const SIOCGIFADDR: c_ulong = 0x80507366; +pub const SIOCGIFBRDADDR: c_ulong = 0x80507367; +pub const SIOCGIFNETMASK: c_ulong = 0x80507368; +pub const SIOCGIFHWADDR: c_ulong = 0x80507369; +pub const SIOCGIFMETRIC: c_ulong = 0x8050736a; +pub const SIOCGIFMTU: c_ulong = 0x8050736b; +pub const SIOCGIFINDEX: c_ulong = 0x8050736c; +pub const SIOGIFINDEX: c_ulong = SIOCGIFINDEX; +pub const SIOCGIFDSTADDR: c_ulong = 0x8050736e; +pub const SOL_SOCKET: c_int = 0xffff; +pub const SO_DEBUG: c_int = 1; +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_PEERCRED: c_int = 0x0200; +pub const SO_PASSCRED: c_int = 0x0400; +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 SCM_CREDENTIALS: c_int = 0x02; +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_NONBLOCK: c_int = 0x01000000; +pub const SOCK_CLOEXEC: c_int = 0x02000000; +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_NETBIOS: c_int = 17; +pub const AF_INET6: c_int = 23; +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_NETBIOS: c_int = AF_NETBIOS; +pub const PF_INET6: c_int = AF_INET6; +pub const SOMAXCONN: c_int = 0x7fffffff; +pub const MSG_OOB: c_int = 0x1; +pub const MSG_PEEK: c_int = 0x2; +pub const MSG_DONTROUTE: c_int = 0x4; +pub const MSG_WAITALL: c_int = 0x8; +pub const MSG_DONTWAIT: c_int = 0x10; +pub const MSG_NOSIGNAL: c_int = 0x20; +pub const MSG_TRUNC: c_int = 0x0100; +pub const MSG_CTRUNC: c_int = 0x0200; +pub const MSG_BCAST: c_int = 0x0400; +pub const MSG_MCAST: c_int = 0x0800; +pub const MSG_CMSG_CLOEXEC: c_int = 0x1000; +pub const MSG_EOR: c_int = 0x8000; +pub const SOL_IP: c_int = 0; +pub const SOL_IPV6: c_int = 41; +pub const SOL_TCP: c_int = 6; +pub const SOL_UDP: c_int = 17; +pub const IPTOS_LOWDELAY: u8 = 0x10; +pub const IPTOS_THROUGHPUT: u8 = 0x08; +pub const IPTOS_RELIABILITY: u8 = 0x04; +pub const IPTOS_LOWCOST: u8 = 0x02; +pub const IPTOS_MINCOST: u8 = IPTOS_LOWCOST; +pub const IP_DEFAULT_MULTICAST_TTL: c_int = 1; +pub const IP_DEFAULT_MULTICAST_LOOP: c_int = 1; +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_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_ADD_SOURCE_MEMBERSHIP: c_int = 15; +pub const IP_DROP_SOURCE_MEMBERSHIP: c_int = 16; +pub const IP_BLOCK_SOURCE: c_int = 17; +pub const IP_UNBLOCK_SOURCE: c_int = 18; +pub const IP_PKTINFO: c_int = 19; +pub const IP_RECVTTL: c_int = 21; +pub const IP_UNICAST_IF: c_int = 31; +pub const IP_RECVTOS: c_int = 40; +pub const IP_MTU_DISCOVER: c_int = 71; +pub const IP_MTU: c_int = 73; +pub const IP_RECVERR: c_int = 75; +pub const IP_PMTUDISC_WANT: c_int = 0; +pub const IP_PMTUDISC_DO: c_int = 1; +pub const IP_PMTUDISC_DONT: c_int = 2; +pub const IP_PMTUDISC_PROBE: c_int = 3; +pub const IPV6_HOPOPTS: c_int = 1; +pub const IPV6_HDRINCL: c_int = 2; +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; +pub const IPV6_JOIN_GROUP: c_int = 12; +pub const IPV6_LEAVE_GROUP: c_int = 13; +pub const IPV6_DONTFRAG: c_int = 14; +pub const IPV6_PKTINFO: c_int = 19; +pub const IPV6_HOPLIMIT: c_int = 21; +pub const IPV6_CHECKSUM: c_int = 26; +pub const IPV6_V6ONLY: c_int = 27; +pub const IPV6_UNICAST_IF: c_int = 31; +pub const IPV6_RTHDR: c_int = 32; +pub const IPV6_RECVRTHDR: c_int = 38; +pub const IPV6_TCLASS: c_int = 39; +pub const IPV6_RECVTCLASS: c_int = 40; +pub const IPV6_MTU_DISCOVER: c_int = 71; +pub const IPV6_MTU: c_int = 72; +pub const IPV6_RECVERR: c_int = 75; +pub const IPV6_PMTUDISC_WANT: c_int = 0; +pub const IPV6_PMTUDISC_DO: c_int = 1; +pub const IPV6_PMTUDISC_DONT: c_int = 2; +pub const IPV6_PMTUDISC_PROBE: c_int = 3; +pub const MCAST_JOIN_GROUP: c_int = 41; +pub const MCAST_LEAVE_GROUP: c_int = 42; +pub const MCAST_BLOCK_SOURCE: c_int = 43; +pub const MCAST_UNBLOCK_SOURCE: c_int = 44; +pub const MCAST_JOIN_SOURCE_GROUP: c_int = 45; +pub const MCAST_LEAVE_SOURCE_GROUP: c_int = 46; +pub const MCAST_INCLUDE: c_int = 0; +pub const MCAST_EXCLUDE: 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 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_IRWXU: mode_t = 448; +pub const S_IRUSR: mode_t = 256; +pub const S_IWUSR: mode_t = 128; +pub const S_IXUSR: mode_t = 64; +pub const S_IRWXG: mode_t = 56; +pub const S_IRGRP: mode_t = 32; +pub const S_IWGRP: mode_t = 16; +pub const S_IXGRP: mode_t = 8; +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 UTIME_NOW: c_long = -2; +pub const UTIME_OMIT: c_long = -1; + +pub const ARG_MAX: c_int = 32000; +pub const CHILD_MAX: c_int = 256; +pub const IOV_MAX: c_int = 1024; +pub const PTHREAD_STACK_MIN: size_t = 65536; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const PATH_MAX: c_int = 4096; + +pub const PIPE_BUF: usize = 4096; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const NGROUPS_MAX: c_int = 1024; + +pub const FILENAME_MAX: c_int = 4096; + +pub const FORK_RELOAD: c_int = 1; +pub const FORK_NO_RELOAD: c_int = 0; + +pub const RTLD_DEFAULT: *mut c_void = ptr::null_mut(); +pub const RTLD_LOCAL: c_int = 0; +pub const RTLD_LAZY: c_int = 1; +pub const RTLD_NOW: c_int = 2; +pub const RTLD_GLOBAL: c_int = 4; +pub const RTLD_NODELETE: c_int = 8; +pub const RTLD_NOLOAD: c_int = 16; +pub const RTLD_DEEPBIND: c_int = 32; + +/// IP6 hop-by-hop options +pub const IPPROTO_HOPOPTS: c_int = 0; + +/// gateway mgmt protocol +pub const IPPROTO_IGMP: c_int = 2; + +/// IPIP tunnels (older KA9Q tunnels use 94) +pub const IPPROTO_IPIP: c_int = 4; + +/// exterior gateway protocol +pub const IPPROTO_EGP: c_int = 8; + +/// pup +pub const IPPROTO_PUP: c_int = 12; + +/// xns idp +pub const IPPROTO_IDP: c_int = 22; + +/// IP6 routing header +pub const IPPROTO_ROUTING: c_int = 43; + +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: c_int = 44; + +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: c_int = 50; + +/// IP6 Auth Header +pub const IPPROTO_AH: c_int = 51; + +/// IP6 no next header +pub const IPPROTO_NONE: c_int = 59; + +/// IP6 destination option +pub const IPPROTO_DSTOPTS: c_int = 60; + +pub const IPPROTO_RAW: c_int = 255; +pub const IPPROTO_MAX: c_int = 256; + +pub const AI_PASSIVE: c_int = 0x1; +pub const AI_CANONNAME: c_int = 0x2; +pub const AI_NUMERICHOST: c_int = 0x4; +pub const AI_NUMERICSERV: c_int = 0x8; +pub const AI_ALL: c_int = 0x100; +pub const AI_ADDRCONFIG: c_int = 0x400; +pub const AI_V4MAPPED: c_int = 0x800; +pub const NI_NOFQDN: c_int = 0x1; +pub const NI_NUMERICHOST: c_int = 0x2; +pub const NI_NAMEREQD: c_int = 0x4; +pub const NI_NUMERICSERV: c_int = 0x8; +pub const NI_DGRAM: c_int = 0x10; +pub const NI_MAXHOST: c_int = 1025; +pub const NI_MAXSERV: c_int = 32; +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 UT_LINESIZE: usize = 16; +pub const UT_NAMESIZE: usize = 16; +pub const UT_HOSTSIZE: usize = 256; +pub const UT_IDLEN: usize = 2; +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 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 = 0x1; +pub const POLLRDBAND: c_short = 0x2; +pub const POLLWRNORM: c_short = 0x4; +pub const POLLWRBAND: c_short = 0x4; + +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_ALL_MASK: c_int = 1 << 0; +pub const LC_COLLATE_MASK: c_int = 1 << 1; +pub const LC_CTYPE_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_MESSAGES_MASK: c_int = 1 << 6; +pub const LC_GLOBAL_LOCALE: locale_t = -1isize as locale_t; + +pub const SEM_FAILED: *mut sem_t = ptr::null_mut(); + +pub const ST_RDONLY: c_ulong = 0x80000; +pub const ST_NOSUID: c_ulong = 0; + +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 TIOCINQ: c_int = 0x541B; +pub const TIOCSCTTY: c_int = 0x540E; +pub const TIOCSBRK: c_int = 0x5427; +pub const TIOCCBRK: c_int = 0x5428; +pub const TIOCM_DTR: c_int = 0x002; +pub const TIOCM_RTS: c_int = 0x004; +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 TCOOFF: c_int = 0; +pub const TCOON: c_int = 1; +pub const TCIOFF: c_int = 2; +pub const TCION: c_int = 3; +pub const TCGETA: c_int = 5; +pub const TCSETA: c_int = 6; +pub const TCSETAW: c_int = 7; +pub const TCSETAF: c_int = 8; +pub const TCIFLUSH: c_int = 0; +pub const TCOFLUSH: c_int = 1; +pub const TCIOFLUSH: c_int = 2; +pub const TCFLSH: c_int = 3; +pub const TCSAFLUSH: c_int = 1; +pub const TCSANOW: c_int = 2; +pub const TCSADRAIN: c_int = 3; +pub const TIOCPKT: c_int = 6; +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 IGNBRK: tcflag_t = 0x00001; +pub const BRKINT: tcflag_t = 0x00002; +pub const IGNPAR: tcflag_t = 0x00004; +pub const IMAXBEL: tcflag_t = 0x00008; +pub const INPCK: tcflag_t = 0x00010; +pub const ISTRIP: tcflag_t = 0x00020; +pub const INLCR: tcflag_t = 0x00040; +pub const IGNCR: tcflag_t = 0x00080; +pub const ICRNL: tcflag_t = 0x00100; +pub const IXON: tcflag_t = 0x00400; +pub const IXOFF: tcflag_t = 0x01000; +pub const IUCLC: tcflag_t = 0x04000; +pub const IXANY: tcflag_t = 0x08000; +pub const PARMRK: tcflag_t = 0x10000; +pub const IUTF8: tcflag_t = 0x20000; +pub const OPOST: tcflag_t = 0x00001; +pub const OLCUC: tcflag_t = 0x00002; +pub const OCRNL: tcflag_t = 0x00004; +pub const ONLCR: tcflag_t = 0x00008; +pub const ONOCR: tcflag_t = 0x00010; +pub const ONLRET: tcflag_t = 0x00020; +pub const OFILL: tcflag_t = 0x00040; +pub const CRDLY: tcflag_t = 0x00180; +pub const CR0: tcflag_t = 0x00000; +pub const CR1: tcflag_t = 0x00080; +pub const CR2: tcflag_t = 0x00100; +pub const CR3: tcflag_t = 0x00180; +pub const NLDLY: tcflag_t = 0x00200; +pub const NL0: tcflag_t = 0x00000; +pub const NL1: tcflag_t = 0x00200; +pub const BSDLY: tcflag_t = 0x00400; +pub const BS0: tcflag_t = 0x00000; +pub const BS1: tcflag_t = 0x00400; +pub const TABDLY: tcflag_t = 0x01800; +pub const TAB0: tcflag_t = 0x00000; +pub const TAB1: tcflag_t = 0x00800; +pub const TAB2: tcflag_t = 0x01000; +pub const TAB3: tcflag_t = 0x01800; +pub const XTABS: tcflag_t = 0x01800; +pub const VTDLY: tcflag_t = 0x02000; +pub const VT0: tcflag_t = 0x00000; +pub const VT1: tcflag_t = 0x02000; +pub const FFDLY: tcflag_t = 0x04000; +pub const FF0: tcflag_t = 0x00000; +pub const FF1: tcflag_t = 0x04000; +pub const OFDEL: tcflag_t = 0x08000; +pub const CBAUD: tcflag_t = 0x0100f; +pub const B0: speed_t = 0x00000; +pub const B50: speed_t = 0x00001; +pub const B75: speed_t = 0x00002; +pub const B110: speed_t = 0x00003; +pub const B134: speed_t = 0x00004; +pub const B150: speed_t = 0x00005; +pub const B200: speed_t = 0x00006; +pub const B300: speed_t = 0x00007; +pub const B600: speed_t = 0x00008; +pub const B1200: speed_t = 0x00009; +pub const B1800: speed_t = 0x0000a; +pub const B2400: speed_t = 0x0000b; +pub const B4800: speed_t = 0x0000c; +pub const B9600: speed_t = 0x0000d; +pub const B19200: speed_t = 0x0000e; +pub const B38400: speed_t = 0x0000f; +pub const CSIZE: tcflag_t = 0x00030; +pub const CS5: tcflag_t = 0x00000; +pub const CS6: tcflag_t = 0x00010; +pub const CS7: tcflag_t = 0x00020; +pub const CS8: tcflag_t = 0x00030; +pub const CSTOPB: tcflag_t = 0x00040; +pub const CREAD: tcflag_t = 0x00080; +pub const PARENB: tcflag_t = 0x00100; +pub const PARODD: tcflag_t = 0x00200; +pub const HUPCL: tcflag_t = 0x00400; +pub const CLOCAL: tcflag_t = 0x00800; +pub const CBAUDEX: tcflag_t = 0x0100f; +pub const B57600: speed_t = 0x01001; +pub const B115200: speed_t = 0x01002; +pub const B230400: speed_t = 0x01004; +pub const B460800: speed_t = 0x01006; +pub const B500000: speed_t = 0x01007; +pub const B576000: speed_t = 0x01008; +pub const B921600: speed_t = 0x01009; +pub const B1000000: speed_t = 0x0100a; +pub const B1152000: speed_t = 0x0100b; +pub const B1500000: speed_t = 0x0100c; +pub const B2000000: speed_t = 0x0100d; +pub const B2500000: speed_t = 0x0100e; +pub const B3000000: speed_t = 0x0100f; +pub const CRTSCTS: tcflag_t = 0x08000; +pub const CMSPAR: tcflag_t = 0x40000000; +pub const ISIG: tcflag_t = 0x0001; +pub const ICANON: tcflag_t = 0x0002; +pub const ECHO: tcflag_t = 0x0004; +pub const ECHOE: tcflag_t = 0x0008; +pub const ECHOK: tcflag_t = 0x0010; +pub const ECHONL: tcflag_t = 0x0020; +pub const NOFLSH: tcflag_t = 0x0040; +pub const TOSTOP: tcflag_t = 0x0080; +pub const IEXTEN: tcflag_t = 0x0100; +pub const FLUSHO: tcflag_t = 0x0200; +pub const ECHOKE: tcflag_t = 0x0400; +pub const ECHOCTL: tcflag_t = 0x0800; +pub const VDISCARD: usize = 1; +pub const VEOL: usize = 2; +pub const VEOL2: usize = 3; +pub const VEOF: usize = 4; +pub const VERASE: usize = 5; +pub const VINTR: usize = 6; +pub const VKILL: usize = 7; +pub const VLNEXT: usize = 8; +pub const VMIN: usize = 9; +pub const VQUIT: usize = 10; +pub const VREPRINT: usize = 11; +pub const VSTART: usize = 12; +pub const VSTOP: usize = 13; +pub const VSUSP: usize = 14; +pub const VSWTC: usize = 15; +pub const VTIME: usize = 16; +pub const VWERASE: usize = 17; +pub const NCCS: usize = 18; + +pub const TIOCGWINSZ: c_int = 0x5401; +pub const TIOCSWINSZ: c_int = 0x5402; +pub const TIOCLINUX: c_int = 0x5403; +pub const TIOCGPGRP: c_int = 0x540f; +pub const TIOCSPGRP: c_int = 0x5410; + +pub const WNOHANG: c_int = 1; +pub const WUNTRACED: c_int = 2; +pub const WCONTINUED: c_int = 8; + +pub const EXIT_FAILURE: c_int = 1; +pub const EXIT_SUCCESS: c_int = 0; + +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_TYPE: c_int = 0xf; +pub const MAP_FIXED: c_int = 0x10; +pub const MAP_ANON: c_int = 0x20; +pub const MAP_ANONYMOUS: c_int = MAP_ANON; +pub const MAP_NORESERVE: c_int = 0x4000; +pub const MAP_FAILED: *mut c_void = !0 as *mut c_void; +pub const MS_ASYNC: c_int = 1; +pub const MS_SYNC: c_int = 2; +pub const MS_INVALIDATE: c_int = 4; +pub const POSIX_MADV_NORMAL: c_int = 0; +pub const POSIX_MADV_SEQUENTIAL: c_int = 1; +pub const POSIX_MADV_RANDOM: c_int = 2; +pub const POSIX_MADV_WILLNEED: c_int = 3; +pub const POSIX_MADV_DONTNEED: c_int = 4; +pub const MADV_NORMAL: c_int = 0; +pub const MADV_SEQUENTIAL: c_int = 1; +pub const MADV_RANDOM: c_int = 2; +pub const MADV_WILLNEED: c_int = 3; +pub const MADV_DONTNEED: c_int = 4; + +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 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 _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 = 5; +pub const _SC_SAVED_IDS: c_int = 6; +pub const _SC_VERSION: c_int = 7; +pub const _SC_PAGESIZE: c_int = 8; +pub const _SC_PAGE_SIZE: c_int = _SC_PAGESIZE; +pub const _SC_NPROCESSORS_CONF: c_int = 9; +pub const _SC_NPROCESSORS_ONLN: c_int = 10; +pub const _SC_PHYS_PAGES: c_int = 11; +pub const _SC_AVPHYS_PAGES: c_int = 12; +pub const _SC_MQ_OPEN_MAX: c_int = 13; +pub const _SC_MQ_PRIO_MAX: c_int = 14; +pub const _SC_RTSIG_MAX: c_int = 15; +pub const _SC_SEM_NSEMS_MAX: c_int = 16; +pub const _SC_SEM_VALUE_MAX: c_int = 17; +pub const _SC_SIGQUEUE_MAX: c_int = 18; +pub const _SC_TIMER_MAX: c_int = 19; +pub const _SC_TZNAME_MAX: c_int = 20; +pub const _SC_ASYNCHRONOUS_IO: c_int = 21; +pub const _SC_FSYNC: c_int = 22; +pub const _SC_MAPPED_FILES: c_int = 23; +pub const _SC_MEMLOCK: c_int = 24; +pub const _SC_MEMLOCK_RANGE: c_int = 25; +pub const _SC_MEMORY_PROTECTION: c_int = 26; +pub const _SC_MESSAGE_PASSING: c_int = 27; +pub const _SC_PRIORITIZED_IO: c_int = 28; +pub const _SC_REALTIME_SIGNALS: c_int = 29; +pub const _SC_SEMAPHORES: c_int = 30; +pub const _SC_SHARED_MEMORY_OBJECTS: c_int = 31; +pub const _SC_SYNCHRONIZED_IO: c_int = 32; +pub const _SC_TIMERS: c_int = 33; +pub const _SC_AIO_LISTIO_MAX: c_int = 34; +pub const _SC_AIO_MAX: c_int = 35; +pub const _SC_AIO_PRIO_DELTA_MAX: c_int = 36; +pub const _SC_DELAYTIMER_MAX: c_int = 37; +pub const _SC_THREAD_KEYS_MAX: c_int = 38; +pub const _SC_THREAD_STACK_MIN: c_int = 39; +pub const _SC_THREAD_THREADS_MAX: c_int = 40; +pub const _SC_TTY_NAME_MAX: c_int = 41; +pub const _SC_THREADS: c_int = 42; +pub const _SC_THREAD_ATTR_STACKADDR: c_int = 43; +pub const _SC_THREAD_ATTR_STACKSIZE: c_int = 44; +pub const _SC_THREAD_PRIORITY_SCHEDULING: c_int = 45; +pub const _SC_THREAD_PRIO_INHERIT: c_int = 46; +pub const _SC_THREAD_PRIO_PROTECT: c_int = 47; +pub const _SC_THREAD_PRIO_CEILING: c_int = _SC_THREAD_PRIO_PROTECT; +pub const _SC_THREAD_PROCESS_SHARED: c_int = 48; +pub const _SC_THREAD_SAFE_FUNCTIONS: c_int = 49; +pub const _SC_GETGR_R_SIZE_MAX: c_int = 50; +pub const _SC_GETPW_R_SIZE_MAX: c_int = 51; +pub const _SC_LOGIN_NAME_MAX: c_int = 52; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: c_int = 53; +pub const _SC_ADVISORY_INFO: c_int = 54; +pub const _SC_ATEXIT_MAX: c_int = 55; +pub const _SC_BARRIERS: c_int = 56; +pub const _SC_BC_BASE_MAX: c_int = 57; +pub const _SC_BC_DIM_MAX: c_int = 58; +pub const _SC_BC_SCALE_MAX: c_int = 59; +pub const _SC_BC_STRING_MAX: c_int = 60; +pub const _SC_CLOCK_SELECTION: c_int = 61; +pub const _SC_COLL_WEIGHTS_MAX: c_int = 62; +pub const _SC_CPUTIME: c_int = 63; +pub const _SC_EXPR_NEST_MAX: c_int = 64; +pub const _SC_HOST_NAME_MAX: c_int = 65; +pub const _SC_IOV_MAX: c_int = 66; +pub const _SC_IPV6: c_int = 67; +pub const _SC_LINE_MAX: c_int = 68; +pub const _SC_MONOTONIC_CLOCK: c_int = 69; +pub const _SC_RAW_SOCKETS: c_int = 70; +pub const _SC_READER_WRITER_LOCKS: c_int = 71; +pub const _SC_REGEXP: c_int = 72; +pub const _SC_RE_DUP_MAX: c_int = 73; +pub const _SC_SHELL: c_int = 74; +pub const _SC_SPAWN: c_int = 75; +pub const _SC_SPIN_LOCKS: c_int = 76; +pub const _SC_SPORADIC_SERVER: c_int = 77; +pub const _SC_SS_REPL_MAX: c_int = 78; +pub const _SC_SYMLOOP_MAX: c_int = 79; +pub const _SC_THREAD_CPUTIME: c_int = 80; +pub const _SC_THREAD_SPORADIC_SERVER: c_int = 81; +pub const _SC_TIMEOUTS: c_int = 82; +pub const _SC_TRACE: c_int = 83; +pub const _SC_TRACE_EVENT_FILTER: c_int = 84; +pub const _SC_TRACE_EVENT_NAME_MAX: c_int = 85; +pub const _SC_TRACE_INHERIT: c_int = 86; +pub const _SC_TRACE_LOG: c_int = 87; +pub const _SC_TRACE_NAME_MAX: c_int = 88; +pub const _SC_TRACE_SYS_MAX: c_int = 89; +pub const _SC_TRACE_USER_EVENT_MAX: c_int = 90; +pub const _SC_TYPED_MEMORY_OBJECTS: c_int = 91; +pub const _SC_V7_ILP32_OFF32: c_int = 92; +pub const _SC_V6_ILP32_OFF32: c_int = _SC_V7_ILP32_OFF32; +pub const _SC_XBS5_ILP32_OFF32: c_int = _SC_V7_ILP32_OFF32; +pub const _SC_V7_ILP32_OFFBIG: c_int = 93; +pub const _SC_V6_ILP32_OFFBIG: c_int = _SC_V7_ILP32_OFFBIG; +pub const _SC_XBS5_ILP32_OFFBIG: c_int = _SC_V7_ILP32_OFFBIG; +pub const _SC_V7_LP64_OFF64: c_int = 94; +pub const _SC_V6_LP64_OFF64: c_int = _SC_V7_LP64_OFF64; +pub const _SC_XBS5_LP64_OFF64: c_int = _SC_V7_LP64_OFF64; +pub const _SC_V7_LPBIG_OFFBIG: c_int = 95; +pub const _SC_V6_LPBIG_OFFBIG: c_int = _SC_V7_LPBIG_OFFBIG; +pub const _SC_XBS5_LPBIG_OFFBIG: c_int = _SC_V7_LPBIG_OFFBIG; +pub const _SC_XOPEN_CRYPT: c_int = 96; +pub const _SC_XOPEN_ENH_I18N: c_int = 97; +pub const _SC_XOPEN_LEGACY: c_int = 98; +pub const _SC_XOPEN_REALTIME: c_int = 99; +pub const _SC_STREAM_MAX: c_int = 100; +pub const _SC_PRIORITY_SCHEDULING: c_int = 101; +pub const _SC_XOPEN_REALTIME_THREADS: c_int = 102; +pub const _SC_XOPEN_SHM: c_int = 103; +pub const _SC_XOPEN_STREAMS: c_int = 104; +pub const _SC_XOPEN_UNIX: c_int = 105; +pub const _SC_XOPEN_VERSION: c_int = 106; +pub const _SC_2_CHAR_TERM: c_int = 107; +pub const _SC_2_C_BIND: c_int = 108; +pub const _SC_2_C_DEV: c_int = 109; +pub const _SC_2_FORT_DEV: c_int = 110; +pub const _SC_2_FORT_RUN: c_int = 111; +pub const _SC_2_LOCALEDEF: c_int = 112; +pub const _SC_2_PBS: c_int = 113; +pub const _SC_2_PBS_ACCOUNTING: c_int = 114; +pub const _SC_2_PBS_CHECKPOINT: c_int = 115; +pub const _SC_2_PBS_LOCATE: c_int = 116; +pub const _SC_2_PBS_MESSAGE: c_int = 117; +pub const _SC_2_PBS_TRACK: c_int = 118; +pub const _SC_2_SW_DEV: c_int = 119; +pub const _SC_2_UPE: c_int = 120; +pub const _SC_2_VERSION: c_int = 121; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: c_int = 122; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: c_int = 123; +pub const _SC_XOPEN_UUCP: c_int = 124; +pub const _SC_LEVEL1_ICACHE_SIZE: c_int = 125; +pub const _SC_LEVEL1_ICACHE_ASSOC: c_int = 126; +pub const _SC_LEVEL1_ICACHE_LINESIZE: c_int = 127; +pub const _SC_LEVEL1_DCACHE_SIZE: c_int = 128; +pub const _SC_LEVEL1_DCACHE_ASSOC: c_int = 129; +pub const _SC_LEVEL1_DCACHE_LINESIZE: c_int = 130; +pub const _SC_LEVEL2_CACHE_SIZE: c_int = 131; +pub const _SC_LEVEL2_CACHE_ASSOC: c_int = 132; +pub const _SC_LEVEL2_CACHE_LINESIZE: c_int = 133; +pub const _SC_LEVEL3_CACHE_SIZE: c_int = 134; +pub const _SC_LEVEL3_CACHE_ASSOC: c_int = 135; +pub const _SC_LEVEL3_CACHE_LINESIZE: c_int = 136; +pub const _SC_LEVEL4_CACHE_SIZE: c_int = 137; +pub const _SC_LEVEL4_CACHE_ASSOC: c_int = 138; +pub const _SC_LEVEL4_CACHE_LINESIZE: c_int = 139; +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_ASYNC_IO: c_int = 9; +pub const _PC_PRIO_IO: c_int = 10; +pub const _PC_SYNC_IO: c_int = 11; +pub const _PC_FILESIZEBITS: c_int = 12; +pub const _PC_2_SYMLINKS: c_int = 13; +pub const _PC_SYMLINK_MAX: c_int = 14; +pub const _PC_ALLOC_SIZE_MIN: c_int = 15; +pub const _PC_REC_INCR_XFER_SIZE: c_int = 16; +pub const _PC_REC_MAX_XFER_SIZE: c_int = 17; +pub const _PC_REC_MIN_XFER_SIZE: c_int = 18; +pub const _PC_REC_XFER_ALIGN: c_int = 19; +pub const _PC_TIMESTAMP_RESOLUTION: c_int = 20; +pub const _CS_PATH: c_int = 0; + +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 = 0x0008; +pub const O_CREAT: c_int = 0x0200; +pub const O_TRUNC: c_int = 0x0400; +pub const O_EXCL: c_int = 0x0800; +pub const O_SYNC: c_int = 0x2000; +pub const O_NONBLOCK: c_int = 0x4000; +pub const O_NOCTTY: c_int = 0x8000; +pub const O_CLOEXEC: c_int = 0x40000; +pub const O_NOFOLLOW: c_int = 0x100000; +pub const O_DIRECTORY: c_int = 0x200000; +pub const O_EXEC: c_int = 0x400000; +pub const O_SEARCH: c_int = 0x400000; +pub const O_DIRECT: c_int = 0x80000; +pub const O_DSYNC: c_int = 0x2000; +pub const O_RSYNC: c_int = 0x2000; +pub const O_TMPFILE: c_int = 0x800000; +pub const O_NOATIME: c_int = 0x1000000; +pub const O_PATH: c_int = 0x2000000; +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 F_RDLCK: c_int = 1; +pub const F_WRLCK: c_int = 2; +pub const F_UNLCK: c_int = 3; +pub const AT_FDCWD: c_int = -2; +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 AT_EMPTY_PATH: c_int = 16; +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 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 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 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 EDOTDOT: c_int = 76; +pub const EBADMSG: c_int = 77; +pub const EFTYPE: 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 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 ESHUTDOWN: c_int = 110; +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 ESOCKTNOSUPPORT: c_int = 124; +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 EPROCLIM: c_int = 130; +pub const EUSERS: c_int = 131; +pub const EDQUOT: c_int = 132; +pub const ESTALE: c_int = 133; +pub const ENOTSUP: c_int = 134; +pub const ENOMEDIUM: c_int = 135; +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 ESTRPIPE: c_int = 143; +pub const EWOULDBLOCK: c_int = EAGAIN; /* Operation would block */ + +pub const SCHED_OTHER: c_int = 3; +pub const SCHED_FIFO: c_int = 1; +pub const SCHED_RR: c_int = 2; + +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = 21 as *mut _; +pub const PTHREAD_CREATE_DETACHED: c_int = 1; +pub const PTHREAD_CREATE_JOINABLE: c_int = 0; +pub const PTHREAD_MUTEX_RECURSIVE: c_int = 0; +pub const PTHREAD_MUTEX_ERRORCHECK: c_int = 1; +pub const PTHREAD_MUTEX_NORMAL: c_int = 2; +pub const PTHREAD_MUTEX_DEFAULT: c_int = PTHREAD_MUTEX_NORMAL; +pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: pthread_mutex_t = 18 as *mut _; +pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: pthread_mutex_t = 20 as *mut _; +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = 19 as *mut _; +pub const PTHREAD_PROCESS_SHARED: c_int = 1; +pub const PTHREAD_PROCESS_PRIVATE: c_int = 0; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = 22 as *mut _; + +pub const LITTLE_ENDIAN: c_int = 1234; +pub const BIG_ENDIAN: c_int = 4321; + +pub const TCP_NODELAY: c_int = 1; +pub const TCP_KEEPIDLE: c_int = 3; +pub const TCP_MAXSEG: c_int = 4; +pub const TCP_QUICKACK: c_int = 12; +pub const TCP_USER_TIMEOUT: c_int = 14; +pub const TCP_FASTOPEN: c_int = 15; +pub const TCP_KEEPCNT: c_int = 16; +pub const TCP_KEEPINTVL: c_int = 17; + +pub const WINDOWS_POST: c_int = 0; +pub const WINDOWS_SEND: c_int = 1; +pub const WINDOWS_HWND: c_int = 2; + +pub const MOUNT_TEXT: c_uint = 0x01; +pub const MOUNT_SYSTEM: c_uint = 0x08; +pub const MOUNT_EXEC: c_uint = 0x10; +pub const MOUNT_CYGDRIVE: c_uint = 0x20; +pub const MOUNT_CYGWIN_EXEC: c_uint = 0x40; +pub const MOUNT_SPARSE: c_uint = 0x80; +pub const MOUNT_NOTEXEC: c_uint = 0x100; +pub const MOUNT_DEVFS: c_uint = 0x200; +pub const MOUNT_PROC: c_uint = 0x400; +pub const MOUNT_RO: c_uint = 0x1000; +pub const MOUNT_NOACL: c_uint = 0x2000; +pub const MOUNT_NOPOSIX: c_uint = 0x4000; +pub const MOUNT_OVERRIDE: c_uint = 0x8000; +pub const MOUNT_IMMUTABLE: c_uint = 0x10000; +pub const MOUNT_AUTOMATIC: c_uint = 0x20000; +pub const MOUNT_DOS: c_uint = 0x40000; +pub const MOUNT_IHASH: c_uint = 0x80000; +pub const MOUNT_BIND: c_uint = 0x100000; +pub const MOUNT_USER_TEMP: c_uint = 0x200000; +pub const MOUNT_DONT_USE: c_uint = 0x80000000; + +pub const _POSIX_VDISABLE: cc_t = 0; + +pub const GRND_NONBLOCK: c_uint = 0x1; +pub const GRND_RANDOM: c_uint = 0x2; + +pub const _IOFBF: c_int = 0; +pub const _IOLBF: c_int = 1; +pub const _IONBF: c_int = 2; +pub const BUFSIZ: c_int = 1024; + +pub const POSIX_SPAWN_RESETIDS: c_int = 0x01; +pub const POSIX_SPAWN_SETPGROUP: c_int = 0x02; +pub const POSIX_SPAWN_SETSCHEDPARAM: c_int = 0x04; +pub const POSIX_SPAWN_SETSCHEDULER: c_int = 0x08; +pub const POSIX_SPAWN_SETSIGDEF: c_int = 0x10; +pub const POSIX_SPAWN_SETSIGMASK: c_int = 0x20; + +pub const POSIX_FADV_NORMAL: c_int = 0; +pub const POSIX_FADV_SEQUENTIAL: c_int = 1; +pub const POSIX_FADV_RANDOM: 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 FALLOC_FL_PUNCH_HOLE: c_int = 0x0001; +pub const FALLOC_FL_ZERO_RANGE: c_int = 0x0002; +pub const FALLOC_FL_UNSHARE_RANGE: c_int = 0x0004; +pub const FALLOC_FL_COLLAPSE_RANGE: c_int = 0x0008; +pub const FALLOC_FL_INSERT_RANGE: c_int = 0x0010; +pub const FALLOC_FL_KEEP_SIZE: c_int = 0x1000; + +f! { + pub unsafe fn FD_CLR(fd: c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] &= !(1 << (fd % size)); + } + + pub unsafe fn FD_ISSET(fd: c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 + } + + pub unsafe fn FD_SET(fd: c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] |= 1 << (fd % size); + } + + pub unsafe fn FD_ZERO(set: *mut fd_set) -> () { + (*set).fds_bits.fill(0); + } + + pub unsafe fn CPU_ALLOC_SIZE(count: c_int) -> size_t { + let _dummy: cpu_set_t = cpu_set_t { bits: [0; 16] }; + let size_in_bits = 8 * size_of_val(&_dummy.bits[0]); + ((count as size_t + size_in_bits - 1) / 8) as size_t + } + + pub unsafe fn CPU_COUNT_S(size: usize, cpuset: &cpu_set_t) -> c_int { + let mut s: u32 = 0; + let size_of_mask = 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 unsafe fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + cpuset.bits.fill(0); + } + + pub unsafe fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); + if cpu < size_in_bits { + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] |= 1 << offset; + } + } + + pub unsafe fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); + if cpu < size_in_bits { + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] &= !(1 << offset); + } + } + + pub unsafe fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); + if cpu < size_in_bits { + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + 0 != (cpuset.bits[idx] & (1 << offset)) + } else { + false + } + } + + pub unsafe fn CPU_COUNT(cpuset: &cpu_set_t) -> c_int { + CPU_COUNT_S(size_of::(), cpuset) + } + + pub unsafe fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.bits == set2.bits + } + + pub unsafe fn CMSG_LEN(length: c_uint) -> c_uint { + CMSG_ALIGN(size_of::()) as c_uint + length + } + + pub const unsafe fn CMSG_SPACE(length: c_uint) -> c_uint { + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(size_of::())) as c_uint + } + + pub unsafe fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize >= size_of::() { + (*mhdr).msg_control.cast() + } else { + ptr::null_mut() + } + } + + pub unsafe fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *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 as usize + CMSG_ALIGN(size_of::()) as usize > max { + ptr::null_mut() + } else { + next + } + } + + pub unsafe fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + cmsg.offset(1).cast_mut().cast() + } +} + +safe_f! { + pub const safe fn makedev(ma: c_uint, mi: c_uint) -> dev_t { + let ma = ma as dev_t; + let mi = mi as dev_t; + (ma << 16) | (mi & 0xffff) + } + + pub const safe fn major(dev: dev_t) -> c_uint { + ((dev >> 16) & 0xffff) as c_uint + } + + pub const safe fn minor(dev: dev_t) -> c_uint { + (dev & 0xffff) as c_uint + } + + pub const safe fn WIFEXITED(status: c_int) -> bool { + (status & 0xff) == 0 + } + + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 + } + + pub const safe fn WIFSTOPPED(status: c_int) -> bool { + (status & 0xff) == 0o177 + } + + pub const safe fn WIFCONTINUED(status: c_int) -> bool { + (status & 0o177777) == 0o177777 + } + + pub const safe fn WEXITSTATUS(status: c_int) -> c_int { + (status >> 8) & 0xff + } + + pub const safe fn WTERMSIG(status: c_int) -> c_int { + status & 0o177 + } + + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + (status >> 8) & 0xff + } + + pub const safe fn WCOREDUMP(status: c_int) -> bool { + WIFSIGNALED(status) && (status & 0x80) != 0 + } +} + +const fn CMSG_ALIGN(len: usize) -> usize { + len + size_of::() - 1 & !(size_of::() - 1) +} + +extern "C" { + 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 pthread_sigmask(how: c_int, set: *const sigset_t, oldset: *mut sigset_t) -> c_int; + pub fn sigsuspend(mask: *const sigset_t) -> c_int; + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> c_int; + pub fn pthread_kill(thread: pthread_t, sig: c_int) -> c_int; + + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const timespec, + ) -> c_int; + + pub fn strftime(s: *mut c_char, max: size_t, format: *const c_char, tm: *const tm) -> size_t; + + 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 strptime(s: *const c_char, format: *const c_char, tm: *mut tm) -> *mut c_char; + pub fn clock_settime(clk_id: clockid_t, tp: *const timespec) -> c_int; + pub fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int; + pub fn clock_getres(clk_id: clockid_t, tp: *mut timespec) -> 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_settime( + timerid: timer_t, + flags: c_int, + new_value: *const itimerspec, + old_value: *mut itimerspec, + ) -> c_int; + + pub fn timer_gettime(timerid: timer_t, curr_value: *mut itimerspec) -> c_int; + pub fn timer_getoverrun(timerid: timer_t) -> c_int; + + pub fn clock_nanosleep( + clk_id: clockid_t, + flags: c_int, + rqtp: *const timespec, + rmtp: *mut timespec, + ) -> c_int; + + pub fn clock_getcpuclockid(pid: pid_t, clk_id: *mut clockid_t) -> c_int; + + pub fn futimes(fd: c_int, times: *const timeval) -> c_int; + pub fn lutimes(file: *const c_char, times: *const timeval) -> c_int; + pub fn settimeofday(tv: *const timeval, tz: *const timezone) -> 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 gettimeofday(tp: *mut timeval, tz: *mut c_void) -> c_int; + pub fn futimesat(fd: c_int, path: *const c_char, times: *const timeval) -> 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 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 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 if_nameindex() -> *mut if_nameindex; + pub fn if_freenameindex(ptr: *mut if_nameindex); + + 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; + + 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 utimensat( + dirfd: 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 dlfork(val: c_int); + + pub fn accept4(s: c_int, addr: *mut sockaddr, addrlen: *mut socklen_t, flags: c_int) -> c_int; + + 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; + + pub fn recvmsg(fd: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t; + pub fn sendmsg(fd: c_int, msg: *const msghdr, flags: c_int) -> ssize_t; + + pub fn getnameinfo( + sa: *const sockaddr, + salen: socklen_t, + host: *mut c_char, + hostlen: socklen_t, + serv: *mut c_char, + sevlen: socklen_t, + flags: c_int, + ) -> c_int; + + pub fn ppoll( + fds: *mut pollfd, + nfds: nfds_t, + timeout: *const timespec, + sigmask: *const sigset_t, + ) -> c_int; + + pub fn newlocale(mask: c_int, locale: *const c_char, base: locale_t) -> locale_t; + pub fn freelocale(loc: locale_t); + pub fn duplocale(base: locale_t) -> locale_t; + pub fn uselocale(loc: locale_t) -> locale_t; + + 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_open(name: *const c_char, oflag: c_int, ...) -> *mut sem_t; + pub fn sem_close(sem: *mut sem_t) -> c_int; + pub fn sem_unlink(name: *const c_char) -> 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 clearenv() -> c_int; + pub fn ptsname_r(fd: c_int, buf: *mut c_char, buflen: size_t) -> c_int; + pub fn getpt() -> c_int; + pub fn memalign(align: size_t, size: size_t) -> *mut c_void; + pub fn getloadavg(loadavg: *mut c_double, nelem: c_int) -> c_int; + + pub fn abs(i: c_int) -> c_int; + pub fn arc4random() -> u32; + pub fn arc4random_uniform(l: u32) -> u32; + pub fn arc4random_buf(buf: *mut c_void, size: size_t); + pub fn labs(i: c_long) -> c_long; + 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 rand() -> c_int; + pub fn reallocarray(ptr: *mut c_void, nmemb: size_t, size: size_t) -> *mut c_void; + pub fn reallocf(ptr: *mut c_void, size: size_t) -> *mut c_void; + pub fn srand(seed: c_uint); + pub fn drand48() -> c_double; + pub fn erand48(xseed: *mut c_ushort) -> c_double; + pub fn jrand48(xseed: *mut c_ushort) -> c_long; + pub fn lcong48(p: *mut c_ushort); + pub fn lrand48() -> c_long; + pub fn mrand48() -> c_long; + pub fn nrand48(xseed: *mut c_ushort) -> c_long; + pub fn seed48(xseed: *mut c_ushort) -> *mut c_ushort; + pub fn srand48(seed: c_long); + + pub fn qsort_r( + base: *mut c_void, + num: size_t, + size: size_t, + compar: Option c_int>, + arg: *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 posix_madvise(addr: *mut c_void, len: size_t, advice: c_int) -> c_int; + pub fn madvise(addr: *mut c_void, len: size_t, advice: 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 explicit_bzero(s: *mut c_void, len: size_t); + 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 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 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 memmem( + haystack: *const c_void, + haystacklen: size_t, + needle: *const c_void, + needlelen: size_t, + ) -> *mut c_void; + + pub fn memrchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; + #[link_name = "__xpg_strerror_r"] + pub fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t) -> c_int; + pub fn strsep(string: *mut *mut c_char, delim: *const c_char) -> *mut c_char; + + #[link_name = "__gnu_basename"] + pub fn basename(path: *const c_char) -> *mut c_char; + + pub fn daemon(nochdir: c_int, noclose: c_int) -> c_int; + pub fn dup3(src: c_int, dst: c_int, flags: c_int) -> c_int; + pub fn eaccess(pathname: *const c_char, mode: c_int) -> c_int; + pub fn euidaccess(pathname: *const c_char, mode: c_int) -> c_int; + + pub fn execvpe( + file: *const c_char, + argv: *const *mut c_char, + envp: *const *mut c_char, + ) -> c_int; + + pub fn faccessat(dirfd: c_int, pathname: *const c_char, mode: c_int, flags: c_int) -> c_int; + + pub fn fexecve(fd: c_int, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int; + + pub fn fdatasync(fd: c_int) -> c_int; + pub fn getdomainname(name: *mut c_char, len: size_t) -> c_int; + pub fn getentropy(buf: *mut c_void, buflen: size_t) -> c_int; + pub fn gethostid() -> c_long; + pub fn getpagesize() -> c_int; + pub fn getpeereid(socket: c_int, euid: *mut uid_t, egid: *mut gid_t) -> c_int; + + pub fn pthread_atfork( + prepare: Option, + parent: Option, + child: Option, + ) -> c_int; + + pub fn pipe2(fds: *mut c_int, flags: c_int) -> c_int; + pub fn sbrk(increment: intptr_t) -> *mut c_void; + pub fn setgroups(ngroups: c_int, ptr: *const gid_t) -> c_int; + pub fn sethostname(name: *const c_char, len: size_t) -> c_int; + pub fn vhangup() -> c_int; + pub fn getdtablesize() -> c_int; + pub fn sync(); + + pub fn __errno() -> *mut 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_setscheduler(pid: pid_t, policy: c_int, param: *const 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, t: *mut timespec) -> c_int; + pub fn sched_getcpu() -> 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, cpuset: *const cpu_set_t) -> c_int; + + pub fn pthread_attr_getguardsize(attr: *const pthread_attr_t, guardsize: *mut size_t) -> c_int; + + pub fn pthread_attr_getschedparam( + attr: *const pthread_attr_t, + param: *mut sched_param, + ) -> c_int; + + pub fn pthread_attr_setschedparam( + attr: *mut pthread_attr_t, + param: *const 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_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_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_barrierattr_getpshared( + attr: *const pthread_barrierattr_t, + shared: *mut c_int, + ) -> c_int; + + pub fn pthread_barrierattr_destroy(attr: *mut pthread_barrierattr_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_destroy(barrier: *mut pthread_barrier_t) -> c_int; + pub fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -> 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_getcpuclockid(thread: pthread_t, clk_id: *mut clockid_t) -> c_int; + + pub fn pthread_getschedparam( + native: pthread_t, + policy: *mut c_int, + param: *mut sched_param, + ) -> 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_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_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; + + 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( + native: 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_getaffinity_np( + thread: pthread_t, + cpusetsize: size_t, + cpuset: *mut cpu_set_t, + ) -> c_int; + + pub fn pthread_getattr_np(native: pthread_t, attr: *mut pthread_attr_t) -> c_int; + pub fn pthread_getname_np(thread: pthread_t, name: *mut c_char, len: size_t) -> c_int; + + pub fn pthread_setaffinity_np( + thread: pthread_t, + cpusetsize: size_t, + cpuset: *const cpu_set_t, + ) -> c_int; + + pub fn pthread_setname_np(thread: pthread_t, name: *const c_char) -> c_int; + pub fn pthread_sigqueue(thread: pthread_t, sig: c_int, value: sigval) -> c_int; + + pub fn ioctl(fd: c_int, request: c_int, ...) -> c_int; + + pub fn getrandom(buf: *mut c_void, buflen: size_t, flags: c_uint) -> ssize_t; + + pub fn mount(src: *const c_char, target: *const c_char, flags: c_uint) -> c_int; + + pub fn umount(target: *const c_char) -> c_int; + pub fn cygwin_umount(target: *const c_char, flags: c_uint) -> c_int; + + 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 uname(buf: *mut utsname) -> 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 posix_spawn_file_actions_addchdir( + actions: *mut crate::posix_spawn_file_actions_t, + path: *const c_char, + ) -> c_int; + pub fn posix_spawn_file_actions_addfchdir( + actions: *mut crate::posix_spawn_file_actions_t, + fd: c_int, + ) -> c_int; + pub fn posix_spawn_file_actions_addchdir_np( + actions: *mut crate::posix_spawn_file_actions_t, + path: *const c_char, + ) -> c_int; + pub fn posix_spawn_file_actions_addfchdir_np( + actions: *mut crate::posix_spawn_file_actions_t, + fd: c_int, + ) -> c_int; + + pub fn forkpty( + amaster: *mut c_int, + name: *mut c_char, + termp: *const termios, + winp: *const crate::winsize, + ) -> crate::pid_t; + pub fn openpty( + amaster: *mut c_int, + aslave: *mut c_int, + name: *mut c_char, + termp: *const termios, + winp: *const crate::winsize, + ) -> c_int; + + pub fn getgrgid(gid: crate::gid_t) -> *mut crate::group; + pub fn getgrgid_r( + gid: crate::gid_t, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn getgrouplist( + user: *const c_char, + group: crate::gid_t, + groups: *mut crate::gid_t, + ngroups: *mut c_int, + ) -> c_int; + pub fn getgrnam(name: *const c_char) -> *mut crate::group; + pub fn getgrnam_r( + name: *const c_char, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn initgroups(user: *const c_char, group: crate::gid_t) -> 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 posix_fadvise(fd: c_int, offset: off_t, len: off_t, advise: c_int) -> c_int; + pub fn posix_fallocate(fd: c_int, offset: off_t, len: off_t) -> c_int; + pub fn fallocate(fd: c_int, mode: c_int, offset: off_t, len: off_t) -> c_int; + + pub fn endutxent(); + pub fn getutxent() -> *mut utmpx; + pub fn getutxid(id: *const utmpx) -> *mut utmpx; + pub fn getutxline(line: *const utmpx) -> *mut utmpx; + pub fn pututxline(utmpx: *const utmpx) -> *mut utmpx; + pub fn setutxent(); + pub fn utmpxname(file: *const c_char) -> c_int; + pub fn updwtmpx(file: *const c_char, utmpx: *const utmpx); +} diff --git a/vendor/libc/src/unix/haiku/b32.rs b/vendor/libc/src/unix/haiku/b32.rs new file mode 100644 index 0000000..1aa27e6 --- /dev/null +++ b/vendor/libc/src/unix/haiku/b32.rs @@ -0,0 +1,18 @@ +pub type time_t = i32; + +pub type Elf_Addr = crate::Elf32_Addr; +pub type Elf_Half = crate::Elf32_Half; +pub type Elf_Phdr = crate::Elf32_Phdr; + +s! { + pub struct Elf32_Phdr { + pub p_type: crate::Elf32_Word, + pub p_offset: crate::Elf32_Off, + pub p_vaddr: crate::Elf32_Addr, + pub p_paddr: crate::Elf32_Addr, + pub p_filesz: crate::Elf32_Word, + pub p_memsz: crate::Elf32_Word, + pub p_flags: crate::Elf32_Word, + pub p_align: crate::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..3355241 --- /dev/null +++ b/vendor/libc/src/unix/haiku/b64.rs @@ -0,0 +1,18 @@ +pub type time_t = i64; + +pub type Elf_Addr = crate::Elf64_Addr; +pub type Elf_Half = crate::Elf64_Half; +pub type Elf_Phdr = crate::Elf64_Phdr; + +s! { + pub struct Elf64_Phdr { + pub p_type: crate::Elf64_Word, + pub p_flags: crate::Elf64_Word, + pub p_offset: crate::Elf64_Off, + pub p_vaddr: crate::Elf64_Addr, + pub p_paddr: crate::Elf64_Addr, + pub p_filesz: crate::Elf64_Xword, + pub p_memsz: crate::Elf64_Xword, + pub p_align: crate::Elf64_Xword, + } +} diff --git a/vendor/libc/src/unix/haiku/bsd.rs b/vendor/libc/src/unix/haiku/bsd.rs new file mode 100644 index 0000000..1e3881e --- /dev/null +++ b/vendor/libc/src/unix/haiku/bsd.rs @@ -0,0 +1,151 @@ +//! This file contains the BSD APIs available in Haiku. It corresponds to the +//! header files in `headers/compatibility/bsd`. +//! +//! Note that Haiku's BSD compatibility is a combination of system APIs and +//! utility libraries. There should only be system APIs in `libc`. When you are +//! trying to determine whether something should be included in this file, the +//! best indicator is whether it also exists in the BSD-specific definitions in +//! this libc crate. + +use crate::prelude::*; + +// stringlist.h (utility library) +// Note: this is kept because it was previously introduced +pub type StringList = _stringlist; + +s! { + // stringlist.h (utility library) + // Note: this is kept because it was previously introduced + pub struct _stringlist { + pub sl_str: *mut *mut c_char, + pub sl_max: size_t, + pub sl_cur: size_t, + } + + // sys/event.h + pub struct kevent { + pub ident: crate::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], + } + + // sys/link_elf.h + pub struct dl_phdr_info { + pub dlpi_addr: crate::Elf_Addr, + pub dlpi_name: *const c_char, + pub dlpi_phdr: *const crate::Elf_Phdr, + pub dlpi_phnum: crate::Elf_Half, + } +} + +// sys/event.h +pub const EVFILT_READ: i16 = -1; +pub const EVFILT_WRITE: i16 = -2; +pub const EVFILT_PROC: i16 = -5; +pub const EV_ADD: u16 = 0x0001; +pub const EV_DELETE: u16 = 0x0002; +pub const EV_ONESHOT: u16 = 0x0010; +pub const EV_CLEAR: u16 = 0x0020; +pub const EV_EOF: u16 = 0x8000; +pub const EV_ERROR: u16 = 0x4000; +pub const NOTE_EXIT: u32 = 0x80000000; + +// sys/ioccom.h +pub const IOC_VOID: c_ulong = 0x20000000; +pub const IOC_OUT: c_ulong = 0x40000000; +pub const IOC_IN: c_ulong = 0x80000000; +pub const IOC_INOUT: c_ulong = IOC_IN | IOC_OUT; +pub const IOC_DIRMASK: c_ulong = 0xe0000000; + +#[link(name = "bsd")] +extern "C" { + // stdlib.h + pub fn daemon(nochdir: c_int, noclose: c_int) -> c_int; + pub fn getprogname() -> *const c_char; + pub fn setprogname(progname: *const c_char); + 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 mkstemps(template: *mut c_char, suffixlen: c_int) -> c_int; + pub fn strtonum( + nptr: *const c_char, + minval: c_longlong, + maxval: c_longlong, + errstr: *mut *const c_char, + ) -> c_longlong; + + // pty.h + pub fn openpty( + amaster: *mut c_int, + aslave: *mut c_int, + name: *mut c_char, + termp: *mut crate::termios, + winp: *mut crate::winsize, + ) -> c_int; + pub fn login_tty(_fd: c_int) -> c_int; + pub fn forkpty( + amaster: *mut c_int, + name: *mut c_char, + termp: *mut crate::termios, + winp: *mut crate::winsize, + ) -> crate::pid_t; + + // string.h + 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); + + // stringlist.h (utility library) + // Note: this is kept because it was previously introduced + 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; + + // sys/event.h + pub fn kqueue() -> c_int; + pub fn kevent( + kq: c_int, + changelist: *const kevent, + nchanges: c_int, + eventlist: *mut kevent, + nevents: c_int, + timeout: *const crate::timespec, + ) -> c_int; + + // sys/link_elf.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; + + // sys/time.h + pub fn lutimes(file: *const c_char, times: *const crate::timeval) -> c_int; + + // sys/uov.h + pub fn preadv( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: crate::off_t, + ) -> ssize_t; + pub fn pwritev( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: crate::off_t, + ) -> ssize_t; + + // sys/wait.h + pub fn wait4( + pid: crate::pid_t, + status: *mut c_int, + options: c_int, + rusage: *mut crate::rusage, + ) -> crate::pid_t; +} diff --git a/vendor/libc/src/unix/haiku/mod.rs b/vendor/libc/src/unix/haiku/mod.rs new file mode 100644 index 0000000..011fa9f --- /dev/null +++ b/vendor/libc/src/unix/haiku/mod.rs @@ -0,0 +1,1962 @@ +use crate::prelude::*; + +// 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. Additionally, Haiku supports several +// non-POSIX APIs from BSD and GNU, which live in libbsd.so and libgnu.so. These +// modules are also supported. +// +// The module is comprised of the following files: +// - `mod.rs` (this file) implements the C11 and POSIX API found in +// `headers/posix` +// - `b32.rs`, `b64.rs` and `x86_64.rs` contain platform-specific definitions +// of the C11 and POSIX APIs +// - `native.rs` defines the native Haiku API that is implemented in +// `libroot.so` and that are found in `headers/os`. +// - `bsd.rs` defines the BSD customizations available on Haiku found in +// `headers/compatibility/bsd` + +pub type rlim_t = crate::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 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 = crate::uintptr_t; +pub type pthread_condattr_t = crate::uintptr_t; +pub type pthread_mutexattr_t = crate::uintptr_t; +pub type pthread_rwlockattr_t = crate::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; + +extern_ty! { + pub type timezone; +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut c_void { + self.si_addr + } + + pub unsafe fn si_pid(&self) -> crate::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> crate::uid_t { + self.si_uid + } + + pub unsafe fn si_status(&self) -> c_int { + self.si_status + } +} + +s! { + pub struct in_addr { + pub s_addr: crate::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: crate::in_port_t, + pub sin_addr: crate::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: crate::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 crate::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 crate::sockaddr, + pub ifa_netmask: *mut crate::sockaddr, + pub ifa_dstaddr: *mut crate::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 crate::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: crate::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: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: c_char, + pub c_ispeed: crate::speed_t, + pub c_ospeed: crate::speed_t, + pub c_cc: [crate::cc_t; crate::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: crate::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: crate::uid_t, + pub st_gid: crate::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: Padding, + pub gl_offs: size_t, + __unused2: Padding, + pub gl_pathv: *mut *mut c_char, + + __unused3: Padding<*mut c_void>, + __unused4: Padding<*mut c_void>, + __unused5: Padding<*mut c_void>, + __unused6: Padding<*mut c_void>, + __unused7: Padding<*mut c_void>, + __unused8: Padding<*mut c_void>, + } + + pub struct pthread_mutex_t { + flags: u32, + lock: i32, + unused: Padding, + owner: i32, + owner_count: i32, + } + + pub struct pthread_cond_t { + flags: u32, + unused: Padding, + 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: crate::uid_t, + pub pw_gid: crate::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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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: crate::pid_t, + pub si_uid: crate::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: crate::sighandler_t, //actually a union with sa_handler + pub sa_mask: crate::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) + padding: Padding<[i32; 2]>, + } + + pub struct ucred { + pub pid: crate::pid_t, + pub uid: crate::uid_t, + pub gid: crate::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: crate::ipc_perm, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + pub msg_stime: crate::time_t, + pub msg_rtime: crate::time_t, + pub msg_ctime: crate::time_t, + } + + pub struct ipc_perm { + pub key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::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 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: Padding<[u8; 6]>, + __ss_pad2: Padding, + __ss_pad3: Padding<[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: crate::sigval, + __unused1: Padding<*mut c_void>, // actually a function pointer + pub sigev_notify_attributes: *mut crate::pthread_attr_t, + } + + pub struct utmpx { + pub ut_type: c_short, + pub ut_tv: crate::timeval, + pub ut_id: [c_char; 8], + pub ut_pid: crate::pid_t, + pub ut_user: [c_char; 32], + pub ut_line: [c_char; 16], + pub ut_host: [c_char; 128], + __ut_reserved: Padding<[c_char; 64]>, + } +} + +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: crate::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 = 0o1_0000; +pub const S_IFCHR: mode_t = 0o2_0000; +pub const S_IFBLK: mode_t = 0o6_0000; +pub const S_IFDIR: mode_t = 0o4_0000; +pub const S_IFREG: mode_t = 0o10_0000; +pub const S_IFLNK: mode_t = 0o12_0000; +pub const S_IFSOCK: mode_t = 0o14_0000; +pub const S_IFMT: mode_t = 0o17_0000; + +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 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 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): 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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +// DIFF(main): changed to `c_int` in 500365e1 +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 = ptr::null_mut(); + +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: Padding::new(0), + owner: -1, + owner_count: 0, +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + flags: 0, + unused: Padding::new(0), + mutex: ptr::null_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: [ptr::null_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(haiku): 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 SOCK_NONBLOCK: c_int = 0x00040000; +pub const SOCK_CLOEXEC: c_int = 0x00080000; + +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: crate::tcflag_t = 0x01; +pub const BRKINT: crate::tcflag_t = 0x02; +pub const IGNPAR: crate::tcflag_t = 0x04; +pub const PARMRK: crate::tcflag_t = 0x08; +pub const INPCK: crate::tcflag_t = 0x10; +pub const ISTRIP: crate::tcflag_t = 0x20; +pub const INLCR: crate::tcflag_t = 0x40; +pub const IGNCR: crate::tcflag_t = 0x80; +pub const ICRNL: crate::tcflag_t = 0x100; +pub const IUCLC: crate::tcflag_t = 0x200; +pub const IXON: crate::tcflag_t = 0x400; +pub const IXANY: crate::tcflag_t = 0x800; +pub const IXOFF: crate::tcflag_t = 0x1000; + +pub const OPOST: crate::tcflag_t = 0x00000001; +pub const OLCUC: crate::tcflag_t = 0x00000002; +pub const ONLCR: crate::tcflag_t = 0x00000004; +pub const OCRNL: crate::tcflag_t = 0x00000008; +pub const ONOCR: crate::tcflag_t = 0x00000010; +pub const ONLRET: crate::tcflag_t = 0x00000020; +pub const OFILL: crate::tcflag_t = 0x00000040; +pub const OFDEL: crate::tcflag_t = 0x00000080; +pub const NLDLY: crate::tcflag_t = 0x00000100; +pub const NL0: crate::tcflag_t = 0x00000000; +pub const NL1: crate::tcflag_t = 0x00000100; +pub const CRDLY: crate::tcflag_t = 0x00000600; +pub const CR0: crate::tcflag_t = 0x00000000; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const TABDLY: crate::tcflag_t = 0x00001800; +pub const TAB0: crate::tcflag_t = 0x00000000; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const BSDLY: crate::tcflag_t = 0x00002000; +pub const BS0: crate::tcflag_t = 0x00000000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const VTDLY: crate::tcflag_t = 0x00004000; +pub const VT0: crate::tcflag_t = 0x00000000; +pub const VT1: crate::tcflag_t = 0x00004000; +pub const FFDLY: crate::tcflag_t = 0x00008000; +pub const FF0: crate::tcflag_t = 0x00000000; +pub const FF1: crate::tcflag_t = 0x00008000; + +pub const CSIZE: crate::tcflag_t = 0x00000020; +pub const CS5: crate::tcflag_t = 0x00000000; +pub const CS6: crate::tcflag_t = 0x00000000; +pub const CS7: crate::tcflag_t = 0x00000000; +pub const CS8: crate::tcflag_t = 0x00000020; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const XLOBLK: crate::tcflag_t = 0x00001000; +pub const CTSFLOW: crate::tcflag_t = 0x00002000; +pub const RTSFLOW: crate::tcflag_t = 0x00004000; +pub const CRTSCTS: crate::tcflag_t = RTSFLOW | CTSFLOW; + +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const XCASE: crate::tcflag_t = 0x00000004; +pub const ECHO: crate::tcflag_t = 0x00000008; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const IEXTEN: crate::tcflag_t = 0x00000200; +pub const ECHOCTL: crate::tcflag_t = 0x00000400; +pub const ECHOPRT: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00001000; +pub const FLUSHO: crate::tcflag_t = 0x00002000; +pub const PENDIN: crate::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 +// DIFF(main): changed to `c_short` in f62eb023ab +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 CMSG_ALIGN(len: usize) -> usize { + len + size_of::() - 1 & !(size_of::() - 1) +} + +f! { + pub unsafe fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize >= size_of::() { + (*mhdr).msg_control.cast() + } else { + ptr::null_mut() + } + } + + pub unsafe fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + (cmsg as *mut c_uchar).offset(CMSG_ALIGN(size_of::()) as isize) + } + + pub const unsafe fn CMSG_SPACE(length: c_uint) -> c_uint { + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(size_of::())) as c_uint + } + + pub const unsafe fn CMSG_LEN(length: c_uint) -> c_uint { + CMSG_ALIGN(size_of::()) as c_uint + length + } + + pub unsafe fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { + if cmsg.is_null() { + return crate::CMSG_FIRSTHDR(mhdr); + } + let next = cmsg as usize + + CMSG_ALIGN((*cmsg).cmsg_len as usize) + + CMSG_ALIGN(size_of::()); + let max = (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize; + if next > max { + ptr::null_mut() + } else { + (cmsg as usize + CMSG_ALIGN((*cmsg).cmsg_len as usize)) as *mut cmsghdr + } + } + + pub unsafe fn FD_CLR(fd: c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] &= !(1 << (fd % size)); + return; + } + + pub unsafe fn FD_ISSET(fd: c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0; + } + + pub unsafe fn FD_SET(fd: c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] |= 1 << (fd % size); + return; + } + + pub unsafe fn FD_ZERO(set: *mut fd_set) -> () { + (*set).fds_bits.fill(0); + } +} + +safe_f! { + pub const safe fn WIFEXITED(status: c_int) -> bool { + (status & !0xff) == 0 + } + + pub const safe fn WEXITSTATUS(status: c_int) -> c_int { + status & 0xff + } + + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + ((status >> 8) & 0xff) != 0 + } + + pub const safe fn WTERMSIG(status: c_int) -> c_int { + (status >> 8) & 0xff + } + + pub const safe fn WIFSTOPPED(status: c_int) -> bool { + ((status >> 16) & 0xff) != 0 + } + + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + (status >> 16) & 0xff + } + + // actually WIFCORED, but this is used everywhere else + pub const safe fn WCOREDUMP(status: c_int) -> bool { + (status & 0x10000) != 0 + } + + pub const safe fn WIFCONTINUED(status: c_int) -> bool { + (status & 0x20000) != 0 + } +} + +extern "C" { + pub fn getrlimit(resource: c_int, rlim: *mut crate::rlimit) -> c_int; + pub fn setrlimit(resource: c_int, rlim: *const crate::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 crate::timespec, + flag: c_int, + ) -> c_int; + pub fn futimens(fd: c_int, times: *const crate::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 crate::ifaddrs) -> c_int; + pub fn freeifaddrs(ifa: *mut crate::ifaddrs); + pub fn ppoll( + fds: *mut crate::pollfd, + numfds: crate::nfds_t, + timeout: *const crate::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 crate::FILE) -> *mut spwd; + pub fn fgetspent_r( + file: *mut crate::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: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_gettime(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_settime(clk_id: crate::clockid_t, tp: *const crate::timespec) -> c_int; + pub fn clock_getcpuclockid(pid: crate::pid_t, clk_id: *mut crate::clockid_t) -> c_int; + pub fn pthread_create( + thread: *mut crate::pthread_t, + attr: *const crate::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 crate::pthread_attr_t, + guardsize: *mut size_t, + ) -> c_int; + pub fn pthread_attr_setguardsize(attr: *mut crate::pthread_attr_t, guardsize: size_t) -> c_int; + pub fn pthread_attr_getstack( + attr: *const crate::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: crate::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 crate::gid_t) -> c_int; + pub fn initgroups(name: *const c_char, basegid: crate::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 crate::DIR) -> c_int; + pub fn getnameinfo( + sa: *const crate::sockaddr, + salen: crate::socklen_t, + host: *mut c_char, + hostlen: crate::socklen_t, + serv: *mut c_char, + servlen: crate::socklen_t, + flags: c_int, + ) -> c_int; + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const crate::timespec, + ) -> c_int; + pub fn pthread_sigqueue(thread: crate::pthread_t, sig: c_int, value: crate::sigval) -> c_int; + pub fn pthread_spin_init(lock: *mut crate::pthread_spinlock_t, pshared: c_int) -> c_int; + pub fn pthread_spin_destroy(lock: *mut crate::pthread_spinlock_t) -> c_int; + pub fn pthread_spin_lock(lock: *mut crate::pthread_spinlock_t) -> c_int; + pub fn pthread_spin_trylock(lock: *mut crate::pthread_spinlock_t) -> c_int; + pub fn pthread_spin_unlock(lock: *mut crate::pthread_spinlock_t) -> c_int; + pub fn waitid( + idtype: idtype_t, + id: id_t, + infop: *mut crate::siginfo_t, + options: c_int, + ) -> c_int; + + pub fn glob( + pattern: *const c_char, + flags: c_int, + errfunc: Option c_int>, + pglob: *mut crate::glob_t, + ) -> c_int; + pub fn globfree(pglob: *mut crate::glob_t); + pub fn gettimeofday(tp: *mut crate::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 crate::DIR, loc: c_long); + + pub fn telldir(dirp: *mut crate::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 crate::sockaddr, + addrlen: *mut crate::socklen_t, + ) -> ssize_t; + pub fn nl_langinfo(item: crate::nl_item) -> *mut c_char; + + pub fn bind( + socket: c_int, + address: *const crate::sockaddr, + address_len: crate::socklen_t, + ) -> c_int; + + pub fn accept4( + socket: c_int, + address: *mut crate::sockaddr, + addressLength: *mut crate::socklen_t, + flags: c_int, + ) -> c_int; + + pub fn writev(fd: c_int, iov: *const crate::iovec, count: c_int) -> ssize_t; + pub fn readv(fd: c_int, iov: *const crate::iovec, count: c_int) -> ssize_t; + + pub fn sendmsg(fd: c_int, msg: *const crate::msghdr, flags: c_int) -> ssize_t; + pub fn recvmsg(fd: c_int, msg: *mut crate::msghdr, flags: c_int) -> ssize_t; + + // DIFF(main): changed to `*const *mut` in e77f551de9 + pub fn execvpe( + file: *const c_char, + argv: *const *const c_char, + environment: *const *const c_char, + ) -> c_int; + + pub fn getgrgid_r( + gid: crate::gid_t, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn getgrouplist( + user: *const c_char, + basegroup: crate::gid_t, + grouplist: *mut crate::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 crate::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 crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::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 crate::group; + pub fn pthread_kill(thread: crate::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: crate::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 crate::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: crate::gid_t) -> *mut crate::group; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut crate::FILE; + pub fn sethostname(name: *const c_char, len: size_t) -> c_int; + pub fn uname(buf: *mut crate::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 crate::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 crate::itimerval) -> c_int; + pub fn setitimer( + which: c_int, + new_value: *const crate::itimerval, + old_value: *mut crate::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: crate::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: crate::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) -> crate::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: crate::ENTRY, action: crate::ACTION) -> *mut crate::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 crate::pid_t, + path: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::posix_spawnattr_t, + argv: *const *mut c_char, + envp: *const *mut c_char, + ) -> c_int; + pub fn posix_spawnp( + pid: *mut crate::pid_t, + file: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::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 crate::pid_t, + ) -> c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, pgroup: crate::pid_t) -> c_int; + pub fn posix_spawnattr_getsigdefault( + attr: *const posix_spawnattr_t, + sigdefault: *mut crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + sigdefault: *const crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + _sigmask: *mut crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + sigmask: *const crate::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: crate::locale_t, + ) -> c_int; + pub fn strncasecmp_l( + string1: *const c_char, + string2: *const c_char, + length: size_t, + locale: crate::locale_t, + ) -> c_int; + + pub fn getentropy(buf: *mut c_void, buflen: size_t) -> c_int; +} + +#[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: crate::pthread_t, attr: *mut crate::pthread_attr_t) -> c_int; + pub fn pthread_getname_np( + thread: crate::pthread_t, + buffer: *mut c_char, + length: size_t, + ) -> c_int; + pub fn pthread_setname_np(thread: crate::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 bsd; +pub use self::bsd::*; + +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..bc0cd5e --- /dev/null +++ b/vendor/libc/src/unix/haiku/native.rs @@ -0,0 +1,1390 @@ +use crate::off_t; +use crate::prelude::*; + +// This file follows the Haiku API for Haiku R1 beta 5. 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; + +c_enum! { + // kernel/OS.h + pub enum thread_state { + pub B_THREAD_RUNNING = 1, + pub B_THREAD_READY, + pub B_THREAD_RECEIVING, + pub B_THREAD_ASLEEP, + pub B_THREAD_SUSPENDED, + pub B_THREAD_WAITING, + } + + // kernel/image.h + pub enum image_type { + pub B_APP_IMAGE = 1, + pub B_LIBRARY_IMAGE, + pub B_ADD_ON_IMAGE, + pub B_SYSTEM_IMAGE, + } + + // kernel/scheduler.h + + pub enum be_task_flags { + pub B_DEFAULT_MEDIA_PRIORITY = 0x000, + pub B_OFFLINE_PROCESSING = 0x001, + pub B_STATUS_RENDERING = 0x002, + pub B_USER_INPUT_HANDLING = 0x004, + pub B_LIVE_VIDEO_MANIPULATION = 0x008, + pub B_VIDEO_PLAYBACK = 0x010, + pub B_VIDEO_RECORDING = 0x020, + pub B_LIVE_AUDIO_MANIPULATION = 0x040, + pub B_AUDIO_PLAYBACK = 0x080, + pub B_AUDIO_RECORDING = 0x100, + pub B_LIVE_3D_RENDERING = 0x200, + pub B_NUMBER_CRUNCHING = 0x400, + pub B_MIDI_PROCESSING = 0x800, + } + + pub enum schduler_mode { + pub SCHEDULER_MODE_LOW_LATENCY, + pub SCHEDULER_MODE_POWER_SAVING, + } + + // FindDirectory.h + pub enum path_base_directory { + pub B_FIND_PATH_INSTALLATION_LOCATION_DIRECTORY, + pub B_FIND_PATH_ADD_ONS_DIRECTORY, + pub B_FIND_PATH_APPS_DIRECTORY, + pub B_FIND_PATH_BIN_DIRECTORY, + pub B_FIND_PATH_BOOT_DIRECTORY, + pub B_FIND_PATH_CACHE_DIRECTORY, + pub B_FIND_PATH_DATA_DIRECTORY, + pub B_FIND_PATH_DEVELOP_DIRECTORY, + pub B_FIND_PATH_DEVELOP_LIB_DIRECTORY, + pub B_FIND_PATH_DOCUMENTATION_DIRECTORY, + pub B_FIND_PATH_ETC_DIRECTORY, + pub B_FIND_PATH_FONTS_DIRECTORY, + pub B_FIND_PATH_HEADERS_DIRECTORY, + pub B_FIND_PATH_LIB_DIRECTORY, + pub B_FIND_PATH_LOG_DIRECTORY, + pub B_FIND_PATH_MEDIA_NODES_DIRECTORY, + pub B_FIND_PATH_PACKAGES_DIRECTORY, + pub B_FIND_PATH_PREFERENCES_DIRECTORY, + pub B_FIND_PATH_SERVERS_DIRECTORY, + pub B_FIND_PATH_SETTINGS_DIRECTORY, + pub B_FIND_PATH_SOUNDS_DIRECTORY, + pub B_FIND_PATH_SPOOL_DIRECTORY, + pub B_FIND_PATH_TRANSLATORS_DIRECTORY, + pub B_FIND_PATH_VAR_DIRECTORY, + pub B_FIND_PATH_IMAGE_PATH = 1000, + pub B_FIND_PATH_PACKAGE_PATH, + } + + pub enum directory_which { + pub B_DESKTOP_DIRECTORY = 0, + pub B_TRASH_DIRECTORY, + pub B_SYSTEM_DIRECTORY = 1000, + pub B_SYSTEM_ADDONS_DIRECTORY = 1002, + pub B_SYSTEM_BOOT_DIRECTORY, + pub B_SYSTEM_FONTS_DIRECTORY, + pub B_SYSTEM_LIB_DIRECTORY, + pub B_SYSTEM_SERVERS_DIRECTORY, + pub B_SYSTEM_APPS_DIRECTORY, + pub B_SYSTEM_BIN_DIRECTORY, + pub B_SYSTEM_DOCUMENTATION_DIRECTORY = 1010, + pub B_SYSTEM_PREFERENCES_DIRECTORY, + pub B_SYSTEM_TRANSLATORS_DIRECTORY, + pub B_SYSTEM_MEDIA_NODES_DIRECTORY, + pub B_SYSTEM_SOUNDS_DIRECTORY, + pub B_SYSTEM_DATA_DIRECTORY, + pub B_SYSTEM_DEVELOP_DIRECTORY, + pub B_SYSTEM_PACKAGES_DIRECTORY, + pub B_SYSTEM_HEADERS_DIRECTORY, + pub B_SYSTEM_ETC_DIRECTORY = 2008, + pub B_SYSTEM_SETTINGS_DIRECTORY = 2010, + pub B_SYSTEM_LOG_DIRECTORY = 2012, + pub B_SYSTEM_SPOOL_DIRECTORY, + pub B_SYSTEM_TEMP_DIRECTORY, + pub B_SYSTEM_VAR_DIRECTORY, + pub B_SYSTEM_CACHE_DIRECTORY = 2020, + pub B_SYSTEM_NONPACKAGED_DIRECTORY = 2023, + pub B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY, + pub B_SYSTEM_NONPACKAGED_TRANSLATORS_DIRECTORY, + pub B_SYSTEM_NONPACKAGED_MEDIA_NODES_DIRECTORY, + pub B_SYSTEM_NONPACKAGED_BIN_DIRECTORY, + pub B_SYSTEM_NONPACKAGED_DATA_DIRECTORY, + pub B_SYSTEM_NONPACKAGED_FONTS_DIRECTORY, + pub B_SYSTEM_NONPACKAGED_SOUNDS_DIRECTORY, + pub B_SYSTEM_NONPACKAGED_DOCUMENTATION_DIRECTORY, + pub B_SYSTEM_NONPACKAGED_LIB_DIRECTORY, + pub B_SYSTEM_NONPACKAGED_HEADERS_DIRECTORY, + pub B_SYSTEM_NONPACKAGED_DEVELOP_DIRECTORY, + pub B_USER_DIRECTORY = 3000, + pub B_USER_CONFIG_DIRECTORY, + pub B_USER_ADDONS_DIRECTORY, + pub B_USER_BOOT_DIRECTORY, + pub B_USER_FONTS_DIRECTORY, + pub B_USER_LIB_DIRECTORY, + pub B_USER_SETTINGS_DIRECTORY, + pub B_USER_DESKBAR_DIRECTORY, + pub B_USER_PRINTERS_DIRECTORY, + pub B_USER_TRANSLATORS_DIRECTORY, + pub B_USER_MEDIA_NODES_DIRECTORY, + pub B_USER_SOUNDS_DIRECTORY, + pub B_USER_DATA_DIRECTORY, + pub B_USER_CACHE_DIRECTORY, + pub B_USER_PACKAGES_DIRECTORY, + pub B_USER_HEADERS_DIRECTORY, + pub B_USER_NONPACKAGED_DIRECTORY, + pub B_USER_NONPACKAGED_ADDONS_DIRECTORY, + pub B_USER_NONPACKAGED_TRANSLATORS_DIRECTORY, + pub B_USER_NONPACKAGED_MEDIA_NODES_DIRECTORY, + pub B_USER_NONPACKAGED_BIN_DIRECTORY, + pub B_USER_NONPACKAGED_DATA_DIRECTORY, + pub B_USER_NONPACKAGED_FONTS_DIRECTORY, + pub B_USER_NONPACKAGED_SOUNDS_DIRECTORY, + pub B_USER_NONPACKAGED_DOCUMENTATION_DIRECTORY, + pub B_USER_NONPACKAGED_LIB_DIRECTORY, + pub B_USER_NONPACKAGED_HEADERS_DIRECTORY, + pub B_USER_NONPACKAGED_DEVELOP_DIRECTORY, + pub B_USER_DEVELOP_DIRECTORY, + pub B_USER_DOCUMENTATION_DIRECTORY, + pub B_USER_SERVERS_DIRECTORY, + pub B_USER_APPS_DIRECTORY, + pub B_USER_BIN_DIRECTORY, + pub B_USER_PREFERENCES_DIRECTORY, + pub B_USER_ETC_DIRECTORY, + pub B_USER_LOG_DIRECTORY, + pub B_USER_SPOOL_DIRECTORY, + pub B_USER_VAR_DIRECTORY, + pub B_APPS_DIRECTORY = 4000, + pub B_PREFERENCES_DIRECTORY, + pub B_UTILITIES_DIRECTORY, + pub B_PACKAGE_LINKS_DIRECTORY, + } + + // kernel/OS.h + + pub enum topology_level_type { + pub B_TOPOLOGY_UNKNOWN, + pub B_TOPOLOGY_ROOT, + pub B_TOPOLOGY_SMT, + pub B_TOPOLOGY_CORE, + pub B_TOPOLOGY_PACKAGE, + } + + pub enum cpu_platform { + pub B_CPU_UNKNOWN, + pub B_CPU_x86, + pub B_CPU_x86_64, + pub B_CPU_PPC, + pub B_CPU_PPC_64, + pub B_CPU_M68K, + pub B_CPU_ARM, + pub B_CPU_ARM_64, + pub B_CPU_ALPHA, + pub B_CPU_MIPS, + pub B_CPU_SH, + pub B_CPU_SPARC, + pub B_CPU_RISC_V, + } + + pub enum cpu_vendor { + pub B_CPU_VENDOR_UNKNOWN, + pub B_CPU_VENDOR_AMD, + pub B_CPU_VENDOR_CYRIX, + pub B_CPU_VENDOR_IDT, + pub B_CPU_VENDOR_INTEL, + pub B_CPU_VENDOR_NATIONAL_SEMICONDUCTOR, + pub B_CPU_VENDOR_RISE, + pub B_CPU_VENDOR_TRANSMETA, + pub B_CPU_VENDOR_VIA, + pub B_CPU_VENDOR_IBM, + pub B_CPU_VENDOR_MOTOROLA, + pub B_CPU_VENDOR_NEC, + pub B_CPU_VENDOR_HYGON, + pub B_CPU_VENDOR_SUN, + pub 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: crate::uid_t, + pub sender_group: crate::gid_t, + pub sender_team: crate::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: crate::uid_t, + pub gid: crate::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: crate::time_t, + pub creation_time: crate::time_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + } + + //kernel/fs_info.h + pub struct fs_info { + pub dev: crate::dev_t, + pub root: crate::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 + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct image_info { + pub id: image_id, + pub image_type: c_int, + pub sequence: i32, + pub init_order: i32, + // FIXME(1.0): these should be made optional + pub init_routine: extern "C" fn(), + pub term_routine: extern "C" fn(), + pub device: crate::dev_t, + pub node: crate::ino_t, + pub name: [c_char; crate::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: Padding, + pub extended_model: u32, + pub extended_family: u32, + __reserved_1: Padding, + 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: Padding<[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, + } + + pub struct cpu_topology_node_info { + pub id: u32, + pub type_: topology_level_type, + pub level: u32, + pub data: __c_anonymous_cpu_topology_info_data, + } +} + +s_no_extra_traits! { + 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, + } + + 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, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + 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 + } + } + } + impl Eq for cpuid_info {} + impl hash::Hash for cpuid_info { + fn hash(&self, _state: &mut H) { + unimplemented!("traits"); + } + } + + 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 + } + } + } + impl Eq for __c_anonymous_cpu_topology_info_data {} + impl hash::Hash for __c_anonymous_cpu_topology_info_data { + fn hash(&self, _state: &mut H) { + unimplemented!("traits"); + } + } + } +} + +// kernel/OS.h +pub const B_OS_NAME_LENGTH: usize = 32; +pub const B_PAGE_SIZE: usize = 4096; +pub const B_INFINITE_TIMEOUT: c_longlong = 0x7FFFFFFFFFFFFFFF; + +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 = crate::FILENAME_MAX as usize; +pub const B_PATH_NAME_LENGTH: usize = crate::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 = crate::O_RDONLY as u32; +pub const B_WRITE_ONLY: u32 = crate::O_WRONLY as u32; +pub const B_READ_WRITE: u32 = crate::O_RDWR as u32; + +pub const B_FAIL_IF_EXISTS: u32 = crate::O_EXCL as u32; +pub const B_CREATE_FILE: u32 = crate::O_CREAT as u32; +pub const B_ERASE_FILE: u32 = crate::O_TRUNC as u32; +pub const B_OPEN_AT_END: u32 = crate::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 = crate::EOVERFLOW; +pub const B_TOO_MANY_ARGS: status_t = crate::E2BIG; +pub const B_FILE_TOO_LARGE: status_t = crate::EFBIG; +pub const B_RESULT_NOT_REPRESENTABLE: status_t = crate::ERANGE; +pub const B_DEVICE_NOT_FOUND: status_t = crate::ENODEV; +pub const B_NOT_SUPPORTED: status_t = crate::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 = 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: crate::bigtime_t, + length: crate::bigtime_t, + ) -> i32; + pub fn estimate_max_scheduling_latency(th: crate::thread_id) -> crate::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: crate::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 crate::DIR; + pub fn fs_lopen_attr_dir(path: *const c_char) -> *mut crate::DIR; + pub fn fs_fopen_attr_dir(fd: c_int) -> *mut crate::DIR; + pub fn fs_close_attr_dir(dir: *mut crate::DIR) -> c_int; + pub fn fs_read_attr_dir(dir: *mut crate::DIR) -> *mut crate::dirent; + pub fn fs_rewind_attr_dir(dir: *mut crate::DIR); + + // kernel/fs_image.h + pub fn fs_create_index( + device: crate::dev_t, + name: *const c_char, + type_: u32, + flags: u32, + ) -> c_int; + pub fn fs_remove_index(device: crate::dev_t, name: *const c_char) -> c_int; + pub fn fs_stat_index( + device: crate::dev_t, + name: *const c_char, + indexInfo: *mut index_info, + ) -> c_int; + + pub fn fs_open_index_dir(device: crate::dev_t) -> *mut crate::DIR; + pub fn fs_close_index_dir(indexDirectory: *mut crate::DIR) -> c_int; + pub fn fs_read_index_dir(indexDirectory: *mut crate::DIR) -> *mut crate::dirent; + pub fn fs_rewind_index_dir(indexDirectory: *mut crate::DIR); + + // kernel/fs_info.h + pub fn dev_for_path(path: *const c_char) -> crate::dev_t; + pub fn next_dev(pos: *mut i32) -> crate::dev_t; + pub fn fs_stat_dev(dev: crate::dev_t, info: *mut fs_info) -> c_int; + + // kernel/fs_query.h + pub fn fs_open_query(device: crate::dev_t, query: *const c_char, flags: u32) + -> *mut crate::DIR; + pub fn fs_open_live_query( + device: crate::dev_t, + query: *const c_char, + flags: u32, + port: port_id, + token: i32, + ) -> *mut crate::DIR; + pub fn fs_close_query(d: *mut crate::DIR) -> c_int; + pub fn fs_read_query(d: *mut crate::DIR) -> *mut crate::dirent; + pub fn get_path_for_dirent(dent: *mut crate::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, + ) -> crate::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, + 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_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: crate::dev_t, + createIt: bool, + pathString: *mut c_char, + length: i32, + ) -> status_t; + + 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, 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, 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, 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, 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, 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, + 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, 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, 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, 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, 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, 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, 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, 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, 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, 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..4a6921d --- /dev/null +++ b/vendor/libc/src/unix/haiku/x86_64.rs @@ -0,0 +1,58 @@ +use crate::prelude::*; + +s! { + 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], + _reserved_416_511: Padding<[c_uchar; 96]>, + } + + pub struct xstate_hdr { + pub bv: c_ulong, + pub xcomp_bv: c_ulong, + _reserved: Padding<[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: crate::sigset_t, + pub uc_stack: crate::stack_t, + pub uc_mcontext: mcontext_t, + } +} diff --git a/vendor/libc/src/unix/hurd/b32.rs b/vendor/libc/src/unix/hurd/b32.rs new file mode 100644 index 0000000..e706789 --- /dev/null +++ b/vendor/libc/src/unix/hurd/b32.rs @@ -0,0 +1,92 @@ +use crate::prelude::*; + +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 = crate::__int64_t; +pub type __uquad_type = crate::__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 = crate::__int64_t; +pub type __u64_type = crate::__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 = crate::Elf32_Addr; +pub type Elf_Half = crate::Elf32_Half; +pub type Elf_Ehdr = crate::Elf32_Ehdr; +pub type Elf_Phdr = crate::Elf32_Phdr; +pub type Elf_Shdr = crate::Elf32_Shdr; +pub type Elf_Sym = crate::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: crate::Elf32_Word, + pub p_offset: crate::Elf32_Off, + pub p_vaddr: crate::Elf32_Addr, + pub p_paddr: crate::Elf32_Addr, + pub p_filesz: crate::Elf32_Word, + pub p_memsz: crate::Elf32_Word, + pub p_flags: crate::Elf32_Word, + pub p_align: crate::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..a44428c --- /dev/null +++ b/vendor/libc/src/unix/hurd/b64.rs @@ -0,0 +1,94 @@ +use crate::prelude::*; + +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 = crate::Elf64_Addr; +pub type Elf_Half = crate::Elf64_Half; +pub type Elf_Ehdr = crate::Elf64_Ehdr; +pub type Elf_Phdr = crate::Elf64_Phdr; +pub type Elf_Shdr = crate::Elf64_Shdr; +pub type Elf_Sym = crate::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: crate::Elf64_Word, + pub p_flags: crate::Elf64_Word, + pub p_offset: crate::Elf64_Off, + pub p_vaddr: crate::Elf64_Addr, + pub p_paddr: crate::Elf64_Addr, + pub p_filesz: crate::Elf64_Xword, + pub p_memsz: crate::Elf64_Xword, + pub p_align: crate::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..1cc87eb --- /dev/null +++ b/vendor/libc/src/unix/hurd/mod.rs @@ -0,0 +1,4578 @@ +#![allow(dead_code)] + +use crate::c_schar; +use crate::prelude::*; + +// types +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 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 = crate::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 = crate::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; + +extern_ty! { + pub type fpos64_t; // FIXME(hurd): fill this out with a struct + pub type timezone; +} + +// 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: crate::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: crate::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, + __ss_padding: Padding<[c_char; 122usize]>, + __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: crate::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: crate::socklen_t, + pub msg_iov: *mut crate::iovec, + pub msg_iovlen: c_int, + pub msg_control: *mut c_void, + pub msg_controllen: crate::socklen_t, + pub msg_flags: c_int, + } + + pub struct cmsghdr { + pub cmsg_len: crate::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: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_cc: [crate::cc_t; 20usize], + pub __ispeed: crate::speed_t, + pub __ospeed: crate::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: crate::sighandler_t, + pub sa_mask: __sigset_t, + pub sa_flags: c_int, + } + + pub struct sigevent { + pub sigev_value: crate::sigval, + pub sigev_signo: c_int, + pub sigev_notify: c_int, + __unused1: Padding<*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: crate::sigval, + } + + #[derive(Default)] + 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: crate::timespec, + pub st_mtim: crate::timespec, + pub st_ctim: crate::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_dev: __fsid_t, /* Actually st_fsid */ + 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: crate::timespec, + pub st_mtim: crate::timespec, + pub st_ctim: crate::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: Padding<[u16; 1]>, + pub stx_ino: u64, + pub stx_size: u64, + pub stx_blocks: u64, + pub stx_attributes_mask: u64, + pub stx_atime: crate::statx_timestamp, + pub stx_btime: crate::statx_timestamp, + pub stx_ctime: crate::statx_timestamp, + pub stx_mtime: crate::statx_timestamp, + pub stx_rdev_major: u32, + pub stx_rdev_minor: u32, + pub stx_dev_major: u32, + pub stx_dev_minor: u32, + __statx_pad2: Padding<[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: crate::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: Padding<[c_char; 4]>, + __glibc_reserved: Padding<[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, + __reserved1: Padding, + __reserved2: Padding, + } + + 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: Padding<[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: crate::timespec, + pub it_value: crate::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 crate::sockaddr, + pub ifa_netmask: *mut crate::sockaddr, + pub ifa_ifu: *mut crate::sockaddr, // FIXME(union) This should be a union + pub ifa_data: *mut c_void, + } + + pub struct arpreq { + pub arp_pa: crate::sockaddr, + pub arp_ha: crate::sockaddr, + pub arp_flags: c_int, + pub arp_netmask: crate::sockaddr, + pub arp_dev: [c_char; 16], + } + + pub struct arpreq_old { + pub arp_pa: crate::sockaddr, + pub arp_ha: crate::sockaddr, + pub arp_flags: c_int, + pub arp_netmask: crate::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; crate::MAX_ADDR_LEN], + } + + pub struct mmsghdr { + pub msg_hdr: crate::msghdr, + pub msg_len: c_uint, + } + + pub struct ifreq { + /// interface name, e.g. "en0" + pub ifr_name: [c_char; crate::IFNAMSIZ], + pub ifr_ifru: crate::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; _UTSNAME_LENGTH], + pub nodename: [c_char; _UTSNAME_LENGTH], + pub release: [c_char; _UTSNAME_LENGTH], + pub version: [c_char; _UTSNAME_LENGTH], + pub machine: [c_char; _UTSNAME_LENGTH], + pub domainname: [c_char; _UTSNAME_LENGTH], + } + + 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: Padding<*mut c_void>, + __unused2: Padding<*mut c_void>, + __unused3: Padding<*mut c_void>, + __unused4: Padding<*mut c_void>, + __unused5: Padding<*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: Padding<*mut c_void>, + __unused2: Padding<*mut c_void>, + __unused3: Padding<*mut c_void>, + __unused4: Padding<*mut c_void>, + __unused5: Padding<*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: Padding<[c_int; 16]>, + } + + pub struct posix_spawnattr_t { + __flags: c_short, + __pgrp: crate::pid_t, + __sd: crate::sigset_t, + __ss: crate::sigset_t, + __sp: crate::sched_param, + __policy: c_int, + __pad: Padding<[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, + } + + pub struct utmpx { + pub ut_type: c_short, + pub ut_pid: crate::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: crate::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: Padding<[c_char; 20]>, + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut c_void { + self.si_addr + } + + pub unsafe fn si_value(&self) -> crate::sigval { + self.si_value + } + + pub unsafe fn si_pid(&self) -> crate::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> crate::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: crate::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 __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: crate::rlim_t = 2147483647; +pub const RLIM64_INFINITY: crate::rlim64_t = 9223372036854775807; +pub const RLIM_SAVED_MAX: crate::rlim_t = RLIM_INFINITY; +pub const RLIM_SAVED_CUR: crate::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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const NAME_MAX: usize = 255; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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: &[u8; 17usize] = b"/etc/hosts.equiv\0"; +pub const _PATH_HOSTS: &[u8; 11usize] = b"/etc/hosts\0"; +pub const _PATH_NETWORKS: &[u8; 14usize] = b"/etc/networks\0"; +pub const _PATH_NSSWITCH_CONF: &[u8; 19usize] = b"/etc/nsswitch.conf\0"; +pub const _PATH_PROTOCOLS: &[u8; 15usize] = b"/etc/protocols\0"; +pub const _PATH_SERVICES: &[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: crate::clockid_t = 0; +pub const CLOCK_MONOTONIC: crate::clockid_t = 1; +pub const CLOCK_PROCESS_CPUTIME_ID: crate::clockid_t = 2; +pub const CLOCK_THREAD_CPUTIME_ID: crate::clockid_t = 3; +pub const CLOCK_MONOTONIC_RAW: crate::clockid_t = 4; +pub const CLOCK_REALTIME_COARSE: crate::clockid_t = 5; +pub const CLOCK_MONOTONIC_COARSE: crate::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: crate::nl_item = 0x20000; +pub const ABDAY_2: crate::nl_item = 0x20001; +pub const ABDAY_3: crate::nl_item = 0x20002; +pub const ABDAY_4: crate::nl_item = 0x20003; +pub const ABDAY_5: crate::nl_item = 0x20004; +pub const ABDAY_6: crate::nl_item = 0x20005; +pub const ABDAY_7: crate::nl_item = 0x20006; + +pub const DAY_1: crate::nl_item = 0x20007; +pub const DAY_2: crate::nl_item = 0x20008; +pub const DAY_3: crate::nl_item = 0x20009; +pub const DAY_4: crate::nl_item = 0x2000A; +pub const DAY_5: crate::nl_item = 0x2000B; +pub const DAY_6: crate::nl_item = 0x2000C; +pub const DAY_7: crate::nl_item = 0x2000D; + +pub const ABMON_1: crate::nl_item = 0x2000E; +pub const ABMON_2: crate::nl_item = 0x2000F; +pub const ABMON_3: crate::nl_item = 0x20010; +pub const ABMON_4: crate::nl_item = 0x20011; +pub const ABMON_5: crate::nl_item = 0x20012; +pub const ABMON_6: crate::nl_item = 0x20013; +pub const ABMON_7: crate::nl_item = 0x20014; +pub const ABMON_8: crate::nl_item = 0x20015; +pub const ABMON_9: crate::nl_item = 0x20016; +pub const ABMON_10: crate::nl_item = 0x20017; +pub const ABMON_11: crate::nl_item = 0x20018; +pub const ABMON_12: crate::nl_item = 0x20019; + +pub const MON_1: crate::nl_item = 0x2001A; +pub const MON_2: crate::nl_item = 0x2001B; +pub const MON_3: crate::nl_item = 0x2001C; +pub const MON_4: crate::nl_item = 0x2001D; +pub const MON_5: crate::nl_item = 0x2001E; +pub const MON_6: crate::nl_item = 0x2001F; +pub const MON_7: crate::nl_item = 0x20020; +pub const MON_8: crate::nl_item = 0x20021; +pub const MON_9: crate::nl_item = 0x20022; +pub const MON_10: crate::nl_item = 0x20023; +pub const MON_11: crate::nl_item = 0x20024; +pub const MON_12: crate::nl_item = 0x20025; + +pub const AM_STR: crate::nl_item = 0x20026; +pub const PM_STR: crate::nl_item = 0x20027; + +pub const D_T_FMT: crate::nl_item = 0x20028; +pub const D_FMT: crate::nl_item = 0x20029; +pub const T_FMT: crate::nl_item = 0x2002A; +pub const T_FMT_AMPM: crate::nl_item = 0x2002B; + +pub const ERA: crate::nl_item = 0x2002C; +pub const ERA_D_FMT: crate::nl_item = 0x2002E; +pub const ALT_DIGITS: crate::nl_item = 0x2002F; +pub const ERA_D_T_FMT: crate::nl_item = 0x20030; +pub const ERA_T_FMT: crate::nl_item = 0x20031; + +pub const CODESET: crate::nl_item = 14; +pub const CRNCYSTR: crate::nl_item = 0x4000F; +pub const RADIXCHAR: crate::nl_item = 0x10000; +pub const THOUSEP: crate::nl_item = 0x10001; +pub const YESEXPR: crate::nl_item = 0x50000; +pub const NOEXPR: crate::nl_item = 0x50001; +pub const YESSTR: crate::nl_item = 0x50002; +pub const NOSTR: crate::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 crate::sem_t = ptr::null_mut(); + +// termios.h +pub const IGNBRK: crate::tcflag_t = 1; +pub const BRKINT: crate::tcflag_t = 2; +pub const IGNPAR: crate::tcflag_t = 4; +pub const PARMRK: crate::tcflag_t = 8; +pub const INPCK: crate::tcflag_t = 16; +pub const ISTRIP: crate::tcflag_t = 32; +pub const INLCR: crate::tcflag_t = 64; +pub const IGNCR: crate::tcflag_t = 128; +pub const ICRNL: crate::tcflag_t = 256; +pub const IXON: crate::tcflag_t = 512; +pub const IXOFF: crate::tcflag_t = 1024; +pub const IXANY: crate::tcflag_t = 2048; +pub const IMAXBEL: crate::tcflag_t = 8192; +pub const IUCLC: crate::tcflag_t = 16384; +pub const OPOST: crate::tcflag_t = 1; +pub const ONLCR: crate::tcflag_t = 2; +pub const ONOEOT: crate::tcflag_t = 8; +pub const OCRNL: crate::tcflag_t = 16; +pub const ONOCR: crate::tcflag_t = 32; +pub const ONLRET: crate::tcflag_t = 64; +pub const NLDLY: crate::tcflag_t = 768; +pub const NL0: crate::tcflag_t = 0; +pub const NL1: crate::tcflag_t = 256; +pub const TABDLY: crate::tcflag_t = 3076; +pub const TAB0: crate::tcflag_t = 0; +pub const TAB1: crate::tcflag_t = 1024; +pub const TAB2: crate::tcflag_t = 2048; +pub const TAB3: crate::tcflag_t = 4; +pub const CRDLY: crate::tcflag_t = 12288; +pub const CR0: crate::tcflag_t = 0; +pub const CR1: crate::tcflag_t = 4096; +pub const CR2: crate::tcflag_t = 8192; +pub const CR3: crate::tcflag_t = 12288; +pub const FFDLY: crate::tcflag_t = 16384; +pub const FF0: crate::tcflag_t = 0; +pub const FF1: crate::tcflag_t = 16384; +pub const BSDLY: crate::tcflag_t = 32768; +pub const BS0: crate::tcflag_t = 0; +pub const BS1: crate::tcflag_t = 32768; +pub const VTDLY: crate::tcflag_t = 65536; +pub const VT0: crate::tcflag_t = 0; +pub const VT1: crate::tcflag_t = 65536; +pub const OLCUC: crate::tcflag_t = 131072; +pub const OFILL: crate::tcflag_t = 262144; +pub const OFDEL: crate::tcflag_t = 524288; +pub const CIGNORE: crate::tcflag_t = 1; +pub const CSIZE: crate::tcflag_t = 768; +pub const CS5: crate::tcflag_t = 0; +pub const CS6: crate::tcflag_t = 256; +pub const CS7: crate::tcflag_t = 512; +pub const CS8: crate::tcflag_t = 768; +pub const CSTOPB: crate::tcflag_t = 1024; +pub const CREAD: crate::tcflag_t = 2048; +pub const PARENB: crate::tcflag_t = 4096; +pub const PARODD: crate::tcflag_t = 8192; +pub const HUPCL: crate::tcflag_t = 16384; +pub const CLOCAL: crate::tcflag_t = 32768; +pub const CRTSCTS: crate::tcflag_t = 65536; +pub const CRTS_IFLOW: crate::tcflag_t = 65536; +pub const CCTS_OFLOW: crate::tcflag_t = 65536; +pub const CDTRCTS: crate::tcflag_t = 131072; +pub const MDMBUF: crate::tcflag_t = 1048576; +pub const CHWFLOW: crate::tcflag_t = 1245184; +pub const ECHOKE: crate::tcflag_t = 1; +pub const _ECHOE: crate::tcflag_t = 2; +pub const ECHOE: crate::tcflag_t = 2; +pub const _ECHOK: crate::tcflag_t = 4; +pub const ECHOK: crate::tcflag_t = 4; +pub const _ECHO: crate::tcflag_t = 8; +pub const ECHO: crate::tcflag_t = 8; +pub const _ECHONL: crate::tcflag_t = 16; +pub const ECHONL: crate::tcflag_t = 16; +pub const ECHOPRT: crate::tcflag_t = 32; +pub const ECHOCTL: crate::tcflag_t = 64; +pub const _ISIG: crate::tcflag_t = 128; +pub const ISIG: crate::tcflag_t = 128; +pub const _ICANON: crate::tcflag_t = 256; +pub const ICANON: crate::tcflag_t = 256; +pub const ALTWERASE: crate::tcflag_t = 512; +pub const _IEXTEN: crate::tcflag_t = 1024; +pub const IEXTEN: crate::tcflag_t = 1024; +pub const EXTPROC: crate::tcflag_t = 2048; +pub const _TOSTOP: crate::tcflag_t = 4194304; +pub const TOSTOP: crate::tcflag_t = 4194304; +pub const FLUSHO: crate::tcflag_t = 8388608; +pub const NOKERNINFO: crate::tcflag_t = 33554432; +pub const PENDIN: crate::tcflag_t = 536870912; +pub const _NOFLSH: crate::tcflag_t = 2147483648; +pub const NOFLSH: crate::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: crate::speed_t = 0; +pub const B50: crate::speed_t = 50; +pub const B75: crate::speed_t = 75; +pub const B110: crate::speed_t = 110; +pub const B134: crate::speed_t = 134; +pub const B150: crate::speed_t = 150; +pub const B200: crate::speed_t = 200; +pub const B300: crate::speed_t = 300; +pub const B600: crate::speed_t = 600; +pub const B1200: crate::speed_t = 1200; +pub const B1800: crate::speed_t = 1800; +pub const B2400: crate::speed_t = 2400; +pub const B4800: crate::speed_t = 4800; +pub const B9600: crate::speed_t = 9600; +pub const B7200: crate::speed_t = 7200; +pub const B14400: crate::speed_t = 14400; +pub const B19200: crate::speed_t = 19200; +pub const B28800: crate::speed_t = 28800; +pub const B38400: crate::speed_t = 38400; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const B57600: crate::speed_t = 57600; +pub const B76800: crate::speed_t = 76800; +pub const B115200: crate::speed_t = 115200; +pub const B230400: crate::speed_t = 230400; +pub const B460800: crate::speed_t = 460800; +pub const B500000: crate::speed_t = 500000; +pub const B576000: crate::speed_t = 576000; +pub const B921600: crate::speed_t = 921600; +pub const B1000000: crate::speed_t = 1000000; +pub const B1152000: crate::speed_t = 1152000; +pub const B1500000: crate::speed_t = 1500000; +pub const B2000000: crate::speed_t = 2000000; +pub const B2500000: crate::speed_t = 2500000; +pub const B3000000: crate::speed_t = 3000000; +pub const B3500000: crate::speed_t = 3500000; +pub const B4000000: crate::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: crate::tcflag_t = 11042; +pub const TTYDEF_LFLAG: crate::tcflag_t = 1483; +pub const TTYDEF_CFLAG: crate::tcflag_t = 23040; +pub const TTYDEF_SPEED: crate::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 = ptr::null_mut(); +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 = 0o17_0000; +pub const __S_IFDIR: mode_t = 0o4_0000; +pub const __S_IFCHR: mode_t = 0o2_0000; +pub const __S_IFBLK: mode_t = 0o6_0000; +pub const __S_IFREG: mode_t = 0o10_0000; +pub const __S_IFLNK: mode_t = 0o12_0000; +pub const __S_IFSOCK: mode_t = 0o14_0000; +pub const __S_IFIFO: mode_t = 0o1_0000; +pub const __S_ISUID: mode_t = 0o4000; +pub const __S_ISGID: mode_t = 0o2000; +pub const __S_ISVTX: mode_t = 0o1000; +pub const __S_IREAD: mode_t = 0o0400; +pub const __S_IWRITE: mode_t = 0o0200; +pub const __S_IEXEC: mode_t = 0o0100; +pub const S_INOCACHE: mode_t = 0o20_0000; +pub const S_IUSEUNK: mode_t = 0o40_0000; +pub const S_IUNKNOWN: mode_t = 0o700_0000; +pub const S_IUNKSHIFT: mode_t = 0o0014; +pub const S_IPTRANS: mode_t = 0o1000_0000; +pub const S_IATRANS: mode_t = 0o2000_0000; +pub const S_IROOT: mode_t = 0o4000_0000; +pub const S_ITRANS: mode_t = 0o7000_0000; +pub const S_IMMAP0: mode_t = 0o10000_0000; +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 = 0o17_0000; +pub const S_IFDIR: mode_t = 0o4_0000; +pub const S_IFCHR: mode_t = 0o2_0000; +pub const S_IFBLK: mode_t = 0o6_0000; +pub const S_IFREG: mode_t = 0o10_0000; +pub const S_IFIFO: mode_t = 0o1_0000; +pub const S_IFLNK: mode_t = 0o12_0000; +pub const S_IFSOCK: mode_t = 0o14_0000; +pub const S_ISUID: mode_t = 0o4000; +pub const S_ISGID: mode_t = 0o2000; +pub const S_ISVTX: mode_t = 0o1000; +pub const S_IRUSR: mode_t = 0o0400; +pub const S_IWUSR: mode_t = 0o0200; +pub const S_IXUSR: mode_t = 0o0100; +pub const S_IRWXU: mode_t = 0o0700; +pub const S_IREAD: mode_t = 0o0400; +pub const S_IWRITE: mode_t = 0o0200; +pub const S_IEXEC: mode_t = 0o0100; +pub const S_IRGRP: mode_t = 0o0040; +pub const S_IWGRP: mode_t = 0o0020; +pub const S_IXGRP: mode_t = 0o0010; +pub const S_IRWXG: mode_t = 0o0070; +pub const S_IROTH: mode_t = 0o0004; +pub const S_IWOTH: mode_t = 0o0002; +pub const S_IXOTH: mode_t = 0o0001; +pub const S_IRWXO: mode_t = 0o0007; +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: crate::tcflag_t = 1; +pub const CBREAK: crate::tcflag_t = 2; +pub const LCASE: crate::tcflag_t = 4; +pub const CRMOD: crate::tcflag_t = 16; +pub const RAW: crate::tcflag_t = 32; +pub const ODDP: crate::tcflag_t = 64; +pub const EVENP: crate::tcflag_t = 128; +pub const ANYP: crate::tcflag_t = 192; +pub const NLDELAY: crate::tcflag_t = 768; +pub const NL2: crate::tcflag_t = 512; +pub const NL3: crate::tcflag_t = 768; +pub const TBDELAY: crate::tcflag_t = 3072; +pub const XTABS: crate::tcflag_t = 3072; +pub const CRDELAY: crate::tcflag_t = 12288; +pub const VTDELAY: crate::tcflag_t = 16384; +pub const BSDELAY: crate::tcflag_t = 32768; +pub const ALLDELAY: crate::tcflag_t = 65280; +pub const CRTBS: crate::tcflag_t = 65536; +pub const PRTERA: crate::tcflag_t = 131072; +pub const CRTERA: crate::tcflag_t = 262144; +pub const TILDE: crate::tcflag_t = 524288; +pub const LITOUT: crate::tcflag_t = 2097152; +pub const NOHANG: crate::tcflag_t = 16777216; +pub const L001000: crate::tcflag_t = 33554432; +pub const CRTKIL: crate::tcflag_t = 67108864; +pub const PASS8: crate::tcflag_t = 134217728; +pub const CTLECH: crate::tcflag_t = 268435456; +pub const DECCTQ: crate::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_HASSEMAPHORE: c_int = 1024; +pub const MAP_INHERIT: c_int = 2048; +pub const MAP_32BIT: c_int = 4096; +pub const MAP_EXCL: c_int = 16384; +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: crate::__rlimit_resource_t = 0; +pub const RLIMIT_FSIZE: crate::__rlimit_resource_t = 1; +pub const RLIMIT_DATA: crate::__rlimit_resource_t = 2; +pub const RLIMIT_STACK: crate::__rlimit_resource_t = 3; +pub const RLIMIT_CORE: crate::__rlimit_resource_t = 4; +pub const RLIMIT_RSS: crate::__rlimit_resource_t = 5; +pub const RLIMIT_MEMLOCK: crate::__rlimit_resource_t = 6; +pub const RLIMIT_NPROC: crate::__rlimit_resource_t = 7; +pub const RLIMIT_OFILE: crate::__rlimit_resource_t = 8; +pub const RLIMIT_NOFILE: crate::__rlimit_resource_t = 8; +pub const RLIMIT_SBSIZE: crate::__rlimit_resource_t = 9; +pub const RLIMIT_AS: crate::__rlimit_resource_t = 10; +pub const RLIMIT_VMEM: crate::__rlimit_resource_t = 10; +pub const RLIMIT_NLIMITS: crate::__rlimit_resource_t = 11; +pub const RLIM_NLIMITS: crate::__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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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: Padding::new(0), + __reserved2: Padding::new(0), +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + __lock: __PTHREAD_SPIN_LOCK_INITIALIZER, + __queue: ptr::null_mut(), + __attr: ptr::null_mut(), + __wrefs: 0, + __data: ptr::null_mut(), +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + __held: __PTHREAD_SPIN_LOCK_INITIALIZER, + __lock: __PTHREAD_SPIN_LOCK_INITIALIZER, + __readers: 0, + __readerqueue: ptr::null_mut(), + __writerqueue: ptr::null_mut(), + __attr: ptr::null_mut(), + __data: ptr::null_mut(), +}; +pub const PTHREAD_STACK_MIN: size_t = 0; + +// Non-public helper constants +const _UTSNAME_LENGTH: usize = 1024; + +const fn CMSG_ALIGN(len: usize) -> usize { + (len + size_of::() - 1) & !(size_of::() - 1) +} + +// functions +f! { + pub unsafe fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize >= size_of::() { + (*mhdr).msg_control.cast() + } else { + ptr::null_mut() + } + } + + pub unsafe fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + (cmsg as *mut c_uchar).offset(CMSG_ALIGN(size_of::()) as isize) + } + + pub const unsafe fn CMSG_SPACE(length: c_uint) -> c_uint { + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(size_of::())) as c_uint + } + + pub const unsafe fn CMSG_LEN(length: c_uint) -> c_uint { + CMSG_ALIGN(size_of::()) as c_uint + length + } + + pub unsafe fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { + if ((*cmsg).cmsg_len as usize) < size_of::() { + return ptr::null_mut(); + } + 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 + { + ptr::null_mut() + } else { + next.cast() + } + } + + pub unsafe fn CPU_ALLOC_SIZE(count: c_int) -> size_t { + let _dummy: cpu_set_t = mem::zeroed(); + let size_in_bits = 8 * size_of_val(&_dummy.bits[0]); + ((count as size_t + size_in_bits - 1) / 8) as size_t + } + + pub unsafe fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + cpuset.bits.fill(0); + } + + pub unsafe fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits = 8 * 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 unsafe fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits = 8 * 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 unsafe fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + 0 != (cpuset.bits[idx] & (1 << offset)) + } + + pub unsafe fn CPU_COUNT_S(size: usize, cpuset: &cpu_set_t) -> c_int { + let mut s: u32 = 0; + let size_of_mask = 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 unsafe fn CPU_COUNT(cpuset: &cpu_set_t) -> c_int { + CPU_COUNT_S(size_of::(), cpuset) + } + + pub unsafe fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.bits == set2.bits + } + + pub unsafe fn IPTOS_TOS(tos: u8) -> u8 { + tos & IPTOS_TOS_MASK + } + + pub unsafe fn IPTOS_PREC(tos: u8) -> u8 { + tos & IPTOS_PREC_MASK + } + + pub unsafe fn FD_CLR(fd: c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] &= !(1 << (fd % size)); + return; + } + + pub unsafe fn FD_ISSET(fd: c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0; + } + + pub unsafe fn FD_SET(fd: c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] |= 1 << (fd % size); + return; + } + + pub unsafe fn FD_ZERO(set: *mut fd_set) -> () { + (*set).fds_bits.fill(0); + } +} + +extern "C" { + pub fn lutimes(file: *const c_char, times: *const crate::timeval) -> c_int; + + pub fn futimes(fd: c_int, times: *const crate::timeval) -> c_int; + pub fn futimens(__fd: c_int, __times: *const crate::timespec) -> c_int; + + pub fn utimensat( + dirfd: c_int, + path: *const c_char, + times: *const crate::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: crate::pid_t, + status: *mut c_int, + options: c_int, + rusage: *mut crate::rusage, + ) -> crate::pid_t; + + pub fn waitid( + idtype: idtype_t, + id: id_t, + infop: *mut crate::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 crate::sigset_t) -> c_int; + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const crate::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 crate::iovec, __count: c_int) -> ssize_t; + pub fn writev(__fd: c_int, __iovec: *const crate::iovec, __count: c_int) -> ssize_t; + + pub fn preadv( + __fd: c_int, + __iovec: *const crate::iovec, + __count: c_int, + __offset: __off_t, + ) -> ssize_t; + pub fn pwritev( + __fd: c_int, + __iovec: *const crate::iovec, + __count: c_int, + __offset: __off_t, + ) -> ssize_t; + + pub fn preadv64(fd: c_int, iov: *const crate::iovec, iovcnt: c_int, offset: off64_t) + -> ssize_t; + pub fn pwritev64( + fd: c_int, + iov: *const crate::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 crate::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 crate::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 crate::sigevent, + ) -> c_int; + + pub fn mq_open(name: *const c_char, oflag: c_int, ...) -> crate::mqd_t; + pub fn mq_close(mqd: crate::mqd_t) -> c_int; + pub fn mq_unlink(name: *const c_char) -> c_int; + pub fn mq_receive( + mqd: crate::mqd_t, + msg_ptr: *mut c_char, + msg_len: size_t, + msg_prio: *mut c_uint, + ) -> ssize_t; + pub fn mq_timedreceive( + mqd: crate::mqd_t, + msg_ptr: *mut c_char, + msg_len: size_t, + msg_prio: *mut c_uint, + abs_timeout: *const crate::timespec, + ) -> ssize_t; + pub fn mq_send( + mqd: crate::mqd_t, + msg_ptr: *const c_char, + msg_len: size_t, + msg_prio: c_uint, + ) -> c_int; + pub fn mq_timedsend( + mqd: crate::mqd_t, + msg_ptr: *const c_char, + msg_len: size_t, + msg_prio: c_uint, + abs_timeout: *const crate::timespec, + ) -> c_int; + pub fn mq_getattr(mqd: crate::mqd_t, attr: *mut crate::mq_attr) -> c_int; + pub fn mq_setattr( + mqd: crate::mqd_t, + newattr: *const crate::mq_attr, + oldattr: *mut crate::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 crate::FILE, ptr: *mut fpos64_t) -> c_int; + pub fn fseeko64(stream: *mut crate::FILE, offset: off64_t, whence: c_int) -> c_int; + pub fn fsetpos64(stream: *mut crate::FILE, ptr: *const fpos64_t) -> c_int; + pub fn ftello64(stream: *mut crate::FILE) -> off64_t; + + pub fn bind(__fd: c_int, __addr: *const sockaddr, __len: crate::socklen_t) -> c_int; + + pub fn accept4( + fd: c_int, + addr: *mut crate::sockaddr, + len: *mut crate::socklen_t, + flg: c_int, + ) -> c_int; + + pub fn ppoll( + fds: *mut crate::pollfd, + nfds: nfds_t, + timeout: *const crate::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 crate::sockaddr, + addrlen: *mut crate::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 crate::sockaddr, + salen: crate::socklen_t, + host: *mut c_char, + hostlen: crate::socklen_t, + serv: *mut c_char, + servlen: crate::socklen_t, + flags: c_int, + ) -> c_int; + + pub fn getifaddrs(ifap: *mut *mut crate::ifaddrs) -> c_int; + pub fn freeifaddrs(ifa: *mut crate::ifaddrs); + + pub fn uname(buf: *mut crate::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 crate::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 crate::passwd, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::passwd, + ) -> c_int; + pub fn getgrent_r( + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn fgetpwent_r( + stream: *mut crate::FILE, + pwd: *mut crate::passwd, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::passwd, + ) -> c_int; + pub fn fgetgrent_r( + stream: *mut crate::FILE, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + + pub fn putpwent(p: *const crate::passwd, stream: *mut crate::FILE) -> c_int; + pub fn putgrent(grp: *const crate::group, stream: *mut crate::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: crate::uid_t, + pwd: *mut passwd, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut passwd, + ) -> c_int; + + pub fn fgetspent_r( + fp: *mut crate::FILE, + spbuf: *mut crate::spwd, + buf: *mut c_char, + buflen: size_t, + spbufp: *mut *mut crate::spwd, + ) -> c_int; + pub fn sgetspent_r( + s: *const c_char, + spbuf: *mut crate::spwd, + buf: *mut c_char, + buflen: size_t, + spbufp: *mut *mut crate::spwd, + ) -> c_int; + pub fn getspent_r( + spbuf: *mut crate::spwd, + buf: *mut c_char, + buflen: size_t, + spbufp: *mut *mut crate::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 crate::FILE, + mntbuf: *mut crate::mntent, + buf: *mut c_char, + buflen: c_int, + ) -> *mut crate::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 crate::uid_t, + euid: *mut crate::uid_t, + suid: *mut crate::uid_t, + ) -> c_int; + pub fn getresgid( + rgid: *mut crate::gid_t, + egid: *mut crate::gid_t, + sgid: *mut crate::gid_t, + ) -> c_int; + pub fn setresuid(ruid: crate::uid_t, euid: crate::uid_t, suid: crate::uid_t) -> c_int; + pub fn setresgid(rgid: crate::gid_t, egid: crate::gid_t, sgid: crate::gid_t) -> c_int; + + pub fn initgroups(user: *const c_char, group: crate::gid_t) -> c_int; + + pub fn getgrgid(gid: crate::gid_t) -> *mut crate::group; + pub fn getgrgid_r( + gid: crate::gid_t, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + + pub fn getgrnam(name: *const c_char) -> *mut crate::group; + pub fn getgrnam_r( + name: *const c_char, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + + pub fn getgrouplist( + user: *const c_char, + group: crate::gid_t, + groups: *mut crate::gid_t, + ngroups: *mut c_int, + ) -> c_int; + + pub fn setgroups(ngroups: size_t, ptr: *const crate::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 crate::FILE; + pub fn getmntent(stream: *mut crate::FILE) -> *mut crate::mntent; + pub fn addmntent(stream: *mut crate::FILE, mnt: *const crate::mntent) -> c_int; + pub fn endmntent(streamp: *mut crate::FILE) -> c_int; + pub fn hasmntopt(mnt: *const crate::mntent, opt: *const c_char) -> *mut c_char; + + pub fn pthread_create( + native: *mut crate::pthread_t, + attr: *const crate::pthread_attr_t, + f: extern "C" fn(*mut c_void) -> *mut c_void, + value: *mut c_void, + ) -> c_int; + pub fn pthread_kill(__threadid: crate::pthread_t, __signo: c_int) -> c_int; + pub fn pthread_cancel(thread: crate::pthread_t) -> c_int; + pub fn __pthread_equal(__t1: __pthread_t, __t2: __pthread_t) -> c_int; + + pub fn pthread_getattr_np(__thr: crate::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 crate::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 crate::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 crate::pthread_barrierattr_t) -> c_int; + pub fn pthread_barrierattr_destroy(attr: *mut crate::pthread_barrierattr_t) -> c_int; + pub fn pthread_barrierattr_getpshared( + attr: *const crate::pthread_barrierattr_t, + shared: *mut c_int, + ) -> c_int; + pub fn pthread_barrierattr_setpshared( + attr: *mut crate::pthread_barrierattr_t, + shared: c_int, + ) -> c_int; + pub fn pthread_barrier_init( + barrier: *mut pthread_barrier_t, + attr: *const crate::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 crate::pthread_spinlock_t, pshared: c_int) -> c_int; + pub fn pthread_spin_destroy(lock: *mut crate::pthread_spinlock_t) -> c_int; + pub fn pthread_spin_lock(lock: *mut crate::pthread_spinlock_t) -> c_int; + pub fn pthread_spin_trylock(lock: *mut crate::pthread_spinlock_t) -> c_int; + pub fn pthread_spin_unlock(lock: *mut crate::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: crate::pid_t, param: *mut crate::sched_param) -> c_int; + pub fn sched_setparam(pid: crate::pid_t, param: *const crate::sched_param) -> c_int; + pub fn sched_getscheduler(pid: crate::pid_t) -> c_int; + pub fn sched_setscheduler( + pid: crate::pid_t, + policy: c_int, + param: *const crate::sched_param, + ) -> c_int; + pub fn pthread_getschedparam( + native: crate::pthread_t, + policy: *mut c_int, + param: *mut crate::sched_param, + ) -> c_int; + pub fn pthread_setschedparam( + native: crate::pthread_t, + policy: c_int, + param: *const crate::sched_param, + ) -> c_int; + + pub fn pthread_getcpuclockid(thread: crate::pthread_t, clk_id: *mut crate::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 crate::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 crate::timespec) -> c_int; + pub fn clock_gettime(__clock_id: clockid_t, __tp: *mut crate::timespec) -> c_int; + pub fn clock_settime(__clock_id: clockid_t, __tp: *const crate::timespec) -> c_int; + pub fn clock_getcpuclockid(pid: crate::pid_t, clk_id: *mut crate::clockid_t) -> c_int; + + pub fn clock_nanosleep( + clk_id: crate::clockid_t, + flags: c_int, + rqtp: *const crate::timespec, + rmtp: *mut crate::timespec, + ) -> c_int; + + pub fn gettimeofday(tp: *mut crate::timeval, tz: *mut crate::timezone) -> c_int; + pub fn settimeofday(tv: *const crate::timeval, tz: *const crate::timezone) -> c_int; + + pub fn asctime_r(tm: *const crate::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 crate::tm, + ) -> size_t; + pub fn strptime(s: *const c_char, format: *const c_char, tm: *mut crate::tm) -> *mut c_char; + + pub fn timer_create( + clockid: crate::clockid_t, + sevp: *mut crate::sigevent, + timerid: *mut crate::timer_t, + ) -> c_int; + pub fn timer_delete(timerid: crate::timer_t) -> c_int; + pub fn timer_getoverrun(timerid: crate::timer_t) -> c_int; + pub fn timer_gettime(timerid: crate::timer_t, curr_value: *mut crate::itimerspec) -> c_int; + pub fn timer_settime( + timerid: crate::timer_t, + flags: c_int, + new_value: *const crate::itimerspec, + old_value: *mut crate::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 crate::FILE; + pub fn freopen64( + filename: *const c_char, + mode: *const c_char, + file: *mut crate::FILE, + ) -> *mut crate::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 crate::FILE; + + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut crate::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 crate::winsize, + ) -> c_int; + + pub fn forkpty( + __amaster: *mut c_int, + __name: *mut c_char, + __termp: *const termios, + __winp: *const crate::winsize, + ) -> crate::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; + + // DIFF(main): changed to `*const *mut` in e77f551de9 + 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 crate::pid_t, + path: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::posix_spawnattr_t, + argv: *const *mut c_char, + envp: *const *mut c_char, + ) -> c_int; + pub fn posix_spawnp( + pid: *mut crate::pid_t, + file: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::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 crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + default: *const crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + default: *mut crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + default: *const crate::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 crate::pid_t, + ) -> c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: crate::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 crate::sched_param, + ) -> c_int; + pub fn posix_spawnattr_setschedparam( + attr: *mut posix_spawnattr_t, + param: *const crate::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 crate::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 crate::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 crate::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 crate::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 crate::DIR) -> *mut crate::dirent; + pub fn readdir64(dirp: *mut crate::DIR) -> *mut crate::dirent64; + pub fn readdir_r( + dirp: *mut crate::DIR, + entry: *mut crate::dirent, + result: *mut *mut crate::dirent, + ) -> c_int; + pub fn readdir64_r( + dirp: *mut crate::DIR, + entry: *mut crate::dirent64, + result: *mut *mut crate::dirent64, + ) -> c_int; + pub fn seekdir(dirp: *mut crate::DIR, loc: c_long); + pub fn telldir(dirp: *mut crate::DIR) -> c_long; + + pub fn dirfd(dirp: *mut crate::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: crate::__rlimit_resource_t, rlim: *mut crate::rlimit) -> c_int; + pub fn getrlimit64(resource: crate::__rlimit_resource_t, rlim: *mut crate::rlimit64) -> c_int; + pub fn setrlimit(resource: crate::__rlimit_resource_t, rlim: *const crate::rlimit) -> c_int; + pub fn setrlimit64(resource: crate::__rlimit_resource_t, rlim: *const crate::rlimit64) + -> c_int; + + pub fn getpriority(which: crate::__priority_which, who: crate::id_t) -> c_int; + pub fn setpriority(which: crate::__priority_which, who: crate::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 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() -> crate::mallinfo; + pub fn mallinfo2() -> crate::mallinfo2; + pub fn malloc_info(options: c_int, stream: *mut crate::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 crate::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 crate::regex_t, + errbuf: *mut c_char, + errbuf_size: size_t, + ) -> size_t; + + pub fn regfree(preg: *mut crate::regex_t); + + pub fn glob( + pattern: *const c_char, + flags: c_int, + errfunc: Option c_int>, + pglob: *mut crate::glob_t, + ) -> c_int; + pub fn globfree(pglob: *mut crate::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 crate::Dl_info, + extra_info: *mut *mut c_void, + flags: c_int, + ) -> c_int; + + pub fn duplocale(base: crate::locale_t) -> crate::locale_t; + pub fn freelocale(loc: crate::locale_t); + pub fn newlocale(mask: c_int, locale: *const c_char, base: crate::locale_t) -> crate::locale_t; + pub fn uselocale(loc: crate::locale_t) -> crate::locale_t; + pub fn nl_langinfo(item: crate::nl_item) -> *mut c_char; + pub fn nl_langinfo_l(item: crate::nl_item, locale: crate::locale_t) -> *mut c_char; + + pub fn dl_iterate_phdr( + callback: Option< + unsafe extern "C" fn( + info: *mut crate::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 safe fn makedev(major: c_uint, minor: c_uint) -> crate::dev_t { + let major = major as crate::dev_t; + let minor = minor as crate::dev_t; + let mut dev = 0; + dev |= major << 8; + dev |= minor; + dev + } + + pub const safe fn major(dev: crate::dev_t) -> c_uint { + ((dev >> 8) & 0xff) as c_uint + } + + pub const safe fn minor(dev: crate::dev_t) -> c_uint { + (dev & 0xffff00ff) as c_uint + } + + pub safe fn SIGRTMAX() -> c_int { + unsafe { __libc_current_sigrtmax() } + } + + pub safe fn SIGRTMIN() -> c_int { + unsafe { __libc_current_sigrtmin() } + } + + pub const safe fn WIFSTOPPED(status: c_int) -> bool { + (status & 0xff) == 0x7f + } + + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + (status >> 8) & 0xff + } + + pub const safe fn WIFCONTINUED(status: c_int) -> bool { + status == 0xffff + } + + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + ((status & 0x7f) + 1) as i8 >= 2 + } + + pub const safe fn WTERMSIG(status: c_int) -> c_int { + status & 0x7f + } + + pub const safe fn WIFEXITED(status: c_int) -> bool { + (status & 0x7f) == 0 + } + + pub const safe fn WEXITSTATUS(status: c_int) -> c_int { + (status >> 8) & 0xff + } + + pub const safe fn WCOREDUMP(status: c_int) -> bool { + (status & 0x80) != 0 + } + + pub const safe fn W_EXITCODE(ret: c_int, sig: c_int) -> c_int { + (ret << 8) | sig + } + + pub const safe fn W_STOPCODE(sig: c_int) -> c_int { + (sig << 8) | 0x7f + } + + pub const safe fn QCMD(cmd: c_int, type_: c_int) -> c_int { + (cmd << 8) | (type_ & 0x00ff) + } + + pub const safe fn IPOPT_COPIED(o: u8) -> u8 { + o & IPOPT_COPY + } + + pub const safe fn IPOPT_CLASS(o: u8) -> u8 { + o & IPOPT_CLASS_MASK + } + + pub const safe fn IPOPT_NUMBER(o: u8) -> u8 { + o & IPOPT_NUMBER_MASK + } + + pub const safe fn IPTOS_ECN(x: u8) -> u8 { + x & crate::IPTOS_ECN_MASK + } +} + +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/linux_like/android/b32/arm.rs b/vendor/libc/src/unix/linux_like/android/b32/arm.rs new file mode 100644 index 0000000..0fe599f --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b32/arm.rs @@ -0,0 +1,494 @@ +use crate::prelude::*; + +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, + } + + pub struct __c_anonymous_uc_sigmask_with_padding { + pub uc_sigmask: crate::sigset_t, + /* Android has a wrong (smaller) sigset_t on x86. */ + __padding_rt_sigset: Padding, + } + + pub struct ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::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: Padding<[c_char; 120]>, + __align: [c_longlong; 0], + uc_regspace: [c_ulong; 128], + } +} + +s_no_extra_traits! { + pub union __c_anonymous_uc_sigmask { + uc_sigmask: __c_anonymous_uc_sigmask_with_padding, + uc_sigmask64: crate::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 hash::Hash for __c_anonymous_uc_sigmask { + fn hash(&self, state: &mut H) { + unsafe { self.uc_sigmask.hash(state) } + } + } + } +} + +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; +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; + +// 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 unsafe fn accept4( + fd: c_int, + addr: *mut crate::sockaddr, + len: *mut crate::socklen_t, + flg: c_int, + ) -> c_int { + crate::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..e744c32 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b32/mod.rs @@ -0,0 +1,237 @@ +use crate::prelude::*; + +// The following definitions are correct for arm and i686, +// but may be wrong for mips + +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; + +s! { + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::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: Padding<[c_uchar; 4]>, + __st_ino: crate::ino_t, + pub st_mode: c_uint, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: c_ulonglong, + __pad3: Padding<[c_uchar; 4]>, + pub st_size: c_longlong, + pub st_blksize: crate::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: Padding<[c_uchar; 4]>, + __st_ino: crate::ino_t, + pub st_mode: c_uint, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: c_ulonglong, + __pad3: Padding<[c_uchar; 4]>, + pub st_size: c_longlong, + pub st_blksize: crate::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: crate::__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: Padding<[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: crate::uid_t, + pub pw_gid: crate::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: crate::__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], + } +} + +// 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 = u32_cast_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: Padding::new([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 crate::tm) -> crate::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/mod.rs b/vendor/libc/src/unix/linux_like/android/b32/x86/mod.rs new file mode 100644 index 0000000..baa285e --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b32/x86/mod.rs @@ -0,0 +1,568 @@ +use crate::prelude::*; + +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, + } + + pub struct __c_anonymous_uc_sigmask_with_padding { + pub uc_sigmask: crate::sigset_t, + /* Android has a wrong (smaller) sigset_t on x86. */ + __padding_rt_sigset: Padding, + } + + pub struct ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask__c_anonymous_union: __c_anonymous_uc_sigmask, + __padding_rt_sigset: Padding, + __fpregs_mem: _libc_fpstate, + } +} + +s_no_extra_traits! { + pub union __c_anonymous_uc_sigmask { + uc_sigmask: __c_anonymous_uc_sigmask_with_padding, + uc_sigmask64: crate::sigset64_t, + } + + #[repr(align(8))] + pub struct max_align_t { + priv_: [f64; 2], + } +} + +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 hash::Hash for __c_anonymous_uc_sigmask { + fn hash(&self, state: &mut H) { + unsafe { self.uc_sigmask.hash(state) } + } + } + } +} + +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 127; +pub const SYS_init_module: c_long = 128; +pub const SYS_delete_module: c_long = 129; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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(android): 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(android): 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(android): 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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; + +// 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 unsafe fn accept4( + fd: c_int, + addr: *mut crate::sockaddr, + len: *mut crate::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]; + crate::syscall(SYS_socketcall, SYS_ACCEPT4, args[..].as_mut_ptr()) + } +} 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..c8c48e5 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b64/aarch64/mod.rs @@ -0,0 +1,471 @@ +use crate::off64_t; +use crate::prelude::*; + +pub type wchar_t = u32; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: c_uint, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad1: Padding, + pub st_size: off64_t, + pub st_blksize: c_int, + __pad2: Padding, + pub st_blocks: c_long, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused4: Padding, + __unused5: Padding, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: c_uint, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad1: Padding, + pub st_size: off64_t, + pub st_blksize: c_int, + __pad2: Padding, + pub st_blocks: c_long, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused4: Padding, + __unused5: Padding, + } + + pub struct user_regs_struct { + pub regs: [u64; 31], + pub sp: u64, + pub pc: u64, + pub pstate: u64, + } + + pub struct ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_sigmask: crate::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, + __reserved: Padding<[u64; 512]>, + } + + pub struct user_fpsimd_struct { + pub vregs: [u128; 32], + pub fpsr: u32, + pub fpcr: u32, + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f32; 8], + } +} + +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_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_syscalls: c_long = 451; + +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; 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..f5a204d --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b64/mod.rs @@ -0,0 +1,218 @@ +use crate::prelude::*; + +// The following definitions are correct for aarch64 and x86_64, +// but may be wrong for mips64 + +pub type mode_t = u32; +pub type off64_t = i64; +pub type socklen_t = u32; + +s! { + pub struct sigset_t { + __val: [c_ulong; 1], + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_flags: c_int, + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::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: Padding<[c_char; 16]>, + } + + pub struct passwd { + pub pw_name: *mut c_char, + pub pw_passwd: *mut c_char, + pub pw_uid: crate::uid_t, + pub pw_gid: crate::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: crate::__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: crate::__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, + } + + pub struct pthread_mutex_t { + value: c_int, + __reserved: Padding<[c_char; 36]>, + } + + pub struct pthread_cond_t { + value: c_int, + __reserved: Padding<[c_char; 44]>, + } + + pub struct pthread_rwlock_t { + numLocks: c_int, + writerThreadId: c_int, + pendingReaders: c_int, + pendingWriters: c_int, + attr: i32, + __reserved: Padding<[c_char; 36]>, + } + + pub struct sigset64_t { + __bits: [c_ulong; 1], + } +} + +// 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 = u32_cast_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 = ptr::null_mut(); + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + value: 0, + __reserved: Padding::new([0; 36]), +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + value: 0, + __reserved: Padding::new([0; 44]), +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + numLocks: 0, + writerThreadId: 0, + pendingReaders: 0, + pendingWriters: 0, + attr: 0, + __reserved: Padding::new([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 unsafe fn accept4( + fd: c_int, + addr: *mut crate::sockaddr, + len: *mut crate::socklen_t, + flg: c_int, + ) -> c_int { + crate::syscall(SYS_accept4, fd, addr, len, flg) as c_int + } +} + +extern "C" { + pub fn __system_property_wait( + pi: *const crate::prop_info, + __old_serial: u32, + __new_serial_ptr: *mut u32, + __relative_timeout: *const crate::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/mod.rs b/vendor/libc/src/unix/linux_like/android/b64/riscv64/mod.rs new file mode 100644 index 0000000..12f8730 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b64/riscv64/mod.rs @@ -0,0 +1,382 @@ +use crate::off64_t; +use crate::prelude::*; + +pub type wchar_t = u32; +pub type greg_t = i64; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: c_uint, + pub st_nlink: c_uint, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad1: Padding, + pub st_size: off64_t, + pub st_blksize: c_int, + __pad2: Padding, + pub st_blocks: c_long, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused4: Padding, + __unused5: Padding, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: c_uint, + pub st_nlink: c_uint, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad1: Padding, + pub st_size: off64_t, + pub st_blksize: c_int, + __pad2: Padding, + pub st_blocks: c_long, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused4: Padding, + __unused5: Padding, + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f32; 8], + } +} + +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_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; + +// 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; 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..6fd06b0 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs @@ -0,0 +1,618 @@ +use crate::off64_t; +use crate::prelude::*; + +pub type wchar_t = i32; +pub type greg_t = i64; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: c_ulong, + pub st_mode: c_uint, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::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: Padding<[c_long; 3]>, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: c_ulong, + pub st_mode: c_uint, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::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: Padding<[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: Padding, + #[cfg(target_pointer_width = "32")] + __pad1: Padding, + pub u_ar0: *mut user_regs_struct, + #[cfg(target_pointer_width = "32")] + __pad2: Padding, + 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, + } + + pub struct _libc_fpxreg { + pub significand: [u16; 4], + pub exponent: u16, + __padding: 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: crate::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: Padding<[c_uint; 24]>, + } +} + +s_no_extra_traits! { + pub union __c_anonymous_uc_sigmask { + uc_sigmask: crate::sigset_t, + uc_sigmask64: crate::sigset64_t, + } + + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4], + } +} + +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 hash::Hash for __c_anonymous_uc_sigmask { + fn hash(&self, state: &mut H) { + unsafe { self.uc_sigmask.hash(state) } + } + } + } +} + +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(android): 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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 174; +pub const SYS_init_module: c_long = 175; +pub const SYS_delete_module: c_long = 176; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_get_kernel_syms: c_long = 177; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; + +// 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; 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..a294768 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/mod.rs @@ -0,0 +1,4008 @@ +//! Android-specific definitions for linux-like values + +use crate::prelude::*; +use crate::{ + cmsghdr, + msghdr, + _IOW, + _IOWR, +}; + +cfg_if! { + if #[cfg(doc)] { + pub(crate) type Ioctl = c_int; + } else { + #[doc(hidden)] + pub type Ioctl = c_int; + } +} + +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 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; + +// 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 termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; crate::NCCS], + } + + pub struct termios2 { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; 19], + pub c_ispeed: crate::speed_t, + pub c_ospeed: crate::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: crate::pid_t, + } + + pub struct flock64 { + pub l_type: c_short, + pub l_whence: c_short, + pub l_start: crate::__kernel_loff_t, + pub l_len: crate::__kernel_loff_t, + pub l_pid: crate::__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: Padding<[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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::fsfilcnt_t, + pub f_fsid: c_ulong, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + #[cfg(target_pointer_width = "64")] + __f_reserved: Padding<[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: Padding, + pub ssi_syscall: i32, + pub ssi_call_addr: u64, + pub ssi_arch: u32, + _pad: Padding<[u8; 28]>, + } + + pub struct itimerspec { + pub it_interval: crate::timespec, + pub it_value: crate::timespec, + } + + 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: crate::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: crate::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/seccomp.h + pub struct seccomp_data { + pub nr: c_int, + pub arch: crate::__u32, + pub instruction_pointer: crate::__u64, + pub args: [crate::__u64; 6], + } + + pub struct seccomp_metadata { + pub filter_off: crate::__u64, + pub flags: crate::__u64, + } + + pub struct seccomp_notif_sizes { + pub seccomp_notif: crate::__u16, + pub seccomp_notif_resp: crate::__u16, + pub seccomp_data: crate::__u16, + } + + pub struct seccomp_notif { + pub id: crate::__u64, + pub pid: crate::__u32, + pub flags: crate::__u32, + pub data: seccomp_data, + } + + pub struct seccomp_notif_resp { + pub id: crate::__u64, + pub val: crate::__s64, + pub error: crate::__s32, + pub flags: crate::__u32, + } + + pub struct seccomp_notif_addfd { + pub id: crate::__u64, + pub flags: crate::__u32, + pub srcfd: crate::__u32, + pub newfd: crate::__u32, + pub newfd_flags: crate::__u32, + } + + pub struct ptrace_peeksiginfo_args { + pub off: crate::__u64, + pub flags: crate::__u32, + pub nr: crate::__s32, + } + + // linux/input.h + pub struct input_event { + pub time: crate::timeval, + pub type_: crate::__u16, + pub code: crate::__u16, + pub value: crate::__s32, + } + + pub struct input_id { + pub bustype: crate::__u16, + pub vendor: crate::__u16, + pub product: crate::__u16, + pub version: crate::__u16, + } + + pub struct input_absinfo { + pub value: crate::__s32, + pub minimum: crate::__s32, + pub maximum: crate::__s32, + pub fuzz: crate::__s32, + pub flat: crate::__s32, + pub resolution: crate::__s32, + } + + pub struct input_keymap_entry { + pub flags: crate::__u8, + pub len: crate::__u8, + pub index: crate::__u16, + pub keycode: crate::__u32, + pub scancode: [crate::__u8; 32], + } + + pub struct input_mask { + pub type_: crate::__u32, + pub codes_size: crate::__u32, + pub codes_ptr: crate::__u64, + } + + pub struct ff_replay { + pub length: crate::__u16, + pub delay: crate::__u16, + } + + pub struct ff_trigger { + pub button: crate::__u16, + pub interval: crate::__u16, + } + + pub struct ff_envelope { + pub attack_length: crate::__u16, + pub attack_level: crate::__u16, + pub fade_length: crate::__u16, + pub fade_level: crate::__u16, + } + + pub struct ff_constant_effect { + pub level: crate::__s16, + pub envelope: ff_envelope, + } + + pub struct ff_ramp_effect { + pub start_level: crate::__s16, + pub end_level: crate::__s16, + pub envelope: ff_envelope, + } + + pub struct ff_condition_effect { + pub right_saturation: crate::__u16, + pub left_saturation: crate::__u16, + + pub right_coeff: crate::__s16, + pub left_coeff: crate::__s16, + + pub deadband: crate::__u16, + pub center: crate::__s16, + } + + pub struct ff_periodic_effect { + pub waveform: crate::__u16, + pub period: crate::__u16, + pub magnitude: crate::__s16, + pub offset: crate::__s16, + pub phase: crate::__u16, + + pub envelope: ff_envelope, + + pub custom_len: crate::__u32, + pub custom_data: *mut crate::__s16, + } + + pub struct ff_rumble_effect { + pub strong_magnitude: crate::__u16, + pub weak_magnitude: crate::__u16, + } + + pub struct ff_effect { + pub type_: crate::__u16, + pub id: crate::__s16, + pub direction: crate::__u16, + pub trigger: ff_trigger, + pub replay: ff_replay, + // FIXME(1.0): 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: crate::__u32, + pub retval: crate::__s32, + pub effect: ff_effect, + pub old: ff_effect, + } + + pub struct uinput_ff_erase { + pub request_id: crate::__u32, + pub retval: crate::__s32, + pub effect_id: crate::__u32, + } + + pub struct uinput_abs_setup { + pub code: crate::__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: crate::in6_addr, + pub ifr6_prefixlen: u32, + pub ifr6_ifindex: c_int, + } + + pub struct sockaddr_nl { + pub nl_family: crate::sa_family_t, + nl_pad: Padding, + 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: crate::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: crate::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: crate::timeval, + pub ut_addr_v6: [i32; 4], + unused: Padding<[c_char; 20]>, + } + + pub struct sockaddr_alg { + pub salg_family: crate::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: crate::__u32, + } + + pub struct uinput_user_dev { + pub name: [c_char; UINPUT_MAX_NAME_SIZE], + pub id: input_id, + pub ff_effects_max: crate::__u32, + pub absmax: [crate::__s32; ABS_CNT], + pub absmin: [crate::__s32; ABS_CNT], + pub absfuzz: [crate::__s32; ABS_CNT], + pub absflat: [crate::__s32; ABS_CNT], + } + + pub struct prop_info { + __name: [c_char; 32], + __serial: c_uint, + __value: [c_char; 92], + } + + // linux/futex.h + pub struct futex_waitv { + pub val: crate::__u64, + pub uaddr: crate::__u64, + pub flags: crate::__u32, + __reserved: Padding, + } +} + +s_no_extra_traits! { + /// 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 union __c_anonymous_ifr_ifru { + pub ifru_addr: crate::sockaddr, + pub ifru_dstaddr: crate::sockaddr, + pub ifru_broadaddr: crate::sockaddr, + pub ifru_netmask: crate::sockaddr, + pub ifru_hwaddr: crate::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; crate::IFNAMSIZ], + pub ifru_newname: [c_char; crate::IFNAMSIZ], + pub ifru_data: *mut c_char, + } + + pub struct ifreq { + /// interface name, e.g. "en0" + pub ifr_name: [c_char; crate::IFNAMSIZ], + pub ifr_ifru: __c_anonymous_ifr_ifru, + } + + pub union __c_anonymous_ifc_ifcu { + pub ifcu_buf: *mut c_char, + pub ifcu_req: *mut crate::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. */ + pub ifc_ifcu: __c_anonymous_ifc_ifcu, + } + + // linux/if_ether.h + + #[repr(C, packed)] + pub struct ethhdr { + pub h_dest: [c_uchar; crate::ETH_ALEN as usize], + pub h_source: [c_uchar; crate::ETH_ALEN as usize], + pub h_proto: crate::__be16, + } + + // Internal, for casts to access union fields + struct sifields_sigchld { + si_pid: crate::pid_t, + si_uid: crate::uid_t, + si_status: c_int, + si_utime: c_long, + si_stime: c_long, + } + + // Internal, for casts to access union fields + 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. + struct siginfo_f { + _siginfo_base: [c_int; 3], + sifields: sifields, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + #[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 hash::Hash for af_alg_iv { + fn hash(&self, state: &mut H) { + self.as_slice().hash(state); + } + } + } +} + +pub const MADV_SOFT_OFFLINE: c_int = 101; +#[allow(overflowing_literals)] // fixed in a future kernel version +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: crate::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 POSIX_SPAWN_RESETIDS: c_short = 1; +pub const POSIX_SPAWN_SETPGROUP: c_short = 2; +pub const POSIX_SPAWN_SETSIGDEF: c_short = 4; +pub const POSIX_SPAWN_SETSIGMASK: c_short = 8; +pub const POSIX_SPAWN_SETSCHEDPARAM: c_short = 16; +pub const POSIX_SPAWN_SETSCHEDULER: c_short = 32; +pub const POSIX_SPAWN_USEVFORK: c_short = 64; +pub const POSIX_SPAWN_SETSID: c_short = 128; +pub const POSIX_SPAWN_CLOEXEC_DEFAULT: c_short = 256; +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 F_SEAL_EXEC: c_int = 0x0020; + +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 = crate::LC_CTYPE_MASK + | crate::LC_NUMERIC_MASK + | crate::LC_TIME_MASK + | crate::LC_COLLATE_MASK + | crate::LC_MONETARY_MASK + | crate::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; +#[deprecated(since = "0.2.70", note = "AF_PACKET must be used instead")] +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; + +/* UDP socket options */ +// 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; +pub const UDP_SEGMENT: c_int = 103; +pub const UDP_GRO: c_int = 104; + +/* 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_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; + +// 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: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::tcflag_t = 0x00001000; +pub const EXTPROC: crate::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: crate::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 = u32_cast_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; + +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 = ptr::null_mut(); + +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 = u32_cast_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 = u32_cast_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 = u32_cast_int(0xCDEF0123); +pub const LINUX_REBOOT_CMD_CAD_ON: c_int = u32_cast_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 = u32_cast_int(0xA1B2C3D4); +pub const LINUX_REBOOT_CMD_SW_SUSPEND: c_int = u32_cast_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: crate::tcflag_t = 0o0010017; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const FF1: crate::tcflag_t = 0x00008000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const VT1: crate::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 IUCLC: crate::tcflag_t = 0x00000200; +pub const IXON: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XCASE: crate::tcflag_t = 0o000004; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const BOTHER: crate::speed_t = 0o010000; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; +pub const IBSHIFT: crate::tcflag_t = 16; + +pub const BLKIOMIN: c_int = 0x1278; +pub const BLKIOOPT: c_int = 0x1279; +pub const BLKSSZGET: c_int = 0x1268; +pub const BLKPBSZGET: c_int = 0x127B; + +pub const EAI_AGAIN: c_int = 2; +pub const EAI_BADFLAGS: c_int = 3; +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 NLM_F_NONREC: c_int = 0x100; +pub const NLM_F_BULK: c_int = 0x200; + +pub const NLM_F_CAPPED: c_int = 0x100; +pub const NLM_F_ACK_TLVS: c_int = 0x200; + +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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_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 << 0; +pub const SECCOMP_FILTER_FLAG_LOG: c_ulong = 1 << 1; +pub const SECCOMP_FILTER_FLAG_SPEC_ALLOW: c_ulong = 1 << 2; +pub const SECCOMP_FILTER_FLAG_NEW_LISTENER: c_ulong = 1 << 3; +pub const SECCOMP_FILTER_FLAG_TSYNC_ESRCH: c_ulong = 1 << 4; +pub const SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV: c_ulong = 1 << 5; + +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 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; + +const SECCOMP_IOC_MAGIC: u32 = b'!' as u32; + +pub const SECCOMP_IOCTL_NOTIF_RECV: Ioctl = _IOWR::(SECCOMP_IOC_MAGIC, 0); +pub const SECCOMP_IOCTL_NOTIF_SEND: Ioctl = _IOWR::(SECCOMP_IOC_MAGIC, 1); +pub const SECCOMP_IOCTL_NOTIF_ID_VALID: Ioctl = _IOW::(SECCOMP_IOC_MAGIC, 2); +pub const SECCOMP_IOCTL_NOTIF_ADDFD: Ioctl = _IOW::(SECCOMP_IOC_MAGIC, 3); +pub const SECCOMP_IOCTL_NOTIF_SET_FLAGS: Ioctl = _IOW::(SECCOMP_IOC_MAGIC, 4); + +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: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::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: crate::tcflag_t = 0x00004000; +pub const CMSPAR: crate::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 = u32_cast_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_INET_INGRESS: c_int = NF_INET_NUMHOOKS; + +pub const NF_NETDEV_INGRESS: c_int = 0; +pub const NF_NETDEV_EGRESS: c_int = 1; +pub const NF_NETDEV_NUMHOOKS: c_int = 2; + +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_arp.h +pub const NF_ARP: c_int = 0; +pub const NF_ARP_IN: c_int = 0; +pub const NF_ARP_OUT: c_int = 1; +pub const NF_ARP_FORWARD: c_int = 2; +pub const NF_ARP_NUMHOOKS: c_int = 3; + +// linux/netfilter_bridge.h +pub const NF_BR_PRE_ROUTING: c_int = 0; +pub const NF_BR_LOCAL_IN: c_int = 1; +pub const NF_BR_FORWARD: c_int = 2; +pub const NF_BR_LOCAL_OUT: c_int = 3; +pub const NF_BR_POST_ROUTING: c_int = 4; +pub const NF_BR_BROUTING: c_int = 5; +pub const NF_BR_NUMHOOKS: c_int = 6; + +pub const NF_BR_PRI_FIRST: c_int = crate::INT_MIN; +pub const NF_BR_PRI_NAT_DST_BRIDGED: c_int = -300; +pub const NF_BR_PRI_FILTER_BRIDGED: c_int = -200; +pub const NF_BR_PRI_BRNF: c_int = 0; +pub const NF_BR_PRI_NAT_DST_OTHER: c_int = 100; +pub const NF_BR_PRI_FILTER_OTHER: c_int = 200; +pub const NF_BR_PRI_NAT_SRC: c_int = 300; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const NF_BR_PRI_LAST: c_int = crate::INT_MAX; + +// 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 = crate::INT_MIN; +pub const NF_IP_PRI_RAW_BEFORE_DEFRAG: c_int = -450; +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 = crate::INT_MAX; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const NF_IP_PRI_LAST: c_int = crate::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 = crate::INT_MIN; +pub const NF_IP6_PRI_RAW_BEFORE_DEFRAG: c_int = -450; +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const NF_IP6_PRI_LAST: c_int = crate::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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const FF_MAX: crate::__u16 = 0x7f; + +pub const FF_CNT: usize = FF_MAX as usize + 1; + +// linux/input-event-codes.h +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const INPUT_PROP_MAX: crate::__u16 = 0x1f; + +pub const INPUT_PROP_CNT: usize = INPUT_PROP_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const EV_MAX: crate::__u16 = 0x1f; + +pub const EV_CNT: usize = EV_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const SYN_MAX: crate::__u16 = 0xf; + +pub const SYN_CNT: usize = SYN_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const KEY_MAX: crate::__u16 = 0x2ff; + +pub const KEY_CNT: usize = KEY_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const REL_MAX: crate::__u16 = 0x0f; + +pub const REL_CNT: usize = REL_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const ABS_MAX: crate::__u16 = 0x3f; + +pub const ABS_CNT: usize = ABS_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const SW_MAX: crate::__u16 = 0x0f; + +pub const SW_CNT: usize = SW_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const MSC_MAX: crate::__u16 = 0x07; + +pub const MSC_CNT: usize = MSC_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const LED_MAX: crate::__u16 = 0x0f; + +pub const LED_CNT: usize = LED_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const REP_MAX: crate::__u16 = 0x01; + +pub const REP_CNT: usize = REP_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const SND_MAX: crate::__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; + +// 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; +pub const SOF_TIMESTAMPING_BIND_PHC: c_uint = 1 << 15; +pub const SOF_TIMESTAMPING_OPT_ID_TCP: c_uint = 1 << 16; +pub const SOF_TIMESTAMPING_OPT_RX_FILTER: c_uint = 1 << 17; + +#[deprecated( + since = "0.2.55", + note = "ENOATTR is not available on Android; use ENODATA instead" +)] +pub const ENOATTR: c_int = crate::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); + +pub const FUTEX2_SIZE_U8: c_int = 0x00; +pub const FUTEX2_SIZE_U16: c_int = 0x01; +pub const FUTEX2_SIZE_U32: c_int = 0x02; +pub const FUTEX2_SIZE_U64: c_int = 0x03; +pub const FUTEX2_NUMA: c_int = 0x04; +pub const FUTEX2_PRIVATE: c_int = FUTEX_PRIVATE_FLAG; +pub const FUTEX2_SIZE_MASK: c_int = 0x03; +pub const FUTEX_32: c_int = FUTEX2_SIZE_U32; +pub const FUTEX_WAITV_MAX: c_int = 128; + +// 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; +pub const CLONE_CLEAR_SIGHAND: c_ulonglong = 0x100000000; +pub const CLONE_INTO_CGROUP: c_ulonglong = 0x200000000; + +// 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/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_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 = (-1 as c_long) as c_ulong; +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_SVE_SET_VL: c_int = 50; +pub const PR_SVE_SET_VL_ONEXEC: c_int = 1 << 18; +pub const PR_SVE_GET_VL: c_int = 51; +pub const PR_SVE_VL_LEN_MASK: c_int = 0xffff; +pub const PR_SVE_VL_INHERIT: c_int = 1 << 17; +pub const PR_GET_SPECULATION_CTRL: c_int = 52; +pub const PR_SET_SPECULATION_CTRL: c_int = 53; +pub const PR_SPEC_STORE_BYPASS: c_int = 0; +pub const PR_SPEC_INDIRECT_BRANCH: c_int = 1; +pub const PR_SPEC_L1D_FLUSH: c_int = 2; +pub const PR_SPEC_NOT_AFFECTED: c_int = 0; +pub const PR_SPEC_PRCTL: c_ulong = 1 << 0; +pub const PR_SPEC_ENABLE: c_ulong = 1 << 1; +pub const PR_SPEC_DISABLE: c_ulong = 1 << 2; +pub const PR_SPEC_FORCE_DISABLE: c_ulong = 1 << 3; +pub const PR_SPEC_DISABLE_NOEXEC: c_ulong = 1 << 4; +pub const PR_PAC_RESET_KEYS: c_int = 54; +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_SET_TAGGED_ADDR_CTRL: c_int = 55; +pub const PR_GET_TAGGED_ADDR_CTRL: c_int = 56; +pub const PR_TAGGED_ADDR_ENABLE: c_ulong = 1 << 0; +pub const PR_MTE_TCF_NONE: c_ulong = 0; +pub const PR_MTE_TCF_SYNC: c_ulong = 1 << 1; +pub const PR_MTE_TCF_ASYNC: c_ulong = 1 << 2; +pub const PR_MTE_TCF_MASK: c_ulong = PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC; +pub const PR_MTE_TAG_SHIFT: c_ulong = 3; +pub const PR_MTE_TAG_MASK: c_ulong = 0xffff << PR_MTE_TAG_SHIFT; +pub const PR_MTE_TCF_SHIFT: c_ulong = 1; +pub const PR_SET_IO_FLUSHER: c_int = 57; +pub const PR_GET_IO_FLUSHER: c_int = 58; +pub const PR_SET_SYSCALL_USER_DISPATCH: c_int = 59; +pub const PR_SYS_DISPATCH_OFF: c_int = 0; +pub const PR_SYS_DISPATCH_ON: c_int = 1; +pub const SYSCALL_DISPATCH_FILTER_ALLOW: c_int = 0; +pub const SYSCALL_DISPATCH_FILTER_BLOCK: c_int = 1; +pub const PR_PAC_SET_ENABLED_KEYS: c_int = 60; +pub const PR_PAC_GET_ENABLED_KEYS: c_int = 61; +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 PR_SME_SET_VL: c_int = 63; +pub const PR_SME_SET_VL_ONEXEC: c_int = 1 << 18; +pub const PR_SME_GET_VL: c_int = 64; +pub const PR_SME_VL_LEN_MASK: c_int = 0xffff; +pub const PR_SME_VL_INHERIT: c_int = 1 << 17; +pub const PR_SET_MDWE: c_int = 65; +pub const PR_MDWE_REFUSE_EXEC_GAIN: c_ulong = 1 << 0; +pub const PR_MDWE_NO_INHERIT: c_ulong = 1 << 1; +pub const PR_GET_MDWE: c_int = 66; +pub const PR_SET_VMA: c_int = 0x53564d41; +pub const PR_SET_VMA_ANON_NAME: c_int = 0; +pub const PR_GET_AUXV: c_int = 0x41555856; +pub const PR_SET_MEMORY_MERGE: c_int = 67; +pub const PR_GET_MEMORY_MERGE: c_int = 68; +pub const PR_RISCV_V_SET_CONTROL: c_int = 69; +pub const PR_RISCV_V_GET_CONTROL: c_int = 70; +pub const PR_RISCV_V_VSTATE_CTRL_DEFAULT: c_int = 0; +pub const PR_RISCV_V_VSTATE_CTRL_OFF: c_int = 1; +pub const PR_RISCV_V_VSTATE_CTRL_ON: c_int = 2; +pub const PR_RISCV_V_VSTATE_CTRL_INHERIT: c_int = 1 << 4; +pub const PR_RISCV_V_VSTATE_CTRL_CUR_MASK: c_int = 0x3; +pub const PR_RISCV_V_VSTATE_CTRL_NEXT_MASK: c_int = 0xc; +pub const PR_RISCV_V_VSTATE_CTRL_MASK: c_int = 0x1f; + +// 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_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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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_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 = u32_cast_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_HWCAP3: c_ulong = 29; +pub const AT_HWCAP4: c_ulong = 30; +pub const AT_EXECFN: c_ulong = 31; +pub const AT_MINSIGSTKSZ: c_ulong = 51; + +// siginfo.h +pub const SI_DETHREAD: c_int = -7; +pub const TRAP_PERF: c_int = 6; + +// 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; +pub const RWF_NOAPPEND: c_int = 0x00000020; +pub const RWF_ATOMIC: c_int = 0x00000040; +pub const RWF_DONTCACHE: c_int = 0x00000080; + +// 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 unsafe 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 { + ptr::null_mut() + } else { + next.cast() + } + } + + pub unsafe fn CPU_ALLOC_SIZE(count: c_int) -> size_t { + let _dummy: cpu_set_t = mem::zeroed(); + let size_in_bits = 8 * size_of_val(&_dummy.__bits[0]); + ((count as size_t + size_in_bits - 1) / 8) as size_t + } + + pub unsafe fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + cpuset.__bits.fill(0); + } + + pub unsafe fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits = 8 * 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 unsafe fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits = 8 * 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 unsafe fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let size_in_bits = 8 * size_of_val(&cpuset.__bits[0]); + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + 0 != (cpuset.__bits[idx] & (1 << offset)) + } + + pub unsafe fn CPU_COUNT_S(size: usize, cpuset: &cpu_set_t) -> c_int { + let mut s: u32 = 0; + let size_of_mask = 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 unsafe fn CPU_COUNT(cpuset: &cpu_set_t) -> c_int { + CPU_COUNT_S(size_of::(), cpuset) + } + + pub unsafe fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.__bits == set2.__bits + } + + pub unsafe fn NLA_ALIGN(len: c_int) -> c_int { + return ((len) + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1); + } + + pub unsafe fn SO_EE_OFFENDER(ee: *const crate::sock_extended_err) -> *mut crate::sockaddr { + ee.offset(1) as *mut crate::sockaddr + } +} + +safe_f! { + pub const safe fn makedev(ma: c_uint, mi: c_uint) -> crate::dev_t { + let ma = ma as crate::dev_t; + let mi = mi as crate::dev_t; + ((ma & 0xfff) << 8) | (mi & 0xff) | ((mi & 0xfff00) << 12) + } + + pub const safe fn major(dev: crate::dev_t) -> c_int { + ((dev >> 8) & 0xfff) as c_int + } + + pub const safe fn minor(dev: crate::dev_t) -> c_int { + ((dev & 0xff) | ((dev >> 12) & 0xfff00)) as c_int + } +} + +extern "C" { + pub fn setpwent(); + pub fn endpwent(); + pub fn getpwent() -> *mut passwd; + pub fn setgrent(); + pub fn endgrent(); + pub fn getgrent() -> *mut crate::group; + 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 crate::rlimit) -> c_int; + pub fn setrlimit(resource: c_int, rlim: *const crate::rlimit) -> c_int; + pub fn prlimit( + pid: crate::pid_t, + resource: c_int, + new_limit: *const crate::rlimit, + old_limit: *mut crate::rlimit, + ) -> c_int; + pub fn prlimit64( + pid: crate::pid_t, + resource: c_int, + new_limit: *const crate::rlimit64, + old_limit: *mut crate::rlimit64, + ) -> c_int; + pub fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t) -> c_int; + + pub fn gettimeofday(tp: *mut crate::timeval, tz: *mut crate::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 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 getnameinfo( + sa: *const crate::sockaddr, + salen: crate::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 crate::iovec, count: c_int, offset: off_t) -> ssize_t; + pub fn pwritev(fd: c_int, iov: *const crate::iovec, count: c_int, offset: off_t) -> ssize_t; + pub fn process_vm_readv( + pid: crate::pid_t, + local_iov: *const crate::iovec, + local_iov_count: c_ulong, + remote_iov: *const crate::iovec, + remote_iov_count: c_ulong, + flags: c_ulong, + ) -> ssize_t; + pub fn process_vm_writev( + pid: crate::pid_t, + local_iov: *const crate::iovec, + local_iov_count: c_ulong, + remote_iov: *const crate::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: crate::id_t) -> c_int; + pub fn setpriority(which: c_int, who: crate::id_t, prio: c_int) -> c_int; + pub fn __sched_cpualloc(count: size_t) -> *mut crate::cpu_set_t; + pub fn __sched_cpufree(set: *mut crate::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() -> crate::mallinfo; + // available from API 23 + pub fn malloc_info(options: c_int, stream: *mut crate::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 crate::DIR, loc: c_long); + pub fn telldir(dirp: *mut crate::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 crate::sigset_t, flags: c_int) -> c_int; + pub fn timerfd_create(clock: crate::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 timer_create( + clockid: crate::clockid_t, + sevp: *mut crate::sigevent, + timerid: *mut crate::timer_t, + ) -> c_int; + pub fn timer_delete(timerid: crate::timer_t) -> c_int; + pub fn timer_getoverrun(timerid: crate::timer_t) -> c_int; + pub fn timer_gettime(timerid: crate::timer_t, curr_value: *mut crate::itimerspec) -> c_int; + pub fn timer_settime( + timerid: crate::timer_t, + flags: c_int, + new_value: *const crate::itimerspec, + old_value: *mut crate::itimerspec, + ) -> c_int; + pub fn syscall(num: c_long, ...) -> c_long; + pub fn sched_getaffinity( + pid: crate::pid_t, + cpusetsize: size_t, + cpuset: *mut cpu_set_t, + ) -> c_int; + pub fn sched_setaffinity( + pid: crate::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 crate::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 crate::epoll_event) -> 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 crate::timeval, tz: *const crate::timezone) -> c_int; + pub fn splice( + fd_in: c_int, + off_in: *mut crate::loff_t, + fd_out: c_int, + off_out: *mut crate::loff_t, + len: size_t, + flags: c_uint, + ) -> ssize_t; + pub fn eventfd(initval: 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: crate::pid_t, tp: *mut crate::timespec) -> c_int; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const crate::timespec) -> c_int; + pub fn sem_getvalue(sem: *mut sem_t, sval: *mut c_int) -> c_int; + pub fn sched_setparam(pid: crate::pid_t, param: *const crate::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 crate::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: crate::pid_t, param: *mut crate::sched_param) -> c_int; + pub fn ppoll( + fds: *mut crate::pollfd, + nfds: nfds_t, + timeout: *const crate::timespec, + sigmask: *const sigset_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: crate::pid_t) -> c_int; + pub fn clock_nanosleep( + clk_id: crate::clockid_t, + flags: c_int, + rqtp: *const crate::timespec, + rmtp: *mut crate::timespec, + ) -> 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 sysinfo(info: *mut crate::sysinfo) -> 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: crate::pid_t, + policy: c_int, + param: *const crate::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: crate::gid_t) -> c_int; + pub fn setfsuid(uid: crate::uid_t) -> c_int; + pub fn sigsuspend(mask: *const crate::sigset_t) -> c_int; + pub fn getgrgid_r( + gid: crate::gid_t, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::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 crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn sem_open(name: *const c_char, oflag: c_int, ...) -> *mut sem_t; + pub fn getgrnam(name: *const c_char) -> *mut crate::group; + pub fn sem_unlink(name: *const c_char) -> c_int; + pub fn daemon(nochdir: c_int, noclose: c_int) -> c_int; + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const crate::timespec, + ) -> c_int; + pub fn sigwait(set: *const sigset_t, sig: *mut c_int) -> c_int; + pub fn getgrgid(gid: crate::gid_t) -> *mut crate::group; + pub fn getgrouplist( + user: *const c_char, + group: crate::gid_t, + groups: *mut crate::gid_t, + ngroups: *mut c_int, + ) -> c_int; + pub fn initgroups(user: *const c_char, group: crate::gid_t) -> c_int; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut crate::FILE; + pub fn faccessat(dirfd: c_int, pathname: *const c_char, mode: c_int, flags: c_int) -> c_int; + pub fn __errno() -> *mut c_int; + pub fn inotify_rm_watch(fd: c_int, wd: u32) -> 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 crate::regex_t, pattern: *const c_char, cflags: c_int) -> c_int; + + pub fn regexec( + preg: *const crate::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 crate::regex_t, + errbuf: *mut c_char, + errbuf_size: size_t, + ) -> size_t; + + pub fn regfree(preg: *mut crate::regex_t); + + pub fn android_set_abort_message(msg: *const c_char); + + pub fn gettid() -> crate::pid_t; + + pub fn tgkill(tgid: crate::pid_t, tid: crate::pid_t, sig: c_int) -> c_int; + + pub fn getauxval(type_: c_ulong) -> c_ulong; + + /// 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 __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 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 crate::FILE, + ) -> size_t; + pub fn fwrite_unlocked( + buf: *const c_void, + size: size_t, + nobj: size_t, + stream: *mut crate::FILE, + ) -> size_t; + pub fn fflush_unlocked(stream: *mut crate::FILE) -> c_int; + pub fn fgets_unlocked(buf: *mut c_char, size: c_int, stream: *mut crate::FILE) -> *mut c_char; + + pub fn klogctl(syslog_type: c_int, bufp: *mut c_char, len: c_int) -> c_int; + + pub fn memfd_create(name: *const c_char, flags: c_uint) -> c_int; + pub fn renameat2( + olddirfd: c_int, + oldpath: *const c_char, + newdirfd: c_int, + newpath: *const c_char, + flags: c_uint, + ) -> c_int; + pub fn preadv2( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: off_t, + flags: c_int, + ) -> ssize_t; + pub fn pwritev2( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: off_t, + flags: c_int, + ) -> ssize_t; +} + +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).cast::()).si_addr + } + + pub unsafe fn si_value(&self) -> crate::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: crate::sigval, + } + (*(self as *const siginfo_t).cast::()).si_sigval + } +} + +impl siginfo_t { + unsafe fn sifields(&self) -> &sifields { + &(*(self as *const siginfo_t).cast::()).sifields + } + + pub unsafe fn si_pid(&self) -> crate::pid_t { + self.sifields().sigchld.si_pid + } + + pub unsafe fn si_uid(&self) -> crate::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/lfs64.rs b/vendor/libc/src/unix/linux_like/emscripten/lfs64.rs new file mode 100644 index 0000000..5ced327 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/emscripten/lfs64.rs @@ -0,0 +1,214 @@ +use crate::off64_t; +use crate::prelude::*; + +// 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: crate::mode_t) -> c_int { + crate::creat(path, mode) +} + +#[inline] +pub unsafe extern "C" fn fgetpos64(stream: *mut crate::FILE, pos: *mut crate::fpos64_t) -> c_int { + crate::fgetpos(stream, pos.cast()) +} + +#[inline] +pub unsafe extern "C" fn fopen64(pathname: *const c_char, mode: *const c_char) -> *mut crate::FILE { + crate::fopen(pathname, mode) +} + +#[inline] +pub unsafe extern "C" fn freopen64( + pathname: *const c_char, + mode: *const c_char, + stream: *mut crate::FILE, +) -> *mut crate::FILE { + crate::freopen(pathname, mode, stream) +} + +#[inline] +pub unsafe extern "C" fn fseeko64( + stream: *mut crate::FILE, + offset: off64_t, + whence: c_int, +) -> c_int { + crate::fseeko(stream, offset, whence) +} + +#[inline] +pub unsafe extern "C" fn fsetpos64(stream: *mut crate::FILE, pos: *const crate::fpos64_t) -> c_int { + crate::fsetpos(stream, pos.cast()) +} + +#[inline] +pub unsafe extern "C" fn fstat64(fildes: c_int, buf: *mut crate::stat64) -> c_int { + crate::fstat(fildes, buf.cast()) +} + +#[inline] +pub unsafe extern "C" fn fstatat64( + fd: c_int, + path: *const c_char, + buf: *mut crate::stat64, + flag: c_int, +) -> c_int { + crate::fstatat(fd, path, buf.cast(), flag) +} + +#[inline] +pub unsafe extern "C" fn fstatfs64(fd: c_int, buf: *mut crate::statfs64) -> c_int { + crate::fstatfs(fd, buf.cast()) +} + +#[inline] +pub unsafe extern "C" fn fstatvfs64(fd: c_int, buf: *mut crate::statvfs64) -> c_int { + crate::fstatvfs(fd, buf.cast()) +} + +#[inline] +pub unsafe extern "C" fn ftello64(stream: *mut crate::FILE) -> off64_t { + crate::ftello(stream) +} + +#[inline] +pub unsafe extern "C" fn ftruncate64(fd: c_int, length: off64_t) -> c_int { + crate::ftruncate(fd, length) +} + +#[inline] +pub unsafe extern "C" fn getrlimit64(resource: c_int, rlim: *mut crate::rlimit64) -> c_int { + crate::getrlimit(resource, rlim.cast()) +} + +#[inline] +pub unsafe extern "C" fn lseek64(fd: c_int, offset: off64_t, whence: c_int) -> off64_t { + crate::lseek(fd, offset, whence) +} + +#[inline] +pub unsafe extern "C" fn lstat64(path: *const c_char, buf: *mut crate::stat64) -> c_int { + crate::lstat(path, buf.cast()) +} + +#[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 { + crate::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 crate::{ + open as open64, + 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 { + crate::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 { + crate::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 { + crate::pread(fd, buf, count, offset) +} + +#[inline] +pub unsafe extern "C" fn preadv64( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: off64_t, +) -> ssize_t { + crate::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 { + crate::pwrite(fd, buf, count, offset) +} + +#[inline] +pub unsafe extern "C" fn pwritev64( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: off64_t, +) -> ssize_t { + crate::pwritev(fd, iov, iovcnt, offset) +} + +#[inline] +pub unsafe extern "C" fn readdir64(dirp: *mut crate::DIR) -> *mut crate::dirent64 { + crate::readdir(dirp).cast() +} + +#[inline] +pub unsafe extern "C" fn readdir64_r( + dirp: *mut crate::DIR, + entry: *mut crate::dirent64, + result: *mut *mut crate::dirent64, +) -> c_int { + crate::readdir_r(dirp, entry.cast(), result.cast()) +} + +#[inline] +pub unsafe extern "C" fn setrlimit64(resource: c_int, rlim: *const crate::rlimit64) -> c_int { + crate::setrlimit(resource, rlim.cast()) +} + +#[inline] +pub unsafe extern "C" fn stat64(pathname: *const c_char, statbuf: *mut crate::stat64) -> c_int { + crate::stat(pathname, statbuf.cast()) +} + +#[inline] +pub unsafe extern "C" fn statfs64(pathname: *const c_char, buf: *mut crate::statfs64) -> c_int { + crate::statfs(pathname, buf.cast()) +} + +#[inline] +pub unsafe extern "C" fn statvfs64(path: *const c_char, buf: *mut crate::statvfs64) -> c_int { + crate::statvfs(path, buf.cast()) +} + +#[inline] +pub unsafe extern "C" fn tmpfile64() -> *mut crate::FILE { + crate::tmpfile() +} + +#[inline] +pub unsafe extern "C" fn truncate64(path: *const c_char, length: off64_t) -> c_int { + crate::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..7a28d89 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/emscripten/mod.rs @@ -0,0 +1,1473 @@ +use crate::prelude::*; + +pub type wchar_t = i32; +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 = i64; +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 nlink_t = u32; + +pub type ino64_t = crate::ino_t; +pub type off64_t = off_t; +pub type blkcnt64_t = crate::blkcnt_t; +pub type rlim64_t = crate::rlim_t; + +pub type rlimit64 = crate::rlimit; +pub type flock64 = crate::flock; +pub type stat64 = crate::stat; +pub type statfs64 = crate::statfs; +pub type statvfs64 = crate::statvfs; +pub type dirent64 = crate::dirent; + +extern_ty! { + pub type fpos64_t; // FIXME(emscripten): fill this out with a struct +} + +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: Padding<*mut c_void>, + __unused2: Padding<*mut c_void>, + __unused3: Padding<*mut c_void>, + __unused4: Padding<*mut c_void>, + __unused5: Padding<*mut c_void>, + } + + pub struct passwd { + pub pw_name: *mut c_char, + pub pw_passwd: *mut c_char, + pub pw_uid: crate::uid_t, + pub pw_gid: crate::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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::fsfilcnt_t, + pub f_fsid: c_ulong, + __f_unused: Padding, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + __f_spare: [c_int; 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: u64, + pub ssi_utime: u64, + pub ssi_stime: u64, + pub ssi_addr: u64, + pub ssi_addr_lsb: u16, + _pad2: Padding, + pub ssi_syscall: i32, + pub ssi_call_addr: u64, + pub ssi_arch: u32, + _pad: Padding<[u8; 28]>, + } + + pub struct fsid_t { + __val: [c_int; 2], + } + + pub struct cpu_set_t { + bits: [u32; 32], + } + + // 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, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + pub struct ipc_perm { + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: mode_t, + pub __seq: c_int, + __unused1: Padding, + __unused2: Padding, + } + + pub struct termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; crate::NCCS], + pub __c_ispeed: crate::speed_t, + pub __c_ospeed: crate::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: crate::pid_t, + } + + pub struct pthread_attr_t { + // 11 pointer-width words: 44 bytes on wasm32, 88 on wasm64 (MEMORY64). + __size: [usize; 11], + } + + pub struct sigset_t { + __val: [c_ulong; 32], + } + + pub struct msghdr { + pub msg_name: *mut c_void, + pub msg_namelen: crate::socklen_t, + pub msg_iov: *mut crate::iovec, + pub msg_iovlen: c_int, + pub msg_control: *mut c_void, + pub msg_controllen: crate::socklen_t, + pub msg_flags: c_int, + } + + pub struct cmsghdr { + pub cmsg_len: crate::socklen_t, + pub cmsg_level: c_int, + pub cmsg_type: c_int, + } + + pub struct in6_pktinfo { + pub ipi6_addr: crate::in6_addr, + pub ipi6_ifindex: c_uint, + } + + pub struct sem_t { + __val: [c_int; 4], + } + pub struct stat { + pub st_dev: crate::dev_t, + #[cfg(emscripten_old_stat_abi)] + __st_dev_padding: Padding, + #[cfg(emscripten_old_stat_abi)] + __st_ino_truncated: c_long, + pub st_mode: mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + #[cfg(emscripten_old_stat_abi)] + __st_rdev_padding: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_ino: crate::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: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: c_ulong, + __pad1: Padding, + __pad2: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + pub msg_stime: crate::time_t, + pub msg_rtime: crate::time_t, + pub msg_ctime: crate::time_t, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __pad1: Padding, + __pad2: Padding, + } + + pub struct statfs { + pub f_type: c_ulong, + pub f_bsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::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; crate::MAX_ADDR_LEN], + } + + #[repr(align(4))] + pub struct pthread_mutex_t { + size: [u8; crate::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[repr(align(4))] + pub struct pthread_rwlock_t { + size: [u8; crate::__SIZEOF_PTHREAD_RWLOCK_T], + } + + #[repr(align(4))] + pub struct pthread_mutexattr_t { + size: [u8; crate::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[repr(align(4))] + pub struct pthread_rwlockattr_t { + size: [u8; crate::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + size: [u8; crate::__SIZEOF_PTHREAD_CONDATTR_T], + } + + pub struct dirent { + pub d_ino: crate::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: Padding<[c_long; 4]>, + } + + #[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; crate::__SIZEOF_PTHREAD_COND_T], + } +} + +s_no_extra_traits! { + #[repr(align(8))] + pub struct max_align_t { + priv_: [f64; 3], + } +} + +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: crate::nl_item = 0x20000; +pub const ABDAY_2: crate::nl_item = 0x20001; +pub const ABDAY_3: crate::nl_item = 0x20002; +pub const ABDAY_4: crate::nl_item = 0x20003; +pub const ABDAY_5: crate::nl_item = 0x20004; +pub const ABDAY_6: crate::nl_item = 0x20005; +pub const ABDAY_7: crate::nl_item = 0x20006; + +pub const DAY_1: crate::nl_item = 0x20007; +pub const DAY_2: crate::nl_item = 0x20008; +pub const DAY_3: crate::nl_item = 0x20009; +pub const DAY_4: crate::nl_item = 0x2000A; +pub const DAY_5: crate::nl_item = 0x2000B; +pub const DAY_6: crate::nl_item = 0x2000C; +pub const DAY_7: crate::nl_item = 0x2000D; + +pub const ABMON_1: crate::nl_item = 0x2000E; +pub const ABMON_2: crate::nl_item = 0x2000F; +pub const ABMON_3: crate::nl_item = 0x20010; +pub const ABMON_4: crate::nl_item = 0x20011; +pub const ABMON_5: crate::nl_item = 0x20012; +pub const ABMON_6: crate::nl_item = 0x20013; +pub const ABMON_7: crate::nl_item = 0x20014; +pub const ABMON_8: crate::nl_item = 0x20015; +pub const ABMON_9: crate::nl_item = 0x20016; +pub const ABMON_10: crate::nl_item = 0x20017; +pub const ABMON_11: crate::nl_item = 0x20018; +pub const ABMON_12: crate::nl_item = 0x20019; + +pub const MON_1: crate::nl_item = 0x2001A; +pub const MON_2: crate::nl_item = 0x2001B; +pub const MON_3: crate::nl_item = 0x2001C; +pub const MON_4: crate::nl_item = 0x2001D; +pub const MON_5: crate::nl_item = 0x2001E; +pub const MON_6: crate::nl_item = 0x2001F; +pub const MON_7: crate::nl_item = 0x20020; +pub const MON_8: crate::nl_item = 0x20021; +pub const MON_9: crate::nl_item = 0x20022; +pub const MON_10: crate::nl_item = 0x20023; +pub const MON_11: crate::nl_item = 0x20024; +pub const MON_12: crate::nl_item = 0x20025; + +pub const AM_STR: crate::nl_item = 0x20026; +pub const PM_STR: crate::nl_item = 0x20027; + +pub const D_T_FMT: crate::nl_item = 0x20028; +pub const D_FMT: crate::nl_item = 0x20029; +pub const T_FMT: crate::nl_item = 0x2002A; +pub const T_FMT_AMPM: crate::nl_item = 0x2002B; + +pub const ERA: crate::nl_item = 0x2002C; +pub const ERA_D_FMT: crate::nl_item = 0x2002E; +pub const ALT_DIGITS: crate::nl_item = 0x2002F; +pub const ERA_D_T_FMT: crate::nl_item = 0x20030; +pub const ERA_T_FMT: crate::nl_item = 0x20031; + +pub const CODESET: crate::nl_item = 14; + +pub const CRNCYSTR: crate::nl_item = 0x4000F; + +pub const RUSAGE_THREAD: c_int = 1; +pub const RUSAGE_CHILDREN: c_int = -1; + +pub const RADIXCHAR: crate::nl_item = 0x10000; +pub const THOUSEP: crate::nl_item = 0x10001; + +pub const YESEXPR: crate::nl_item = 0x50000; +pub const NOEXPR: crate::nl_item = 0x50001; +pub const YESSTR: crate::nl_item = 0x50002; +pub const NOSTR: crate::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: crate::rlim_t = RLIM_INFINITY; +pub const RLIM_SAVED_CUR: crate::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 = 0o0100; +pub const S_IWRITE: mode_t = 0o0200; +pub const S_IREAD: mode_t = 0o0400; + +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 = ptr::null_mut(); +pub const RTLD_NODELETE: c_int = 0x1000; +pub const RTLD_NOW: c_int = 0x2; + +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: crate::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 LOG_NFACILITIES: c_int = 24; + +pub const SEM_FAILED: *mut crate::sem_t = ptr::null_mut(); + +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 MREMAP_MAYMOVE: c_int = 1; +pub const MREMAP_FIXED: c_int = 2; + +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: crate::cc_t = 0; + +pub const FALLOC_FL_KEEP_SIZE: c_int = 0x01; +pub const FALLOC_FL_PUNCH_HOLE: c_int = 0x02; + +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 = u32_cast_int(0x80000000); +pub const SA_RESTART: c_int = 0x10000000; +pub const SA_NOCLDSTOP: c_int = 0x00000001; + +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: crate::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: crate::rlim_t = !0; +#[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; + +#[doc(hidden)] +#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] +pub const SIGUNUSED: c_int = crate::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 = 1024; + +pub const TCSANOW: c_int = 0; +pub const TCSADRAIN: c_int = 1; +pub const TCSAFLUSH: c_int = 2; + +pub const TIOCINQ: c_int = crate::FIONREAD; + +pub const RTLD_GLOBAL: c_int = 0x100; +pub const RTLD_NOLOAD: c_int = 0x4; + +pub const CLOCK_SGI_CYCLE: crate::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: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; + +pub const SO_BINDTODEVICE: c_int = 25; +pub const SO_TIMESTAMP: c_int = 63; +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; + +#[cfg(target_pointer_width = "32")] +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; +#[cfg(target_pointer_width = "64")] +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +#[cfg(target_pointer_width = "32")] +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24; +#[cfg(target_pointer_width = "64")] +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + +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 = 263; + +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 = 66; +pub const SO_SNDTIMEO: c_int = 67; +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: crate::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: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::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 = 0x410000; + +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 unsafe fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { + if ((*cmsg).cmsg_len as usize) < size_of::() { + return ptr::null_mut(); + } + 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 { + ptr::null_mut() + } else { + next.cast() + } + } + + pub unsafe fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + cpuset.bits.fill(0); + } + + pub unsafe fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits = 8 * 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 unsafe fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits = 8 * 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 unsafe fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + 0 != (cpuset.bits[idx] & (1 << offset)) + } + + pub unsafe fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.bits == set2.bits + } +} + +safe_f! { + pub const safe fn makedev(major: c_uint, minor: c_uint) -> crate::dev_t { + let major = major as crate::dev_t; + let minor = minor as crate::dev_t; + let mut dev = 0; + dev |= (major & 0xfffff000) << 31 << 1; + dev |= (major & 0x00000fff) << 8; + dev |= (minor & 0xffffff00) << 12; + dev |= minor & 0x000000ff; + dev + } + + pub const safe fn major(dev: crate::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 >> 31 >> 1) & 0xfffff000; + major |= (dev >> 8) & 0x00000fff; + major as c_uint + } + + pub const safe fn minor(dev: crate::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 >> 12) & 0xffffff00; + minor |= dev & 0x000000ff; + minor as c_uint + } +} + +extern "C" { + pub fn getrlimit(resource: c_int, rlim: *mut crate::rlimit) -> c_int; + pub fn setrlimit(resource: c_int, rlim: *const crate::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 crate::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 crate::iovec, iovcnt: c_int, offset: off_t) -> ssize_t; + pub fn preadv(fd: c_int, iov: *const crate::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 nl_langinfo_l(item: crate::nl_item, locale: crate::locale_t) -> *mut c_char; + pub fn accept4( + fd: c_int, + addr: *mut crate::sockaddr, + len: *mut crate::socklen_t, + flg: c_int, + ) -> c_int; + pub fn getnameinfo( + sa: *const crate::sockaddr, + salen: crate::socklen_t, + host: *mut c_char, + hostlen: crate::socklen_t, + serv: *mut c_char, + servlen: crate::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 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 crate::glob_t, + ) -> c_int; + pub fn globfree(pglob: *mut crate::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 crate::DIR, loc: c_long); + + pub fn telldir(dirp: *mut crate::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 crate::sockaddr, + addrlen: *mut crate::socklen_t, + ) -> ssize_t; + pub fn mkstemps(template: *mut c_char, suffixlen: c_int) -> c_int; + pub fn nl_langinfo(item: crate::nl_item) -> *mut c_char; + + pub fn sendmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: c_uint, + flags: c_uint, + ) -> c_int; + pub fn recvmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: c_uint, + flags: c_uint, + timeout: *mut crate::timespec, + ) -> c_int; + pub fn sync(); + pub fn ioctl(fd: c_int, request: c_int, ...) -> c_int; + pub fn getpriority(which: c_int, who: crate::id_t) -> c_int; + pub fn setpriority(which: c_int, who: crate::id_t, prio: c_int) -> c_int; + + pub fn getentropy(buf: *mut c_void, buflen: size_t) -> c_int; + + // grp.h + pub fn getgrgid(gid: crate::gid_t) -> *mut crate::group; + pub fn getgrnam(name: *const c_char) -> *mut crate::group; + pub fn getgrnam_r( + name: *const c_char, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn getgrgid_r( + gid: crate::gid_t, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn sigwait(set: *const crate::sigset_t, sig: *mut c_int) -> c_int; + pub fn sigwaitinfo(set: *const crate::sigset_t, info: *mut crate::siginfo_t) -> c_int; + pub fn sigtimedwait( + set: *const crate::sigset_t, + info: *mut crate::siginfo_t, + timeout: *const crate::timespec, + ) -> c_int; + pub fn faccessat(dirfd: c_int, pathname: *const c_char, mode: c_int, flags: c_int) -> c_int; +} + +// Alias to 64 to mimic glibc's LFS64 support +mod lfs64; +pub use self::lfs64::*; diff --git a/vendor/libc/src/unix/linux_like/l4re/mod.rs b/vendor/libc/src/unix/linux_like/l4re/mod.rs new file mode 100644 index 0000000..5ac4868 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/l4re/mod.rs @@ -0,0 +1,204 @@ +///! 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. +use crate::prelude::*; + +pub type l4_umword_t = c_ulong; // Unsigned machine word. +pub type pthread_t = *mut c_void; + +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 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; + +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, + } + + pub struct pthread_attr_t { + __detachstate: c_int, + __schedpolicy: c_int, + __schedparam: super::__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, + // 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; + +pub const BOTHER: crate::speed_t = 0o010000; + +pub const RLIMIT_CPU: crate::__rlimit_resource_t = 0; +pub const RLIMIT_FSIZE: crate::__rlimit_resource_t = 1; +pub const RLIMIT_DATA: crate::__rlimit_resource_t = 2; +pub const RLIMIT_STACK: crate::__rlimit_resource_t = 3; +pub const RLIMIT_CORE: crate::__rlimit_resource_t = 4; +pub const RLIMIT_RSS: crate::__rlimit_resource_t = 5; +pub const RLIMIT_NPROC: crate::__rlimit_resource_t = 6; +pub const RLIMIT_NOFILE: crate::__rlimit_resource_t = 7; +pub const RLIMIT_MEMLOCK: crate::__rlimit_resource_t = 8; +pub const RLIMIT_AS: crate::__rlimit_resource_t = 9; +pub const RLIMIT_LOCKS: crate::__rlimit_resource_t = 10; +pub const RLIMIT_SIGPENDING: crate::__rlimit_resource_t = 11; +pub const RLIMIT_MSGQUEUE: crate::__rlimit_resource_t = 12; +pub const RLIMIT_NICE: crate::__rlimit_resource_t = 13; +pub const RLIMIT_RTPRIO: crate::__rlimit_resource_t = 14; +pub const RLIMIT_RTTIME: crate::__rlimit_resource_t = 15; +pub const RLIMIT_NLIMITS: crate::__rlimit_resource_t = RLIM_NLIMITS; +pub const RLIM_NLIMITS: crate::__rlimit_resource_t = 16; + +pub const SOL_SOCKET: c_int = 1; + +// 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_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_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_PEERNAME: c_int = 28; + +pub const SO_ACCEPTCONN: c_int = 30; +pub const SO_PEERSEC: c_int = 31; + +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 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 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 TIOCGPTN: Ioctl = 0x80045430; +pub const TIOCSPTLCK: Ioctl = 0x40045431; +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 BLKSSZGET: Ioctl = 0x1268; + +cfg_if! { + if #[cfg(not(target_env = "uclibc"))] { + 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; + } +} + +cfg_if! { + if #[cfg(target_env = "uclibc")] { + mod uclibc; + pub use self::uclibc::*; + } +} diff --git a/vendor/libc/src/unix/linux_like/l4re/uclibc/aarch64/mod.rs b/vendor/libc/src/unix/linux_like/l4re/uclibc/aarch64/mod.rs new file mode 100644 index 0000000..23421f0 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/l4re/uclibc/aarch64/mod.rs @@ -0,0 +1,398 @@ +use crate::prelude::*; + +pub type wchar_t = c_uint; +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 nlink_t = c_ulong; +pub type off_t = c_long; +pub type fsword_t = c_long; +pub type suseconds_t = c_long; + +pub type blksize_t = c_long; +pub type blkcnt_t = c_long; + +pub type fsblkcnt64_t = c_ulong; +pub type fsfilcnt64_t = c_ulong; +pub type __u64 = c_ulong; + +s! { + pub struct stat { + pub st_dev: c_ulong, + pub __pad1: c_ushort, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: c_ulong, + pub __pad2: c_ushort, + pub st_size: crate::off64_t, + pub st_blksize: blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atim: crate::timespec, + pub st_mtim: crate::timespec, + pub st_ctim: crate::timespec, + pub __uclibc_unused4: c_ulong, + pub __uclibc_unused5: c_ulong, + } + + pub struct stat64 { + pub st_dev: c_ulong, + pub __pad1: c_uint, + pub __st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: c_ulong, + pub __pad2: c_uint, + pub st_size: crate::off64_t, + pub st_blksize: blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atim: crate::timespec, + pub st_mtim: crate::timespec, + pub st_ctim: crate::timespec, + pub st_ino: crate::ino64_t, + } + + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_handler: crate::sighandler_t, + pub sa_flags: c_ulong, + pub sa_restorer: Option, + pub sa_mask: sigset_t, + } + + pub struct sigset_t { + __val: [c_ulong; 1], + } + + #[repr(align(8))] + pub struct siginfo_t { + pub si_signo: c_int, + pub si_errno: c_int, + pub si_code: c_int, + pub _pad: [c_int; 28], + } + + pub struct stack_t { + pub ss_sp: *mut c_void, + pub ss_flags: c_int, + pub ss_size: crate::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: crate::pid_t, + } + + pub struct termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; crate::NCCS], + pub c_ispeed: crate::speed_t, + pub c_ospeed: crate::speed_t, + } +} + +s_no_extra_traits! { + pub union sem_t { + __size: [c_char; 32], + __align: c_longlong, + } +} + +pub const O_CLOEXEC: c_int = 0o2000000; +pub const __SIZEOF_PTHREAD_ATTR_T: usize = 36; +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_COND_COMPAT_T: usize = 12; +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 NCCS: usize = 32; + +pub const FIOQSIZE: crate::Ioctl = 0x545E; + +// 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: crate::speed_t = 0; +pub const B1000000: crate::speed_t = 0x1008; +pub const B110: crate::speed_t = 0x3; +pub const B115200: crate::speed_t = 0x1002; +pub const B1152000: crate::speed_t = 0x1009; +pub const B1200: crate::speed_t = 0x9; +pub const B134: crate::speed_t = 0x4; +pub const B150: crate::speed_t = 0x5; +pub const B1500000: crate::speed_t = 0x100a; +pub const B1800: crate::speed_t = 0xa; +pub const B19200: crate::speed_t = 0xe; +pub const B200: crate::speed_t = 0x6; +pub const B2000000: crate::speed_t = 0x100b; +pub const B230400: crate::speed_t = 0x1003; +pub const B2400: crate::speed_t = 0xb; +pub const B2500000: crate::speed_t = 0x100c; +pub const B300: crate::speed_t = 0x7; +pub const B3000000: crate::speed_t = 0x100d; +pub const B3500000: crate::speed_t = 0x100e; +pub const B38400: crate::speed_t = 0xf; +pub const B4000000: crate::speed_t = 0x100f; +pub const B460800: crate::speed_t = 0x1004; +pub const B4800: crate::speed_t = 0xc; +pub const B50: crate::speed_t = 0x1; +pub const B500000: crate::speed_t = 0x1005; +pub const B57600: crate::speed_t = 0x1001; +pub const B576000: crate::speed_t = 0x1006; +pub const B600: crate::speed_t = 0x8; +pub const B75: crate::speed_t = 0x2; +pub const B921600: crate::speed_t = 0x1007; +pub const B9600: crate::speed_t = 0xd; +pub const BS1: c_int = 0x2000; +pub const BSDLY: c_int = 0x2000; +pub const CBAUD: crate::tcflag_t = 0x100f; +pub const CBAUDEX: crate::tcflag_t = 0x1000; +pub const CIBAUD: crate::tcflag_t = 0x100f0000; +pub const CLOCAL: crate::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: crate::tcflag_t = 0x80; +pub const CS6: crate::tcflag_t = 0x10; +pub const CS7: crate::tcflag_t = 0x20; +pub const CS8: crate::tcflag_t = 0x30; +pub const CSIZE: crate::tcflag_t = 0x30; +pub const CSTOPB: crate::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: crate::tcflag_t = 0x200; +pub const ECHOE: crate::tcflag_t = 0x10; +pub const ECHOK: crate::tcflag_t = 0x20; +pub const ECHOKE: crate::tcflag_t = 0x800; +pub const ECHONL: crate::tcflag_t = 0x40; +pub const ECHOPRT: crate::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 EDESTADDRREQ: c_int = 0x59; +pub const EDOTDOT: c_int = 0x49; +pub const EDQUOT: c_int = 0x7a; +pub const EHOSTDOWN: c_int = 0x70; +pub const EHOSTUNREACH: c_int = 0x71; +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 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: crate::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: crate::tcflag_t = 0x400; +pub const ICANON: crate::tcflag_t = 0x2; +pub const IEXTEN: crate::tcflag_t = 0x8000; +pub const ISIG: crate::tcflag_t = 0x1; +pub const IXOFF: crate::tcflag_t = 0x1000; +pub const IXON: crate::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 MINSIGSTKSZ: c_int = 5120; +pub const NLDLY: crate::tcflag_t = 0x100; +pub const NOFLSH: crate::tcflag_t = 0x80; +pub const OLCUC: crate::tcflag_t = 0x2; +pub const ONLCR: crate::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: crate::tcflag_t = 0x100; +pub const PARODD: crate::tcflag_t = 0x200; +pub const PENDIN: crate::tcflag_t = 0x4000; +pub const POLLWRBAND: c_short = 0x200; +pub const POLLWRNORM: c_short = 0x100; +pub const RTLD_GLOBAL: c_int = 0x00100; + +// 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 SIGBUS: c_int = 0x7; +pub const SIGCHLD: c_int = 0x11; +pub const SIGCONT: c_int = 0x12; +pub const SIGIO: c_int = 0x1d; +pub const SIGPOLL: c_int = SIGIO; +pub const SIGPROF: c_int = 0x1b; +pub const SIGPWR: c_int = 0x1e; +pub const SIGSTKFLT: c_int = 0x10; +pub const SIGSTKSZ: c_int = 16384; +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_UNBLOCK: c_int = 0x1; +pub const SIG_SETMASK: c_int = 0x2; +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: crate::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: crate::tcflag_t = 0x1800; diff --git a/vendor/libc/src/unix/linux_like/l4re/uclibc/mod.rs b/vendor/libc/src/unix/linux_like/l4re/uclibc/mod.rs new file mode 100644 index 0000000..e897946 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/l4re/uclibc/mod.rs @@ -0,0 +1,562 @@ +use crate::off64_t; +use crate::prelude::*; + +pub type shmatt_t = c_ulong; +pub type regoff_t = c_int; +pub type rlim_t = c_ulong; +pub type __rlimit_resource_t = c_int; +pub type __priority_which_t = c_uint; + +pub type _pthread_descr = *mut c_void; +pub type __pthread_cond_align_t = c_long; + +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 cmsghdr { + pub cmsg_len: crate::size_t, + pub cmsg_level: c_int, + pub cmsg_type: c_int, + } + + pub struct msghdr { + pub msg_name: *mut c_void, + pub msg_namelen: crate::socklen_t, + pub msg_iov: *mut crate::iovec, + #[cfg(target_pointer_width = "32")] + pub msg_iovlen: c_int, + #[cfg(target_pointer_width = "64")] + pub msg_iovlen: crate::size_t, + pub msg_control: *mut c_void, + #[cfg(target_pointer_width = "32")] + pub msg_controllen: crate::socklen_t, + #[cfg(target_pointer_width = "64")] + pub msg_controllen: crate::size_t, + pub msg_flags: c_int, + } + + pub struct statfs { + pub f_type: fsword_t, + pub f_bsize: fsword_t, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::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: crate::fsblkcnt64_t, + pub f_bfree: crate::fsblkcnt64_t, + pub f_bavail: crate::fsblkcnt64_t, + pub f_files: crate::fsfilcnt64_t, + pub f_ffree: crate::fsfilcnt64_t, + pub f_fsid: crate::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: crate::fsfilcnt64_t, + pub f_bfree: crate::fsfilcnt64_t, + pub f_bavail: crate::fsfilcnt64_t, + pub f_files: crate::fsfilcnt64_t, + pub f_ffree: crate::fsfilcnt64_t, + pub f_favail: crate::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 ipc_perm { + pub __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + #[cfg(target_pointer_width = "32")] + pub mode: c_ushort, + #[cfg(target_pointer_width = "64")] + pub mode: c_uint, + #[cfg(target_pointer_width = "32")] + __pad1: c_ushort, + pub __seq: c_ushort, + __pad2: c_ushort, + __unused1: c_ulong, + __unused2: c_ulong, + } + + pub struct statvfs { + // Different than GNU! + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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 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, + #[cfg(target_pointer_width = "32")] + pub _f: [c_char; 8], + #[cfg(target_pointer_width = "64")] + pub _f: [c_char; 0], + } + + 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: crate::sockaddr, + pub rt_gateway: crate::sockaddr, + pub rt_genmask: crate::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 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 __sched_param { + __sched_priority: c_int, + } + + pub struct _pthread_fastlock { + __status: c_long, + __spinlock: c_int, + } + + pub struct pthread_cond_t { + __c_lock: _pthread_fastlock, + __c_waiting: _pthread_descr, + __padding: [u8; PTHREAD_COND_PADDING_SIZE], + __align: __pthread_cond_align_t, + } + + pub struct pthread_condattr_t { + __dummy: c_int, + } + + pub struct pthread_mutex_t { + __m_reserved: c_int, + __m_count: c_int, + __m_owner: _pthread_descr, + __m_kind: c_int, + __m_lock: _pthread_fastlock, + } + + pub struct pthread_mutexattr_t { + __mutexkind: c_int, + __mutexprotocol: c_int, + } + + pub struct pthread_rwlock_t { + __rw_lock: _pthread_fastlock, + __rw_readers: c_int, + __rw_writer: _pthread_descr, + __rw_read_waiting: _pthread_descr, + __rw_write_waiting: _pthread_descr, + __rw_kind: c_int, + __rw_pshared: c_int, + } + + pub struct pthread_rwlockattr_t { + __lockkind: c_int, + __pshared: c_int, + } + + pub struct pthread_barrier_t { + __ba_lock: _pthread_fastlock, + __ba_required: c_int, + __ba_present: c_int, + __ba_waiting: _pthread_descr, + } + + pub struct pthread_barrierattr_t { + __pshared: c_int, + } + + pub struct __mbstate_t { + pub __mask: crate::wchar_t, + pub __wc: crate::wchar_t, + } + + pub struct fpos64_t { + pub __pos: crate::off64_t, + pub __mbstate: __mbstate_t, + pub __mblen_pending: c_int, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: crate::size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused4: c_ulong, + __unused5: c_ulong, + } +} + +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, + } + (*core::ptr::from_ref(self).cast::()).si_addr + } + + pub unsafe fn si_value(&self) -> crate::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: crate::sigval, + } + (*core::ptr::from_ref(self).cast::()).si_value + } +} + +s_no_extra_traits! { + // Internal, for casts to access union fields + struct sifields_sigchld { + si_pid: crate::pid_t, + si_uid: crate::uid_t, + si_status: c_int, + si_utime: c_long, + si_stime: c_long, + } + + // Internal, for casts to access union fields + 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. + struct siginfo_f { + _siginfo_base: [c_int; 3], + sifields: sifields, + } +} + +impl siginfo_t { + unsafe fn sifields(&self) -> &sifields { + &(*core::ptr::from_ref(self).cast::()).sifields + } + + pub unsafe fn si_pid(&self) -> crate::pid_t { + self.sifields().sigchld.si_pid + } + + pub unsafe fn si_uid(&self) -> crate::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; + +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 = + crate::MS_RDONLY | crate::MS_SYNCHRONOUS | crate::MS_MANDLOCK | crate::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; + +// 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 SO_TIMESTAMP: c_int = 29; + +pub const RLIM_INFINITY: crate::rlim_t = !0; + +pub const AF_NFC: c_int = PF_NFC; +pub const BUFSIZ: c_int = 256; +pub const EDEADLK: c_int = 0x23; +pub const EDEADLOCK: c_int = EDEADLK; +pub const EXTA: c_uint = B19200; +pub const EXTB: c_uint = B38400; +pub const EXTPROC: crate::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 MSG_COPY: c_int = 0o40000; +pub const NI_MAXHOST: crate::socklen_t = 1025; +pub const O_TMPFILE: c_int = 0o20000000 | O_DIRECTORY; +pub const PF_NFC: c_int = 39; +pub const PF_VSOCK: c_int = 40; +pub const RTLD_NOLOAD: c_int = 0x00004; +pub const RUSAGE_THREAD: c_int = 1; +pub const SHM_EXEC: c_int = 0o100000; +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 PTHREAD_RWLOCK_PREFER_READER_NP: c_int = 0; +pub const PTHREAD_RWLOCK_PREFER_WRITER_NP: c_int = 1; +pub const PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP: c_int = 2; +pub const PTHREAD_RWLOCK_DEFAULT_NP: c_int = PTHREAD_RWLOCK_PREFER_WRITER_NP; + +pub const PTHREAD_MUTEX_TIMED_NP: c_int = 0; +pub const PTHREAD_MUTEX_RECURSIVE_NP: c_int = 1; +pub const PTHREAD_MUTEX_ERRORCHECK_NP: c_int = 2; +pub const PTHREAD_MUTEX_ADAPTIVE_NP: c_int = 3; + +pub const __LT_SPINLOCK_INIT: c_int = 0; + +pub const __LOCK_INITIALIZER: _pthread_fastlock = _pthread_fastlock { + __status: 0, + __spinlock: __LT_SPINLOCK_INIT, +}; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + __m_reserved: 0, + __m_count: 0, + __m_owner: ptr::null_mut(), + __m_kind: PTHREAD_MUTEX_TIMED_NP, + __m_lock: __LOCK_INITIALIZER, +}; + +const PTHREAD_COND_PADDING_SIZE: usize = 48 + - size_of::<_pthread_fastlock>() + - size_of::<_pthread_descr>() + - size_of::<__pthread_cond_align_t>(); + +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + __c_lock: __LOCK_INITIALIZER, + __c_waiting: ptr::null_mut(), + __padding: [0; PTHREAD_COND_PADDING_SIZE], + __align: 0, +}; + +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + __rw_lock: __LOCK_INITIALIZER, + __rw_readers: 0, + __rw_writer: ptr::null_mut(), + __rw_read_waiting: ptr::null_mut(), + __rw_write_waiting: ptr::null_mut(), + __rw_kind: PTHREAD_RWLOCK_DEFAULT_NP, + __rw_pshared: crate::PTHREAD_PROCESS_PRIVATE, +}; + +extern "C" { + pub fn gettimeofday(tp: *mut crate::timeval, tz: *mut crate::timezone) -> c_int; + + pub fn pthread_rwlockattr_getkind_np( + attr: *const crate::pthread_rwlockattr_t, + val: *mut c_int, + ) -> c_int; + pub fn pthread_rwlockattr_setkind_np( + attr: *mut crate::pthread_rwlockattr_t, + val: c_int, + ) -> c_int; + + pub fn openpty( + amaster: *mut c_int, + aslave: *mut c_int, + name: *mut c_char, + termp: *mut termios, + winp: *mut crate::winsize, + ) -> c_int; + + pub fn getnameinfo( + sa: *const crate::sockaddr, + salen: crate::socklen_t, + host: *mut c_char, + hostlen: crate::socklen_t, + serv: *mut c_char, + servlen: crate::socklen_t, + flags: c_int, + ) -> c_int; + + pub fn pwritev(fd: c_int, iov: *const crate::iovec, iovcnt: c_int, offset: off64_t) -> ssize_t; + pub fn preadv(fd: c_int, iov: *const crate::iovec, iovcnt: c_int, offset: off64_t) -> ssize_t; + + pub fn getrlimit64(resource: crate::__rlimit_resource_t, rlim: *mut crate::rlimit64) -> c_int; + pub fn setrlimit64(resource: crate::__rlimit_resource_t, rlim: *const crate::rlimit64) + -> c_int; + pub fn getrlimit(resource: crate::__rlimit_resource_t, rlim: *mut crate::rlimit) -> c_int; + pub fn setrlimit(resource: crate::__rlimit_resource_t, rlim: *const crate::rlimit) -> c_int; + pub fn getauxval(type_: c_ulong) -> c_ulong; + +} + +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 { + // unsupported target + } +} diff --git a/vendor/libc/src/unix/linux_like/l4re/uclibc/x86_64/mod.rs b/vendor/libc/src/unix/linux_like/l4re/uclibc/x86_64/mod.rs new file mode 100644 index 0000000..ed62740 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/l4re/uclibc/x86_64/mod.rs @@ -0,0 +1,403 @@ +//! Definitions for uclibc on 64bit systems + +use crate::prelude::*; + +pub type wchar_t = c_int; +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 nlink_t = c_ulong; +pub type off_t = c_long; +pub type fsword_t = c_long; +pub type suseconds_t = c_long; + +pub type blksize_t = c_long; +pub type blkcnt_t = c_long; + +pub type fsblkcnt64_t = c_ulong; +pub type fsfilcnt64_t = c_ulong; + +pub type __u32 = c_uint; +pub type __u64 = c_ulong; + +s! { + pub struct stat { + pub st_dev: c_ulong, + pub st_ino: crate::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: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + __pad0: c_int, + pub st_rdev: c_ulong, + pub st_size: crate::off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atim: crate::timespec, + pub st_mtim: crate::timespec, + pub st_ctim: crate::timespec, + __uclibc_unused: [c_long; 3], + } + + pub struct stat64 { + pub st_dev: c_ulong, + pub st_ino: crate::ino_t, + pub st_nlink: nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + __pad0: c_int, + pub st_rdev: c_ulong, + pub st_size: crate::off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atim: crate::timespec, + pub st_mtim: crate::timespec, + pub st_ctim: crate::timespec, + st_pad4: [c_long; 3], + } + + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_handler: crate::sighandler_t, + pub sa_flags: c_ulong, + pub sa_restorer: Option, + pub sa_mask: sigset_t, + } + + pub struct sigset_t { + __val: [c_ulong; 1], + } + + #[repr(align(8))] + pub struct siginfo_t { + pub si_signo: c_int, + pub si_errno: c_int, + pub si_code: c_int, + pub _pad: [c_int; 28], + } + + pub struct stack_t { + pub ss_sp: *mut c_void, + pub ss_flags: c_int, + pub ss_size: crate::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: crate::pid_t, + } + + pub struct termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; crate::NCCS], + pub c_ispeed: crate::speed_t, + pub c_ospeed: crate::speed_t, + } +} + +s_no_extra_traits! { + pub union 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 const O_CLOEXEC: c_int = 0o2000000; +pub const __SIZEOF_PTHREAD_ATTR_T: usize = 36; +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_COND_COMPAT_T: usize = 12; +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 NCCS: usize = 32; + +pub const FIOQSIZE: crate::Ioctl = 0x5460; + +// 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: crate::speed_t = 0; +pub const B1000000: crate::speed_t = 0x1008; +pub const B110: crate::speed_t = 0x3; +pub const B115200: crate::speed_t = 0x1002; +pub const B1152000: crate::speed_t = 0x1009; +pub const B1200: crate::speed_t = 0x9; +pub const B134: crate::speed_t = 0x4; +pub const B150: crate::speed_t = 0x5; +pub const B1500000: crate::speed_t = 0x100a; +pub const B1800: crate::speed_t = 0xa; +pub const B19200: crate::speed_t = 0xe; +pub const B200: crate::speed_t = 0x6; +pub const B2000000: crate::speed_t = 0x100b; +pub const B230400: crate::speed_t = 0x1003; +pub const B2400: crate::speed_t = 0xb; +pub const B2500000: crate::speed_t = 0x100c; +pub const B300: crate::speed_t = 0x7; +pub const B3000000: crate::speed_t = 0x100d; +pub const B3500000: crate::speed_t = 0x100e; +pub const B38400: crate::speed_t = 0xf; +pub const B4000000: crate::speed_t = 0x100f; +pub const B460800: crate::speed_t = 0x1004; +pub const B4800: crate::speed_t = 0xc; +pub const B50: crate::speed_t = 0x1; +pub const B500000: crate::speed_t = 0x1005; +pub const B57600: crate::speed_t = 0x1001; +pub const B576000: crate::speed_t = 0x1006; +pub const B600: crate::speed_t = 0x8; +pub const B75: crate::speed_t = 0x2; +pub const B921600: crate::speed_t = 0x1007; +pub const B9600: crate::speed_t = 0xd; +pub const BS1: c_int = 0x2000; +pub const BSDLY: c_int = 0x2000; +pub const CBAUD: crate::tcflag_t = 0x100f; +pub const CBAUDEX: crate::tcflag_t = 0x1000; +pub const CIBAUD: crate::tcflag_t = 0x100f0000; +pub const CLOCAL: crate::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: crate::tcflag_t = 0x80; +pub const CS6: crate::tcflag_t = 0x10; +pub const CS7: crate::tcflag_t = 0x20; +pub const CS8: crate::tcflag_t = 0x30; +pub const CSIZE: crate::tcflag_t = 0x30; +pub const CSTOPB: crate::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: crate::tcflag_t = 0x200; +pub const ECHOE: crate::tcflag_t = 0x10; +pub const ECHOK: crate::tcflag_t = 0x20; +pub const ECHOKE: crate::tcflag_t = 0x800; +pub const ECHONL: crate::tcflag_t = 0x40; +pub const ECHOPRT: crate::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 EDESTADDRREQ: c_int = 0x59; +pub const EDOTDOT: c_int = 0x49; +pub const EDQUOT: c_int = 0x7a; +pub const EHOSTDOWN: c_int = 0x70; +pub const EHOSTUNREACH: c_int = 0x71; +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 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: crate::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: crate::tcflag_t = 0x400; +pub const ICANON: crate::tcflag_t = 0x2; +pub const IEXTEN: crate::tcflag_t = 0x8000; +pub const ISIG: crate::tcflag_t = 0x1; +pub const IXOFF: crate::tcflag_t = 0x1000; +pub const IXON: crate::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 MINSIGSTKSZ: c_int = 2048; +pub const NLDLY: crate::tcflag_t = 0x100; +pub const NOFLSH: crate::tcflag_t = 0x80; +pub const OLCUC: crate::tcflag_t = 0x2; +pub const ONLCR: crate::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 = 0o40000; +pub const O_DIRECTORY: c_int = 0o200000; +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 = 0; +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 = 0o400000; +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: crate::tcflag_t = 0x100; +pub const PARODD: crate::tcflag_t = 0x200; +pub const PENDIN: crate::tcflag_t = 0x4000; +pub const POLLWRBAND: c_short = 0x200; +pub const POLLWRNORM: c_short = 0x100; +pub const RTLD_GLOBAL: c_int = 0x00100; + +// 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 SIGBUS: c_int = 0x7; +pub const SIGCHLD: c_int = 0x11; +pub const SIGCONT: c_int = 0x12; +pub const SIGIO: c_int = 0x1d; +pub const SIGPOLL: c_int = SIGIO; +pub const SIGPROF: c_int = 0x1b; +pub const SIGPWR: c_int = 0x1e; +pub const SIGSTKFLT: c_int = 0x10; +pub const SIGSTKSZ: c_int = 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_UNBLOCK: c_int = 0x1; +pub const SIG_SETMASK: c_int = 0x2; +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: crate::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: crate::tcflag_t = 0x1800; 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..9b9a11d --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/arch/generic/mod.rs @@ -0,0 +1,336 @@ +use crate::prelude::*; +use crate::Ioctl; + +s! { + pub struct termios2 { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; 19], + pub c_ispeed: crate::speed_t, + pub c_ospeed: crate::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_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; + +cfg_if! { + if #[cfg(all( + linux_time_bits64, + any(target_arch = "arm", target_arch = "x86"), + not(any(target_env = "musl", target_env = "ohos")) + ))] { + pub const SO_TIMESTAMP: c_int = SO_TIMESTAMP_NEW; + pub const SO_TIMESTAMPNS: c_int = SO_TIMESTAMPNS_NEW; + pub const SO_TIMESTAMPING: c_int = SO_TIMESTAMPING_NEW; + pub const SO_RCVTIMEO: c_int = SO_RCVTIMEO_NEW; + pub const SO_SNDTIMEO: c_int = SO_SNDTIMEO_NEW; + } else if #[cfg(all( + linux_time_bits64, + any(target_arch = "arm", target_arch = "x86"), + any(target_env = "musl", target_env = "ohos") + ))] { + pub const SO_TIMESTAMP: c_int = 63; + pub const SO_TIMESTAMPNS: c_int = 64; + pub const SO_TIMESTAMPING: c_int = 65; + pub const SO_RCVTIMEO: c_int = 66; + pub const SO_SNDTIMEO: c_int = 67; + } else { + const SO_TIMESTAMP_OLD: c_int = 29; + const SO_TIMESTAMPNS_OLD: c_int = 35; + const SO_TIMESTAMPING_OLD: c_int = 37; + const SO_RCVTIMEO_OLD: c_int = 20; + const SO_SNDTIMEO_OLD: c_int = 21; + + pub const SO_TIMESTAMP: c_int = SO_TIMESTAMP_OLD; + pub const SO_TIMESTAMPNS: c_int = SO_TIMESTAMPNS_OLD; + pub const SO_TIMESTAMPING: c_int = SO_TIMESTAMPING_OLD; + pub const SO_RCVTIMEO: c_int = SO_RCVTIMEO_OLD; + pub const SO_SNDTIMEO: c_int = SO_SNDTIMEO_OLD; + } +} + +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_MARK: c_int = 36; +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 = "arm", + target_arch = "aarch64", + target_arch = "csky", + target_arch = "loongarch64" + ), + // FIXME(musl): + // Musl hardcodes the SO_* constants instead + // of inheriting them from the kernel headers. + // For new constants you might need consider updating + // musl in the CI as well. + 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; +pub const SO_NETNS_COOKIE: c_int = 71; +pub const SO_BUF_LOCK: c_int = 72; +pub const SO_RESERVE_MEM: c_int = 73; +pub const SO_TXREHASH: c_int = 74; +pub const SO_RCVMARK: c_int = 75; +pub const SO_PASSPIDFD: c_int = 76; +pub const SO_PEERPIDFD: c_int = 77; +pub const SO_DEVMEM_LINEAR: c_int = 78; +pub const SO_DEVMEM_DMABUF: c_int = 79; +pub const SO_DEVMEM_DONTNEED: c_int = 80; + +// 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 SCM_DEVMEM_LINEAR: c_int = SO_DEVMEM_LINEAR; +pub const SCM_DEVMEM_DMABUF: c_int = SO_DEVMEM_DMABUF; + +// 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 = u32_cast_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 = u32_cast_ioctl(0x80045430); +pub const TIOCSPTLCK: Ioctl = 0x40045431; +pub const TIOCGDEV: Ioctl = u32_cast_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 = u32_cast_ioctl(0x80045438); +pub const TIOCGPTLCK: Ioctl = u32_cast_ioctl(0x80045439); +pub const TIOCGEXCL: Ioctl = u32_cast_ioctl(0x80045440); +pub const TIOCGPTPEER: Ioctl = 0x5441; +// pub const TIOCGISO7816: Ioctl = 0x80285442; +// pub const TIOCSISO7816: Ioctl = 0xc0285443; +pub const FIONCLEX: Ioctl = 0x5450; +pub const FIOCLEX: Ioctl = 0x5451; +pub const FIOASYNC: Ioctl = 0x5452; +pub const TIOCSERCONFIG: Ioctl = 0x5453; +pub const TIOCSERGWILD: Ioctl = 0x5454; +pub const TIOCSERSWILD: Ioctl = 0x5455; +pub const TIOCGLCKTRMIOS: Ioctl = 0x5456; +pub const TIOCSLCKTRMIOS: Ioctl = 0x5457; +pub const TIOCSERGSTRUCT: Ioctl = 0x5458; +pub const TIOCSERGETLSR: Ioctl = 0x5459; +pub const TIOCSERGETMULTI: Ioctl = 0x545A; +pub const TIOCSERSETMULTI: Ioctl = 0x545B; +pub const TIOCMIWAIT: Ioctl = 0x545C; +pub const TIOCGICOUNT: Ioctl = 0x545D; +pub const BLKIOMIN: Ioctl = 0x1278; +pub const BLKIOOPT: Ioctl = 0x1279; +pub const BLKSSZGET: Ioctl = 0x1268; +pub const BLKPBSZGET: Ioctl = 0x127B; + +cfg_if! { + if #[cfg(any(target_arch = "arm", target_arch = "s390x"))] { + pub const FIOQSIZE: Ioctl = 0x545E; + } else { + pub const FIOQSIZE: Ioctl = 0x5460; + } +} + +pub const TIOCM_LE: c_int = 0x001; +pub const TIOCM_DTR: c_int = 0x002; +pub const TIOCM_RTS: c_int = 0x004; +pub const TIOCM_ST: c_int = 0x008; +pub const TIOCM_SR: c_int = 0x010; +pub const TIOCM_CTS: c_int = 0x020; +pub const TIOCM_CAR: c_int = 0x040; +pub const TIOCM_CD: c_int = TIOCM_CAR; +pub const TIOCM_RNG: c_int = 0x080; +pub const TIOCM_RI: c_int = TIOCM_RNG; +pub const TIOCM_DSR: c_int = 0x100; + +pub const BOTHER: crate::speed_t = 0o010000; +pub const IBSHIFT: crate::tcflag_t = 16; +pub const IUCLC: crate::tcflag_t = 0o0001000; +pub const XCASE: crate::tcflag_t = 0o0000004; + +// RLIMIT Constants + +cfg_if! { + if #[cfg(any(target_env = "gnu", target_env = "uclibc"))] { + pub const RLIMIT_CPU: crate::__rlimit_resource_t = 0; + pub const RLIMIT_FSIZE: crate::__rlimit_resource_t = 1; + pub const RLIMIT_DATA: crate::__rlimit_resource_t = 2; + pub const RLIMIT_STACK: crate::__rlimit_resource_t = 3; + pub const RLIMIT_CORE: crate::__rlimit_resource_t = 4; + pub const RLIMIT_RSS: crate::__rlimit_resource_t = 5; + pub const RLIMIT_NPROC: crate::__rlimit_resource_t = 6; + pub const RLIMIT_NOFILE: crate::__rlimit_resource_t = 7; + pub const RLIMIT_MEMLOCK: crate::__rlimit_resource_t = 8; + pub const RLIMIT_AS: crate::__rlimit_resource_t = 9; + pub const RLIMIT_LOCKS: crate::__rlimit_resource_t = 10; + pub const RLIMIT_SIGPENDING: crate::__rlimit_resource_t = 11; + pub const RLIMIT_MSGQUEUE: crate::__rlimit_resource_t = 12; + pub const RLIMIT_NICE: crate::__rlimit_resource_t = 13; + pub const RLIMIT_RTPRIO: crate::__rlimit_resource_t = 14; + pub const RLIMIT_RTTIME: crate::__rlimit_resource_t = 15; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIMIT_NLIMITS: crate::__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 = 16; + #[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: crate::__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: crate::__rlimit_resource_t = 15; + } +} + +pub const RLIM_INFINITY: crate::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..44c5f12 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/arch/mips/mod.rs @@ -0,0 +1,335 @@ +use crate::prelude::*; +use crate::Ioctl; + +s! { + pub struct termios2 { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; 23], + pub c_ispeed: crate::speed_t, + pub c_ospeed: crate::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; +cfg_if! { + if #[cfg(linux_time_bits64)] { + const SO_RCVTIMEO_NEW: c_int = 66; + const SO_SNDTIMEO_NEW: c_int = 67; + + pub const SO_SNDTIMEO: c_int = SO_SNDTIMEO_NEW; + pub const SO_RCVTIMEO: c_int = SO_RCVTIMEO_NEW; + } else { + const SO_SNDTIMEO_OLD: c_int = 0x1005; + const SO_RCVTIMEO_OLD: c_int = 0x1006; + + pub const SO_SNDTIMEO: c_int = SO_SNDTIMEO_OLD; + pub const SO_RCVTIMEO: c_int = SO_RCVTIMEO_OLD; + } +} +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; + +cfg_if! { + if #[cfg(linux_time_bits64)] { + const SO_TIMESTAMP_NEW: c_int = 63; + const SO_TIMESTAMPNS_NEW: c_int = 64; + const SO_TIMESTAMPING_NEW: c_int = 65; + + pub const SO_TIMESTAMP: c_int = SO_TIMESTAMP_NEW; + pub const SO_TIMESTAMPNS: c_int = SO_TIMESTAMPNS_NEW; + pub const SO_TIMESTAMPING: c_int = SO_TIMESTAMPING_NEW; + } else { + const SO_TIMESTAMP_OLD: c_int = 29; + const SO_TIMESTAMPNS_OLD: c_int = 35; + const SO_TIMESTAMPING_OLD: c_int = 37; + + pub const SO_TIMESTAMP: c_int = SO_TIMESTAMP_OLD; + pub const SO_TIMESTAMPNS: c_int = SO_TIMESTAMPNS_OLD; + pub const SO_TIMESTAMPING: c_int = SO_TIMESTAMPING_OLD; + } +} + +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 SO_NETNS_COOKIE: c_int = 71; +pub const SO_BUF_LOCK: c_int = 72; +pub const SO_RESERVE_MEM: c_int = 73; +pub const SO_TXREHASH: c_int = 74; +pub const SO_RCVMARK: c_int = 75; +pub const SO_PASSPIDFD: c_int = 76; +pub const SO_PEERPIDFD: c_int = 77; +pub const SO_DEVMEM_LINEAR: c_int = 78; +pub const SO_DEVMEM_DMABUF: c_int = 79; +pub const SO_DEVMEM_DONTNEED: c_int = 80; + +// 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 SCM_DEVMEM_LINEAR: c_int = SO_DEVMEM_LINEAR; +pub const SCM_DEVMEM_DMABUF: c_int = SO_DEVMEM_DMABUF; + +// 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 = u32_cast_ioctl(0x80047476); +pub const TIOCOUTQ: Ioctl = 0x7472; +pub const TIOCSTI: Ioctl = 0x5472; +pub const TIOCGWINSZ: Ioctl = 0x40087468; +pub const TIOCSWINSZ: Ioctl = u32_cast_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 = u32_cast_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 = u32_cast_ioctl(0x4030542a); +pub const TCSETS2: Ioctl = u32_cast_ioctl(0x8030542b); +pub const TCSETSW2: Ioctl = u32_cast_ioctl(0x8030542c); +pub const TCSETSF2: Ioctl = u32_cast_ioctl(0x8030542d); +pub const TIOCGPTN: Ioctl = 0x40045430; +pub const TIOCSPTLCK: Ioctl = u32_cast_ioctl(0x80045431); +pub const TIOCGDEV: Ioctl = 0x40045432; +pub const TIOCSIG: Ioctl = u32_cast_ioctl(0x80045436); +pub const TIOCVHANGUP: Ioctl = 0x5437; +pub const TIOCGPKT: Ioctl = 0x40045438; +pub const TIOCGPTLCK: Ioctl = 0x40045439; +pub const TIOCGEXCL: Ioctl = 0x40045440; +pub const TIOCGPTPEER: Ioctl = 0x20005441; +//pub const TIOCGISO7816: Ioctl = 0x40285442; +//pub const TIOCSISO7816: Ioctl = 0xc0285443; +pub const FIONCLEX: Ioctl = 0x6602; +pub const FIOCLEX: Ioctl = 0x6601; +pub const FIOASYNC: Ioctl = 0x667d; +pub const TIOCSERCONFIG: Ioctl = 0x5488; +pub const TIOCSERGWILD: Ioctl = 0x5489; +pub const TIOCSERSWILD: Ioctl = 0x548a; +pub const TIOCGLCKTRMIOS: Ioctl = 0x548b; +pub const TIOCSLCKTRMIOS: Ioctl = 0x548c; +pub const TIOCSERGSTRUCT: Ioctl = 0x548d; +pub const TIOCSERGETLSR: Ioctl = 0x548e; +pub const TIOCSERGETMULTI: Ioctl = 0x548f; +pub const TIOCSERSETMULTI: Ioctl = 0x5490; +pub const TIOCMIWAIT: Ioctl = 0x5491; +pub const TIOCGICOUNT: Ioctl = 0x5492; +pub const FIOQSIZE: Ioctl = 0x667f; +pub const TIOCSLTC: Ioctl = 0x7475; +pub const TIOCGETP: Ioctl = 0x7408; +pub const TIOCSETP: Ioctl = 0x7409; +pub const TIOCSETN: Ioctl = 0x740a; +pub const BLKIOMIN: Ioctl = 0x20001278; +pub const BLKIOOPT: Ioctl = 0x20001279; +pub const BLKSSZGET: Ioctl = 0x20001268; +pub const BLKPBSZGET: Ioctl = 0x2000127B; + +cfg_if! { + if #[cfg(target_env = "musl")] { + pub const TIOCGRS485: Ioctl = 0x4020542e; + pub const TIOCSRS485: Ioctl = u32_cast_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: crate::speed_t = 0o010000; +pub const IBSHIFT: crate::tcflag_t = 16; +pub const IUCLC: crate::tcflag_t = 0o0001000; +pub const XCASE: crate::tcflag_t = 0o0000004; + +// RLIMIT Constants + +cfg_if! { + if #[cfg(any(target_env = "gnu", target_env = "uclibc"))] { + pub const RLIMIT_CPU: crate::__rlimit_resource_t = 0; + pub const RLIMIT_FSIZE: crate::__rlimit_resource_t = 1; + pub const RLIMIT_DATA: crate::__rlimit_resource_t = 2; + pub const RLIMIT_STACK: crate::__rlimit_resource_t = 3; + pub const RLIMIT_CORE: crate::__rlimit_resource_t = 4; + pub const RLIMIT_NOFILE: crate::__rlimit_resource_t = 5; + pub const RLIMIT_AS: crate::__rlimit_resource_t = 6; + pub const RLIMIT_RSS: crate::__rlimit_resource_t = 7; + pub const RLIMIT_NPROC: crate::__rlimit_resource_t = 8; + pub const RLIMIT_MEMLOCK: crate::__rlimit_resource_t = 9; + pub const RLIMIT_LOCKS: crate::__rlimit_resource_t = 10; + pub const RLIMIT_SIGPENDING: crate::__rlimit_resource_t = 11; + pub const RLIMIT_MSGQUEUE: crate::__rlimit_resource_t = 12; + pub const RLIMIT_NICE: crate::__rlimit_resource_t = 13; + pub const RLIMIT_RTPRIO: crate::__rlimit_resource_t = 14; + pub const RLIMIT_RTTIME: crate::__rlimit_resource_t = 15; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIMIT_NLIMITS: crate::__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 = 16; + #[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: crate::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: crate::__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: crate::__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: crate::rlim_t = !0; + } +} + +cfg_if! { + if #[cfg(all( + any(target_arch = "mips", target_arch = "mips32r6"), + any( + all(target_env = "uclibc", linux_time_bits64), + all( + target_env = "gnu", + any(linux_time_bits64, gnu_file_offset_bits64) + ) + ) + ))] { + pub const RLIM_INFINITY: crate::rlim_t = !0; + } else if #[cfg(all( + any(target_arch = "mips", target_arch = "mips32r6"), + any(target_env = "uclibc", target_env = "gnu"), + not(linux_time_bits64) + ))] { + pub const RLIM_INFINITY: crate::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..00914a4 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/arch/mod.rs @@ -0,0 +1,20 @@ +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..1aaa4c7 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/arch/powerpc/mod.rs @@ -0,0 +1,282 @@ +use crate::prelude::*; +use crate::Ioctl; + +// 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; + +cfg_if! { + if #[cfg(linux_time_bits64)] { + const SO_RCVTIMEO_NEW: c_int = 66; + const SO_SNDTIMEO_NEW: c_int = 67; + + pub const SO_RCVTIMEO: c_int = SO_RCVTIMEO_NEW; + pub const SO_SNDTIMEO: c_int = SO_SNDTIMEO_NEW; + } else { + const SO_RCVTIMEO_OLD: c_int = 18; + const SO_SNDTIMEO_OLD: c_int = 19; + + pub const SO_RCVTIMEO: c_int = SO_RCVTIMEO_OLD; + pub const SO_SNDTIMEO: c_int = SO_SNDTIMEO_OLD; + } +} + +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; +cfg_if! { + if #[cfg(linux_time_bits64)] { + const SO_TIMESTAMP_NEW: c_int = 63; + const SO_TIMESTAMPNS_NEW: c_int = 64; + const SO_TIMESTAMPING_NEW: c_int = 65; + + pub const SO_TIMESTAMP: c_int = SO_TIMESTAMP_NEW; + pub const SO_TIMESTAMPNS: c_int = SO_TIMESTAMPNS_NEW; + pub const SO_TIMESTAMPING: c_int = SO_TIMESTAMPING_NEW; + } else { + const SO_TIMESTAMP_OLD: c_int = 29; + const SO_TIMESTAMPNS_OLD: c_int = 35; + const SO_TIMESTAMPING_OLD: c_int = 37; + + pub const SO_TIMESTAMP: c_int = SO_TIMESTAMP_OLD; + pub const SO_TIMESTAMPNS: c_int = SO_TIMESTAMPNS_OLD; + pub const SO_TIMESTAMPING: c_int = SO_TIMESTAMPING_OLD; + } +} +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_MARK: c_int = 36; +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_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 SO_NETNS_COOKIE: c_int = 71; +pub const SO_BUF_LOCK: c_int = 72; +pub const SO_RESERVE_MEM: c_int = 73; +pub const SO_TXREHASH: c_int = 74; +pub const SO_RCVMARK: c_int = 75; +pub const SO_PASSPIDFD: c_int = 76; +pub const SO_PEERPIDFD: c_int = 77; +pub const SO_DEVMEM_LINEAR: c_int = 78; +pub const SO_DEVMEM_DMABUF: c_int = 79; +pub const SO_DEVMEM_DONTNEED: c_int = 80; + +// 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 SCM_DEVMEM_LINEAR: c_int = SO_DEVMEM_LINEAR; +pub const SCM_DEVMEM_DMABUF: c_int = SO_DEVMEM_DMABUF; + +// Ioctl Constants + +cfg_if! { + if #[cfg(target_env = "gnu")] { + pub const TCGETS: Ioctl = 0x403c7413; + pub const TCSETS: Ioctl = u32_cast_ioctl(0x803c7414); + pub const TCSETSW: Ioctl = u32_cast_ioctl(0x803c7415); + pub const TCSETSF: Ioctl = u32_cast_ioctl(0x803c7416); + } else if #[cfg(target_env = "musl")] { + pub const TCGETS: Ioctl = 0x402c7413; + pub const TCSETS: Ioctl = u32_cast_ioctl(0x802c7414); + pub const TCSETSW: Ioctl = u32_cast_ioctl(0x802c7415); + pub const TCSETSF: Ioctl = u32_cast_ioctl(0x802c7416); + } +} + +pub const TCGETA: Ioctl = 0x40147417; +pub const TCSETA: Ioctl = u32_cast_ioctl(0x80147418); +pub const TCSETAW: Ioctl = u32_cast_ioctl(0x80147419); +pub const TCSETAF: Ioctl = u32_cast_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 = u32_cast_ioctl(0x80047476); +pub const TIOCOUTQ: Ioctl = 0x40047473; +pub const TIOCSTI: Ioctl = 0x5412; +pub const TIOCGWINSZ: Ioctl = 0x40087468; +pub const TIOCSWINSZ: Ioctl = u32_cast_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 = u32_cast_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 = u32_cast_ioctl(0x80045431); +pub const TIOCGDEV: Ioctl = 0x40045432; +pub const TIOCSIG: Ioctl = u32_cast_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 = u32_cast_ioctl(0x8004667d); +pub const TIOCSERCONFIG: Ioctl = 0x5453; +pub const TIOCSERGWILD: Ioctl = 0x5454; +pub const TIOCSERSWILD: Ioctl = 0x5455; +pub const TIOCGLCKTRMIOS: Ioctl = 0x5456; +pub const TIOCSLCKTRMIOS: Ioctl = 0x5457; +pub const TIOCSERGSTRUCT: Ioctl = 0x5458; +pub const TIOCSERGETLSR: Ioctl = 0x5459; +pub const TIOCSERGETMULTI: Ioctl = 0x545A; +pub const TIOCSERSETMULTI: Ioctl = 0x545B; +pub const TIOCMIWAIT: Ioctl = 0x545C; +pub const TIOCGICOUNT: Ioctl = 0x545D; +pub const BLKIOMIN: Ioctl = 0x20001278; +pub const BLKIOOPT: Ioctl = 0x20001279; +pub const BLKSSZGET: Ioctl = 0x20001268; +pub const BLKPBSZGET: Ioctl = 0x2000127B; +//pub const FIOQSIZE: Ioctl = 0x40086680; + +pub const TIOCM_LE: c_int = 0x001; +pub const TIOCM_DTR: c_int = 0x002; +pub const TIOCM_RTS: c_int = 0x004; +pub const TIOCM_ST: c_int = 0x008; +pub const TIOCM_SR: c_int = 0x010; +pub const TIOCM_CTS: c_int = 0x020; +pub const TIOCM_CAR: c_int = 0x040; +pub const TIOCM_CD: c_int = TIOCM_CAR; +pub const TIOCM_RNG: c_int = 0x080; +pub const TIOCM_RI: c_int = TIOCM_RNG; +pub const TIOCM_DSR: c_int = 0x100; + +pub const BOTHER: crate::speed_t = 0o0037; +pub const IBSHIFT: crate::tcflag_t = 16; +pub const IUCLC: crate::tcflag_t = 0o0010000; +pub const XCASE: crate::tcflag_t = 0o0040000; + +// RLIMIT Constants + +cfg_if! { + if #[cfg(target_env = "gnu")] { + pub const RLIMIT_CPU: crate::__rlimit_resource_t = 0; + pub const RLIMIT_FSIZE: crate::__rlimit_resource_t = 1; + pub const RLIMIT_DATA: crate::__rlimit_resource_t = 2; + pub const RLIMIT_STACK: crate::__rlimit_resource_t = 3; + pub const RLIMIT_CORE: crate::__rlimit_resource_t = 4; + pub const RLIMIT_RSS: crate::__rlimit_resource_t = 5; + pub const RLIMIT_NPROC: crate::__rlimit_resource_t = 6; + pub const RLIMIT_NOFILE: crate::__rlimit_resource_t = 7; + pub const RLIMIT_MEMLOCK: crate::__rlimit_resource_t = 8; + pub const RLIMIT_AS: crate::__rlimit_resource_t = 9; + pub const RLIMIT_LOCKS: crate::__rlimit_resource_t = 10; + pub const RLIMIT_SIGPENDING: crate::__rlimit_resource_t = 11; + pub const RLIMIT_MSGQUEUE: crate::__rlimit_resource_t = 12; + pub const RLIMIT_NICE: crate::__rlimit_resource_t = 13; + pub const RLIMIT_RTPRIO: crate::__rlimit_resource_t = 14; + pub const RLIMIT_RTTIME: crate::__rlimit_resource_t = 15; + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: crate::__rlimit_resource_t = 16; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIMIT_NLIMITS: crate::__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 = 16; + #[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: crate::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..42799cd --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/arch/sparc/mod.rs @@ -0,0 +1,249 @@ +use crate::prelude::*; +use crate::Ioctl; + +s! { + pub struct termios2 { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; 19], + pub c_ispeed: crate::speed_t, + pub c_ospeed: crate::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; +pub const SO_NETNS_COOKIE: c_int = 0x0050; +pub const SO_BUF_LOCK: c_int = 0x0051; +pub const SO_RESERVE_MEM: c_int = 0x0052; +pub const SO_TXREHASH: c_int = 0x0053; +pub const SO_RCVMARK: c_int = 0x0054; +pub const SO_PASSPIDFD: c_int = 0x0055; +pub const SO_PEERPIDFD: c_int = 0x0056; +pub const SO_DEVMEM_LINEAR: c_int = 0x0057; +pub const SO_DEVMEM_DMABUF: c_int = 0x0058; +pub const SO_DEVMEM_DONTNEED: c_int = 0x0059; + +// 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 SCM_DEVMEM_LINEAR: c_int = SO_DEVMEM_LINEAR; +pub const SCM_DEVMEM_DMABUF: c_int = SO_DEVMEM_DMABUF; + +// 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 = u32_cast_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: crate::speed_t = 0x1000; +pub const IBSHIFT: crate::tcflag_t = 16; +pub const IUCLC: crate::tcflag_t = 0o0001000; +pub const XCASE: crate::tcflag_t = 0o0000004; + +// RLIMIT Constants + +pub const RLIMIT_CPU: crate::__rlimit_resource_t = 0; +pub const RLIMIT_FSIZE: crate::__rlimit_resource_t = 1; +pub const RLIMIT_DATA: crate::__rlimit_resource_t = 2; +pub const RLIMIT_STACK: crate::__rlimit_resource_t = 3; +pub const RLIMIT_CORE: crate::__rlimit_resource_t = 4; +pub const RLIMIT_RSS: crate::__rlimit_resource_t = 5; +pub const RLIMIT_NOFILE: crate::__rlimit_resource_t = 6; +pub const RLIMIT_NPROC: crate::__rlimit_resource_t = 7; +pub const RLIMIT_MEMLOCK: crate::__rlimit_resource_t = 8; +pub const RLIMIT_AS: crate::__rlimit_resource_t = 9; +pub const RLIMIT_LOCKS: crate::__rlimit_resource_t = 10; +pub const RLIMIT_SIGPENDING: crate::__rlimit_resource_t = 11; +pub const RLIMIT_MSGQUEUE: crate::__rlimit_resource_t = 12; +pub const RLIMIT_NICE: crate::__rlimit_resource_t = 13; +pub const RLIMIT_RTPRIO: crate::__rlimit_resource_t = 14; +pub const RLIMIT_RTTIME: crate::__rlimit_resource_t = 15; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: crate::__rlimit_resource_t = 16; +#[allow(deprecated)] +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIMIT_NLIMITS: crate::__rlimit_resource_t = RLIM_NLIMITS; + +cfg_if! { + if #[cfg(target_arch = "sparc64")] { + pub const RLIM_INFINITY: crate::rlim_t = !0; + } else if #[cfg(target_arch = "sparc")] { + pub const RLIM_INFINITY: crate::rlim_t = 0x7fffffff; + } +} 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..d05bccf --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/mod.rs @@ -0,0 +1,907 @@ +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +pub type wchar_t = u32; + +s! { + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + pub struct statfs { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__fsword_t, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::fsid_t, + + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + f_spare: [crate::__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: crate::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: crate::pid_t, + } + + pub struct ipc_perm { + pub __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_ushort, + __pad1: Padding, + pub __seq: c_ushort, + __pad2: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + #[cfg(not(gnu_time_bits64))] + __pad1: Padding, + #[cfg(not(gnu_time_bits64))] + __st_ino: c_ulong, + #[cfg(gnu_time_bits64)] + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + #[cfg(not(gnu_time_bits64))] + __pad2: Padding, + pub st_size: off64_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + #[cfg(gnu_time_bits64)] + _atime_pad: Padding, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + #[cfg(gnu_time_bits64)] + _mtime_pad: Padding, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + #[cfg(gnu_time_bits64)] + _ctime_pad: Padding, + #[cfg(not(gnu_time_bits64))] + pub st_ino: crate::ino64_t, + } + + pub struct statfs64 { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__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: crate::fsid_t, + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + pub f_spare: [crate::__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: Padding, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + __f_spare: [c_int; 6], + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __unused1: Padding, + pub shm_dtime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __unused2: Padding, + pub shm_ctime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __unused3: Padding, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused4: Padding, + __unused5: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + pub msg_stime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved1: Padding, + pub msg_rtime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved2: Padding, + pub msg_ctime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved3: Padding, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __glibc_reserved4: Padding, + __glibc_reserved5: Padding, + } + + 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, + } + + #[repr(align(8))] + pub struct ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_mcontext: crate::mcontext_t, + pub uc_sigmask: crate::sigset_t, + pub uc_regspace: [c_ulong; 128], + } +} + +s_no_extra_traits! { + #[repr(align(8))] + pub struct max_align_t { + priv_: [i64; 2], + } +} + +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; + +cfg_if! { + if #[cfg(gnu_file_offset_bits64)] { + pub const F_GETLK: c_int = 12; + } else { + 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: crate::tcflag_t = 0o0010017; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const FF1: crate::tcflag_t = 0x00008000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const VT1: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; + +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::tcflag_t = 0x00001000; +pub const EXTPROC: crate::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; 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..dc88c63 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/mod.rs @@ -0,0 +1,748 @@ +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +pub type wchar_t = u32; + +s! { + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + pub struct statfs { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__fsword_t, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::fsid_t, + + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + f_spare: [crate::__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: crate::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: crate::pid_t, + } + + pub struct ipc_perm { + pub __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_ushort, + __pad1: Padding, + pub __seq: c_ushort, + __pad2: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + __pad1: Padding, + __st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad2: Padding, + pub st_size: off64_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_ino: crate::ino64_t, + } + + pub struct statfs64 { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__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: crate::fsid_t, + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + pub f_spare: [crate::__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: Padding, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + __f_spare: [c_int; 6], + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + __unused1: Padding, + pub shm_dtime: crate::time_t, + __unused2: Padding, + pub shm_ctime: crate::time_t, + __unused3: Padding, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused4: Padding, + __unused5: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + pub msg_stime: crate::time_t, + __glibc_reserved1: Padding, + pub msg_rtime: crate::time_t, + __glibc_reserved2: Padding, + pub msg_ctime: crate::time_t, + __glibc_reserved3: Padding, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __glibc_reserved4: Padding, + __glibc_reserved5: Padding, + } + + 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! { + #[repr(align(8))] + pub struct max_align_t { + priv_: [i64; 2], + } +} + +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: crate::tcflag_t = 0o0010017; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const FF1: crate::tcflag_t = 0x00008000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const VT1: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; + +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::tcflag_t = 0x00001000; +pub const EXTPROC: crate::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; 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..2d91f98 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/mod.rs @@ -0,0 +1,885 @@ +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +pub type wchar_t = i32; + +s! { + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + pub struct statfs { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__fsword_t, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::fsid_t, + + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + f_spare: [crate::__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: crate::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: crate::pid_t, + } + + pub struct ipc_perm { + __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + __seq: c_ushort, + __pad1: Padding, + __glibc_reserved1: Padding, + __glibc_reserved2: Padding, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + __pad1: Padding, + pub __st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad2: Padding, + pub st_size: off64_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_ulong, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_ulong, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_ulong, + pub st_ino: crate::ino64_t, + } + + pub struct statfs64 { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__fsword_t, + pub f_blocks: crate::fsblkcnt64_t, + pub f_bfree: crate::fsblkcnt64_t, + pub f_bavail: crate::fsblkcnt64_t, + pub f_files: crate::fsblkcnt64_t, + pub f_ffree: crate::fsblkcnt64_t, + pub f_fsid: crate::fsid_t, + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + pub f_spare: [crate::__fsword_t; 4], + } + + pub struct statvfs64 { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt64_t, + pub f_bfree: crate::fsblkcnt64_t, + pub f_bavail: crate::fsblkcnt64_t, + pub f_files: crate::fsblkcnt64_t, + pub f_ffree: crate::fsblkcnt64_t, + pub f_favail: crate::fsblkcnt64_t, + pub f_fsid: c_ulong, + __f_unused: Padding, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + __f_spare: [c_int; 6], + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + __glibc_reserved1: Padding, + pub shm_dtime: crate::time_t, + __glibc_reserved2: Padding, + pub shm_ctime: crate::time_t, + __glibc_reserved3: Padding, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __glibc_reserved5: Padding, + __glibc_reserved6: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + pub msg_stime: crate::time_t, + __glibc_reserved1: Padding, + pub msg_rtime: crate::time_t, + __glibc_reserved2: Padding, + pub msg_ctime: crate::time_t, + __glibc_reserved3: Padding, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __glibc_reserved4: Padding, + __glibc_reserved5: Padding, + } + + pub struct siginfo_t { + pub si_signo: c_int, + pub si_code: c_int, + pub si_errno: c_int, + _pad: Padding<[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! { + #[repr(align(2))] + pub struct max_align_t { + priv_: [i8; 20], + } +} + +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_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: crate::tcflag_t = 0o0010017; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const FF1: crate::tcflag_t = 0x00008000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const VT1: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; + +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::tcflag_t = 0x00001000; +pub const EXTPROC: crate::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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 127; +pub const SYS_init_module: c_long = 128; +pub const SYS_delete_module: c_long = 129; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +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 SYS_statmount: c_long = 457; +pub const SYS_listmount: c_long = 458; +pub const SYS_lsm_get_self_attr: c_long = 459; +pub const SYS_lsm_set_self_attr: c_long = 460; +pub const SYS_lsm_list_modules: c_long = 461; +pub const SYS_mseal: c_long = 462; +pub const SYS_setxattrat: c_long = 463; +pub const SYS_getxattrat: c_long = 464; +pub const SYS_listxattrat: c_long = 465; +pub const SYS_removexattrat: c_long = 466; +pub const SYS_open_tree_attr: c_long = 467; +pub const SYS_file_get_attr: c_long = 468; +pub const SYS_file_set_attr: c_long = 469; 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..18bb193 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/mod.rs @@ -0,0 +1,928 @@ +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +pub type wchar_t = i32; + +s! { + pub struct stat { + #[cfg(not(gnu_time_bits64))] + pub st_dev: c_ulong, + #[cfg(gnu_time_bits64)] + pub st_dev: crate::dev_t, + + #[cfg(not(gnu_time_bits64))] + st_pad1: Padding<[c_long; 3]>, + + pub st_ino: crate::ino_t, + + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + + #[cfg(not(gnu_time_bits64))] + pub st_rdev: c_ulong, + #[cfg(gnu_time_bits64)] + pub st_rdev: crate::dev_t, + + #[cfg(not(gnu_file_offset_bits64))] + st_pad2: Padding<[c_long; 2]>, + #[cfg(all(not(gnu_time_bits64), gnu_file_offset_bits64))] + st_pad2: Padding<[c_long; 3]>, + + pub st_size: off_t, + + #[cfg(not(gnu_file_offset_bits64))] + st_pad3: Padding, + + #[cfg(gnu_time_bits64)] + pub st_blksize: crate::blksize_t, + #[cfg(gnu_time_bits64)] + pub st_blocks: crate::blkcnt_t, + + pub st_atime: crate::time_t, + #[cfg(gnu_time_bits64)] + _atime_pad: Padding, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + #[cfg(gnu_time_bits64)] + _mtime_pad: Padding, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + #[cfg(gnu_time_bits64)] + _ctime_pad: Padding, + pub st_ctime_nsec: c_long, + + #[cfg(not(gnu_time_bits64))] + pub st_blksize: crate::blksize_t, + #[cfg(all(not(gnu_time_bits64), gnu_file_offset_bits64))] + st_pad4: Padding, + #[cfg(not(gnu_time_bits64))] + pub st_blocks: crate::blkcnt_t, + #[cfg(not(gnu_time_bits64))] + st_pad5: Padding<[c_long; 14]>, + } + + pub struct stat64 { + #[cfg(not(gnu_time_bits64))] + pub st_dev: c_ulong, + #[cfg(gnu_time_bits64)] + pub st_dev: crate::dev_t, + + #[cfg(not(gnu_time_bits64))] + st_pad1: Padding<[c_long; 3]>, + + pub st_ino: crate::ino64_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + + #[cfg(not(gnu_time_bits64))] + pub st_rdev: c_ulong, + #[cfg(gnu_time_bits64)] + pub st_rdev: crate::dev_t, + + #[cfg(not(gnu_time_bits64))] + st_pad2: Padding<[c_long; 3]>, + + pub st_size: off64_t, + + #[cfg(gnu_time_bits64)] + pub st_blksize: crate::blksize_t, + #[cfg(gnu_time_bits64)] + pub st_blocks: crate::blkcnt_t, + + pub st_atime: crate::time_t, + #[cfg(gnu_time_bits64)] + _atime_pad: Padding, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + #[cfg(gnu_time_bits64)] + _mtime_pad: Padding, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + #[cfg(gnu_time_bits64)] + _ctime_pad: Padding, + pub st_ctime_nsec: c_long, + + #[cfg(not(gnu_time_bits64))] + pub st_blksize: crate::blksize_t, + #[cfg(not(gnu_time_bits64))] + st_pad3: Padding, + #[cfg(not(gnu_time_bits64))] + pub st_blocks: crate::blkcnt64_t, + #[cfg(not(gnu_time_bits64))] + st_pad5: Padding<[c_long; 14]>, + } + + pub struct statfs { + pub f_type: c_long, + pub f_bsize: c_long, + pub f_frsize: c_long, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_files: crate::fsblkcnt_t, + pub f_ffree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_fsid: crate::fsid_t, + + pub f_namelen: c_long, + pub f_flags: c_long, + f_spare: [c_long; 5], + } + + 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: crate::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: Padding, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + __f_spare: [c_int; 6], + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_flags: c_int, + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::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: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_uint, + pub __seq: c_ushort, + __pad1: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused4: Padding, + __unused5: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + #[cfg(all(not(gnu_time_bits64), target_endian = "big"))] + __glibc_reserved1: Padding, + pub msg_stime: crate::time_t, + #[cfg(all(not(gnu_time_bits64), target_endian = "little"))] + __glibc_reserved1: Padding, + #[cfg(all(not(gnu_time_bits64), target_endian = "big"))] + __glibc_reserved2: Padding, + pub msg_rtime: crate::time_t, + #[cfg(all(not(gnu_time_bits64), target_endian = "little"))] + __glibc_reserved2: Padding, + #[cfg(all(not(gnu_time_bits64), target_endian = "big"))] + __glibc_reserved3: Padding, + pub msg_ctime: crate::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved3: Padding, + __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __glibc_reserved4: Padding, + __glibc_reserved5: Padding, + } + + pub struct flock { + pub l_type: c_short, + pub l_whence: c_short, + pub l_start: off_t, + pub l_len: off_t, + #[cfg(not(gnu_file_offset_bits64))] + pub l_sysid: c_long, + pub l_pid: crate::pid_t, + #[cfg(not(gnu_file_offset_bits64))] + __glibc_reserved0: Padding<[c_long; 4]>, + } +} + +s_no_extra_traits! { + #[repr(align(8))] + pub struct max_align_t { + priv_: [f32; 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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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 SIGEMT: c_int = 7; +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: crate::tcflag_t = 0x00000100; +pub const TOSTOP: crate::tcflag_t = 0x00008000; +pub const FLUSHO: crate::tcflag_t = 0x00002000; +pub const EXTPROC: crate::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; + +cfg_if! { + if #[cfg(gnu_file_offset_bits64)] { + pub const F_GETLK: c_int = 33; + } else { + 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: crate::tcflag_t = 0o0010017; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const FF1: crate::tcflag_t = 0x00008000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const VT1: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; + +pub const EHWPOISON: c_int = 168; 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..11ada71 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/mod.rs @@ -0,0 +1,451 @@ +//! 32-bit specific definitions for linux-like values + +use crate::prelude::*; + +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 __fsword_t = i32; +pub type fsblkcnt64_t = u64; +pub type fsfilcnt64_t = u64; +pub type __syscall_ulong_t = c_ulong; +pub type __suseconds64_t = i64; + +cfg_if! { + if #[cfg(target_arch = "riscv32")] { + pub type time_t = i64; + pub type suseconds_t = i64; + type __ino_t = c_ulong; + type __ino64_t = u64; + pub type ino_t = __ino64_t; + 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 if #[cfg(gnu_time_bits64)] { + pub type time_t = i64; + pub type suseconds_t = i32; + type __ino_t = c_ulong; + type __ino64_t = u64; + pub type ino_t = __ino64_t; + 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 = i32; + } else if #[cfg(gnu_file_offset_bits64)] { + pub type time_t = i32; + pub type suseconds_t = i32; + type __ino_t = c_ulong; + type __ino64_t = u64; + pub type ino_t = __ino64_t; + 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 = i32; + } else { + pub type time_t = i32; + pub type suseconds_t = i32; + type __ino_t = c_ulong; + type __ino64_t = u64; + pub type ino_t = __ino_t; + 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; + } +} + +cfg_if! { + if #[cfg(not(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "powerpc", + target_arch = "sparc" + )))] { + s! { + pub struct stat { + pub st_dev: crate::dev_t, + + #[cfg(not(gnu_time_bits64))] + __pad1: Padding, + + #[cfg(any(gnu_time_bits64, not(gnu_file_offset_bits64)))] + pub st_ino: crate::ino_t, + #[cfg(all(not(gnu_time_bits64), gnu_file_offset_bits64))] + __st_ino: __ino_t, + + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + + pub st_rdev: crate::dev_t, + + #[cfg(not(gnu_time_bits64))] + __pad2: Padding, + + pub st_size: off_t, + + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + #[cfg(gnu_time_bits64)] + _atime_pad: Padding, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + #[cfg(gnu_time_bits64)] + _mtime_pad: Padding, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + #[cfg(gnu_time_bits64)] + _ctime_pad: Padding, + + #[cfg(not(gnu_file_offset_bits64))] + __glibc_reserved4: Padding, + #[cfg(not(gnu_file_offset_bits64))] + __glibc_reserved5: Padding, + #[cfg(all(not(gnu_time_bits64), gnu_file_offset_bits64))] + pub st_ino: crate::ino_t, + } + } + } +} + +s! { + pub struct statvfs { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::fsfilcnt_t, + pub f_fsid: c_ulong, + __f_unused: Padding, + 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(all(not(gnu_time_bits64), target_arch = "powerpc"))] + __reserved: Padding, + pub sem_otime: crate::time_t, + #[cfg(not(any( + gnu_time_bits64, + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "powerpc" + )))] + __reserved: Padding, + #[cfg(all(not(gnu_time_bits64), target_arch = "powerpc"))] + __reserved2: Padding, + pub sem_ctime: crate::time_t, + #[cfg(not(any( + gnu_time_bits64, + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "powerpc" + )))] + __reserved2: Padding, + pub sem_nsems: crate::__syscall_ulong_t, + #[cfg(all( + gnu_time_bits64, + not(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "powerpc", + target_arch = "arm", + target_arch = "x86" + )) + ))] + __reserved2: Padding, + __glibc_reserved3: Padding, + __glibc_reserved4: Padding, + } + + #[cfg(gnu_time_bits64)] + pub struct timex { + pub modes: c_uint, + _pad1: Padding, + pub offset: c_longlong, + pub freq: c_longlong, + pub maxerror: c_longlong, + pub esterror: c_longlong, + pub status: c_int, + _pad2: Padding, + pub constant: c_longlong, + pub precision: c_longlong, + pub tolerance: c_longlong, + pub time: crate::timeval, + pub tick: c_longlong, + pub ppsfreq: c_longlong, + pub jitter: c_longlong, + pub shift: c_int, + _pad3: Padding, + pub stabil: c_longlong, + pub jitcnt: c_longlong, + pub calcnt: c_longlong, + pub errcnt: c_longlong, + pub stbcnt: c_longlong, + 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, + } + + #[cfg(not(gnu_time_bits64))] + 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: crate::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 __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 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_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_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 = u32_cast_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; + } +} +cfg_if! { + if #[cfg(target_arch = "sparc")] { + pub const F_SETLK: c_int = 8; + pub const F_SETLKW: c_int = 9; + } else if #[cfg(all( + gnu_file_offset_bits64, + any(target_arch = "mips", target_arch = "mips32r6") + ))] { + pub const F_SETLK: c_int = 34; + pub const F_SETLKW: c_int = 35; + } else if #[cfg(gnu_file_offset_bits64)] { + pub const F_SETLK: c_int = 13; + pub const F_SETLKW: c_int = 14; + } else { + pub const F_SETLK: c_int = 6; + pub const F_SETLKW: c_int = 7; + } +} + +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..b5d3631 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/powerpc.rs @@ -0,0 +1,895 @@ +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +pub type wchar_t = i32; + +s! { + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + pub struct statfs { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__fsword_t, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::fsid_t, + + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + f_spare: [crate::__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: crate::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: crate::pid_t, + } + + pub struct ipc_perm { + __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + __seq: u32, + __pad1: Padding, + __glibc_reserved1: Padding, + __glibc_reserved2: Padding, + } + + pub struct stat { + pub st_dev: crate::dev_t, + #[cfg(not(gnu_file_offset_bits64))] + __pad1: Padding, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + #[cfg(not(gnu_time_bits64))] + __pad2: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + #[cfg(gnu_time_bits64)] + _atime_pad: Padding, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + #[cfg(gnu_time_bits64)] + _mtime_pad: Padding, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + #[cfg(gnu_time_bits64)] + _ctime_pad: Padding, + pub st_ctime_nsec: c_long, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved4: Padding, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved5: Padding, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino64_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + #[cfg(not(gnu_time_bits64))] + __pad2: Padding, + pub st_size: off64_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atime: crate::time_t, + #[cfg(gnu_time_bits64)] + _atime_pad: Padding, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + #[cfg(gnu_time_bits64)] + _mtime_pad: Padding, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + #[cfg(gnu_time_bits64)] + _ctime_pad: Padding, + pub st_ctime_nsec: c_long, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved4: Padding, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved5: Padding, + } + + pub struct statfs64 { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__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: crate::fsid_t, + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + pub f_spare: [crate::__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: Padding, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + __f_spare: [c_int; 6], + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + #[cfg(gnu_time_bits64)] + pub shm_segsz: size_t, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved1: Padding, + pub shm_atime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved2: Padding, + pub shm_dtime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved3: Padding, + pub shm_ctime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved4: Padding, + #[cfg(not(gnu_time_bits64))] + pub shm_segsz: size_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __glibc_reserved5: Padding, + __glibc_reserved6: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved1: Padding, + pub msg_stime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved2: Padding, + pub msg_rtime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved3: Padding, + pub msg_ctime: crate::time_t, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __glibc_reserved4: Padding, + __glibc_reserved5: Padding, + } + + 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; + +cfg_if! { + if #[cfg(gnu_file_offset_bits64)] { + pub const F_GETLK: c_int = 12; + } else { + 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: crate::tcflag_t = 0xff; +pub const TAB1: crate::tcflag_t = 0x400; +pub const TAB2: crate::tcflag_t = 0x800; +pub const TAB3: crate::tcflag_t = 0xc00; +pub const CR1: crate::tcflag_t = 0x1000; +pub const CR2: crate::tcflag_t = 0x2000; +pub const CR3: crate::tcflag_t = 0x3000; +pub const FF1: crate::tcflag_t = 0x4000; +pub const BS1: crate::tcflag_t = 0x8000; +pub const VT1: crate::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: crate::tcflag_t = 0x200; +pub const IXOFF: crate::tcflag_t = 0x400; +pub const ONLCR: crate::tcflag_t = 0x2; +pub const CSIZE: crate::tcflag_t = 0x300; +pub const CS6: crate::tcflag_t = 0x100; +pub const CS7: crate::tcflag_t = 0x200; +pub const CS8: crate::tcflag_t = 0x300; +pub const CSTOPB: crate::tcflag_t = 0x400; +pub const CREAD: crate::tcflag_t = 0x800; +pub const PARENB: crate::tcflag_t = 0x1000; +pub const PARODD: crate::tcflag_t = 0x2000; +pub const HUPCL: crate::tcflag_t = 0x4000; +pub const CLOCAL: crate::tcflag_t = 0x8000; +pub const ECHOKE: crate::tcflag_t = 0x1; +pub const ECHOE: crate::tcflag_t = 0x2; +pub const ECHOK: crate::tcflag_t = 0x4; +pub const ECHONL: crate::tcflag_t = 0x10; +pub const ECHOPRT: crate::tcflag_t = 0x20; +pub const ECHOCTL: crate::tcflag_t = 0x40; +pub const ISIG: crate::tcflag_t = 0x80; +pub const ICANON: crate::tcflag_t = 0x100; +pub const PENDIN: crate::tcflag_t = 0x20000000; +pub const NOFLSH: crate::tcflag_t = 0x80000000; +pub const VSWTC: usize = 9; +pub const OLCUC: crate::tcflag_t = 0o000004; +pub const NLDLY: crate::tcflag_t = 0o001400; +pub const CRDLY: crate::tcflag_t = 0o030000; +pub const TABDLY: crate::tcflag_t = 0o006000; +pub const BSDLY: crate::tcflag_t = 0o100000; +pub const FFDLY: crate::tcflag_t = 0o040000; +pub const VTDLY: crate::tcflag_t = 0o200000; +pub const XTABS: crate::tcflag_t = 0o006000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const CBAUDEX: crate::speed_t = 0o000020; +pub const B57600: crate::speed_t = 0o0020; +pub const B115200: crate::speed_t = 0o0021; +pub const B230400: crate::speed_t = 0o0022; +pub const B460800: crate::speed_t = 0o0023; +pub const B500000: crate::speed_t = 0o0024; +pub const B576000: crate::speed_t = 0o0025; +pub const B921600: crate::speed_t = 0o0026; +pub const B1000000: crate::speed_t = 0o0027; +pub const B1152000: crate::speed_t = 0o0030; +pub const B1500000: crate::speed_t = 0o0031; +pub const B2000000: crate::speed_t = 0o0032; +pub const B2500000: crate::speed_t = 0o0033; +pub const B3000000: crate::speed_t = 0o0034; +pub const B3500000: crate::speed_t = 0o0035; +pub const B4000000: crate::speed_t = 0o0036; + +pub const VEOL: usize = 6; +pub const VEOL2: usize = 8; +pub const VMIN: usize = 5; +pub const IEXTEN: crate::tcflag_t = 0x400; +pub const TOSTOP: crate::tcflag_t = 0x400000; +pub const FLUSHO: crate::tcflag_t = 0x800000; +pub const EXTPROC: crate::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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 127; +pub const SYS_init_module: c_long = 128; +pub const SYS_delete_module: c_long = 129; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs new file mode 100644 index 0000000..5484a68 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs @@ -0,0 +1,811 @@ +//! RISC-V-specific definitions for 32-bit linux-like values + +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +pub type wchar_t = c_int; + +s! { + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + pub msg_stime: crate::time_t, + pub msg_rtime: crate::time_t, + pub msg_ctime: crate::time_t, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __glibc_reserved4: Padding, + __glibc_reserved5: Padding, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino64_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub __pad1: crate::dev_t, + pub st_size: off64_t, + pub st_blksize: crate::blksize_t, + pub __pad2: c_int, + pub st_blocks: crate::blkcnt64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_int; 2]>, + } + + pub struct statfs { + pub f_type: c_long, + pub f_bsize: c_long, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::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: crate::fsblkcnt64_t, + pub f_bfree: crate::fsblkcnt64_t, + pub f_bavail: crate::fsblkcnt64_t, + pub f_files: crate::fsfilcnt64_t, + pub f_ffree: crate::fsfilcnt64_t, + pub f_fsid: crate::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 statvfs64 { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt64_t, + pub f_bfree: crate::fsblkcnt64_t, + pub f_bavail: crate::fsblkcnt64_t, + pub f_files: crate::fsfilcnt64_t, + pub f_ffree: crate::fsfilcnt64_t, + pub f_favail: crate::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, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + pub struct ipc_perm { + pub __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_ushort, + __pad1: Padding, + pub __seq: c_ushort, + __pad2: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused5: Padding, + __unused6: Padding, + } + + 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: crate::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: crate::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, + } +} + +s_no_extra_traits! { + pub struct ucontext_t { + pub __uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_sigmask: crate::sigset_t, + pub uc_mcontext: mcontext_t, + } + + #[repr(align(16))] + pub struct mcontext_t { + pub __gregs: [c_ulong; 32], + pub __fpregs: __riscv_mc_fp_state, + } + + 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, + } + + pub struct __riscv_mc_f_ext_state { + pub __f: [c_uint; 32], + pub __fcsr: c_uint, + } + + pub struct __riscv_mc_d_ext_state { + pub __f: [c_ulonglong; 32], + pub __fcsr: c_uint, + } + + #[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], + } +} + +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: crate::tcflag_t = 4111; +pub const TAB1: crate::tcflag_t = 2048; +pub const TAB2: crate::tcflag_t = 4096; +pub const TAB3: crate::tcflag_t = 6144; +pub const CR1: crate::tcflag_t = 512; +pub const CR2: crate::tcflag_t = 1024; +pub const CR3: crate::tcflag_t = 1536; +pub const FF1: crate::tcflag_t = 32768; +pub const BS1: crate::tcflag_t = 8192; +pub const VT1: crate::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: crate::tcflag_t = 1024; +pub const IXOFF: crate::tcflag_t = 4096; +pub const ONLCR: crate::tcflag_t = 4; +pub const CSIZE: crate::tcflag_t = 48; +pub const CS6: crate::tcflag_t = 16; +pub const CS7: crate::tcflag_t = 32; +pub const CS8: crate::tcflag_t = 48; +pub const CSTOPB: crate::tcflag_t = 64; +pub const CREAD: crate::tcflag_t = 128; +pub const PARENB: crate::tcflag_t = 256; +pub const PARODD: crate::tcflag_t = 512; +pub const HUPCL: crate::tcflag_t = 1024; +pub const CLOCAL: crate::tcflag_t = 2048; +pub const ECHOKE: crate::tcflag_t = 2048; +pub const ECHOE: crate::tcflag_t = 16; +pub const ECHOK: crate::tcflag_t = 32; +pub const ECHONL: crate::tcflag_t = 64; +pub const ECHOPRT: crate::tcflag_t = 1024; +pub const ECHOCTL: crate::tcflag_t = 512; +pub const ISIG: crate::tcflag_t = 1; +pub const ICANON: crate::tcflag_t = 2; +pub const PENDIN: crate::tcflag_t = 16384; +pub const NOFLSH: crate::tcflag_t = 128; +pub const CIBAUD: crate::tcflag_t = 269418496; +pub const CBAUDEX: crate::tcflag_t = 4096; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 2; +pub const NLDLY: crate::tcflag_t = 256; +pub const CRDLY: crate::tcflag_t = 1536; +pub const TABDLY: crate::tcflag_t = 6144; +pub const BSDLY: crate::tcflag_t = 8192; +pub const FFDLY: crate::tcflag_t = 32768; +pub const VTDLY: crate::tcflag_t = 16384; +pub const XTABS: crate::tcflag_t = 6144; +pub const B0: crate::speed_t = 0; +pub const B50: crate::speed_t = 1; +pub const B75: crate::speed_t = 2; +pub const B110: crate::speed_t = 3; +pub const B134: crate::speed_t = 4; +pub const B150: crate::speed_t = 5; +pub const B200: crate::speed_t = 6; +pub const B300: crate::speed_t = 7; +pub const B600: crate::speed_t = 8; +pub const B1200: crate::speed_t = 9; +pub const B1800: crate::speed_t = 10; +pub const B2400: crate::speed_t = 11; +pub const B4800: crate::speed_t = 12; +pub const B9600: crate::speed_t = 13; +pub const B19200: crate::speed_t = 14; +pub const B38400: crate::speed_t = 15; +pub const EXTA: crate::speed_t = 14; +pub const EXTB: crate::speed_t = 15; +pub const B57600: crate::speed_t = 4097; +pub const B115200: crate::speed_t = 4098; +pub const B230400: crate::speed_t = 4099; +pub const B460800: crate::speed_t = 4100; +pub const B500000: crate::speed_t = 4101; +pub const B576000: crate::speed_t = 4102; +pub const B921600: crate::speed_t = 4103; +pub const B1000000: crate::speed_t = 4104; +pub const B1152000: crate::speed_t = 4105; +pub const B1500000: crate::speed_t = 4106; +pub const B2000000: crate::speed_t = 4107; +pub const B2500000: crate::speed_t = 4108; +pub const B3000000: crate::speed_t = 4109; +pub const B3500000: crate::speed_t = 4110; +pub const B4000000: crate::speed_t = 4111; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: crate::tcflag_t = 32768; +pub const TOSTOP: crate::tcflag_t = 256; +pub const FLUSHO: crate::tcflag_t = 4096; +pub const EXTPROC: crate::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; 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..76b8998 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs @@ -0,0 +1,867 @@ +//! SPARC-specific definitions for 32-bit linux-like values + +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +pub type wchar_t = i32; + +s! { + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + pub struct statfs { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__fsword_t, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::fsid_t, + + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + f_spare: [crate::__fsword_t; 4], + } + + pub struct siginfo_t { + pub si_signo: c_int, + pub si_errno: c_int, + pub si_code: c_int, + _pad: Padding<[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: crate::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: crate::pid_t, + __reserved: Padding, + } + + 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: crate::dev_t, + #[cfg(not(gnu_file_offset_bits64))] + __pad1: Padding, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad2: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __glibc_reserved4: Padding, + __glibc_reserved5: Padding, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino64_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad2: Padding, + pub st_size: off64_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __glibc_reserved4: Padding, + __glibc_reserved5: Padding, + } + + pub struct statfs64 { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__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: crate::fsid_t, + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + pub f_spare: [crate::__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: Padding, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + __f_spare: [c_int; 6], + } + + pub struct ipc_perm { + pub __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + __pad1: Padding, + pub mode: c_ushort, + __pad2: Padding, + pub __seq: c_ushort, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + #[cfg(gnu_time_bits64)] + pub shm_segsz: size_t, + #[cfg(not(gnu_time_bits64))] + __pad1: Padding, + pub shm_atime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __pad2: Padding, + pub shm_dtime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __pad3: Padding, + pub shm_ctime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + pub shm_segsz: size_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __reserved1: Padding, + __reserved2: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + #[cfg(not(gnu_time_bits64))] + __pad1: Padding, + pub msg_stime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __pad2: Padding, + pub msg_rtime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __pad3: Padding, + pub msg_ctime: crate::time_t, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __glibc_reserved4: Padding, + __glibc_reserved5: Padding, + } +} + +s_no_extra_traits! { + #[repr(align(8))] + pub struct max_align_t { + priv_: [i64; 3], + } +} + +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 SIGEMT: 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 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: crate::tcflag_t = 0x0000100f; +pub const TAB1: crate::tcflag_t = 0x800; +pub const TAB2: crate::tcflag_t = 0x1000; +pub const TAB3: crate::tcflag_t = 0x1800; +pub const CR1: crate::tcflag_t = 0x200; +pub const CR2: crate::tcflag_t = 0x400; +pub const CR3: crate::tcflag_t = 0x600; +pub const FF1: crate::tcflag_t = 0x8000; +pub const BS1: crate::tcflag_t = 0x2000; +pub const VT1: crate::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: crate::tcflag_t = 0x400; +pub const IXOFF: crate::tcflag_t = 0x1000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x30; +pub const CS6: crate::tcflag_t = 0x10; +pub const CS7: crate::tcflag_t = 0x20; +pub const CS8: crate::tcflag_t = 0x30; +pub const CSTOPB: crate::tcflag_t = 0x40; +pub const CREAD: crate::tcflag_t = 0x80; +pub const PARENB: crate::tcflag_t = 0x100; +pub const PARODD: crate::tcflag_t = 0x200; +pub const HUPCL: crate::tcflag_t = 0x400; +pub const CLOCAL: crate::tcflag_t = 0x800; +pub const ECHOKE: crate::tcflag_t = 0x800; +pub const ECHOE: crate::tcflag_t = 0x10; +pub const ECHOK: crate::tcflag_t = 0x20; +pub const ECHONL: crate::tcflag_t = 0x40; +pub const ECHOPRT: crate::tcflag_t = 0x400; +pub const ECHOCTL: crate::tcflag_t = 0x200; +pub const ISIG: crate::tcflag_t = 0x1; +pub const ICANON: crate::tcflag_t = 0x2; +pub const PENDIN: crate::tcflag_t = 0x4000; +pub const NOFLSH: crate::tcflag_t = 0x80; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0x00001000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const B57600: crate::speed_t = 0x1001; +pub const B115200: crate::speed_t = 0x1002; +pub const B230400: crate::speed_t = 0x1003; +pub const B460800: crate::speed_t = 0x1004; +pub const B76800: crate::speed_t = 0x1005; +pub const B153600: crate::speed_t = 0x1006; +pub const B307200: crate::speed_t = 0x1007; +pub const B614400: crate::speed_t = 0x1008; +pub const B921600: crate::speed_t = 0x1009; +pub const B500000: crate::speed_t = 0x100a; +pub const B576000: crate::speed_t = 0x100b; +pub const B1000000: crate::speed_t = 0x100c; +pub const B1152000: crate::speed_t = 0x100d; +pub const B1500000: crate::speed_t = 0x100e; +pub const B2000000: crate::speed_t = 0x100f; + +pub const VEOL: usize = 5; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const IEXTEN: crate::tcflag_t = 0x8000; +pub const TOSTOP: crate::tcflag_t = 0x100; +pub const FLUSHO: crate::tcflag_t = 0x1000; +pub const EXTPROC: crate::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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 221; +pub const SYS_delete_module: c_long = 222; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +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; 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..97429da --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/mod.rs @@ -0,0 +1,1035 @@ +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +pub type wchar_t = i32; +pub type greg_t = i32; + +s! { + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + pub struct statfs { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__fsword_t, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::fsid_t, + + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + f_spare: [crate::__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: crate::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: crate::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: Padding, + 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: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_ushort, + __pad1: Padding, + pub __seq: c_ushort, + __pad2: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + #[cfg(not(gnu_time_bits64))] + __pad1: Padding, + #[cfg(not(gnu_time_bits64))] + __st_ino: c_ulong, + #[cfg(gnu_time_bits64)] + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + #[cfg(not(gnu_time_bits64))] + __pad2: Padding, + pub st_size: off64_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + #[cfg(gnu_time_bits64)] + _atime_pad: Padding, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + #[cfg(gnu_time_bits64)] + _mtime_pad: Padding, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + #[cfg(gnu_time_bits64)] + _ctime_pad: Padding, + #[cfg(not(gnu_time_bits64))] + pub st_ino: crate::ino64_t, + } + + pub struct statfs64 { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__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: crate::fsid_t, + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + pub f_spare: [crate::__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: Padding, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + __f_spare: [c_int; 6], + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __unused1: Padding, + pub shm_dtime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __unused2: Padding, + pub shm_ctime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __unused3: Padding, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused4: Padding, + __unused5: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + pub msg_stime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved1: Padding, + pub msg_rtime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved2: Padding, + pub msg_ctime: crate::time_t, + #[cfg(not(gnu_time_bits64))] + __glibc_reserved3: Padding, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __glibc_reserved4: Padding, + __glibc_reserved5: Padding, + } + + 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 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: Padding, + pub st_space: [c_long; 32], + pub xmm_space: [c_long; 32], + padding: Padding<[c_long; 56]>, + } + + pub struct ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: crate::sigset_t, + __private: [u8; 112], + __ssp: [c_ulong; 4], + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 6], + } +} + +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: c_int = 0x8; +pub const RTLD_GLOBAL: c_int = 0x100; +pub const RTLD_NOLOAD: c_int = 0x4; +pub const 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; + +cfg_if! { + if #[cfg(gnu_file_offset_bits64)] { + pub const F_GETLK: c_int = 12; + } else { + 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: crate::tcflag_t = 0o0010017; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const FF1: crate::tcflag_t = 0x00008000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const VT1: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; + +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::tcflag_t = 0x00001000; +pub const EXTPROC: crate::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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 127; +pub const SYS_init_module: c_long = 128; +pub const SYS_delete_module: c_long = 129; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +} 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..db73bf0 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs @@ -0,0 +1,10 @@ +use crate::prelude::*; + +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; + +pub const SYS_sync_file_range2: c_long = 84; 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..c734227 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs @@ -0,0 +1,13 @@ +use crate::prelude::*; + +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; + +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..a4fe3ba --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs @@ -0,0 +1,976 @@ +//! AArch64-specific definitions for 64-bit linux-like values + +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +pub type wchar_t = u32; +pub type nlink_t = u32; +pub type blksize_t = i32; +pub type suseconds_t = i64; + +s! { + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + #[cfg(target_arch = "sparc64")] + __reserved0: Padding, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + pub struct statfs { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__fsword_t, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::fsid_t, + + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + f_spare: [crate::__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: crate::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: crate::pid_t, + } + + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad1: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + __pad2: Padding, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_int; 2]>, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad1: Padding, + pub st_size: off64_t, + pub st_blksize: crate::blksize_t, + __pad2: Padding, + pub st_blocks: crate::blkcnt64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_int; 2]>, + } + + pub struct statfs64 { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__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: crate::fsid_t, + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + pub f_spare: [crate::__fsword_t; 4], + } + + pub struct statvfs { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_uint, + pub __seq: c_ushort, + __pad1: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused4: Padding, + __unused5: Padding, + } + + 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 ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_sigmask: crate::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, + __reserved: Padding<[u64; 512]>, + } + + pub struct user_fpsimd_struct { + pub vregs: [u128; 32], + pub fpsr: c_uint, + pub fpcr: c_uint, + } + + #[repr(align(8))] + pub struct clone_args { + pub flags: c_ulonglong, + pub pidfd: c_ulonglong, + pub child_tid: c_ulonglong, + pub parent_tid: c_ulonglong, + pub exit_signal: c_ulonglong, + pub stack: c_ulonglong, + pub stack_size: c_ulonglong, + pub tls: c_ulonglong, + pub set_tid: c_ulonglong, + pub set_tid_size: c_ulonglong, + pub cgroup: c_ulonglong, + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f32; 8], + } +} + +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 = u32_cast_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: crate::tcflag_t = 0o0010017; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const FF1: crate::tcflag_t = 0x00008000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const VT1: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; + +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::tcflag_t = 0x00001000; +pub const EXTPROC: crate::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(linux): 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_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_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_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_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; + + 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 ilp32; + pub use self::ilp32::*; + } else { + mod lp64; + pub use self::lp64::*; + } +} 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..0104488 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs @@ -0,0 +1,879 @@ +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +pub type wchar_t = i32; + +pub type blksize_t = i32; +pub type nlink_t = u32; +pub type suseconds_t = i64; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad1: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + __pad2: Padding, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_int; 2]>, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino64_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub __pad1: crate::dev_t, + pub st_size: off64_t, + pub st_blksize: crate::blksize_t, + pub __pad2: c_int, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_int; 2]>, + } + + pub struct statfs { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__fsword_t, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::fsid_t, + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + pub f_spare: [crate::__fsword_t; 4], + } + + pub struct statfs64 { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__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: crate::fsid_t, + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + pub f_spare: [crate::__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: crate::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: crate::pid_t, + } + + pub struct statvfs { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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], + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::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: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_uint, + pub __seq: c_ushort, + __pad2: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused4: Padding, + __unused5: Padding, + } + + 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 struct ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_sigmask: crate::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, + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4], + } +} + +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 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 = u32_cast_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: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::tcflag_t = 0x00001000; +pub const EXTPROC: crate::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: crate::tcflag_t = 0o0010017; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const FF1: crate::tcflag_t = 0x00008000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; +pub const VT1: crate::tcflag_t = 0x00004000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const IXON: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::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; 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..7fed1e5 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs @@ -0,0 +1,888 @@ +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +pub type blksize_t = i64; +pub type nlink_t = u64; +pub type suseconds_t = i64; +pub type wchar_t = i32; + +s! { + pub struct stat { + pub st_dev: c_ulong, + st_pad1: Padding<[c_long; 2]>, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: c_ulong, + st_pad2: Padding<[c_ulong; 1]>, + pub st_size: off_t, + st_pad3: Padding, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_blksize: crate::blksize_t, + st_pad4: Padding, + pub st_blocks: crate::blkcnt_t, + st_pad5: Padding<[c_long; 7]>, + } + + pub struct statfs { + pub f_type: c_long, + pub f_bsize: c_long, + pub f_frsize: c_long, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_files: crate::fsblkcnt_t, + pub f_ffree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_fsid: crate::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: crate::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: crate::pid_t, + } + + pub struct stat64 { + pub st_dev: c_ulong, + st_pad1: Padding<[c_long; 2]>, + pub st_ino: crate::ino64_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: c_ulong, + st_pad2: Padding<[c_long; 2]>, + pub st_size: off64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_blksize: crate::blksize_t, + st_pad3: Padding, + pub st_blocks: crate::blkcnt64_t, + st_pad5: Padding<[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: crate::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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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], + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_flags: c_int, + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::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: Padding, + _pad2: Padding<[c_long; 14]>, + } + + pub struct ipc_perm { + pub __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_uint, + pub __seq: c_ushort, + __pad1: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused4: Padding, + __unused5: Padding, + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4], + } +} + +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_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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_get_kernel_syms: c_long = 5000 + 170; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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 = u32_cast_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 SIGEMT: c_int = 7; +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: crate::tcflag_t = 0x00000100; +pub const TOSTOP: crate::tcflag_t = 0x00008000; +pub const FLUSHO: crate::tcflag_t = 0x00002000; +pub const EXTPROC: crate::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: crate::tcflag_t = 0o0010017; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const FF1: crate::tcflag_t = 0x00008000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const VT1: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::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; +} 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..16b7bef --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/mod.rs @@ -0,0 +1,224 @@ +//! 64-bit specific definitions for linux-like values + +use crate::prelude::*; + +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: crate::ipc_perm, + pub msg_stime: crate::time_t, + pub msg_rtime: crate::time_t, + pub msg_ctime: crate::time_t, + pub __msg_cbytes: u64, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __glibc_reserved4: Padding, + __glibc_reserved5: Padding, + } + + pub struct semid_ds { + pub sem_perm: ipc_perm, + pub sem_otime: crate::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", + target_arch = "s390x", + )))] + __reserved: Padding, + pub sem_ctime: crate::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", + target_arch = "s390x", + )))] + __reserved2: Padding, + pub sem_nsems: crate::__syscall_ulong_t, + __glibc_reserved3: Padding, + __glibc_reserved4: Padding, + } + + // net/iucv/iucv.h + + pub struct sockaddr_iucv { + pub siucv_family: crate::sa_family_t, + __siucv_port: Padding, // unused crate::in_port_t + __siucv_addr: Padding, // unused crate::in_addr_t + pub siucv_nodeid: [c_char; 8], + pub siucv_user_id: [c_char; 8], + pub siucv_name: [c_char; 8], + } + + 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: crate::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 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(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/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs new file mode 100644 index 0000000..f304507 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs @@ -0,0 +1,1016 @@ +//! PowerPC64-specific definitions for 64-bit linux-like values + +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +pub type wchar_t = i32; +pub type nlink_t = u64; +pub type blksize_t = i64; +pub type suseconds_t = i64; +pub type gregset_t = [c_ulong; __NGREG]; +pub type fpregset_t = [c_ulong; __NFPREG]; + +s! { + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + #[cfg(target_arch = "sparc64")] + __reserved0: Padding, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + pub struct statfs { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__fsword_t, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::fsid_t, + + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + f_spare: [crate::__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: crate::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: crate::pid_t, + } + + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + __pad0: Padding, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_long; 3]>, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino64_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + __pad0: Padding, + pub st_rdev: crate::dev_t, + pub st_size: off64_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __reserved: Padding<[c_long; 3]>, + } + + pub struct statfs64 { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__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: crate::fsid_t, + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + pub f_spare: [crate::__fsword_t; 4], + } + + pub struct statvfs { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: u32, + __pad1: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_segsz: size_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused4: Padding, + __unused5: Padding, + } + + 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, + } + + #[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, + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [i64; 4], + } + + pub struct ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_sigmask: crate::sigset_t, + pub uc_mcontext: mcontext_t, + } + + pub struct pt_regs { + pub gpr: [c_ulong; 32], + pub nip: c_ulong, + pub msr: c_ulong, + pub orig_gpr3: c_ulong, + pub ctr: c_ulong, + pub link: c_ulong, + pub xer: c_ulong, + pub ccr: c_ulong, + pub softe: c_ulong, + pub trap: c_ulong, + pub dar: c_ulong, + pub dsisr: c_ulong, + pub result: c_ulong, + } + + pub struct mcontext_t { + __glibc_reserved: Padding<[c_ulong; 4]>, + pub signal: c_int, + __pad0: Padding, + pub handler: c_ulong, + pub oldmask: c_ulong, + pub regs: *mut pt_regs, + pub gp_regs: crate::gregset_t, + pub fp_regs: crate::fpregset_t, + pub v_regs: *mut vrregset_t, + pub vmx_reserve: [c_long; __NVRREG + __NVRREG + 1], + } + + #[repr(align(16))] + pub struct vrregset_t { + pub vrregs: [[c_uint; 4]; 32], + pub vscr: vscr_t, + pub vrsave: c_uint, + __pad: Padding<[c_uint; 3]>, + } + + #[repr(align(4))] + pub struct vscr_t { + #[cfg(target_endian = "big")] + __pad: Padding<[c_uint; 3]>, + #[cfg(target_endian = "big")] + pub vscr_word: c_uint, + + #[cfg(target_endian = "little")] + pub vscr_word: c_uint, + #[cfg(target_endian = "little")] + __pad: Padding<[c_uint; 3]>, + } +} + +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 __NGREG: usize = 48; +pub const __NFPREG: usize = 33; +pub const __NVRREG: usize = 34; + +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 = u32_cast_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; + +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: crate::tcflag_t = 0xff; +pub const TAB1: crate::tcflag_t = 0x400; +pub const TAB2: crate::tcflag_t = 0x800; +pub const TAB3: crate::tcflag_t = 0xc00; +pub const CR1: crate::tcflag_t = 0x1000; +pub const CR2: crate::tcflag_t = 0x2000; +pub const CR3: crate::tcflag_t = 0x3000; +pub const FF1: crate::tcflag_t = 0x4000; +pub const BS1: crate::tcflag_t = 0x8000; +pub const VT1: crate::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: crate::tcflag_t = 0x200; +pub const IXOFF: crate::tcflag_t = 0x400; +pub const ONLCR: crate::tcflag_t = 0x2; +pub const CSIZE: crate::tcflag_t = 0x300; +pub const CS6: crate::tcflag_t = 0x100; +pub const CS7: crate::tcflag_t = 0x200; +pub const CS8: crate::tcflag_t = 0x300; +pub const CSTOPB: crate::tcflag_t = 0x400; +pub const CREAD: crate::tcflag_t = 0x800; +pub const PARENB: crate::tcflag_t = 0x1000; +pub const PARODD: crate::tcflag_t = 0x2000; +pub const HUPCL: crate::tcflag_t = 0x4000; +pub const CLOCAL: crate::tcflag_t = 0x8000; +pub const ECHOKE: crate::tcflag_t = 0x1; +pub const ECHOE: crate::tcflag_t = 0x2; +pub const ECHOK: crate::tcflag_t = 0x4; +pub const ECHONL: crate::tcflag_t = 0x10; +pub const ECHOPRT: crate::tcflag_t = 0x20; +pub const ECHOCTL: crate::tcflag_t = 0x40; +pub const ISIG: crate::tcflag_t = 0x80; +pub const ICANON: crate::tcflag_t = 0x100; +pub const PENDIN: crate::tcflag_t = 0x20000000; +pub const NOFLSH: crate::tcflag_t = 0x80000000; +pub const VSWTC: usize = 9; +pub const OLCUC: crate::tcflag_t = 0o000004; +pub const NLDLY: crate::tcflag_t = 0o001400; +pub const CRDLY: crate::tcflag_t = 0o030000; +pub const TABDLY: crate::tcflag_t = 0o006000; +pub const BSDLY: crate::tcflag_t = 0o100000; +pub const FFDLY: crate::tcflag_t = 0o040000; +pub const VTDLY: crate::tcflag_t = 0o200000; +pub const XTABS: crate::tcflag_t = 0o006000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const CBAUDEX: crate::speed_t = 0o000020; +pub const B57600: crate::speed_t = 0o0020; +pub const B115200: crate::speed_t = 0o0021; +pub const B230400: crate::speed_t = 0o0022; +pub const B460800: crate::speed_t = 0o0023; +pub const B500000: crate::speed_t = 0o0024; +pub const B576000: crate::speed_t = 0o0025; +pub const B921600: crate::speed_t = 0o0026; +pub const B1000000: crate::speed_t = 0o0027; +pub const B1152000: crate::speed_t = 0o0030; +pub const B1500000: crate::speed_t = 0o0031; +pub const B2000000: crate::speed_t = 0o0032; +pub const B2500000: crate::speed_t = 0o0033; +pub const B3000000: crate::speed_t = 0o0034; +pub const B3500000: crate::speed_t = 0o0035; +pub const B4000000: crate::speed_t = 0o0036; + +pub const VEOL: usize = 6; +pub const VEOL2: usize = 8; +pub const VMIN: usize = 5; +pub const IEXTEN: crate::tcflag_t = 0x400; +pub const TOSTOP: crate::tcflag_t = 0x400000; +pub const FLUSHO: crate::tcflag_t = 0x800000; +pub const EXTPROC: crate::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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 127; +pub const SYS_init_module: c_long = 128; +pub const SYS_delete_module: c_long = 129; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; + + pub fn getcontext(ucp: *mut ucontext_t) -> c_int; + pub fn setcontext(ucp: *const ucontext_t) -> c_int; + pub fn swapcontext(oucp: *mut ucontext_t, ucp: *const ucontext_t) -> c_int; + pub fn makecontext(ucp: *mut ucontext_t, func: extern "C" fn(), argc: c_int, ...); +} 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..3371f03 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs @@ -0,0 +1,916 @@ +//! RISC-V-specific definitions for 64-bit linux-like values + +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +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; + +s! { + pub struct pthread_attr_t { + __size: [c_ulong; 7], + } + + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub __pad1: crate::dev_t, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub __pad2: c_int, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_int; 2usize]>, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino64_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub __pad1: crate::dev_t, + pub st_size: off64_t, + pub st_blksize: crate::blksize_t, + pub __pad2: c_int, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_int; 2]>, + } + + pub struct statfs { + pub f_type: c_long, + pub f_bsize: c_long, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::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: crate::fsblkcnt64_t, + pub f_bfree: crate::fsblkcnt64_t, + pub f_bavail: crate::fsblkcnt64_t, + pub f_files: crate::fsfilcnt64_t, + pub f_ffree: crate::fsfilcnt64_t, + pub f_fsid: crate::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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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: crate::fsblkcnt64_t, + pub f_bfree: crate::fsblkcnt64_t, + pub f_bavail: crate::fsblkcnt64_t, + pub f_files: crate::fsfilcnt64_t, + pub f_ffree: crate::fsfilcnt64_t, + pub f_favail: crate::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, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + pub struct ipc_perm { + pub __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_ushort, + __pad1: Padding, + pub __seq: c_ushort, + __pad2: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused5: Padding, + __unused6: Padding, + } + + 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: crate::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: crate::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, + } + + #[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, + } +} + +s_no_extra_traits! { + pub struct ucontext_t { + pub __uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_sigmask: crate::sigset_t, + pub uc_mcontext: mcontext_t, + } + + #[repr(align(16))] + pub struct mcontext_t { + pub __gregs: [c_ulong; 32], + pub __fpregs: __riscv_mc_fp_state, + } + + 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, + } + + pub struct __riscv_mc_f_ext_state { + pub __f: [c_uint; 32], + pub __fcsr: c_uint, + } + + pub struct __riscv_mc_d_ext_state { + pub __f: [c_ulonglong; 32], + pub __fcsr: c_uint, + } + + #[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], + } + + #[repr(align(16))] + pub struct max_align_t { + priv_: [f32; 8], + } +} + +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: crate::tcflag_t = 4111; +pub const TAB1: crate::tcflag_t = 2048; +pub const TAB2: crate::tcflag_t = 4096; +pub const TAB3: crate::tcflag_t = 6144; +pub const CR1: crate::tcflag_t = 512; +pub const CR2: crate::tcflag_t = 1024; +pub const CR3: crate::tcflag_t = 1536; +pub const FF1: crate::tcflag_t = 32768; +pub const BS1: crate::tcflag_t = 8192; +pub const VT1: crate::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: crate::tcflag_t = 1024; +pub const IXOFF: crate::tcflag_t = 4096; +pub const ONLCR: crate::tcflag_t = 4; +pub const CSIZE: crate::tcflag_t = 48; +pub const CS6: crate::tcflag_t = 16; +pub const CS7: crate::tcflag_t = 32; +pub const CS8: crate::tcflag_t = 48; +pub const CSTOPB: crate::tcflag_t = 64; +pub const CREAD: crate::tcflag_t = 128; +pub const PARENB: crate::tcflag_t = 256; +pub const PARODD: crate::tcflag_t = 512; +pub const HUPCL: crate::tcflag_t = 1024; +pub const CLOCAL: crate::tcflag_t = 2048; +pub const ECHOKE: crate::tcflag_t = 2048; +pub const ECHOE: crate::tcflag_t = 16; +pub const ECHOK: crate::tcflag_t = 32; +pub const ECHONL: crate::tcflag_t = 64; +pub const ECHOPRT: crate::tcflag_t = 1024; +pub const ECHOCTL: crate::tcflag_t = 512; +pub const ISIG: crate::tcflag_t = 1; +pub const ICANON: crate::tcflag_t = 2; +pub const PENDIN: crate::tcflag_t = 16384; +pub const NOFLSH: crate::tcflag_t = 128; +pub const CIBAUD: crate::tcflag_t = 269418496; +pub const CBAUDEX: crate::tcflag_t = 4096; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 2; +pub const NLDLY: crate::tcflag_t = 256; +pub const CRDLY: crate::tcflag_t = 1536; +pub const TABDLY: crate::tcflag_t = 6144; +pub const BSDLY: crate::tcflag_t = 8192; +pub const FFDLY: crate::tcflag_t = 32768; +pub const VTDLY: crate::tcflag_t = 16384; +pub const XTABS: crate::tcflag_t = 6144; +pub const B0: crate::speed_t = 0; +pub const B50: crate::speed_t = 1; +pub const B75: crate::speed_t = 2; +pub const B110: crate::speed_t = 3; +pub const B134: crate::speed_t = 4; +pub const B150: crate::speed_t = 5; +pub const B200: crate::speed_t = 6; +pub const B300: crate::speed_t = 7; +pub const B600: crate::speed_t = 8; +pub const B1200: crate::speed_t = 9; +pub const B1800: crate::speed_t = 10; +pub const B2400: crate::speed_t = 11; +pub const B4800: crate::speed_t = 12; +pub const B9600: crate::speed_t = 13; +pub const B19200: crate::speed_t = 14; +pub const B38400: crate::speed_t = 15; +pub const EXTA: crate::speed_t = 14; +pub const EXTB: crate::speed_t = 15; +pub const B57600: crate::speed_t = 4097; +pub const B115200: crate::speed_t = 4098; +pub const B230400: crate::speed_t = 4099; +pub const B460800: crate::speed_t = 4100; +pub const B500000: crate::speed_t = 4101; +pub const B576000: crate::speed_t = 4102; +pub const B921600: crate::speed_t = 4103; +pub const B1000000: crate::speed_t = 4104; +pub const B1152000: crate::speed_t = 4105; +pub const B1500000: crate::speed_t = 4106; +pub const B2000000: crate::speed_t = 4107; +pub const B2500000: crate::speed_t = 4108; +pub const B3000000: crate::speed_t = 4109; +pub const B3500000: crate::speed_t = 4110; +pub const B4000000: crate::speed_t = 4111; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: crate::tcflag_t = 32768; +pub const TOSTOP: crate::tcflag_t = 256; +pub const FLUSHO: crate::tcflag_t = 4096; +pub const EXTPROC: crate::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'); +#[allow(clippy::eq_op)] +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; 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..c5a7cc4 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/s390x.rs @@ -0,0 +1,936 @@ +//! s390x + +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +pub type blksize_t = i64; +pub type nlink_t = u64; +pub type suseconds_t = i64; +pub type wchar_t = i32; +pub type greg_t = u64; + +s! { + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + __glibc_reserved0: Padding, + pub sa_flags: c_int, + pub sa_restorer: Option, + pub sa_mask: crate::sigset_t, + } + + pub struct statfs { + pub f_type: c_uint, + pub f_bsize: c_uint, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::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: crate::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: crate::pid_t, + } + + pub struct siginfo_t { + pub si_signo: c_int, + pub si_errno: c_int, + pub si_code: c_int, + _pad: Padding, + _pad2: Padding<[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: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + st_pad0: Padding, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + __glibc_reserved: Padding<[c_long; 3]>, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino64_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + st_pad0: Padding, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt64_t, + __glibc_reserved: Padding<[c_long; 3]>, + } + + pub struct pthread_attr_t { + __size: [c_ulong; 7], + } + + pub struct ipc_perm { + pub __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: c_ushort, + __pad1: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused4: Padding, + __unused5: Padding, + } + + pub struct statvfs { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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: Padding, + 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: crate::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: crate::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: crate::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(union): 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 hash::Hash for fpreg_t { + fn hash(&self, state: &mut H) { + let d: u64 = self.d.to_bits(); + 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 = u32_cast_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; + +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: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::tcflag_t = 0x00001000; + +pub const EXTPROC: crate::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: crate::tcflag_t = 0o000002; +pub const ONLCR: crate::tcflag_t = 0o000004; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const FF1: crate::tcflag_t = 0x00008000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const VT1: crate::tcflag_t = 0x00004000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const CBAUD: crate::speed_t = 0o010017; +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const CSIZE: crate::tcflag_t = 0o000060; +pub const CS6: crate::tcflag_t = 0o000020; +pub const CS7: crate::tcflag_t = 0o000040; +pub const CS8: crate::tcflag_t = 0o000060; +pub const CSTOPB: crate::tcflag_t = 0o000100; +pub const CREAD: crate::tcflag_t = 0o000200; +pub const PARENB: crate::tcflag_t = 0o000400; +pub const PARODD: crate::tcflag_t = 0o001000; +pub const HUPCL: crate::tcflag_t = 0o002000; +pub const CLOCAL: crate::tcflag_t = 0o004000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; + +pub const ISIG: crate::tcflag_t = 0o000001; +pub const ICANON: crate::tcflag_t = 0o000002; +pub const ECHOE: crate::tcflag_t = 0o000020; +pub const ECHOK: crate::tcflag_t = 0o000040; +pub const ECHONL: crate::tcflag_t = 0o000100; +pub const NOFLSH: crate::tcflag_t = 0o000200; +pub const ECHOCTL: crate::tcflag_t = 0o001000; +pub const ECHOPRT: crate::tcflag_t = 0o002000; +pub const ECHOKE: crate::tcflag_t = 0o004000; +pub const PENDIN: crate::tcflag_t = 0o040000; + +pub const POLLWRNORM: c_short = 0x100; +pub const POLLWRBAND: c_short = 0x200; + +pub const IXON: crate::tcflag_t = 0o002000; +pub const IXOFF: crate::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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 127; +pub const SYS_init_module: c_long = 128; +pub const SYS_delete_module: c_long = 129; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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 crate::ucontext_t) -> c_int; + pub fn setcontext(ucp: *const crate::ucontext_t) -> c_int; + pub fn makecontext(ucp: *mut crate::ucontext_t, func: extern "C" fn(), argc: c_int, ...); + pub fn swapcontext(uocp: *mut crate::ucontext_t, ucp: *const crate::ucontext_t) -> c_int; +} 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..6e3673e --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs @@ -0,0 +1,911 @@ +//! SPARC64-specific definitions for 64-bit linux-like values + +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +pub type wchar_t = i32; +pub type nlink_t = u32; +pub type blksize_t = i64; +pub type suseconds_t = i32; + +s! { + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + #[cfg(target_arch = "sparc64")] + __reserved0: Padding, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + pub struct statfs { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__fsword_t, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::fsid_t, + + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + f_spare: [crate::__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: crate::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: crate::pid_t, + __reserved: Padding, + } + + 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: crate::dev_t, + __pad0: Padding, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad1: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_long; 2]>, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + __pad0: Padding, + pub st_ino: crate::ino64_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad2: Padding, + pub st_size: off64_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __reserved: Padding<[c_long; 2]>, + } + + pub struct statfs64 { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__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: crate::fsid_t, + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + pub f_spare: [crate::__fsword_t; 4], + } + + pub struct statvfs { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + __pad0: Padding, + pub __seq: c_ushort, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_segsz: size_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __reserved1: Padding, + __reserved2: Padding, + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [i64; 4], + } +} + +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 SIGEMT: 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 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; + +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: crate::tcflag_t = 0x0000100f; +pub const TAB1: crate::tcflag_t = 0x800; +pub const TAB2: crate::tcflag_t = 0x1000; +pub const TAB3: crate::tcflag_t = 0x1800; +pub const CR1: crate::tcflag_t = 0x200; +pub const CR2: crate::tcflag_t = 0x400; +pub const CR3: crate::tcflag_t = 0x600; +pub const FF1: crate::tcflag_t = 0x8000; +pub const BS1: crate::tcflag_t = 0x2000; +pub const VT1: crate::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: crate::tcflag_t = 0x400; +pub const IXOFF: crate::tcflag_t = 0x1000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x30; +pub const CS6: crate::tcflag_t = 0x10; +pub const CS7: crate::tcflag_t = 0x20; +pub const CS8: crate::tcflag_t = 0x30; +pub const CSTOPB: crate::tcflag_t = 0x40; +pub const CREAD: crate::tcflag_t = 0x80; +pub const PARENB: crate::tcflag_t = 0x100; +pub const PARODD: crate::tcflag_t = 0x200; +pub const HUPCL: crate::tcflag_t = 0x400; +pub const CLOCAL: crate::tcflag_t = 0x800; +pub const ECHOKE: crate::tcflag_t = 0x800; +pub const ECHOE: crate::tcflag_t = 0x10; +pub const ECHOK: crate::tcflag_t = 0x20; +pub const ECHONL: crate::tcflag_t = 0x40; +pub const ECHOPRT: crate::tcflag_t = 0x400; +pub const ECHOCTL: crate::tcflag_t = 0x200; +pub const ISIG: crate::tcflag_t = 0x1; +pub const ICANON: crate::tcflag_t = 0x2; +pub const PENDIN: crate::tcflag_t = 0x4000; +pub const NOFLSH: crate::tcflag_t = 0x80; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0x00001000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const B57600: crate::speed_t = 0x1001; +pub const B115200: crate::speed_t = 0x1002; +pub const B230400: crate::speed_t = 0x1003; +pub const B460800: crate::speed_t = 0x1004; +pub const B76800: crate::speed_t = 0x1005; +pub const B153600: crate::speed_t = 0x1006; +pub const B307200: crate::speed_t = 0x1007; +pub const B614400: crate::speed_t = 0x1008; +pub const B921600: crate::speed_t = 0x1009; +pub const B500000: crate::speed_t = 0x100a; +pub const B576000: crate::speed_t = 0x100b; +pub const B1000000: crate::speed_t = 0x100c; +pub const B1152000: crate::speed_t = 0x100d; +pub const B1500000: crate::speed_t = 0x100e; +pub const B2000000: crate::speed_t = 0x100f; + +pub const VEOL: usize = 5; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const IEXTEN: crate::tcflag_t = 0x8000; +pub const TOSTOP: crate::tcflag_t = 0x100; +pub const FLUSHO: crate::tcflag_t = 0x1000; +pub const EXTPROC: crate::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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 221; +pub const SYS_delete_module: c_long = 222; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +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; +} 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..9658aeb --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs @@ -0,0 +1,741 @@ +//! x86_64-specific definitions for 64-bit linux-like values + +use crate::prelude::*; +use crate::{ + off64_t, + off_t, +}; + +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; + +s! { + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + #[cfg(target_arch = "sparc64")] + __reserved0: Padding, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + pub struct statfs { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__fsword_t, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::fsid_t, + + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + f_spare: [crate::__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: crate::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: crate::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: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + __pad0: Padding, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: i64, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: i64, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: i64, + __unused: Padding<[i64; 3]>, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino64_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + __pad0: Padding, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: i64, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: i64, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: i64, + __reserved: Padding<[i64; 3]>, + } + + pub struct statfs64 { + pub f_type: crate::__fsword_t, + pub f_bsize: crate::__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: crate::fsid_t, + pub f_namelen: crate::__fsword_t, + pub f_frsize: crate::__fsword_t, + pub f_flags: crate::__fsword_t, + pub f_spare: [crate::__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: Padding, + #[cfg(target_pointer_width = "32")] + __pad1: Padding, + pub u_ar0: *mut user_regs_struct, + #[cfg(target_pointer_width = "32")] + __pad2: Padding, + 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: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_ushort, + __pad1: Padding, + pub __seq: c_ushort, + __pad2: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused4: Padding, + __unused5: Padding, + } + + pub struct ptrace_rseq_configuration { + pub rseq_abi_pointer: crate::__u64, + pub rseq_abi_size: crate::__u32, + pub signature: crate::__u32, + pub flags: crate::__u32, + pub pad: crate::__u32, + } + + #[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, + } + + 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: Padding<[c_uint; 24]>, + } + + pub struct ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: crate::sigset_t, + __private: [u8; 512], + __ssp: [c_ulonglong; 4], + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4], + } +} + +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 = u32_cast_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(linux): 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: crate::tcflag_t = 0o0010017; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const FF1: crate::tcflag_t = 0x00008000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const VT1: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::speed_t = B38400; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; + +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::tcflag_t = 0x00001000; +pub const EXTPROC: crate::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::*; + } +} 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..9f9a618 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs @@ -0,0 +1,402 @@ +use crate::prelude::*; + +s! { + pub struct statvfs { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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; + +// 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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 174; +pub const SYS_init_module: c_long = 175; +pub const SYS_delete_module: c_long = 176; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_get_kernel_syms: c_long = 177; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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..183eccc --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs @@ -0,0 +1,378 @@ +use crate::prelude::*; + +s! { + pub struct statvfs { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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; + +// 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..d162a26 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs @@ -0,0 +1,1354 @@ +use crate::off64_t; +use crate::prelude::*; + +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; +pub type __be16 = crate::__u16; + +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 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: crate::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(gnu_file_offset_bits64), + not(target_arch = "x86_64"), + target_pointer_width = "32" + ))] + __unused1: Padding<[c_char; 4]>, + __glibc_reserved: Padding<[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: Padding<*mut c_void>, + __unused2: Padding<*mut c_void>, + __unused3: Padding<*mut c_void>, + __unused4: Padding<*mut c_void>, + __unused5: Padding<*mut c_void>, + } + + pub struct msghdr { + pub msg_name: *mut c_void, + pub msg_namelen: crate::socklen_t, + pub msg_iov: *mut crate::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: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; crate::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: crate::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: crate::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 ntptimeval { + pub time: crate::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: crate::Elf64_Word, + pub ch_reserved: crate::Elf64_Word, + pub ch_size: crate::Elf64_Xword, + pub ch_addralign: crate::Elf64_Xword, + } + + pub struct Elf32_Chdr { + pub ch_type: crate::Elf32_Word, + pub ch_size: crate::Elf32_Word, + pub ch_addralign: crate::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: crate::__u64, + pub flags: crate::__u32, + pub nr: crate::__s32, + } + + pub struct __c_anonymous_ptrace_syscall_info_entry { + pub nr: crate::__u64, + pub args: [crate::__u64; 6], + } + + pub struct __c_anonymous_ptrace_syscall_info_exit { + pub sval: crate::__s64, + pub is_error: crate::__u8, + } + + pub struct __c_anonymous_ptrace_syscall_info_seccomp { + pub nr: crate::__u64, + pub args: [crate::__u64; 6], + pub ret_data: crate::__u32, + reserved2: Padding, + } + + pub struct ptrace_syscall_info { + pub op: crate::__u8, + reserved: Padding, + pub flags: crate::__u16, + pub arch: crate::__u32, + pub instruction_pointer: crate::__u64, + pub stack_pointer: crate::__u64, + pub u: __c_anonymous_ptrace_syscall_info_data, + } + + pub struct ptrace_sud_config { + pub mode: crate::__u64, + pub selector: crate::__u64, + pub offset: crate::__u64, + pub len: crate::__u64, + } + + pub struct iocb { + pub aio_data: crate::__u64, + #[cfg(target_endian = "little")] + pub aio_key: crate::__u32, + #[cfg(target_endian = "little")] + pub aio_rw_flags: crate::__kernel_rwf_t, + #[cfg(target_endian = "big")] + pub aio_rw_flags: crate::__kernel_rwf_t, + #[cfg(target_endian = "big")] + pub aio_key: crate::__u32, + pub aio_lio_opcode: crate::__u16, + pub aio_reqprio: crate::__s16, + pub aio_fildes: crate::__u32, + pub aio_buf: crate::__u64, + pub aio_nbytes: crate::__u64, + pub aio_offset: crate::__s64, + aio_reserved2: Padding, + pub aio_flags: crate::__u32, + pub aio_resfd: crate::__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 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, + + pub tcpi_rcv_ooopack: u32, + pub tcpi_snd_wnd: u32, + pub tcpi_rcv_wnd: u32, + + pub tcpi_rehash: u32, + pub tcpi_total_rto: u16, + pub tcpi_total_rto_recoveries: u16, + pub tcpi_total_rto_time: u32, + pub tcpi_received_ce: u32, + pub tcpi_delivered_e1_bytes: u32, + pub tcpi_delivered_e0_bytes: u32, + pub tcpi_delivered_ce_bytes: u32, + pub tcpi_received_e1_bytes: u32, + pub tcpi_received_e0_bytes: u32, + pub tcpi_received_ce_bytes: u32, + pub tcpi_accecn_fail_mode: u16, + pub tcpi_accecn_opt_seen: u16, + } + + pub struct fanotify_event_info_pidfd { + pub hdr: crate::fanotify_event_info_header, + pub pidfd: crate::__s32, + } + + pub struct fanotify_event_info_error { + pub hdr: crate::fanotify_event_info_header, + pub error: crate::__s32, + pub error_count: crate::__u32, + } + + // FIXME(1.0) 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], + } + + pub struct mbstate_t { + __count: c_int, + __wchb: [c_char; 4], + } + + pub struct fpos64_t { + __pos: off64_t, + __state: crate::mbstate_t, + } + + pub struct fpos_t { + #[cfg(not(gnu_file_offset_bits64))] + __pos: off_t, + #[cfg(gnu_file_offset_bits64)] + __pos: off64_t, + __state: crate::mbstate_t, + } + + // linux x32 compatibility + // See https://sourceware.org/bugzilla/show_bug.cgi?id=16437 + #[derive(Default)] + pub struct timespec { + pub tv_sec: time_t, + #[cfg(all(gnu_time_bits64, target_endian = "big"))] + __pad: Padding, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub tv_nsec: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub tv_nsec: i64, + #[cfg(all(gnu_time_bits64, target_endian = "little"))] + __pad: Padding, + } + + pub struct utmpx { + pub ut_type: c_short, + pub ut_pid: crate::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: crate::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: Padding<[c_char; 20]>, + } +} + +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).cast::()).si_addr + } + + pub unsafe fn si_value(&self) -> crate::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: crate::sigval, + } + (*(self as *const siginfo_t).cast::()).si_sigval + } +} + +s_no_extra_traits! { + // linux/if_ether.h + + #[repr(C, packed)] + pub struct ethhdr { + pub h_dest: [c_uchar; crate::ETH_ALEN as usize], + pub h_source: [c_uchar; crate::ETH_ALEN as usize], + pub h_proto: crate::__be16, + } + + // Internal, for casts to access union fields + struct sifields_sigchld { + si_pid: crate::pid_t, + si_uid: crate::uid_t, + si_status: c_int, + si_utime: c_long, + si_stime: c_long, + } + + // Internal, for casts to access union fields + 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. + struct siginfo_f { + _siginfo_base: [c_int; 3], + sifields: sifields, + } +} + +impl siginfo_t { + unsafe fn sifields(&self) -> &sifields { + &(*(self as *const siginfo_t).cast::()).sifields + } + + pub unsafe fn si_pid(&self) -> crate::pid_t { + self.sifields().sigchld.si_pid + } + + pub unsafe fn si_uid(&self) -> crate::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_no_extra_traits! { + 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, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + 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 + } + } + } + + impl Eq for __c_anonymous_ptrace_syscall_info_data {} + + 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: crate::__priority_which_t = 0; +pub const PRIO_PGRP: crate::__priority_which_t = 1; +pub const PRIO_USER: crate::__priority_which_t = 2; + +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 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 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 = crate::LC_CTYPE_MASK + | crate::LC_NUMERIC_MASK + | crate::LC_TIME_MASK + | crate::LC_COLLATE_MASK + | crate::LC_MONETARY_MASK + | crate::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; +#[deprecated(since = "0.2.70", note = "AF_PACKET must be used instead")] +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 _CS_GNU_LIBC_VERSION: c_int = 2; +pub const _CS_GNU_LIBPTHREAD_VERSION: c_int = 3; +pub const _CS_V6_ENV: c_int = 1148; +pub const _CS_V7_ENV: c_int = 1149; +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: crate::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_SET_SYSCALL_INFO: c_uint = 0x4212; +pub const PTRACE_SYSCALL_INFO_NONE: crate::__u8 = 0; +pub const PTRACE_SYSCALL_INFO_ENTRY: crate::__u8 = 1; +pub const PTRACE_SYSCALL_INFO_EXIT: crate::__u8 = 2; +pub const PTRACE_SYSCALL_INFO_SECCOMP: crate::__u8 = 3; +pub const PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG: c_uint = 0x4210; +pub const PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG: c_uint = 0x4211; + +// 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; + +pub const GENL_UNS_ADMIN_PERM: c_int = 0x10; + +pub const GENL_ID_VFS_DQUOT: c_int = crate::NLMSG_MIN_TYPE + 1; +pub const GENL_ID_PMCRAID: c_int = crate::NLMSG_MIN_TYPE + 2; + +pub const ELFOSABI_ARM_AEABI: u8 = 64; + +// linux/sched.h +pub const CLONE_NEWTIME: c_int = 0x80; +// DIFF(main): changed to `c_ulonglong` in e9abac9ac2. This is broken so should be fixed. +#[allow(overflowing_literals)] +#[deprecated( + since = "0.2.188", + note = "This constant overflows. In the near future, `libc` will change to a wider type, see #3584." +)] +pub const CLONE_CLEAR_SIGHAND: c_int = 0x100000000; +#[allow(overflowing_literals)] +#[deprecated( + since = "0.2.188", + note = "This constant overflows. In the near future, `libc` will change to a wider type, see #3584." +)] +pub const CLONE_INTO_CGROUP: c_int = 0x200000000; + +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 SOMAXCONN: c_int = 4096; + +// 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 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 crate::FILE, + spbuf: *mut crate::spwd, + buf: *mut c_char, + buflen: size_t, + spbufp: *mut *mut crate::spwd, + ) -> c_int; + pub fn sgetspent_r( + s: *const c_char, + spbuf: *mut crate::spwd, + buf: *mut c_char, + buflen: size_t, + spbufp: *mut *mut crate::spwd, + ) -> c_int; + pub fn getspent_r( + spbuf: *mut crate::spwd, + buf: *mut c_char, + buflen: size_t, + spbufp: *mut *mut crate::spwd, + ) -> c_int; + pub fn qsort_r( + base: *mut c_void, + num: size_t, + size: size_t, + compar: Option c_int>, + arg: *mut c_void, + ); + #[cfg_attr(gnu_time_bits64, link_name = "__sendmmsg64")] + pub fn sendmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: c_uint, + flags: c_int, + ) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__recvmmsg64")] + pub fn recvmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: c_uint, + flags: c_int, + timeout: *mut crate::timespec, + ) -> c_int; + + pub fn getrlimit64(resource: crate::__rlimit_resource_t, rlim: *mut crate::rlimit64) -> c_int; + pub fn setrlimit64(resource: crate::__rlimit_resource_t, rlim: *const crate::rlimit64) + -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "getrlimit64")] + pub fn getrlimit(resource: crate::__rlimit_resource_t, rlim: *mut crate::rlimit) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "setrlimit64")] + pub fn setrlimit(resource: crate::__rlimit_resource_t, rlim: *const crate::rlimit) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "prlimit64")] + pub fn prlimit( + pid: crate::pid_t, + resource: crate::__rlimit_resource_t, + new_limit: *const crate::rlimit, + old_limit: *mut crate::rlimit, + ) -> c_int; + pub fn prlimit64( + pid: crate::pid_t, + resource: crate::__rlimit_resource_t, + new_limit: *const crate::rlimit64, + old_limit: *mut crate::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; + #[cfg_attr(gnu_time_bits64, link_name = "__gettimeofday64")] + pub fn gettimeofday(tp: *mut crate::timeval, tz: *mut crate::timezone) -> 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; + + #[cfg_attr(gnu_time_bits64, link_name = "___adjtimex64")] + pub fn adjtimex(buf: *mut timex) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "___adjtimex64")] + pub fn ntp_adjtime(buf: *mut timex) -> c_int; + #[cfg_attr(not(gnu_time_bits64), link_name = "ntp_gettimex")] + #[cfg_attr(gnu_time_bits64, link_name = "__ntp_gettime64")] + pub fn ntp_gettime(buf: *mut ntptimeval) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__clock_adjtime64")] + pub fn clock_adjtime(clk_id: crate::clockid_t, buf: *mut crate::timex) -> c_int; + + pub fn fanotify_mark( + fd: c_int, + flags: c_uint, + mask: u64, + dirfd: c_int, + path: *const c_char, + ) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "preadv64v2")] + pub fn preadv2( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: off_t, + flags: c_int, + ) -> ssize_t; + #[cfg_attr(gnu_file_offset_bits64, link_name = "pwritev64v2")] + pub fn pwritev2( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: off_t, + flags: c_int, + ) -> ssize_t; + pub fn preadv64v2( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: off64_t, + flags: c_int, + ) -> ssize_t; + pub fn pwritev64v2( + fd: c_int, + iov: *const crate::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 backtrace_symbols(buffer: *const *mut c_void, len: c_int) -> *mut *mut c_char; + pub fn backtrace_symbols_fd(buffer: *const *mut c_void, len: c_int, fd: c_int); + #[cfg_attr(gnu_time_bits64, link_name = "__glob64_time64")] + pub fn glob64( + pattern: *const c_char, + flags: c_int, + errfunc: Option c_int>, + pglob: *mut glob64_t, + ) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__globfree64_time64")] + pub fn globfree64(pglob: *mut glob64_t); + pub fn ptrace(request: c_uint, ...) -> c_long; + pub fn pthread_attr_getaffinity_np( + attr: *const crate::pthread_attr_t, + cpusetsize: size_t, + cpuset: *mut crate::cpu_set_t, + ) -> c_int; + pub fn pthread_attr_setaffinity_np( + attr: *mut crate::pthread_attr_t, + cpusetsize: size_t, + cpuset: *const crate::cpu_set_t, + ) -> c_int; + pub fn getpriority(which: crate::__priority_which_t, who: crate::id_t) -> c_int; + pub fn setpriority(which: crate::__priority_which_t, who: crate::id_t, prio: c_int) -> c_int; + pub fn pthread_rwlockattr_getkind_np( + attr: *const crate::pthread_rwlockattr_t, + val: *mut c_int, + ) -> c_int; + pub fn pthread_rwlockattr_setkind_np( + attr: *mut crate::pthread_rwlockattr_t, + val: c_int, + ) -> c_int; + pub fn pthread_sigqueue(thread: crate::pthread_t, sig: c_int, value: crate::sigval) -> c_int; + pub fn pthread_tryjoin_np(thread: crate::pthread_t, retval: *mut *mut c_void) -> c_int; + #[cfg_attr( + all(target_pointer_width = "32", gnu_time_bits64), + link_name = "__pthread_timedjoin_np64" + )] + pub fn pthread_timedjoin_np( + thread: crate::pthread_t, + retval: *mut *mut c_void, + abstime: *const crate::timespec, + ) -> c_int; + pub fn mallinfo() -> crate::mallinfo; + pub fn mallinfo2() -> crate::mallinfo2; + pub fn malloc_stats(); + pub fn malloc_info(options: c_int, stream: *mut crate::FILE) -> c_int; + pub fn malloc_usable_size(ptr: *mut c_void) -> size_t; + pub fn getpwent_r( + pwd: *mut crate::passwd, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::passwd, + ) -> c_int; + pub fn getgrent_r( + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn fgetpwent_r( + stream: *mut crate::FILE, + pwd: *mut crate::passwd, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::passwd, + ) -> c_int; + pub fn fgetgrent_r( + stream: *mut crate::FILE, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn getnetent_r( + result_buf: *mut crate::netent, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::netent, + h_errnop: *mut c_int, + ) -> c_int; + pub fn getnetbyname_r( + name: *const c_char, + result_buf: *mut crate::netent, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::netent, + h_errnop: *mut c_int, + ) -> c_int; + pub fn getnetbyaddr_r( + net: u32, + type_: c_int, + result_buf: *mut crate::netent, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::netent, + h_errnop: *mut c_int, + ) -> c_int; + + pub fn putpwent(p: *const crate::passwd, stream: *mut crate::FILE) -> c_int; + pub fn putgrent(grp: *const crate::group, stream: *mut crate::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 crate::tm, buf: *mut c_char) -> *mut c_char; + #[cfg_attr(gnu_time_bits64, link_name = "__ctime64_r")] + pub fn ctime_r(timep: *const time_t, buf: *mut c_char) -> *mut c_char; + + pub fn dirname(path: *mut c_char) -> *mut c_char; + /// POSIX version of `basename(3)`, defined in `libgen.h`. + #[link_name = "__xpg_basename"] + pub fn posix_basename(path: *mut c_char) -> *mut c_char; + /// GNU version of `basename(3)`, defined in `string.h`. + #[link_name = "basename"] + pub fn gnu_basename(path: *const c_char) -> *mut c_char; + 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 crate::Dl_info, + extra_info: *mut *mut c_void, + flags: c_int, + ) -> c_int; + pub fn dlvsym( + handle: *mut c_void, + symbol: *const c_char, + version: *const c_char, + ) -> *mut c_void; + 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 crate::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 crate::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 crate::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 crate::posix_spawn_file_actions_t, + tcfd: c_int, + ) -> c_int; + + // mntent.h + pub fn getmntent_r( + stream: *mut crate::FILE, + mntbuf: *mut crate::mntent, + buf: *mut c_char, + buflen: c_int, + ) -> *mut crate::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: crate::mqd_t, sevp: *const crate::sigevent) -> c_int; + + #[cfg_attr(gnu_time_bits64, link_name = "__epoll_pwait2_time64")] + pub fn epoll_pwait2( + epfd: c_int, + events: *mut crate::epoll_event, + maxevents: c_int, + timeout: *const crate::timespec, + sigmask: *const crate::sigset_t, + ) -> c_int; + + pub fn mempcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + + pub fn tgkill(tgid: crate::pid_t, tid: crate::pid_t, sig: c_int) -> 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 + } +} 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..a41d03d --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/mod.rs @@ -0,0 +1,3857 @@ +//! Linux-specific definitions for linux-like values +use crate::prelude::*; +use crate::{ + __s16, + __s32, + __u16, + __u32, + __u64, + __u8, + sock_filter, + _IO, + _IOR, + _IOW, + _IOWR, +}; + +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 __kernel_clockid_t = c_int; + +pub type eventfd_t = u64; + +c_enum! { + pub enum pid_type { + pub PIDTYPE_PID, + pub PIDTYPE_TGID, + pub PIDTYPE_PGID, + pub PIDTYPE_SID, + pub PIDTYPE_MAX, + } +} + +s! { + 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: Padding, + pub ssi_syscall: i32, + pub ssi_call_addr: u64, + pub ssi_arch: u32, + _pad: Padding<[u8; 28]>, + } + + // 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 input_event { + // FIXME(1.0): Change to the commented variant, see https://github.com/rust-lang/libc/pull/4148#discussion_r1857511742 + #[cfg(any(target_pointer_width = "64", not(linux_time_bits64)))] + pub time: crate::timeval, + // #[cfg(any(target_pointer_width = "64", not(linux_time_bits64)))] + // pub input_event_sec: time_t, + // #[cfg(any(target_pointer_width = "64", not(linux_time_bits64)))] + // pub input_event_usec: suseconds_t, + // #[cfg(target_arch = "sparc64")] + // _pad1: c_int, + #[cfg(all(target_pointer_width = "32", linux_time_bits64))] + pub input_event_sec: c_ulong, + + #[cfg(all(target_pointer_width = "32", linux_time_bits64))] + pub input_event_usec: c_ulong, + + 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: crate::__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(1.0): 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 __c_anonymous__kernel_fsid_t { + pub val: [c_int; 2], + } + + pub struct posix_spawn_file_actions_t { + __allocated: c_int, + __used: c_int, + __actions: *mut c_int, + __pad: Padding<[c_int; 16]>, + } + + pub struct posix_spawnattr_t { + __flags: c_short, + __pgrp: crate::pid_t, + __sd: crate::sigset_t, + __ss: crate::sigset_t, + #[cfg(any(target_env = "musl", target_env = "ohos"))] + __prio: c_int, + #[cfg(not(any(target_env = "musl", target_env = "ohos")))] + __sp: crate::sched_param, + __policy: c_int, + __pad: Padding<[c_int; 16]>, + } + + pub struct genlmsghdr { + pub cmd: u8, + pub version: u8, + pub reserved: u16, + } + + 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: crate::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 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/seccomp.h + pub struct seccomp_data { + pub nr: c_int, + pub arch: __u32, + pub instruction_pointer: crate::__u64, + pub args: [crate::__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: crate::__u64, + pub pid: __u32, + pub flags: __u32, + pub data: seccomp_data, + } + + pub struct seccomp_notif_resp { + pub id: crate::__u64, + pub val: crate::__s64, + pub error: __s32, + pub flags: __u32, + } + + pub struct seccomp_notif_addfd { + pub id: crate::__u64, + pub flags: __u32, + pub srcfd: __u32, + pub newfd: __u32, + pub newfd_flags: __u32, + } + + pub struct in6_ifreq { + pub ifr6_addr: crate::in6_addr, + pub ifr6_prefixlen: u32, + pub ifr6_ifindex: c_int, + } + + // linux/openat2.h + #[non_exhaustive] + pub struct open_how { + pub flags: crate::__u64, + pub mode: crate::__u64, + pub resolve: crate::__u64, + } + + // linux/ptp_clock.h + pub struct ptp_clock_time { + pub sec: crate::__s64, + pub nsec: __u32, + pub reserved: __u32, + } + + pub struct ptp_extts_request { + pub index: c_uint, + pub flags: c_uint, + pub rsv: [c_uint; 2], + } + + pub struct ptp_sys_offset_extended { + pub n_samples: c_uint, + pub clockid: __kernel_clockid_t, + pub rsv: [c_uint; 2], + pub ts: [[ptp_clock_time; 3]; PTP_MAX_SAMPLES as usize], + } + + pub struct ptp_sys_offset_precise { + pub device: ptp_clock_time, + pub sys_realtime: ptp_clock_time, + pub sys_monoraw: ptp_clock_time, + pub rsv: [c_uint; 4], + } + + pub struct ptp_extts_event { + pub t: ptp_clock_time, + index: c_uint, + flags: c_uint, + rsv: [c_uint; 2], + } + + // linux/wireless.h + + pub struct iw_param { + pub value: __s32, + pub fixed: __u8, + pub disabled: __u8, + pub flags: __u16, + } + + pub struct iw_point { + pub pointer: *mut c_void, + pub length: __u16, + pub flags: __u16, + } + + pub struct iw_freq { + pub m: __s32, + pub e: __s16, + pub i: __u8, + pub flags: __u8, + } + + pub struct iw_quality { + pub qual: __u8, + pub level: __u8, + pub noise: __u8, + pub updated: __u8, + } + + pub struct iw_discarded { + pub nwid: __u32, + pub code: __u32, + pub fragment: __u32, + pub retries: __u32, + pubmisc: __u32, + } + + pub struct iw_missed { + pub beacon: __u32, + } + + pub struct iw_scan_req { + pub scan_type: __u8, + pub essid_len: __u8, + pub num_channels: __u8, + pub flags: __u8, + pub bssid: crate::sockaddr, + pub essid: [__u8; IW_ESSID_MAX_SIZE], + pub min_channel_time: __u32, + pub max_channel_time: __u32, + pub channel_list: [iw_freq; IW_MAX_FREQUENCIES], + } + + pub struct iw_encode_ext { + pub ext_flags: __u32, + pub tx_seq: [__u8; IW_ENCODE_SEQ_MAX_SIZE], + pub rx_seq: [__u8; IW_ENCODE_SEQ_MAX_SIZE], + pub addr: crate::sockaddr, + pub alg: __u16, + pub key_len: __u16, + pub key: [__u8; 0], + } + + pub struct iw_pmksa { + pub cmd: __u32, + pub bssid: crate::sockaddr, + pub pmkid: [__u8; IW_PMKID_LEN], + } + + pub struct iw_pmkid_cand { + pub flags: __u32, + pub index: __u32, + pub bssid: crate::sockaddr, + } + + pub struct iw_statistics { + pub status: __u16, + pub qual: iw_quality, + pub discard: iw_discarded, + pub miss: iw_missed, + } + + pub struct iw_range { + pub throughput: __u32, + pub min_nwid: __u32, + pub max_nwid: __u32, + pub old_num_channels: __u16, + pub old_num_frequency: __u8, + pub scan_capa: __u8, + pub event_capa: [__u32; 6], + pub sensitivity: __s32, + pub max_qual: iw_quality, + pub avg_qual: iw_quality, + pub num_bitrates: __u8, + pub bitrate: [__s32; IW_MAX_BITRATES], + pub min_rts: __s32, + pub max_rts: __s32, + pub min_frag: __s32, + pub max_frag: __s32, + pub min_pmp: __s32, + pub max_pmp: __s32, + pub min_pmt: __s32, + pub max_pmt: __s32, + pub pmp_flags: __u16, + pub pmt_flags: __u16, + pub pm_capa: __u16, + pub encoding_size: [__u16; IW_MAX_ENCODING_SIZES], + pub num_encoding_sizes: __u8, + pub max_encoding_tokens: __u8, + pub encoding_login_index: __u8, + pub txpower_capa: __u16, + pub num_txpower: __u8, + pub txpower: [__s32; IW_MAX_TXPOWER], + pub we_version_compiled: __u8, + pub we_version_source: __u8, + pub retry_capa: __u16, + pub retry_flags: __u16, + pub r_time_flags: __u16, + pub min_retry: __s32, + pub max_retry: __s32, + pub min_r_time: __s32, + pub max_r_time: __s32, + pub num_channels: __u16, + pub num_frequency: __u8, + pub freq: [iw_freq; IW_MAX_FREQUENCIES], + pub enc_capa: __u32, + } + + pub struct iw_priv_args { + pub cmd: __u32, + pub set_args: __u16, + pub get_args: __u16, + pub name: [c_char; crate::IFNAMSIZ], + } + + // #include + + pub struct epoll_params { + pub busy_poll_usecs: u32, + pub busy_poll_budget: u16, + pub prefer_busy_poll: u8, + pub __pad: u8, // Must be zero + } + + #[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; crate::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[cfg_attr( + any( + target_env = "musl", + target_env = "ohos", + target_env = "uclibc", + target_pointer_width = "32" + ), + repr(align(4)) + )] + #[cfg_attr( + all( + not(target_env = "musl"), + not(target_env = "ohos"), + not(target_env = "uclibc"), + target_pointer_width = "64" + ), + repr(align(8)) + )] + pub struct pthread_rwlockattr_t { + #[doc(hidden)] + size: [u8; crate::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + #[doc(hidden)] + size: [u8; crate::__SIZEOF_PTHREAD_CONDATTR_T], + } + + #[repr(align(4))] + pub struct pthread_barrierattr_t { + #[doc(hidden)] + size: [u8; crate::__SIZEOF_PTHREAD_BARRIERATTR_T], + } + + #[cfg(not(any(target_env = "musl", target_env = "ohos")))] + #[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, + } + + // linux/ptp_clock.h + + pub struct ptp_sys_offset { + pub n_samples: c_uint, + pub rsv: [c_uint; 3], + // FIXME(garando): replace length with `2 * PTP_MAX_SAMPLES + 1` when supported + pub ts: [ptp_clock_time; 51], + } + + pub struct ptp_pin_desc { + pub name: [c_char; 64], + pub index: c_uint, + pub func: c_uint, + pub chan: c_uint, + pub rsv: [c_uint; 5], + } + + pub struct ptp_clock_caps { + pub max_adj: c_int, + pub n_alarm: c_int, + pub n_ext_ts: c_int, + pub n_per_out: c_int, + pub pps: c_int, + pub n_pins: c_int, + pub cross_timestamping: c_int, + pub adjust_phase: c_int, + pub max_phase_adj: c_int, + pub rsv: [c_int; 11], + } + + // linux/if_xdp.h + + pub struct sockaddr_xdp { + pub sxdp_family: crate::__u16, + pub sxdp_flags: crate::__u16, + pub sxdp_ifindex: crate::__u32, + pub sxdp_queue_id: crate::__u32, + pub sxdp_shared_umem_fd: crate::__u32, + } + + pub struct xdp_ring_offset { + pub producer: crate::__u64, + pub consumer: crate::__u64, + pub desc: crate::__u64, + pub flags: crate::__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: crate::__u64, + pub consumer: crate::__u64, + pub desc: crate::__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: crate::__u64, + pub len: crate::__u64, + pub chunk_size: crate::__u32, + pub headroom: crate::__u32, + pub flags: crate::__u32, + pub tx_metadata_len: crate::__u32, + } + + pub struct xdp_umem_reg_v1 { + pub addr: crate::__u64, + pub len: crate::__u64, + pub chunk_size: crate::__u32, + pub headroom: crate::__u32, + } + + pub struct xdp_statistics { + pub rx_dropped: crate::__u64, + pub rx_invalid_descs: crate::__u64, + pub tx_invalid_descs: crate::__u64, + pub rx_ring_full: crate::__u64, + pub rx_fill_ring_empty_descs: crate::__u64, + pub tx_ring_empty_descs: crate::__u64, + } + + pub struct xdp_statistics_v1 { + pub rx_dropped: crate::__u64, + pub rx_invalid_descs: crate::__u64, + pub tx_invalid_descs: crate::__u64, + } + + pub struct xdp_options { + pub flags: crate::__u32, + } + + pub struct xdp_desc { + pub addr: crate::__u64, + pub len: crate::__u32, + pub options: crate::__u32, + } + + pub struct xsk_tx_metadata_completion { + pub tx_timestamp: crate::__u64, + } + + pub struct xsk_tx_metadata_request { + pub csum_start: __u16, + pub csum_offset: __u16, + } + + // linux/nsfs.h + pub struct mnt_ns_info { + pub size: crate::__u32, + pub nr_mounts: crate::__u32, + pub mnt_ns_id: crate::__u64, + } + + // linux/pidfd.h + + // linux/uio.h + + pub struct dmabuf_cmsg { + pub frag_offset: crate::__u64, + pub frag_size: crate::__u32, + pub frag_token: crate::__u32, + pub dmabuf_id: crate::__u32, + pub flags: crate::__u32, + } + + pub struct dmabuf_token { + pub token_start: crate::__u32, + pub token_count: crate::__u32, + } + + pub struct sockaddr_alg { + pub salg_family: crate::sa_family_t, + pub salg_type: [c_uchar; 14], + pub salg_feat: u32, + pub salg_mask: u32, + pub salg_name: [c_uchar; 64], + } + + #[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; crate::__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 { + pub(crate) size: [c_char; crate::__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; crate::__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; crate::__SIZEOF_PTHREAD_BARRIER_T], + } + + 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], + } + + // 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: Padding<[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: Padding<[c_long; 4]>, + } + + pub struct hwtstamp_config { + pub flags: c_int, + pub tx_type: c_int, + pub rx_filter: c_int, + } + + pub struct sched_attr { + pub size: __u32, + pub sched_policy: __u32, + pub sched_flags: crate::__u64, + pub sched_nice: __s32, + pub sched_priority: __u32, + pub sched_runtime: crate::__u64, + pub sched_deadline: crate::__u64, + pub sched_period: crate::__u64, + } + + // linux/fcntl.h + + pub struct file_handle { + pub handle_bytes: c_uint, + pub handle_type: c_int, + pub f_handle: [c_uchar; 0], + } + + // include/uapi/linux/rtnetlink.h + pub struct ifinfomsg { + pub ifi_family: c_uchar, + __ifi_pad: Padding, + pub ifi_type: c_ushort, + pub ifi_index: c_int, + pub ifi_flags: c_uint, + pub ifi_change: c_uint, + } + + pub struct rtattr { + pub rta_len: c_ushort, + pub rta_type: c_ushort, + } + + // netdb.h + pub struct netent { + pub n_name: *mut c_char, + pub n_aliases: *mut *mut c_char, + pub n_addrtype: c_int, + pub n_net: u32, + } +} + +cfg_if! { + if #[cfg(not(target_env = "gnu"))] { + extern_ty! { + pub type fpos64_t; // FIXME(linux): fill this out with a struct + } + } +} + +cfg_if! { + if #[cfg(not(target_arch = "sparc64"))] { + s! { + pub struct iw_thrspy { + pub addr: crate::sockaddr, + pub qual: iw_quality, + pub low: iw_quality, + pub high: iw_quality, + } + + pub struct iw_mlme { + pub cmd: __u16, + pub reason_code: __u16, + pub addr: crate::sockaddr, + } + + pub struct iw_michaelmicfailure { + pub flags: __u32, + pub src_addr: crate::sockaddr, + pub tsc: [__u8; IW_ENCODE_SEQ_MAX_SIZE], + } + } + } +} + +s_no_extra_traits! { + /// 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], + } + + // linux/net_tstamp.h + pub struct sock_txtime { + pub clockid: crate::clockid_t, + pub flags: __u32, + } + + // linux/wireless.h + pub union iwreq_data { + pub name: [c_char; crate::IFNAMSIZ], + pub essid: iw_point, + pub nwid: iw_param, + pub freq: iw_freq, + pub sens: iw_param, + pub bitrate: iw_param, + pub txpower: iw_param, + pub rts: iw_param, + pub frag: iw_param, + pub mode: __u32, + pub retry: iw_param, + pub encoding: iw_point, + pub power: iw_param, + pub qual: iw_quality, + pub ap_addr: crate::sockaddr, + pub addr: crate::sockaddr, + pub param: iw_param, + pub data: iw_point, + } + + pub struct iw_event { + pub len: __u16, + pub cmd: __u16, + pub u: iwreq_data, + } + + pub union __c_anonymous_iwreq { + pub ifrn_name: [c_char; crate::IFNAMSIZ], + } + + pub struct iwreq { + pub ifr_ifrn: __c_anonymous_iwreq, + pub u: iwreq_data, + } + + // linux/ptp_clock.h + pub union __c_anonymous_ptp_perout_request_1 { + pub start: ptp_clock_time, + pub phase: ptp_clock_time, + } + + pub union __c_anonymous_ptp_perout_request_2 { + pub on: ptp_clock_time, + pub rsv: [c_uint; 4], + } + + pub struct ptp_perout_request { + pub anonymous_1: __c_anonymous_ptp_perout_request_1, + pub period: ptp_clock_time, + pub index: c_uint, + pub flags: c_uint, + pub anonymous_2: __c_anonymous_ptp_perout_request_2, + } + + // linux/if_xdp.h + pub struct xsk_tx_metadata { + pub flags: crate::__u64, + pub xsk_tx_metadata_union: __c_anonymous_xsk_tx_metadata_union, + } + + pub union __c_anonymous_xsk_tx_metadata_union { + pub request: xsk_tx_metadata_request, + pub completion: xsk_tx_metadata_completion, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + #[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 hash::Hash for af_alg_iv { + fn hash(&self, state: &mut H) { + self.as_slice().hash(state); + } + } + } +} + +pub const POSIX_SPAWN_USEVFORK: c_short = 64; +#[cfg(not(target_env = "uclibc"))] +pub const POSIX_SPAWN_SETSID: c_short = 128; + +pub const F_SEAL_FUTURE_WRITE: c_int = 0x0010; +pub const F_SEAL_EXEC: c_int = 0x0020; + +pub const IFF_LOWER_UP: c_int = 0x10000; +pub const IFF_DORMANT: c_int = 0x20000; +pub const IFF_ECHO: c_int = 0x40000; + +// linux/fcntl.h +pub const AT_EXECVE_CHECK: c_int = 0x10000; + +pub const MAX_HANDLE_SZ: c_int = 128; +pub const AT_HANDLE_FID: c_int = 0x200; +pub const AT_HANDLE_MNT_ID_UNIQUE: c_int = 0x001; +pub const AT_HANDLE_CONNECTABLE: c_int = 0x002; + +// 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; +pub const RWF_NOAPPEND: c_int = 0x00000020; +pub const RWF_ATOMIC: c_int = 0x00000040; +pub const RWF_DONTCACHE: c_int = 0x00000080; + +// Since Linux 3.1 +pub const SEEK_DATA: c_int = 3; +pub const SEEK_HOLE: c_int = 4; + +// 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; + +#[cfg(not(target_env = "gnu"))] // defined in `new/glibc` +pub const PTHREAD_MUTEX_INITIALIZER: crate::pthread_mutex_t = crate::pthread_mutex_t { + size: [0; crate::__SIZEOF_PTHREAD_MUTEX_T], +}; +pub const PTHREAD_COND_INITIALIZER: crate::pthread_cond_t = crate::pthread_cond_t { + size: [0; crate::__SIZEOF_PTHREAD_COND_T], +}; +pub const PTHREAD_RWLOCK_INITIALIZER: crate::pthread_rwlock_t = crate::pthread_rwlock_t { + size: [0; crate::__SIZEOF_PTHREAD_RWLOCK_T], +}; + +pub const RENAME_NOREPLACE: c_uint = 1; +pub const RENAME_EXCHANGE: c_uint = 2; +pub const RENAME_WHITEOUT: c_uint = 4; + +pub const MSG_STAT: c_int = 11 | (crate::IPC_STAT & 0x100); +pub const MSG_INFO: c_int = 12; + +pub const MSG_NOERROR: c_int = 0o10000; +pub const MSG_EXCEPT: c_int = 0o20000; +pub const MSG_ZEROCOPY: c_int = 0x4000000; + +pub const SEM_UNDO: c_int = 0x1000; + +pub const GETPID: c_int = 11; +pub const GETVAL: c_int = 12; +pub const GETALL: c_int = 13; +pub const GETNCNT: c_int = 14; +pub const GETZCNT: c_int = 15; +pub const SETVAL: c_int = 16; +pub const SETALL: c_int = 17; +pub const SEM_STAT: c_int = 18 | (crate::IPC_STAT & 0x100); +pub const SEM_INFO: c_int = 19; +pub const SEM_STAT_ANY: c_int = 20 | (crate::IPC_STAT & 0x100); + +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 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 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 MREMAP_MAYMOVE: c_int = 1; +pub const MREMAP_FIXED: c_int = 2; +pub const MREMAP_DONTUNMAP: c_int = 4; + +// linux/nsfs.h +const NSIO: c_uint = 0xb7; + +pub const NS_GET_USERNS: Ioctl = _IO(NSIO, 0x1); +pub const NS_GET_PARENT: Ioctl = _IO(NSIO, 0x2); +pub const NS_GET_NSTYPE: Ioctl = _IO(NSIO, 0x3); +pub const NS_GET_OWNER_UID: Ioctl = _IO(NSIO, 0x4); + +pub const NS_GET_MNTNS_ID: Ioctl = _IOR::<__u64>(NSIO, 0x5); + +pub const NS_GET_PID_FROM_PIDNS: Ioctl = _IOR::(NSIO, 0x6); +pub const NS_GET_TGID_FROM_PIDNS: Ioctl = _IOR::(NSIO, 0x7); +pub const NS_GET_PID_IN_PIDNS: Ioctl = _IOR::(NSIO, 0x8); +pub const NS_GET_TGID_IN_PIDNS: Ioctl = _IOR::(NSIO, 0x9); + +pub const MNT_NS_INFO_SIZE_VER0: Ioctl = 16; + +pub const NS_MNT_GET_INFO: Ioctl = _IOR::(NSIO, 10); +pub const NS_MNT_GET_NEXT: Ioctl = _IOR::(NSIO, 11); +pub const NS_MNT_GET_PREV: Ioctl = _IOR::(NSIO, 12); + +pub const PR_SET_MDWE: c_int = 65; +pub const PR_GET_MDWE: c_int = 66; +pub const PR_MDWE_REFUSE_EXEC_GAIN: c_uint = 1 << 0; +pub const PR_MDWE_NO_INHERIT: c_uint = 1 << 1; +pub const PR_SET_MEMORY_MERGE: c_int = 67; +pub const PR_GET_MEMORY_MERGE: c_int = 68; + +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 << 0; +pub const SECCOMP_FILTER_FLAG_LOG: c_ulong = 1 << 1; +pub const SECCOMP_FILTER_FLAG_SPEC_ALLOW: c_ulong = 1 << 2; +pub const SECCOMP_FILTER_FLAG_NEW_LISTENER: c_ulong = 1 << 3; +pub const SECCOMP_FILTER_FLAG_TSYNC_ESRCH: c_ulong = 1 << 4; +pub const SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV: c_ulong = 1 << 5; + +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 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; + +const SECCOMP_IOC_MAGIC: u32 = b'!' as u32; + +pub const SECCOMP_IOCTL_NOTIF_RECV: Ioctl = _IOWR::(SECCOMP_IOC_MAGIC, 0); +pub const SECCOMP_IOCTL_NOTIF_SEND: Ioctl = _IOWR::(SECCOMP_IOC_MAGIC, 1); +pub const SECCOMP_IOCTL_NOTIF_ID_VALID: Ioctl = _IOW::(SECCOMP_IOC_MAGIC, 2); +pub const SECCOMP_IOCTL_NOTIF_ADDFD: Ioctl = _IOW::(SECCOMP_IOC_MAGIC, 3); +pub const SECCOMP_IOCTL_NOTIF_SET_FLAGS: Ioctl = _IOW::(SECCOMP_IOC_MAGIC, 4); + +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 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 = crate::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; + +// 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; + +// 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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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/filter.h + +pub const BPF_A: __u32 = 0x10; +pub const BPF_TAX: __u32 = 0x00; +pub const BPF_TXA: __u32 = 0x80; + +// linux/openat2.h +pub const RESOLVE_NO_XDEV: crate::__u64 = 0x01; +pub const RESOLVE_NO_MAGICLINKS: crate::__u64 = 0x02; +pub const RESOLVE_NO_SYMLINKS: crate::__u64 = 0x04; +pub const RESOLVE_BENEATH: crate::__u64 = 0x08; +pub const RESOLVE_IN_ROOT: crate::__u64 = 0x10; +pub const RESOLVE_CACHED: crate::__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; + +// DIFF(main): changed to `c_short` in f62eb023ab +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; + +// 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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const NFNL_SUBSYS_COUNT: c_int = 13; + +pub const NFNL_MSG_BATCH_BEGIN: c_int = crate::NLMSG_MIN_TYPE; +pub const NFNL_MSG_BATCH_END: c_int = crate::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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 = crate::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 = crate::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/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 = u32_cast_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_INET_INGRESS: c_int = NF_INET_NUMHOOKS; + +pub const NF_NETDEV_INGRESS: c_int = 0; +pub const NF_NETDEV_EGRESS: c_int = 1; +pub const NF_NETDEV_NUMHOOKS: c_int = 2; + +// Some NFPROTO are not compatible with musl and are defined in submodules. +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_arp.h +pub const NF_ARP: c_int = 0; +pub const NF_ARP_IN: c_int = 0; +pub const NF_ARP_OUT: c_int = 1; +pub const NF_ARP_FORWARD: c_int = 2; +pub const NF_ARP_NUMHOOKS: c_int = 3; + +// linux/netfilter_bridge.h +pub const NF_BR_PRE_ROUTING: c_int = 0; +pub const NF_BR_LOCAL_IN: c_int = 1; +pub const NF_BR_FORWARD: c_int = 2; +pub const NF_BR_LOCAL_OUT: c_int = 3; +pub const NF_BR_POST_ROUTING: c_int = 4; +pub const NF_BR_BROUTING: c_int = 5; +pub const NF_BR_NUMHOOKS: c_int = 6; + +pub const NF_BR_PRI_FIRST: c_int = crate::INT_MIN; +pub const NF_BR_PRI_NAT_DST_BRIDGED: c_int = -300; +pub const NF_BR_PRI_FILTER_BRIDGED: c_int = -200; +pub const NF_BR_PRI_BRNF: c_int = 0; +pub const NF_BR_PRI_NAT_DST_OTHER: c_int = 100; +pub const NF_BR_PRI_FILTER_OTHER: c_int = 200; +pub const NF_BR_PRI_NAT_SRC: c_int = 300; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const NF_BR_PRI_LAST: c_int = crate::INT_MAX; + +// 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 = crate::INT_MIN; +pub const NF_IP_PRI_RAW_BEFORE_DEFRAG: c_int = -450; +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 = crate::INT_MAX; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const NF_IP_PRI_LAST: c_int = crate::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 = crate::INT_MIN; +pub const NF_IP6_PRI_RAW_BEFORE_DEFRAG: c_int = -450; +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const NF_IP6_PRI_LAST: c_int = crate::INT_MAX; + +// linux/netfilter_ipv6/ip6_tables.h +pub const IP6T_SO_ORIGINAL_DST: c_int = 80; + +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const SIOCIWLASTPRIV: c_ulong = 0x8BFF; + +pub const SIOCIWFIRST: c_ulong = 0x8B00; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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_EVENT_CAPA_K_0: c_ulong = 0x4000050; // IW_EVENT_CAPA_MASK(0x8B04) | IW_EVENT_CAPA_MASK(0x8B06) | IW_EVENT_CAPA_MASK(0x8B1A); +pub const IW_EVENT_CAPA_K_1: c_ulong = 0x400; // W_EVENT_CAPA_MASK(0x8B2A); + +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 = 20; // IW_EV_LCP_PK_LEN + crate::IFNAMSIZ; +pub const IW_EV_UINT_PK_LEN: usize = 8; // IW_EV_LCP_PK_LEN + size_of::(); +pub const IW_EV_FREQ_PK_LEN: usize = 12; // IW_EV_LCP_PK_LEN + size_of::(); +pub const IW_EV_PARAM_PK_LEN: usize = 12; // IW_EV_LCP_PK_LEN + size_of::(); +pub const IW_EV_ADDR_PK_LEN: usize = 20; // IW_EV_LCP_PK_LEN + size_of::(); +pub const IW_EV_QUAL_PK_LEN: usize = 8; // IW_EV_LCP_PK_LEN + size_of::(); +pub const IW_EV_POINT_PK_LEN: usize = 8; // IW_EV_LCP_PK_LEN + 4; + +// 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 NLM_F_BULK: c_int = 0x200; + +// 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 = crate::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 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/cn_proc.h +c_enum! { + pub enum proc_cn_mcast_op { + pub PROC_CN_MCAST_LISTEN = 1, + pub PROC_CN_MCAST_IGNORE = 2, + } + + pub enum proc_cn_event { + pub PROC_EVENT_NONE = 0x00000000, + pub PROC_EVENT_FORK = 0x00000001, + pub PROC_EVENT_EXEC = 0x00000002, + pub PROC_EVENT_UID = 0x00000004, + pub PROC_EVENT_GID = 0x00000040, + pub PROC_EVENT_SID = 0x00000080, + pub PROC_EVENT_PTRACE = 0x00000100, + pub PROC_EVENT_COMM = 0x00000200, + pub PROC_EVENT_NONZERO_EXIT = 0x20000000, + pub PROC_EVENT_COREDUMP = 0x40000000, + pub PROC_EVENT_EXIT = 0x80000000, + } +} + +// linux/connector.h +pub const CN_IDX_PROC: c_uint = 0x1; +pub const CN_VAL_PROC: c_uint = 0x1; +pub const CN_IDX_CIFS: c_uint = 0x2; +pub const CN_VAL_CIFS: c_uint = 0x1; +pub const CN_W1_IDX: c_uint = 0x3; +pub const CN_W1_VAL: c_uint = 0x1; +pub const CN_IDX_V86D: c_uint = 0x4; +pub const CN_VAL_V86D_UVESAFB: c_uint = 0x1; +pub const CN_IDX_BB: c_uint = 0x5; +pub const CN_DST_IDX: c_uint = 0x6; +pub const CN_DST_VAL: c_uint = 0x1; +pub const CN_IDX_DM: c_uint = 0x7; +pub const CN_VAL_DM_USERSPACE_LOG: c_uint = 0x1; +pub const CN_IDX_DRBD: c_uint = 0x8; +pub const CN_VAL_DRBD: c_uint = 0x1; +pub const CN_KVP_IDX: c_uint = 0x9; +pub const CN_KVP_VAL: c_uint = 0x1; +pub const CN_VSS_IDX: c_uint = 0xA; +pub const CN_VSS_VAL: c_uint = 0x1; + +// 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_TIMESTAMPING_BIND_PHC: c_uint = 1 << 15; +pub const SOF_TIMESTAMPING_OPT_ID_TCP: c_uint = 1 << 16; +pub const SOF_TIMESTAMPING_OPT_RX_FILTER: c_uint = 1 << 17; +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/ptp_clock.h +pub const PTP_MAX_SAMPLES: c_uint = 25; // Maximum allowed offset measurement samples. + +const PTP_CLK_MAGIC: u32 = b'=' as u32; + +pub const PTP_CLOCK_GETCAPS: Ioctl = _IOR::(PTP_CLK_MAGIC, 1); +pub const PTP_EXTTS_REQUEST: Ioctl = _IOW::(PTP_CLK_MAGIC, 2); +pub const PTP_PEROUT_REQUEST: Ioctl = _IOW::(PTP_CLK_MAGIC, 3); +pub const PTP_ENABLE_PPS: Ioctl = _IOW::(PTP_CLK_MAGIC, 4); +pub const PTP_SYS_OFFSET: Ioctl = _IOW::(PTP_CLK_MAGIC, 5); +pub const PTP_PIN_GETFUNC: Ioctl = _IOWR::(PTP_CLK_MAGIC, 6); +pub const PTP_PIN_SETFUNC: Ioctl = _IOW::(PTP_CLK_MAGIC, 7); +pub const PTP_SYS_OFFSET_PRECISE: Ioctl = _IOWR::(PTP_CLK_MAGIC, 8); +pub const PTP_SYS_OFFSET_EXTENDED: Ioctl = _IOWR::(PTP_CLK_MAGIC, 9); + +pub const PTP_CLOCK_GETCAPS2: Ioctl = _IOR::(PTP_CLK_MAGIC, 10); +pub const PTP_EXTTS_REQUEST2: Ioctl = _IOW::(PTP_CLK_MAGIC, 11); +pub const PTP_PEROUT_REQUEST2: Ioctl = _IOW::(PTP_CLK_MAGIC, 12); +pub const PTP_ENABLE_PPS2: Ioctl = _IOW::(PTP_CLK_MAGIC, 13); +pub const PTP_SYS_OFFSET2: Ioctl = _IOW::(PTP_CLK_MAGIC, 14); +pub const PTP_PIN_GETFUNC2: Ioctl = _IOWR::(PTP_CLK_MAGIC, 15); +pub const PTP_PIN_SETFUNC2: Ioctl = _IOW::(PTP_CLK_MAGIC, 16); +pub const PTP_SYS_OFFSET_PRECISE2: Ioctl = _IOWR::(PTP_CLK_MAGIC, 17); +pub const PTP_SYS_OFFSET_EXTENDED2: Ioctl = _IOWR::(PTP_CLK_MAGIC, 18); + +// enum ptp_pin_function +pub const PTP_PF_NONE: c_uint = 0; +pub const PTP_PF_EXTTS: c_uint = 1; +pub const PTP_PF_PEROUT: c_uint = 2; +pub const PTP_PF_PHYSYNC: c_uint = 3; + +// linux/socket.h + +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/mman.h +pub const MAP_SHARED_VALIDATE: c_int = 0x3; +pub const MAP_DROPPABLE: c_int = 0x8; + +// 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; + +// uapi/linux/securebits.h +const SECURE_NOROOT: c_int = 0; +const SECURE_NOROOT_LOCKED: c_int = 1; + +pub const SECBIT_NOROOT: c_int = issecure_mask(SECURE_NOROOT); +pub const SECBIT_NOROOT_LOCKED: c_int = issecure_mask(SECURE_NOROOT_LOCKED); + +const SECURE_NO_SETUID_FIXUP: c_int = 2; +const SECURE_NO_SETUID_FIXUP_LOCKED: c_int = 3; + +pub const SECBIT_NO_SETUID_FIXUP: c_int = issecure_mask(SECURE_NO_SETUID_FIXUP); +pub const SECBIT_NO_SETUID_FIXUP_LOCKED: c_int = issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED); + +const SECURE_KEEP_CAPS: c_int = 4; +const SECURE_KEEP_CAPS_LOCKED: c_int = 5; + +pub const SECBIT_KEEP_CAPS: c_int = issecure_mask(SECURE_KEEP_CAPS); +pub const SECBIT_KEEP_CAPS_LOCKED: c_int = issecure_mask(SECURE_KEEP_CAPS_LOCKED); + +const SECURE_NO_CAP_AMBIENT_RAISE: c_int = 6; +const SECURE_NO_CAP_AMBIENT_RAISE_LOCKED: c_int = 7; + +pub const SECBIT_NO_CAP_AMBIENT_RAISE: c_int = issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE); +pub const SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED: c_int = + issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_LOCKED); + +const SECURE_EXEC_RESTRICT_FILE: c_int = 8; +const SECURE_EXEC_RESTRICT_FILE_LOCKED: c_int = 9; + +pub const SECBIT_EXEC_RESTRICT_FILE: c_int = issecure_mask(SECURE_EXEC_RESTRICT_FILE); +pub const SECBIT_EXEC_RESTRICT_FILE_LOCKED: c_int = issecure_mask(SECURE_EXEC_RESTRICT_FILE_LOCKED); + +const SECURE_EXEC_DENY_INTERACTIVE: c_int = 10; +const SECURE_EXEC_DENY_INTERACTIVE_LOCKED: c_int = 11; + +pub const SECBIT_EXEC_DENY_INTERACTIVE: c_int = issecure_mask(SECURE_EXEC_DENY_INTERACTIVE); +pub const SECBIT_EXEC_DENY_INTERACTIVE_LOCKED: c_int = + issecure_mask(SECURE_EXEC_DENY_INTERACTIVE_LOCKED); + +pub const SECUREBITS_DEFAULT: c_int = 0x00000000; +pub const SECURE_ALL_BITS: c_int = SECBIT_NOROOT + | SECBIT_NO_SETUID_FIXUP + | SECBIT_KEEP_CAPS + | SECBIT_NO_CAP_AMBIENT_RAISE + | SECBIT_EXEC_RESTRICT_FILE + | SECBIT_EXEC_DENY_INTERACTIVE; +pub const SECURE_ALL_LOCKS: c_int = SECURE_ALL_BITS << 1; + +pub const SECURE_ALL_UNPRIVILEGED: c_int = + issecure_mask(SECURE_EXEC_RESTRICT_FILE) | issecure_mask(SECURE_EXEC_DENY_INTERACTIVE); + +const fn issecure_mask(x: c_int) -> c_int { + 1 << x +} + +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/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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + } +} + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const NFT_MSG_MAX: c_int = 34; + +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 +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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_POINTER: __u16 = 0x00; +pub const INPUT_PROP_DIRECT: __u16 = 0x01; +pub const INPUT_PROP_BUTTONPAD: __u16 = 0x02; +pub const INPUT_PROP_SEMI_MT: __u16 = 0x03; +pub const INPUT_PROP_TOPBUTTONPAD: __u16 = 0x04; +pub const INPUT_PROP_POINTING_STICK: __u16 = 0x05; +pub const INPUT_PROP_ACCELEROMETER: __u16 = 0x06; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const INPUT_PROP_MAX: __u16 = 0x1f; + +pub const INPUT_PROP_CNT: usize = INPUT_PROP_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const EV_MAX: __u16 = 0x1f; +pub const EV_CNT: usize = EV_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const SYN_MAX: __u16 = 0xf; +pub const SYN_CNT: usize = SYN_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const KEY_MAX: __u16 = 0x2ff; +pub const KEY_CNT: usize = KEY_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const REL_MAX: __u16 = 0x0f; +pub const REL_CNT: usize = REL_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const ABS_MAX: __u16 = 0x3f; +pub const ABS_CNT: usize = ABS_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const SW_MAX: __u16 = 0x11; +pub const SW_CNT: usize = SW_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const MSC_MAX: __u16 = 0x07; +pub const MSC_CNT: usize = MSC_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const LED_MAX: __u16 = 0x0f; +pub const LED_CNT: usize = LED_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const REP_MAX: __u16 = 0x01; +pub const REP_CNT: usize = REP_MAX as usize + 1; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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/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 = u32_cast_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 = u32_cast_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 = u32_cast_int(0xCDEF0123); +pub const LINUX_REBOOT_CMD_CAD_ON: c_int = u32_cast_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 = u32_cast_int(0xA1B2C3D4); +pub const LINUX_REBOOT_CMD_SW_SUSPEND: c_int = u32_cast_int(0xD000FCE2); +pub const LINUX_REBOOT_CMD_KEXEC: c_int = 0x45584543; + +// 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; + +/* 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_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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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_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 +/// I'm a virtual CPU. +pub const PF_VCPU: c_int = 0x00000001; +/// I am an IDLE thread. +pub const PF_IDLE: c_int = 0x00000002; +/// Getting shut down. +pub const PF_EXITING: c_int = 0x00000004; +/// Coredumps should ignore this task. +pub const PF_POSTCOREDUMP: c_int = 0x00000008; +/// Task is an IO worker. +pub const PF_IO_WORKER: c_int = 0x00000010; +/// I'm a workqueue worker. +pub const PF_WQ_WORKER: c_int = 0x00000020; +/// Forked but didn't exec. +pub const PF_FORKNOEXEC: c_int = 0x00000040; +/// Process policy on mce errors. +pub const PF_MCE_PROCESS: c_int = 0x00000080; +/// Used super-user privileges. +pub const PF_SUPERPRIV: c_int = 0x00000100; +/// Dumped core. +pub const PF_DUMPCORE: c_int = 0x00000200; +/// Killed by a signal. +pub const PF_SIGNALED: c_int = 0x00000400; +/// Allocating memory to free memory. +/// +/// See `memalloc_noreclaim_save()`. +pub const PF_MEMALLOC: c_int = 0x00000800; +/// `set_user()` noticed that `RLIMIT_NPROC` was exceeded. +pub const PF_NPROC_EXCEEDED: c_int = 0x00001000; +/// If unset the fpu must be initialized before use. +pub const PF_USED_MATH: c_int = 0x00002000; +/// Kernel thread cloned from userspace thread. +pub const PF_USER_WORKER: c_int = 0x00004000; +/// This thread should not be frozen. +pub const PF_NOFREEZE: c_int = 0x00008000; +/// I am `kswapd`. +pub const PF_KSWAPD: c_int = 0x00020000; +/// All allocations inherit `GFP_NOFS`. +/// +/// See `memalloc_nfs_save()`. +pub const PF_MEMALLOC_NOFS: c_int = 0x00040000; +/// All allocations inherit `GFP_NOIO`. +/// +/// See `memalloc_noio_save()`. +pub const PF_MEMALLOC_NOIO: c_int = 0x00080000; +/// Throttle writes only against the bdi I write to, I am cleaning +/// dirty pages from some other bdi. +pub const PF_LOCAL_THROTTLE: c_int = 0x00100000; +/// I am a kernel thread. +pub const PF_KTHREAD: c_int = 0x00200000; +/// Randomize virtual address space. +pub const PF_RANDOMIZE: c_int = 0x00400000; +/// Userland is not allowed to meddle with `cpus_mask`. +pub const PF_NO_SETAFFINITY: c_int = 0x04000000; +/// Early kill for mce process policy. +pub const PF_MCE_EARLY: c_int = 0x08000000; +/// Allocations constrained to zones which allow long term pinning. +/// +/// See `memalloc_pin_save()`. +pub const PF_MEMALLOC_PIN: c_int = 0x10000000; +/// Plug has ts that needs updating. +pub const PF_BLOCK_TS: c_int = 0x20000000; +/// This thread called `freeze_processes()` and should not be frozen. +pub const PF_SUSPEND_TASK: c_int = u32_cast_int(PF_SUSPEND_TASK_UINT); +// The used value is the highest possible bit fitting on 32 bits, so directly +// defining it as a signed integer causes the compiler to report an overflow. +// Use instead a private intermediary that assuringly has the correct type and +// cast it where necessary to the wanted final type, which preserves the +// desired information as-is in terms of integer representation. +const PF_SUSPEND_TASK_UINT: c_uint = 0x80000000; + +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; + +// linux/if_xdp.h +pub const XDP_SHARED_UMEM: crate::__u16 = 1 << 0; +pub const XDP_COPY: crate::__u16 = 1 << 1; +pub const XDP_ZEROCOPY: crate::__u16 = 1 << 2; +pub const XDP_USE_NEED_WAKEUP: crate::__u16 = 1 << 3; +pub const XDP_USE_SG: crate::__u16 = 1 << 4; + +pub const XDP_UMEM_UNALIGNED_CHUNK_FLAG: crate::__u32 = 1 << 0; + +pub const XDP_RING_NEED_WAKEUP: crate::__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: crate::__u32 = 1 << 0; + +pub const XDP_PGOFF_RX_RING: crate::off_t = 0; +pub const XDP_PGOFF_TX_RING: crate::off_t = 0x80000000u32 as crate::off_t; +pub const XDP_UMEM_PGOFF_FILL_RING: crate::c_ulonglong = 0x100000000; +pub const XDP_UMEM_PGOFF_COMPLETION_RING: crate::c_ulonglong = 0x180000000; + +pub const XSK_UNALIGNED_BUF_OFFSET_SHIFT: crate::c_int = 48; +pub const XSK_UNALIGNED_BUF_ADDR_MASK: crate::c_ulonglong = + (1 << XSK_UNALIGNED_BUF_OFFSET_SHIFT) - 1; + +pub const XDP_PKT_CONTD: crate::__u32 = 1 << 0; + +pub const XDP_UMEM_TX_SW_CSUM: crate::__u32 = 1 << 1; +pub const XDP_UMEM_TX_METADATA_LEN: crate::__u32 = 1 << 2; + +pub const XDP_TXMD_FLAGS_TIMESTAMP: crate::__u32 = 1 << 0; +pub const XDP_TXMD_FLAGS_CHECKSUM: crate::__u32 = 1 << 1; + +pub const XDP_TX_METADATA: crate::__u32 = 1 << 1; + +pub const SOL_XDP: c_int = 283; + +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; + +// ioctl_eventpoll: added in Linux 6.9 +const EPOLL_IOC_TYPE: u32 = 0x8A; +pub const EPIOCSPARAMS: Ioctl = _IOW::(EPOLL_IOC_TYPE, 0x01); +pub const EPIOCGPARAMS: Ioctl = _IOR::(EPOLL_IOC_TYPE, 0x02); + +// siginfo.h +pub const SI_DETHREAD: c_int = -7; +pub const TRAP_PERF: c_int = 6; + +f! { + pub unsafe fn SO_EE_OFFENDER(ee: *const crate::sock_extended_err) -> *mut crate::sockaddr { + ee.offset(1) as *mut crate::sockaddr + } + + pub unsafe fn BPF_CLASS(code: __u32) -> __u32 { + code & 0x07 + } + + pub unsafe fn BPF_SIZE(code: __u32) -> __u32 { + code & 0x18 + } + + pub unsafe fn BPF_MODE(code: __u32) -> __u32 { + code & 0xe0 + } + + pub unsafe fn BPF_OP(code: __u32) -> __u32 { + code & 0xf0 + } + + pub unsafe fn BPF_SRC(code: __u32) -> __u32 { + code & 0x08 + } + + pub unsafe fn BPF_RVAL(code: __u32) -> __u32 { + code & 0x18 + } + + pub unsafe fn BPF_MISCOP(code: __u32) -> __u32 { + code & 0xf8 + } + + pub unsafe fn BPF_STMT(code: __u16, k: __u32) -> sock_filter { + sock_filter { + code, + jt: 0, + jf: 0, + k, + } + } + + pub unsafe fn BPF_JUMP(code: __u16, k: __u32, jt: __u8, jf: __u8) -> sock_filter { + sock_filter { code, jt, jf, k } + } + + #[cfg(target_env = "gnu")] + pub unsafe fn SUN_LEN(s: crate::sockaddr_un) -> usize { + offset_of!(crate::sockaddr_un, sun_path) + crate::strlen(s.sun_path.as_ptr()) + } + + #[cfg(target_env = "musl")] + pub unsafe fn SUN_LEN(s: crate::sockaddr_un) -> usize { + 2 * crate::strlen(s.sun_path.as_ptr()) + } +} + +// 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 crate::spwd, + buf: *mut c_char, + buflen: size_t, + spbufp: *mut *mut crate::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; + #[cfg_attr( + any(gnu_time_bits64, musl_redir_time64), + link_name = "__mq_timedreceive_time64" + )] + pub fn mq_timedreceive( + mqd: mqd_t, + msg_ptr: *mut c_char, + msg_len: size_t, + msg_prio: *mut c_uint, + abs_timeout: *const crate::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; + #[cfg_attr( + any(gnu_time_bits64, musl_redir_time64), + link_name = "__mq_timedsend_time64" + )] + pub fn mq_timedsend( + mqd: mqd_t, + msg_ptr: *const c_char, + msg_len: size_t, + msg_prio: c_uint, + abs_timeout: *const crate::timespec, + ) -> c_int; + pub fn mq_getattr(mqd: mqd_t, attr: *mut crate::mq_attr) -> c_int; + pub fn mq_setattr( + mqd: mqd_t, + newattr: *const crate::mq_attr, + oldattr: *mut crate::mq_attr, + ) -> c_int; + } + } +} + +extern "C" { + pub fn mrand48() -> c_long; + pub fn seed48(xseed: *mut c_ushort) -> *mut c_ushort; + pub fn lcong48(p: *mut c_ushort); + + #[cfg_attr(gnu_time_bits64, link_name = "__lutimes64")] + #[cfg_attr(musl_redir_time64, link_name = "__lutimes_time64")] + pub fn lutimes(file: *const c_char, times: *const crate::timeval) -> 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; + + // System V IPC + pub fn ftok(pathname: *const c_char, proj_id: c_int) -> crate::key_t; + pub fn semget(key: crate::key_t, nsems: c_int, semflag: c_int) -> c_int; + pub fn semop(semid: c_int, sops: *mut crate::sembuf, nsops: size_t) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__semctl64")] + pub fn semctl(semid: c_int, semnum: c_int, cmd: c_int, ...) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__msgctl64")] + pub fn msgctl(msqid: c_int, cmd: c_int, buf: *mut msqid_ds) -> c_int; + pub fn msgget(key: crate::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; + + #[cfg_attr(gnu_file_offset_bits64, link_name = "fallocate64")] + pub fn fallocate(fd: c_int, mode: c_int, offset: off_t, len: off_t) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "posix_fallocate64")] + 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 crate::sigset_t, flags: c_int) -> c_int; + pub fn timerfd_create(clockid: crate::clockid_t, flags: c_int) -> c_int; + #[cfg_attr( + any(gnu_time_bits64, musl_redir_time64), + link_name = "__timerfd_gettime64" + )] + pub fn timerfd_gettime(fd: c_int, curr_value: *mut crate::itimerspec) -> c_int; + #[cfg_attr( + any(gnu_time_bits64, musl_redir_time64), + link_name = "__timerfd_settime64" + )] + pub fn timerfd_settime( + fd: c_int, + flags: c_int, + new_value: *const crate::itimerspec, + old_value: *mut crate::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 crate::epoll_event, + maxevents: c_int, + timeout: c_int, + sigmask: *const crate::sigset_t, + ) -> c_int; + pub fn dup3(oldfd: c_int, newfd: c_int, flags: c_int) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__sigtimedwait64")] + #[cfg_attr(musl_redir_time64, link_name = "__sigtimedwait_time64")] + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const crate::timespec, + ) -> c_int; + pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> c_int; + pub fn accept4(fd: c_int, addr: *mut crate::sockaddr, len: *mut socklen_t, flg: c_int) + -> c_int; + pub fn reboot(how_to: c_int) -> c_int; + pub fn setfsgid(gid: crate::gid_t) -> c_int; + pub fn setfsuid(uid: crate::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 sync_file_range(fd: c_int, offset: off64_t, nbytes: off64_t, flags: c_uint) -> c_int; + + pub fn posix_madvise(addr: *mut c_void, len: size_t, advice: c_int) -> c_int; + + pub fn mremap( + addr: *mut c_void, + len: size_t, + new_len: size_t, + flags: c_int, + ... + ) -> *mut c_void; + pub fn remap_file_pages( + addr: *mut c_void, + size: size_t, + prot: c_int, + pgoff: size_t, + flags: c_int, + ) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "mkstemps64")] + pub fn mkstemps(template: *mut c_char, suffixlen: c_int) -> 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_setaffinity( + pid: crate::pid_t, + cpusetsize: size_t, + cpuset: *const crate::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 crate::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 crate::epoll_event) -> c_int; + pub fn unshare(flags: c_int) -> c_int; + pub fn umount(target: *const c_char) -> c_int; + pub fn tee(fd_in: c_int, fd_out: c_int, len: size_t, flags: c_uint) -> ssize_t; + 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(initval: 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; + + #[cfg_attr(gnu_time_bits64, link_name = "__sched_rr_get_interval64")] + #[cfg_attr(musl_redir_time64, link_name = "__sched_rr_get_interval_time64")] + pub fn sched_rr_get_interval(pid: crate::pid_t, tp: *mut crate::timespec) -> c_int; + pub fn sched_setparam(pid: crate::pid_t, param: *const crate::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 crate::iovec, nr_segs: size_t, flags: c_uint) + -> ssize_t; + pub fn personality(persona: c_ulong) -> c_int; + pub fn sched_getparam(pid: crate::pid_t, param: *mut crate::sched_param) -> 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: crate::pid_t) -> c_int; + #[cfg_attr( + any(gnu_time_bits64, musl_redir_time64), + link_name = "__clock_nanosleep_time64" + )] + pub fn clock_nanosleep( + clk_id: crate::clockid_t, + flags: c_int, + rqtp: *const crate::timespec, + rmtp: *mut crate::timespec, + ) -> 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: crate::pid_t, + policy: c_int, + param: *const crate::sched_param, + ) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "sendfile64")] + pub fn sendfile(out_fd: c_int, in_fd: c_int, offset: *mut off_t, count: size_t) -> ssize_t; + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> c_int; + pub fn getdtablesize() -> c_int; + pub fn getgrouplist( + user: *const c_char, + group: crate::gid_t, + groups: *mut crate::gid_t, + ngroups: *mut c_int, + ) -> c_int; + pub fn posix_spawn( + pid: *mut crate::pid_t, + path: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::posix_spawnattr_t, + argv: *const *mut c_char, + envp: *const *mut c_char, + ) -> c_int; + pub fn posix_spawnp( + pid: *mut crate::pid_t, + file: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::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 crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + default: *const crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + default: *mut crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + default: *const crate::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 crate::pid_t, + ) -> c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: crate::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 crate::sched_param, + ) -> c_int; + pub fn posix_spawnattr_setschedparam( + attr: *mut posix_spawnattr_t, + param: *const crate::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 crate::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 gethostid() -> c_long; + + pub fn klogctl(syslog_type: c_int, bufp: *mut c_char, len: c_int) -> c_int; + + pub fn name_to_handle_at( + dirfd: c_int, + path: *const c_char, + handle: *mut file_handle, + mount_id: *mut c_int, + flags: c_int, + ) -> c_int; + pub fn open_by_handle_at(mount_fd: c_int, handle: *mut file_handle, flags: c_int) -> c_int; + pub fn getnetbyname(name: *const c_char) -> *mut netent; + pub fn getnetbyaddr(net: u32, type_: c_int) -> *mut netent; + pub fn getnetent() -> *mut netent; + pub fn setnetent(stayopen: c_int); + pub fn endnetent(); +} + +// LFS64 extensions +// +// * musl has 64-bit versions only so aliases the LFS64 symbols to the standard ones +cfg_if! { + if #[cfg(not(any(target_env = "musl", target_env = "ohos")))] { + extern "C" { + pub fn fallocate64(fd: c_int, mode: c_int, offset: off64_t, len: off64_t) -> c_int; + pub fn fgetpos64(stream: *mut crate::FILE, ptr: *mut crate::fpos64_t) -> c_int; + pub fn fopen64(filename: *const c_char, mode: *const c_char) -> *mut crate::FILE; + 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 crate::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::*; 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..26d3380 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/mod.rs @@ -0,0 +1,832 @@ +use crate::off_t; +use crate::prelude::*; + +pub type wchar_t = u32; + +pub type stat64 = stat; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + __st_dev_padding: Padding, + __st_ino_truncated: c_long, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __st_rdev_padding: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + + #[cfg(musl32_time64)] + __st_atim32: Padding<__c_anonymous_timespec32>, + #[cfg(musl32_time64)] + __st_mtim32: Padding<__c_anonymous_timespec32>, + #[cfg(musl32_time64)] + __st_ctim32: Padding<__c_anonymous_timespec32>, + + #[cfg(musl_v1_2_3)] + pub st_ino: crate::ino_t, + + pub st_atime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad0: Padding, + pub st_atime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad0: Padding, + pub st_mtime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad1: Padding, + pub st_mtime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad1: Padding, + pub st_ctime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad2: Padding, + pub st_ctime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad2: Padding, + + #[cfg(not(musl_v1_2_3))] + pub st_ino: crate::ino_t, + } + + struct __c_anonymous_timespec32 { + __tv_sec: c_long, + __tv_nsec: c_long, + } + + pub struct stack_t { + pub ss_sp: *mut c_void, + pub ss_flags: c_int, + pub ss_size: size_t, + } + + pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: c_int, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + + #[cfg(musl32_time64)] + __shm_atime_lo: Padding, + #[cfg(musl32_time64)] + __shm_atime_hi: Padding, + #[cfg(musl32_time64)] + __shm_dtime_lo: Padding, + #[cfg(musl32_time64)] + __shm_dtime_hi: Padding, + #[cfg(musl32_time64)] + __msg_ctime_lo: Padding, + #[cfg(musl32_time64)] + __msg_ctime_hi: Padding, + + #[cfg(not(musl32_time64))] + pub shm_atime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused1: Padding, + #[cfg(not(musl32_time64))] + pub shm_dtime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused2: Padding, + #[cfg(not(musl32_time64))] + pub shm_ctime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused3: Padding, + + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: c_ulong, + __pad1: Padding, + __pad2: Padding, + + #[cfg(musl32_time64)] + __pad3: c_ulong, + #[cfg(musl32_time64)] + shm_atime: crate::time_t, + #[cfg(musl32_time64)] + shm_dtime: crate::time_t, + #[cfg(musl32_time64)] + shm_ctime: crate::time_t, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + + #[cfg(musl32_time64)] + __msg_stime_lo: Padding, + #[cfg(musl32_time64)] + __msg_stime_hi: Padding, + #[cfg(musl32_time64)] + __msg_rtime_lo: Padding, + #[cfg(musl32_time64)] + __msg_rtime_hi: Padding, + #[cfg(musl32_time64)] + __msg_ctime_lo: Padding, + #[cfg(musl32_time64)] + __msg_ctime_hi: Padding, + + #[cfg(not(musl32_time64))] + pub msg_stime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused1: Padding, + #[cfg(not(musl32_time64))] + pub msg_rtime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused2: Padding, + #[cfg(not(musl32_time64))] + pub msg_ctime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused3: Padding, + + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __pad1: Padding, + __pad2: Padding, + + #[cfg(musl32_time64)] + pub msg_stime: crate::time_t, + #[cfg(musl32_time64)] + pub msg_rtime: crate::time_t, + #[cfg(musl32_time64)] + pub msg_ctime: crate::time_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 ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: crate::sigset_t, + pub uc_regspace: [c_ulonglong; 64], + } +} + +s_no_extra_traits! { + #[repr(align(8))] + pub struct max_align_t { + priv_: (i64, i64), + } +} + +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: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::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 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: crate::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: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::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; 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..c8c3377 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/hexagon.rs @@ -0,0 +1,727 @@ +use crate::prelude::*; + +pub type wchar_t = u32; +pub type stat64 = crate::stat; + +s! { + pub struct stat { + pub st_dev: crate::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: Padding, + pub st_size: c_longlong, + pub st_blksize: crate::blksize_t, + __st_blksize_padding: Padding, + pub st_blocks: crate::blkcnt_t, + + pub st_atime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad0: Padding, + pub st_atime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad0: Padding, + pub st_mtime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad1: Padding, + pub st_mtime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad1: Padding, + pub st_ctime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad2: Padding, + pub st_ctime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad2: Padding, + + __unused: Padding<[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 { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release" + )] + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: c_int, + __pad1: Padding, + __pad2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + __unused1: Padding, + pub shm_dtime: crate::time_t, + __unused2: Padding, + pub shm_ctime: crate::time_t, + __unused3: Padding, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: c_ulong, + __pad1: Padding, + __pad2: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + pub msg_stime: crate::time_t, + __unused1: Padding, + pub msg_rtime: crate::time_t, + __unused2: Padding, + pub msg_ctime: crate::time_t, + __unused3: Padding, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __pad1: Padding, + __pad2: Padding, + } +} + +pub const AF_FILE: c_int = 1; +pub const AF_KCM: c_int = 41; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 EBADFD: c_int = 77; +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 EPROTOTYPE: c_int = 91; +pub const EPROTONOSUPPORT: c_int = 93; +pub const EREMCHG: c_int = 78; +pub const ERESTART: c_int = 85; +pub const EREMOTEIO: c_int = 121; +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: crate::tcflag_t = 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: crate::tcflag_t = 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: crate::tcflag_t = 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_SYNC: c_int = 0x080000; +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 O_RSYNC: c_int = 1052672; +pub const PF_FILE: c_int = 1; +pub const PF_KCM: c_int = 41; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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(musl) check these +pub const SIG_BLOCK: c_int = 0x000000; +pub const SIG_UNBLOCK: c_int = 0x01; +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 POLLWRNORM: c_short = 256; +pub const POLLWRBAND: c_short = 512; +pub const MADV_SOFT_OFFLINE: c_int = 101; +pub const MCL_CURRENT: c_int = 1; +pub const MCL_FUTURE: c_int = 2; +pub const MCL_ONFAULT: c_int = 4; + +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_long = 285; +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_statfs: 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 SYS_userfaultfd: c_long = 282; +pub const SYS_membarrier: c_long = 283; +pub const SYS_mlock2: c_long = 284; +pub const SYS_preadv2: c_long = 286; +pub const SYS_pwritev2: c_long = 287; +pub const SYS_futex_waitv: c_long = 449; +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: crate::tcflag_t = 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; +pub const CBAUD: crate::tcflag_t = 4111; +pub const CIBAUD: crate::tcflag_t = 269418496; +pub const CLOCAL: crate::tcflag_t = 2048; +pub const CREAD: crate::tcflag_t = 128; +pub const CS6: crate::tcflag_t = 16; +pub const CS7: crate::tcflag_t = 32; +pub const CS8: crate::tcflag_t = 48; +pub const CSIZE: crate::tcflag_t = 48; +pub const CSTOPB: crate::tcflag_t = 64; +pub const HUPCL: crate::tcflag_t = 1024; +pub const PARENB: crate::tcflag_t = 256; +pub const PARODD: crate::tcflag_t = 512; +pub const ECHOCTL: crate::tcflag_t = 512; +pub const ECHOE: crate::tcflag_t = 16; +pub const ECHOK: crate::tcflag_t = 32; +pub const ECHOKE: crate::tcflag_t = 2048; +pub const ECHONL: crate::tcflag_t = 64; +pub const ECHOPRT: crate::tcflag_t = 1024; +pub const ICANON: crate::tcflag_t = 2; +pub const ISIG: crate::tcflag_t = 1; +pub const IXOFF: crate::tcflag_t = 4096; +pub const IXON: crate::tcflag_t = 1024; +pub const NOFLSH: crate::tcflag_t = 128; +pub const PENDIN: crate::tcflag_t = 16384; +pub const BSDLY: crate::tcflag_t = 8192; +pub const CRDLY: crate::tcflag_t = 1536; +pub const FFDLY: crate::tcflag_t = 32768; +pub const NLDLY: crate::tcflag_t = 256; +pub const OLCUC: crate::tcflag_t = 2; +pub const ONLCR: crate::tcflag_t = 4; +pub const TABDLY: crate::tcflag_t = 6144; +pub const VTDLY: crate::tcflag_t = 16384; +pub const XTABS: crate::tcflag_t = 6144; +pub const BS1: crate::tcflag_t = 8192; +pub const CBAUDEX: crate::tcflag_t = 4096; +pub const CR1: crate::tcflag_t = 512; +pub const CR2: crate::tcflag_t = 1024; +pub const CR3: crate::tcflag_t = 1536; +pub const FF1: crate::tcflag_t = 32768; +pub const TAB1: crate::tcflag_t = 2048; +pub const TAB2: crate::tcflag_t = 4096; +pub const TAB3: crate::tcflag_t = 6144; +pub const VT1: crate::tcflag_t = 16384; +pub const VDISCARD: usize = 13; +pub const VREPRINT: usize = 12; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VSUSP: usize = 10; +pub const VSWTC: usize = 7; +pub const VTIME: usize = 5; +pub const VWERASE: usize = 14; +pub const B57600: crate::speed_t = 4097; +pub const B115200: crate::speed_t = 4098; +pub const B230400: crate::speed_t = 4099; +pub const B460800: crate::speed_t = 4100; +pub const B500000: crate::speed_t = 4101; +pub const B576000: crate::speed_t = 4102; +pub const B921600: crate::speed_t = 4103; +pub const B1000000: crate::speed_t = 4104; +pub const B1152000: crate::speed_t = 4105; +pub const B1500000: crate::speed_t = 4106; +pub const B2000000: crate::speed_t = 4107; +pub const B2500000: crate::speed_t = 4108; +pub const B3000000: crate::speed_t = 4109; +pub const B3500000: crate::speed_t = 4110; +pub const B4000000: crate::speed_t = 4111; 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..7edcf57 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/mod.rs @@ -0,0 +1,878 @@ +use crate::off_t; +use crate::prelude::*; + +pub type wchar_t = c_int; + +pub type stat64 = stat; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + __st_padding1: Padding<[c_long; 2]>, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __st_padding2: Padding<[c_long; 2]>, + pub st_size: off_t, + + #[cfg(musl32_time64)] + __st_atim32: Padding<__c_anonymous_timespec32>, + #[cfg(musl32_time64)] + __st_mtim32: Padding<__c_anonymous_timespec32>, + #[cfg(musl32_time64)] + __st_ctim32: Padding<__c_anonymous_timespec32>, + + #[cfg(musl_v1_2_3)] + pub st_blksize: crate::blksize_t, + #[cfg(musl_v1_2_3)] + __st_padding3: Padding, + #[cfg(musl_v1_2_3)] + pub st_blocks: crate::blkcnt_t, + + pub st_atime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad0: Padding, + pub st_atime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad0: Padding, + pub st_mtime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad1: Padding, + pub st_mtime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad1: Padding, + pub st_ctime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad2: Padding, + pub st_ctime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad2: Padding, + + #[cfg(not(musl_v1_2_3))] + pub st_blksize: crate::blksize_t, + #[cfg(not(musl_v1_2_3))] + __st_padding3: Padding, + #[cfg(not(musl_v1_2_3))] + pub st_blocks: crate::blkcnt_t, + + #[cfg(not(musl_v1_2_3))] + __st_padding4: Padding<[c_long; 14]>, + #[cfg(musl_v1_2_3)] + __st_padding4: Padding<[c_long; 2]>, + } + + struct __c_anonymous_timespec32 { + __tv_sec: c_long, + __tv_nsec: c_long, + } + + pub struct stack_t { + pub ss_sp: *mut c_void, + pub ss_size: size_t, + pub ss_flags: c_int, + } + + pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: c_int, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + #[cfg(not(musl32_time64))] + pub shm_atime: crate::time_t, + #[cfg(not(musl32_time64))] + pub shm_dtime: crate::time_t, + #[cfg(not(musl32_time64))] + pub shm_ctime: crate::time_t, + #[cfg(musl32_time64)] + __shm_atime_lo: Padding, + #[cfg(musl32_time64)] + __shm_dtime_lo: Padding, + #[cfg(musl32_time64)] + __shm_ctime_lo: Padding, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: c_ulong, + #[cfg(not(musl32_time64))] + __pad1: Padding, + #[cfg(not(musl32_time64))] + __pad2: Padding, + + #[cfg(musl32_time64)] + __shm_atime_hi: Padding, + #[cfg(musl32_time64)] + __shm_dtime_hi: Padding, + #[cfg(musl32_time64)] + __shm_ctime_hi: Padding, + #[cfg(musl32_time64)] + __pad1: Padding, + #[cfg(musl32_time64)] + pub shm_atime: crate::time_t, + #[cfg(musl32_time64)] + pub shm_dtime: crate::time_t, + #[cfg(musl32_time64)] + pub shm_ctime: crate::time_t, + } + + pub struct statfs { + pub f_type: c_ulong, + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_fsid: crate::fsid_t, + pub f_namelen: 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_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_fsid: crate::fsid_t, + pub f_namelen: c_ulong, + pub f_flags: c_ulong, + pub f_spare: [c_ulong; 5], + } +} + +cfg_if! { + if #[cfg(musl32_time64)] { + s! { + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + + #[cfg(target_endian = "big")] + __msg_stime_hi: Padding, + #[cfg(target_endian = "big")] + __msg_stime_lo: Padding, + #[cfg(target_endian = "big")] + __msg_rtime_hi: Padding, + #[cfg(target_endian = "big")] + __msg_rtime_lo: Padding, + #[cfg(target_endian = "big")] + __msg_ctime_hi: Padding, + #[cfg(target_endian = "big")] + __msg_ctime_lo: Padding, + + #[cfg(target_endian = "little")] + __msg_stime_lo: Padding, + #[cfg(target_endian = "little")] + __msg_stime_hi: Padding, + #[cfg(target_endian = "little")] + __msg_rtime_lo: Padding, + #[cfg(target_endian = "little")] + __msg_rtime_hi: Padding, + #[cfg(target_endian = "little")] + __msg_ctime_lo: Padding, + #[cfg(target_endian = "little")] + __msg_ctime_hi: Padding, + + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __pad1: Padding, + __pad2: Padding, + + pub msg_stime: crate::time_t, + pub msg_rtime: crate::time_t, + pub msg_ctime: crate::time_t, + } + } + } else { + s! { + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + + #[cfg(target_endian = "big")] + __unused1: Padding, + #[cfg(target_endian = "big")] + pub msg_stime: crate::time_t, + #[cfg(target_endian = "big")] + __unused2: Padding, + #[cfg(target_endian = "big")] + pub msg_rtime: crate::time_t, + #[cfg(target_endian = "big")] + __unused3: Padding, + #[cfg(target_endian = "big")] + pub msg_ctime: crate::time_t, + + #[cfg(target_endian = "little")] + pub msg_stime: crate::time_t, + #[cfg(target_endian = "little")] + __unused1: Padding, + #[cfg(target_endian = "little")] + pub msg_rtime: crate::time_t, + #[cfg(target_endian = "little")] + __unused2: Padding, + #[cfg(target_endian = "little")] + pub msg_ctime: crate::time_t, + #[cfg(target_endian = "little")] + __unused3: Padding, + + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __pad1: Padding, + __pad2: Padding, + } + } + } +} + +s_no_extra_traits! { + #[repr(align(8))] + pub struct max_align_t { + priv_: [f32; 4], + } +} + +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: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::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 SA_ONSTACK: c_int = 0x08000000; +pub const SA_SIGINFO: c_int = 8; +pub const SA_NOCLDWAIT: c_int = 0x10000; + +pub const SIGEMT: c_int = 7; +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 = crate::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: crate::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: crate::tcflag_t = 0o000400; +pub const TOSTOP: crate::tcflag_t = 0o100000; +pub const FLUSHO: crate::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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; 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..8b662af --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/mod.rs @@ -0,0 +1,47 @@ +use crate::prelude::*; + +pub type nlink_t = u32; +pub type blksize_t = c_long; +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 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..f0d92c0 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/powerpc.rs @@ -0,0 +1,835 @@ +use crate::off_t; +use crate::prelude::*; + +pub type wchar_t = i32; + +pub type stat64 = stat; + +s! { + pub struct termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_cc: [crate::cc_t; crate::NCCS], + pub c_line: crate::cc_t, + pub __c_ispeed: crate::speed_t, + pub __c_ospeed: crate::speed_t, + } + + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __st_rdev_padding: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + + #[cfg(musl32_time64)] + __st_atim32: Padding<__c_anonymous_timespec32>, + #[cfg(musl32_time64)] + __st_mtim32: Padding<__c_anonymous_timespec32>, + #[cfg(musl32_time64)] + __st_ctim32: Padding<__c_anonymous_timespec32>, + + #[cfg(musl_v1_2_3)] + __unused: Padding<[c_long; 2]>, + + pub st_atime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad0: Padding, + pub st_atime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad0: Padding, + pub st_mtime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad1: Padding, + pub st_mtime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad1: Padding, + pub st_ctime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad2: Padding, + pub st_ctime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad2: Padding, + + #[cfg(not(musl_v1_2_3))] + __unused: Padding<[c_long; 2]>, + } + + struct __c_anonymous_timespec32 { + __tv_sec: c_long, + __tv_nsec: c_long, + } + + pub struct stack_t { + pub ss_sp: *mut c_void, + pub ss_flags: c_int, + pub ss_size: size_t, + } + + pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: c_int, + __pad1: Padding, + __pad2: Padding, + __pad3: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + + #[cfg(musl32_time64)] + __shm_atime_hi: Padding, + #[cfg(musl32_time64)] + __shm_atime_lo: Padding, + #[cfg(musl32_time64)] + __shm_dtime_hi: Padding, + #[cfg(musl32_time64)] + __shm_dtime_lo: Padding, + #[cfg(musl32_time64)] + __shm_ctime_hi: Padding, + #[cfg(musl32_time64)] + __shm_ctime_lo: Padding, + + #[cfg(not(musl32_time64))] + __unused1: Padding, + #[cfg(not(musl32_time64))] + pub shm_atime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused2: Padding, + #[cfg(not(musl32_time64))] + pub shm_dtime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused3: Padding, + #[cfg(not(musl32_time64))] + pub shm_ctime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused4: Padding, + + #[cfg(musl32_time64)] + __pad1: Padding, + + pub shm_segsz: size_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: c_ulong, + #[cfg(not(musl32_time64))] + __pad1: Padding, + __pad2: Padding, + + #[cfg(musl32_time64)] + pub shm_atime: crate::time_t, + #[cfg(musl32_time64)] + pub shm_dtime: crate::time_t, + #[cfg(musl32_time64)] + pub shm_ctime: crate::time_t, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + + #[cfg(musl32_time64)] + __msg_stime_hi: Padding, + #[cfg(musl32_time64)] + __msg_stime_lo: Padding, + #[cfg(musl32_time64)] + __msg_rtime_hi: Padding, + #[cfg(musl32_time64)] + __msg_rtime_lo: Padding, + #[cfg(musl32_time64)] + __msg_ctime_hi: Padding, + #[cfg(musl32_time64)] + __msg_ctime_lo: Padding, + + #[cfg(not(musl32_time64))] + __unused1: Padding, + #[cfg(not(musl32_time64))] + pub msg_stime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused2: Padding, + #[cfg(not(musl32_time64))] + pub msg_rtime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused3: Padding, + #[cfg(not(musl32_time64))] + pub msg_ctime: crate::time_t, + + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __pad1: Padding, + __pad2: Padding, + + #[cfg(musl32_time64)] + pub msg_stime: crate::time_t, + #[cfg(musl32_time64)] + pub msg_rtime: crate::time_t, + #[cfg(musl32_time64)] + pub msg_ctime: crate::time_t, + } +} + +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: crate::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: crate::tcflag_t = 0x00000200; +pub const IXOFF: crate::tcflag_t = 0x00000400; +pub const ONLCR: crate::tcflag_t = 0x00000002; +pub const CSIZE: crate::tcflag_t = 0x00000300; +pub const CS6: crate::tcflag_t = 0x00000100; +pub const CS7: crate::tcflag_t = 0x00000200; +pub const CS8: crate::tcflag_t = 0x00000300; +pub const CSTOPB: crate::tcflag_t = 0x00000400; +pub const CREAD: crate::tcflag_t = 0x00000800; +pub const PARENB: crate::tcflag_t = 0x00001000; +pub const PARODD: crate::tcflag_t = 0x00002000; +pub const HUPCL: crate::tcflag_t = 0x00004000; +pub const CLOCAL: crate::tcflag_t = 0x00008000; +pub const ECHOKE: crate::tcflag_t = 0x00000001; +pub const ECHOE: crate::tcflag_t = 0x00000002; +pub const ECHOK: crate::tcflag_t = 0x00000004; +pub const ECHONL: crate::tcflag_t = 0x00000010; +pub const ECHOPRT: crate::tcflag_t = 0x00000020; +pub const ECHOCTL: crate::tcflag_t = 0x00000040; +pub const ISIG: crate::tcflag_t = 0x00000080; +pub const ICANON: crate::tcflag_t = 0x00000100; +pub const PENDIN: crate::tcflag_t = 0x20000000; +pub const NOFLSH: crate::tcflag_t = 0x80000000; +pub const CIBAUD: crate::tcflag_t = 0o00077600000; +pub const CBAUDEX: crate::tcflag_t = 0o000020; +pub const VSWTC: usize = 9; +pub const OLCUC: crate::tcflag_t = 0o000004; +pub const NLDLY: crate::tcflag_t = 0o001400; +pub const CRDLY: crate::tcflag_t = 0o030000; +pub const TABDLY: crate::tcflag_t = 0o006000; +pub const BSDLY: crate::tcflag_t = 0o100000; +pub const FFDLY: crate::tcflag_t = 0o040000; +pub const VTDLY: crate::tcflag_t = 0o200000; +pub const XTABS: crate::tcflag_t = 0o006000; +pub const B57600: crate::speed_t = 0o000020; +pub const B115200: crate::speed_t = 0o000021; +pub const B230400: crate::speed_t = 0o000022; +pub const B460800: crate::speed_t = 0o000023; +pub const B500000: crate::speed_t = 0o000024; +pub const B576000: crate::speed_t = 0o000025; +pub const B921600: crate::speed_t = 0o000026; +pub const B1000000: crate::speed_t = 0o000027; +pub const B1152000: crate::speed_t = 0o000030; +pub const B1500000: crate::speed_t = 0o000031; +pub const B2000000: crate::speed_t = 0o000032; +pub const B2500000: crate::speed_t = 0o000033; +pub const B3000000: crate::speed_t = 0o000034; +pub const B3500000: crate::speed_t = 0o000035; +pub const B4000000: crate::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 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: crate::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: crate::tcflag_t = 0x00000400; +pub const TOSTOP: crate::tcflag_t = 0x00400000; +pub const FLUSHO: crate::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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 127; +pub const SYS_init_module: c_long = 128; +pub const SYS_delete_module: c_long = 129; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; 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..1dea8d2 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs @@ -0,0 +1,645 @@ +//! RISC-V-specific definitions for 32-bit linux-like values + +use crate::off_t; +use crate::prelude::*; + +pub type wchar_t = c_int; + +pub type stat64 = stat; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __st_rdev_padding: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + __st_blksize_padding: Padding, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad0: Padding, + pub st_atime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad0: Padding, + pub st_mtime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad1: Padding, + pub st_mtime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad1: Padding, + pub st_ctime: crate::time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad2: Padding, + pub st_ctime_nsec: c_long, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad2: Padding, + __unused: Padding<[c_int; 2usize]>, + } + + 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: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_ushort, + __pad1: Padding, + pub __seq: c_ushort, + __pad2: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused5: Padding, + __unused6: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + pub msg_stime: crate::time_t, + __unused1: Padding, + pub msg_rtime: crate::time_t, + __unused2: Padding, + pub msg_ctime: crate::time_t, + __unused3: Padding, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __pad1: Padding, + __pad2: Padding, + } +} + +s_no_extra_traits! { + #[repr(align(8))] + pub struct max_align_t { + priv_: (i64, f64), + } +} + +//pub const RLIM_INFINITY: crate::rlim_t = !0; +pub const VEOF: usize = 4; +//pub const RLIMIT_RSS: crate::__rlimit_resource_t = 5; +//pub const RLIMIT_AS: crate::__rlimit_resource_t = 9; +//pub const RLIMIT_MEMLOCK: crate::__rlimit_resource_t = 8; +//pub const RLIMIT_NOFILE: crate::__rlimit_resource_t = 7; +//pub const RLIMIT_NPROC: crate::__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 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 SA_ONSTACK: c_int = 0x08000000; +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 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 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 MADV_SOFT_OFFLINE: c_int = 101; +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_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: crate::tcflag_t = 4111; +pub const TAB1: crate::tcflag_t = 2048; +pub const TAB2: crate::tcflag_t = 4096; +pub const TAB3: crate::tcflag_t = 6144; +pub const CR1: crate::tcflag_t = 512; +pub const CR2: crate::tcflag_t = 1024; +pub const CR3: crate::tcflag_t = 1536; +pub const FF1: crate::tcflag_t = 32768; +pub const BS1: crate::tcflag_t = 8192; +pub const VT1: crate::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: crate::tcflag_t = 1024; +pub const IXOFF: crate::tcflag_t = 4096; +pub const ONLCR: crate::tcflag_t = 4; +pub const CSIZE: crate::tcflag_t = 48; +pub const CS6: crate::tcflag_t = 16; +pub const CS7: crate::tcflag_t = 32; +pub const CS8: crate::tcflag_t = 48; +pub const CSTOPB: crate::tcflag_t = 64; +pub const CREAD: crate::tcflag_t = 128; +pub const PARENB: crate::tcflag_t = 256; +pub const PARODD: crate::tcflag_t = 512; +pub const HUPCL: crate::tcflag_t = 1024; +pub const CLOCAL: crate::tcflag_t = 2048; +pub const ECHOKE: crate::tcflag_t = 2048; +pub const ECHOE: crate::tcflag_t = 16; +pub const ECHOK: crate::tcflag_t = 32; +pub const ECHONL: crate::tcflag_t = 64; +pub const ECHOPRT: crate::tcflag_t = 1024; +pub const ECHOCTL: crate::tcflag_t = 512; +pub const ISIG: crate::tcflag_t = 1; +pub const ICANON: crate::tcflag_t = 2; +pub const PENDIN: crate::tcflag_t = 16384; +pub const NOFLSH: crate::tcflag_t = 128; +pub const CIBAUD: crate::tcflag_t = 269418496; +pub const CBAUDEX: crate::tcflag_t = 4096; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 2; +pub const NLDLY: crate::tcflag_t = 256; +pub const CRDLY: crate::tcflag_t = 1536; +pub const TABDLY: crate::tcflag_t = 6144; +pub const BSDLY: crate::tcflag_t = 8192; +pub const FFDLY: crate::tcflag_t = 32768; +pub const VTDLY: crate::tcflag_t = 16384; +pub const XTABS: crate::tcflag_t = 6144; +pub const B57600: crate::speed_t = 4097; +pub const B115200: crate::speed_t = 4098; +pub const B230400: crate::speed_t = 4099; +pub const B460800: crate::speed_t = 4100; +pub const B500000: crate::speed_t = 4101; +pub const B576000: crate::speed_t = 4102; +pub const B921600: crate::speed_t = 4103; +pub const B1000000: crate::speed_t = 4104; +pub const B1152000: crate::speed_t = 4105; +pub const B1500000: crate::speed_t = 4106; +pub const B2000000: crate::speed_t = 4107; +pub const B2500000: crate::speed_t = 4108; +pub const B3000000: crate::speed_t = 4109; +pub const B3500000: crate::speed_t = 4110; +pub const B4000000: crate::speed_t = 4111; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: crate::tcflag_t = 32768; +pub const TOSTOP: crate::tcflag_t = 256; +pub const FLUSHO: crate::tcflag_t = 4096; +pub const EXTPROC: crate::tcflag_t = 65536; + +pub const SYS_read: c_long = 63; +pub const SYS_write: c_long = 64; +pub const SYS_close: c_long = 57; +// RISC-V don't have SYS_fstat, use statx instead. +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_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; +// RISC-V don't have wait4, use waitid instead. +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; +// RISC-V don't have gettimeofday, use clock_gettime64 instead. +// RISC-V don't have getrlimit, use prlimit64 instead. +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_time64: c_long = 421; +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_time64: c_long = 423; +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; +// RISC-V don't have setrlimit, use prlimit64 instead. +pub const SYS_chroot: c_long = 51; +pub const SYS_sync: c_long = 81; +pub const SYS_acct: c_long = 89; +// RISC-V don't have settimeofday, use clock_settime64 instead. +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_time64: c_long = 422; +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_pgetevents_time64: c_long = 416; +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_time64: c_long = 420; +pub const SYS_fadvise64: c_long = 223; +pub const SYS_timer_create: c_long = 107; +pub const SYS_timer_settime64: c_long = 409; +pub const SYS_timer_gettime64: c_long = 408; +pub const SYS_timer_getoverrun: c_long = 109; +pub const SYS_timer_delete: c_long = 111; +pub const SYS_clock_settime64: c_long = 404; +pub const SYS_clock_gettime64: c_long = 403; +pub const SYS_clock_getres_time64: c_long = 406; +pub const SYS_clock_nanosleep_time64: c_long = 407; +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_time64: c_long = 418; +pub const SYS_mq_timedreceive_time64: c_long = 419; +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; +// RISC-V don't have newfstatat, use statx instead. +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_time64: c_long = 413; +pub const SYS_ppoll_time64: c_long = 414; +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_time64: c_long = 412; +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_settime64: c_long = 411; +pub const SYS_timerfd_gettime64: c_long = 410; +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_time64: c_long = 417; +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_adjtime64: c_long = 405; +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; + +// Plain syscalls aliased to their time64 variants +pub const SYS_clock_gettime: c_long = SYS_clock_gettime64; +pub const SYS_clock_settime: c_long = SYS_clock_settime64; +pub const SYS_clock_adjtime: c_long = SYS_clock_adjtime64; +pub const SYS_clock_getres: c_long = SYS_clock_getres_time64; +pub const SYS_clock_nanosleep: c_long = SYS_clock_nanosleep_time64; +pub const SYS_timer_gettime: c_long = SYS_timer_gettime64; +pub const SYS_timer_settime: c_long = SYS_timer_settime64; +pub const SYS_timerfd_gettime: c_long = SYS_timerfd_gettime64; +pub const SYS_timerfd_settime: c_long = SYS_timerfd_settime64; +pub const SYS_utimensat: c_long = SYS_utimensat_time64; +pub const SYS_pselect6: c_long = SYS_pselect6_time64; +pub const SYS_ppoll: c_long = SYS_ppoll_time64; +pub const SYS_recvmmsg: c_long = SYS_recvmmsg_time64; +pub const SYS_mq_timedsend: c_long = SYS_mq_timedsend_time64; +pub const SYS_mq_timedreceive: c_long = SYS_mq_timedreceive_time64; +pub const SYS_rt_sigtimedwait: c_long = SYS_rt_sigtimedwait_time64; +pub const SYS_futex: c_long = SYS_futex_time64; +pub const SYS_sched_rr_get_interval: c_long = SYS_sched_rr_get_interval_time64; 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..1a34807 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/mod.rs @@ -0,0 +1,878 @@ +use crate::off_t; +use crate::prelude::*; + +pub type wchar_t = i32; + +pub type stat64 = stat; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + __st_dev_padding: Padding, + __st_ino_truncated: c_long, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __st_rdev_padding: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + + #[cfg(musl32_time64)] + __st_atim32: Padding<__c_anonymous_timespec32>, + #[cfg(musl32_time64)] + __st_mtim32: Padding<__c_anonymous_timespec32>, + #[cfg(musl32_time64)] + __st_ctim32: Padding<__c_anonymous_timespec32>, + + #[cfg(musl_v1_2_3)] + pub st_ino: crate::ino_t, + + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + #[cfg(musl32_time64)] + __pad0: Padding, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + #[cfg(musl32_time64)] + __pad1: Padding, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + #[cfg(musl32_time64)] + __pad2: Padding, + + #[cfg(not(musl_v1_2_3))] + pub st_ino: crate::ino_t, + } + + struct __c_anonymous_timespec32 { + __tv_sec: c_long, + __tv_nsec: c_long, + } + + pub struct mcontext_t { + __private: [u32; 22], + } + + pub struct stack_t { + pub ss_sp: *mut c_void, + pub ss_flags: c_int, + pub ss_size: size_t, + } + + pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: c_int, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + + #[cfg(musl32_time64)] + __shm_atime_lo: c_ulong, + #[cfg(musl32_time64)] + __shm_atime_hi: c_ulong, + #[cfg(musl32_time64)] + __shm_dtime_lo: c_ulong, + #[cfg(musl32_time64)] + __shm_dtime_hi: c_ulong, + #[cfg(musl32_time64)] + __msg_ctime_lo: c_ulong, + #[cfg(musl32_time64)] + __msg_ctime_hi: c_ulong, + + #[cfg(not(musl32_time64))] + pub shm_atime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused1: Padding, + #[cfg(not(musl32_time64))] + pub shm_dtime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused2: Padding, + #[cfg(not(musl32_time64))] + pub shm_ctime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused3: Padding, + + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: c_ulong, + __pad1: Padding, + __pad2: Padding, + + #[cfg(musl32_time64)] + __pad3: c_ulong, + #[cfg(musl32_time64)] + shm_atime: crate::time_t, + #[cfg(musl32_time64)] + shm_dtime: crate::time_t, + #[cfg(musl32_time64)] + shm_ctime: crate::time_t, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + + #[cfg(musl32_time64)] + __msg_stime_lo: c_ulong, + #[cfg(musl32_time64)] + __msg_stime_hi: c_ulong, + #[cfg(musl32_time64)] + __msg_rtime_lo: c_ulong, + #[cfg(musl32_time64)] + __msg_rtime_hi: c_ulong, + #[cfg(musl32_time64)] + __msg_ctime_lo: c_ulong, + #[cfg(musl32_time64)] + __msg_ctime_hi: c_ulong, + + #[cfg(not(musl32_time64))] + pub msg_stime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused1: Padding, + #[cfg(not(musl32_time64))] + pub msg_rtime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused2: Padding, + #[cfg(not(musl32_time64))] + pub msg_ctime: crate::time_t, + #[cfg(not(musl32_time64))] + __unused3: Padding, + + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __pad1: Padding, + __pad2: Padding, + + #[cfg(musl32_time64)] + pub msg_stime: crate::time_t, + #[cfg(musl32_time64)] + pub msg_rtime: crate::time_t, + #[cfg(musl32_time64)] + pub msg_ctime: crate::time_t, + } + + 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: Padding, + pub st_space: [c_long; 32], + pub xmm_space: [c_long; 32], + padding: Padding<[c_long; 56]>, + } + + pub struct ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: crate::sigset_t, + __private: [u8; 112], + } +} + +s_no_extra_traits! { + #[repr(align(8))] + pub struct max_align_t { + priv_: [f64; 3], + } +} + +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: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::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 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: crate::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: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 127; +pub const SYS_init_module: c_long = 128; +pub const SYS_delete_module: c_long = 129; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; 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..04bbb8d --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs @@ -0,0 +1,689 @@ +use crate::off_t; +use crate::prelude::*; + +pub type wchar_t = u32; +pub type nlink_t = u32; +pub type blksize_t = c_int; + +pub type stat64 = stat; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad0: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + __pad1: Padding, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[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 { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + + #[cfg(musl_v1_2_3)] + pub __seq: c_int, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "The type of this field has changed from c_ushort to c_int, + we'll follow that change in the future release." + )] + pub __seq: c_ushort, + __unused1: Padding, + __unused2: Padding, + } + + pub struct ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_sigmask: crate::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: Padding<[u64; 512]>, + } + + #[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, + } + + pub struct user_fpsimd_struct { + pub vregs: [u128; 32], + pub fpsr: u32, + pub fpcr: u32, + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f32; 8], + } +} + +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 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_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_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_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_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_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: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; + +pub const EDEADLK: c_int = 35; +pub const EDEADLOCK: c_int = EDEADLK; + +pub const EXTPROC: crate::tcflag_t = 0x00010000; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::tcflag_t = 0x00001000; 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..27853cd --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/loongarch64/mod.rs @@ -0,0 +1,641 @@ +//! LoongArch-specific definitions for 64-bit linux-like values + +use crate::off_t; +use crate::prelude::*; + +pub type wchar_t = c_int; + +pub type nlink_t = c_uint; +pub type blksize_t = c_int; + +pub type stat64 = stat; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad1: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + __pad2: Padding, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_int; 2usize]>, + } + + pub struct ipc_perm { + pub __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_uint, + pub __seq: c_int, + __unused1: Padding, + __unused2: Padding, + } + + 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 struct ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_sigmask: crate::sigset_t, + pub uc_mcontext: mcontext_t, + } + + #[repr(align(16))] + pub struct mcontext_t { + pub __pc: c_ulong, + pub __gregs: [c_ulong; 32], + pub __flags: c_uint, + pub __extcontext: [c_ulong; 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, + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4], + } +} + +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 = 0o0100000; +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 = 0o20000; + +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 MADV_SOFT_OFFLINE: c_int = 101; + +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 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: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; + +pub const EDEADLK: c_int = 35; +pub const EDEADLOCK: c_int = EDEADLK; +pub const EXTPROC: crate::tcflag_t = 0x00010000; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::tcflag_t = 0x00001000; 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..dc59d58 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs @@ -0,0 +1,681 @@ +use crate::off_t; +use crate::prelude::*; + +pub type wchar_t = i32; +pub type nlink_t = c_uint; +pub type blksize_t = i64; + +pub type stat64 = stat; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + __pad1: Padding<[c_int; 3]>, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad2: Padding<[c_uint; 2]>, + pub st_size: off_t, + __pad3: Padding, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_blksize: crate::blksize_t, + __pad4: Padding, + pub st_blocks: crate::blkcnt_t, + __pad5: Padding<[c_int; 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 { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: c_int, + __pad1: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct statfs { + pub f_type: c_ulong, + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_fsid: crate::fsid_t, + pub f_namelen: 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_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt64_t, + pub f_bfree: crate::fsblkcnt64_t, + pub f_files: crate::fsfilcnt64_t, + pub f_ffree: crate::fsfilcnt64_t, + pub f_bavail: crate::fsblkcnt64_t, + pub f_fsid: crate::fsid_t, + pub f_namelen: c_ulong, + pub f_flags: c_ulong, + pub f_spare: [c_ulong; 5], + } +} + +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_get_kernel_syms: c_long = 5000 + 170; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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 SA_ONSTACK: c_int = 0x08000000; +pub const SA_SIGINFO: c_int = 0x00000008; +pub const SA_NOCLDWAIT: c_int = 0x00010000; + +pub const SIGEMT: c_int = 7; +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: crate::tcflag_t = 0x00000100; +pub const TOSTOP: crate::tcflag_t = 0x00008000; +pub const FLUSHO: crate::tcflag_t = 0x00002000; +pub const EXTPROC: crate::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: crate::tcflag_t = 0o0010017; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const FF1: crate::tcflag_t = 0x00008000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const VT1: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::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..6365dbe --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/mod.rs @@ -0,0 +1,88 @@ +use crate::prelude::*; + +pub type regoff_t = c_long; + +s! { + // MIPS implementation is special, see the subfolder. + #[cfg(not(target_arch = "mips64"))] + 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], + } + + // PowerPC implementation is special, see the subfolder. + #[cfg(not(target_arch = "powerpc64"))] + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: c_ulong, + __pad1: Padding, + __pad2: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + pub msg_stime: crate::time_t, + pub msg_rtime: crate::time_t, + pub msg_ctime: crate::time_t, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __pad1: Padding, + __pad2: Padding, + } + + pub struct sem_t { + __val: [c_int; 8], + } +} + +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + +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 if #[cfg(any(target_arch = "wasm32"))] { + mod wasm32; + pub use self::wasm32::*; + } 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..32c3807 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs @@ -0,0 +1,728 @@ +use crate::off_t; +use crate::prelude::*; + +pub type wchar_t = i32; +pub type nlink_t = u64; +pub type blksize_t = c_long; + +pub type stat64 = stat; + +s! { + pub struct termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_cc: [crate::cc_t; crate::NCCS], + pub c_line: crate::cc_t, + pub __c_ispeed: crate::speed_t, + pub __c_ospeed: crate::speed_t, + } + + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + __pad0: Padding, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_long; 3]>, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_segsz: size_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: c_ulong, + __unused: Padding<[c_ulong; 2]>, + } + + pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: c_int, + __unused1: Padding, + __unused2: Padding, + } +} + +pub const MADV_SOFT_OFFLINE: c_int = 101; +#[deprecated( + since = "0.2.175", + note = "Linux does not define MAP_32BIT on any architectures \ + other than x86 and x86_64, this constant will be removed in the future" +)] +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 = 0x80; +pub const MAP_NORESERVE: c_int = 0x40; +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 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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 127; +pub const SYS_init_module: c_long = 128; +pub const SYS_delete_module: c_long = 129; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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_pkey_alloc: c_long = 384; +pub const SYS_pkey_free: c_long = 385; +pub const SYS_pkey_mprotect: c_long = 386; +pub const SYS_rseq: c_long = 387; +pub const SYS_io_pgetevents: c_long = 388; +pub const SYS_semtimedop: c_long = 392; +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_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 = 35; +pub const EDEADLOCK: c_int = 58; + +pub const EXTPROC: crate::tcflag_t = 0x10000000; +pub const VEOL: usize = 6; +pub const VEOL2: usize = 8; +pub const VMIN: usize = 5; +pub const IEXTEN: crate::tcflag_t = 0x00000400; +pub const TOSTOP: crate::tcflag_t = 0x00400000; +pub const FLUSHO: crate::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: crate::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: crate::tcflag_t = 0x00000200; +pub const IXOFF: crate::tcflag_t = 0x00000400; +pub const ONLCR: crate::tcflag_t = 0x2; +pub const CSIZE: crate::tcflag_t = 0x00000300; + +pub const CS6: crate::tcflag_t = 0x00000100; +pub const CS7: crate::tcflag_t = 0x00000200; +pub const CS8: crate::tcflag_t = 0x00000300; +pub const CSTOPB: crate::tcflag_t = 0x00000400; +pub const CREAD: crate::tcflag_t = 0x00000800; +pub const PARENB: crate::tcflag_t = 0x00001000; +pub const PARODD: crate::tcflag_t = 0x00002000; +pub const HUPCL: crate::tcflag_t = 0x00004000; +pub const CLOCAL: crate::tcflag_t = 0x00008000; +pub const ECHOKE: crate::tcflag_t = 0x00000001; +pub const ECHOE: crate::tcflag_t = 0x00000002; +pub const ECHOK: crate::tcflag_t = 0x00000004; +pub const ECHONL: crate::tcflag_t = 0x00000010; +pub const ECHOPRT: crate::tcflag_t = 0x00000020; +pub const ECHOCTL: crate::tcflag_t = 0x00000040; +pub const ISIG: crate::tcflag_t = 0x00000080; +pub const ICANON: crate::tcflag_t = 0x00000100; +pub const PENDIN: crate::tcflag_t = 0x20000000; +pub const NOFLSH: crate::tcflag_t = 0x80000000; + +pub const CIBAUD: crate::tcflag_t = 0o77600000; +pub const CBAUDEX: crate::tcflag_t = 0o0000020; +pub const VSWTC: usize = 9; +pub const OLCUC: crate::tcflag_t = 0o000004; +pub const NLDLY: crate::tcflag_t = 0o0001400; +pub const CRDLY: crate::tcflag_t = 0o0030000; +pub const TABDLY: crate::tcflag_t = 0o0006000; +pub const BSDLY: crate::tcflag_t = 0o0100000; +pub const FFDLY: crate::tcflag_t = 0o0040000; +pub const VTDLY: crate::tcflag_t = 0o0200000; +pub const XTABS: crate::tcflag_t = 0o00006000; + +pub const B57600: crate::speed_t = 0o00020; +pub const B115200: crate::speed_t = 0o00021; +pub const B230400: crate::speed_t = 0o00022; +pub const B460800: crate::speed_t = 0o00023; +pub const B500000: crate::speed_t = 0o00024; +pub const B576000: crate::speed_t = 0o00025; +pub const B921600: crate::speed_t = 0o00026; +pub const B1000000: crate::speed_t = 0o00027; +pub const B1152000: crate::speed_t = 0o00030; +pub const B1500000: crate::speed_t = 0o00031; +pub const B2000000: crate::speed_t = 0o00032; +pub const B2500000: crate::speed_t = 0o00033; +pub const B3000000: crate::speed_t = 0o00034; +pub const B3500000: crate::speed_t = 0o00035; +pub const B4000000: crate::speed_t = 0o00036; 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..4baced6 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs @@ -0,0 +1,647 @@ +//! RISC-V-specific definitions for 64-bit linux-like values + +use crate::off_t; +use crate::prelude::*; + +pub type wchar_t = c_int; + +pub type nlink_t = c_uint; +pub type blksize_t = c_int; + +pub type stat64 = stat; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + __pad1: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + __pad2: Padding, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_int; 2usize]>, + } + + pub struct ipc_perm { + pub __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_ushort, + __pad1: Padding, + pub __seq: c_ushort, + __pad2: Padding, + __unused1: Padding, + __unused2: Padding, + } + + #[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, + } +} + +s_no_extra_traits! { + pub struct ucontext_t { + pub __uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_sigmask: crate::sigset_t, + pub uc_mcontext: mcontext_t, + } + + #[repr(align(16))] + pub struct mcontext_t { + pub __gregs: [c_ulong; 32], + pub __fpregs: __riscv_mc_fp_state, + } + + 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, + } + + pub struct __riscv_mc_f_ext_state { + pub __f: [c_uint; 32], + pub __fcsr: c_uint, + } + + pub struct __riscv_mc_d_ext_state { + pub __f: [c_ulonglong; 32], + pub __fcsr: c_uint, + } + + #[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], + } +} + +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_io_pgetevents: c_long = 292; +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_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 = 0o100000; +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 MADV_SOFT_OFFLINE: c_int = 101; +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: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; + +pub const EDEADLK: c_int = 35; +pub const EDEADLOCK: c_int = EDEADLK; +pub const EXTPROC: crate::tcflag_t = 0x00010000; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::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; 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..3291acc --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs @@ -0,0 +1,732 @@ +use crate::off_t; +use crate::prelude::*; + +pub type blksize_t = i64; +pub type nlink_t = u64; +pub type wchar_t = i32; +pub type greg_t = u64; +pub type statfs64 = statfs; +pub type stat64 = stat; + +s! { + pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: c_int, + __pad1: Padding, + __pad2: Padding, + } + + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + __unused: Padding<[c_long; 3]>, + } + + pub struct statfs { + pub f_type: c_uint, + pub f_bsize: c_uint, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::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 __psw_t { + pub mask: c_ulong, + pub addr: c_ulong, + } + + pub struct fpregset_t { + pub fpc: c_uint, + pub fprs: [fpreg_t; 16], + } + + pub struct mcontext_t { + pub psw: __psw_t, + pub gregs: [c_ulong; 16], + pub aregs: [c_uint; 16], + pub fpregs: fpregset_t, + } + + pub struct ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: crate::sigset_t, + } +} + +s_no_extra_traits! { + pub union fpreg_t { + pub d: c_double, + pub f: c_float, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for fpreg_t { + fn eq(&self, _other: &fpreg_t) -> bool { + unimplemented!("traits") + } + } + + impl Eq for fpreg_t {} + + impl hash::Hash for fpreg_t { + fn hash(&self, _state: &mut H) { + unimplemented!("traits") + } + } + } +} + +pub const VEOF: usize = 4; + +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 = 10240; +pub const MINSIGSTKSZ: size_t = 4096; +pub const SIG_SETMASK: 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_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: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::tcflag_t = 0x00001000; + +pub const EXTPROC: crate::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: crate::tcflag_t = 0o000002; +pub const ONLCR: crate::tcflag_t = 0o000004; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const FF1: crate::tcflag_t = 0x00008000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const VT1: crate::tcflag_t = 0x00004000; +pub const XTABS: crate::tcflag_t = 0o014000; + +pub const CBAUD: crate::speed_t = 0o010017; +pub const CSIZE: crate::tcflag_t = 0o000060; +pub const CS6: crate::tcflag_t = 0o000020; +pub const CS7: crate::tcflag_t = 0o000040; +pub const CS8: crate::tcflag_t = 0o000060; +pub const CSTOPB: crate::tcflag_t = 0o000100; +pub const CREAD: crate::tcflag_t = 0o000200; +pub const PARENB: crate::tcflag_t = 0o000400; +pub const PARODD: crate::tcflag_t = 0o001000; +pub const HUPCL: crate::tcflag_t = 0o002000; +pub const CLOCAL: crate::tcflag_t = 0o004000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; + +pub const ISIG: crate::tcflag_t = 0o000001; +pub const ICANON: crate::tcflag_t = 0o000002; +pub const ECHOE: crate::tcflag_t = 0o000020; +pub const ECHOK: crate::tcflag_t = 0o000040; +pub const ECHONL: crate::tcflag_t = 0o000100; +pub const NOFLSH: crate::tcflag_t = 0o000200; +pub const ECHOCTL: crate::tcflag_t = 0o001000; +pub const ECHOPRT: crate::tcflag_t = 0o002000; +pub const ECHOKE: crate::tcflag_t = 0o004000; +pub const PENDIN: crate::tcflag_t = 0o040000; + +pub const POLLWRNORM: c_short = 0x100; +pub const POLLWRBAND: c_short = 0x200; + +pub const IXON: crate::tcflag_t = 0o002000; +pub const IXOFF: crate::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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 127; +pub const SYS_init_module: c_long = 128; +pub const SYS_delete_module: c_long = 129; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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_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: c_long = 161; +pub const SYS_nanosleep: c_long = 162; +pub const SYS_mremap: c_long = 163; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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_getrlimit: c_long = 191; +pub const SYS_lchown: 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_chown: 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_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_newfstatat: 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: 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_s390_guarded_storage: c_long = 378; +pub const SYS_statx: c_long = 379; +pub const SYS_s390_sthyi: c_long = 380; +pub const SYS_kexec_file_load: c_long = 381; +pub const SYS_io_pgetevents: c_long = 382; +pub const SYS_rseq: c_long = 383; +pub const SYS_pkey_mprotect: c_long = 384; +pub const SYS_pkey_alloc: c_long = 385; +pub const SYS_pkey_free: c_long = 386; +pub const SYS_semtimedop: c_long = 392; +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_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 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_cachestat: c_long = 451; +pub const SYS_fchmodat2: c_long = 452; +pub const SYS_mseal: c_long = 462; diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/wasm32/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/wasm32/mod.rs new file mode 100644 index 0000000..7064a13 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/wasm32/mod.rs @@ -0,0 +1,664 @@ +//! Wasm32 definitions conforming to the WALI ABI. +//! The WALI ABI closely mirrors `x86_64` Linux and is thus implemented within the `b64` module as opposed to `b32` +use crate::off_t; +use crate::prelude::*; + +pub type wchar_t = i32; +pub type nlink_t = u64; +pub type blksize_t = c_long; + +pub type stat64 = stat; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + __pad0: Padding, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused: Padding<[c_long; 3]>, + } + + pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: c_int, + __unused1: Padding, + __unused2: Padding, + } +} + +// 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_io_pgetevents: c_long = 333; +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; + +// Syscall aliases for WALI +pub const SYS_fadvise: c_long = SYS_fadvise64; + +pub const MADV_SOFT_OFFLINE: c_int = 101; +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 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: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; + +pub const EDEADLK: c_int = 35; +pub const EDEADLOCK: c_int = EDEADLK; + +pub const EXTPROC: crate::tcflag_t = 0x00010000; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::tcflag_t = 0x00001000; + +cfg_if! { + if #[cfg(all(target_family = "wasm", target_env = "musl"))] { + mod wali; + pub use self::wali::*; + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/wasm32/wali.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/wasm32/wali.rs new file mode 100644 index 0000000..f347e8a --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/wasm32/wali.rs @@ -0,0 +1,441 @@ +//! WebAssembly Linux Interface syscall specification + +use crate::prelude::*; + +// --- Autogenerated from WALI/scripts/autogen.py --- +#[link(wasm_import_module = "wali")] +extern "C" { + /* 0 */ + #[link_name = "SYS_read"] + pub fn __syscall_SYS_read(a1: i32, a2: i32, a3: u32) -> c_long; + /* 1 */ + #[link_name = "SYS_write"] + pub fn __syscall_SYS_write(a1: i32, a2: i32, a3: u32) -> c_long; + /* 2 */ + #[link_name = "SYS_open"] + pub fn __syscall_SYS_open(a1: i32, a2: i32, a3: i32) -> c_long; + /* 3 */ + #[link_name = "SYS_close"] + pub fn __syscall_SYS_close(a1: i32) -> c_long; + /* 4 */ + #[link_name = "SYS_stat"] + pub fn __syscall_SYS_stat(a1: i32, a2: i32) -> c_long; + /* 5 */ + #[link_name = "SYS_fstat"] + pub fn __syscall_SYS_fstat(a1: i32, a2: i32) -> c_long; + /* 6 */ + #[link_name = "SYS_lstat"] + pub fn __syscall_SYS_lstat(a1: i32, a2: i32) -> c_long; + /* 7 */ + #[link_name = "SYS_poll"] + pub fn __syscall_SYS_poll(a1: i32, a2: u32, a3: i32) -> c_long; + /* 8 */ + #[link_name = "SYS_lseek"] + pub fn __syscall_SYS_lseek(a1: i32, a2: i64, a3: i32) -> c_long; + /* 9 */ + #[link_name = "SYS_mmap"] + pub fn __syscall_SYS_mmap(a1: i32, a2: u32, a3: i32, a4: i32, a5: i32, a6: i64) -> c_long; + /* 10 */ + #[link_name = "SYS_mprotect"] + pub fn __syscall_SYS_mprotect(a1: i32, a2: u32, a3: i32) -> c_long; + /* 11 */ + #[link_name = "SYS_munmap"] + pub fn __syscall_SYS_munmap(a1: i32, a2: u32) -> c_long; + /* 12 */ + #[link_name = "SYS_brk"] + pub fn __syscall_SYS_brk(a1: i32) -> c_long; + /* 13 */ + #[link_name = "SYS_rt_sigaction"] + pub fn __syscall_SYS_rt_sigaction(a1: i32, a2: i32, a3: i32, a4: u32) -> c_long; + /* 14 */ + #[link_name = "SYS_rt_sigprocmask"] + pub fn __syscall_SYS_rt_sigprocmask(a1: i32, a2: i32, a3: i32, a4: u32) -> c_long; + /* 15 */ + #[link_name = "SYS_rt_sigreturn"] + pub fn __syscall_SYS_rt_sigreturn(a1: i64) -> c_long; + /* 16 */ + #[link_name = "SYS_ioctl"] + pub fn __syscall_SYS_ioctl(a1: i32, a2: i32, a3: i32) -> c_long; + /* 17 */ + #[link_name = "SYS_pread64"] + pub fn __syscall_SYS_pread64(a1: i32, a2: i32, a3: u32, a4: i64) -> c_long; + /* 18 */ + #[link_name = "SYS_pwrite64"] + pub fn __syscall_SYS_pwrite64(a1: i32, a2: i32, a3: u32, a4: i64) -> c_long; + /* 19 */ + #[link_name = "SYS_readv"] + pub fn __syscall_SYS_readv(a1: i32, a2: i32, a3: i32) -> c_long; + /* 20 */ + #[link_name = "SYS_writev"] + pub fn __syscall_SYS_writev(a1: i32, a2: i32, a3: i32) -> c_long; + /* 21 */ + #[link_name = "SYS_access"] + pub fn __syscall_SYS_access(a1: i32, a2: i32) -> c_long; + /* 22 */ + #[link_name = "SYS_pipe"] + pub fn __syscall_SYS_pipe(a1: i32) -> c_long; + /* 23 */ + #[link_name = "SYS_select"] + pub fn __syscall_SYS_select(a1: i32, a2: i32, a3: i32, a4: i32, a5: i32) -> c_long; + /* 24 */ + #[link_name = "SYS_sched_yield"] + pub fn __syscall_SYS_sched_yield() -> c_long; + /* 25 */ + #[link_name = "SYS_mremap"] + pub fn __syscall_SYS_mremap(a1: i32, a2: u32, a3: u32, a4: i32, a5: i32) -> c_long; + /* 26 */ + #[link_name = "SYS_msync"] + pub fn __syscall_SYS_msync(a1: i32, a2: u32, a3: i32) -> c_long; + /* 28 */ + #[link_name = "SYS_madvise"] + pub fn __syscall_SYS_madvise(a1: i32, a2: u32, a3: i32) -> c_long; + /* 32 */ + #[link_name = "SYS_dup"] + pub fn __syscall_SYS_dup(a1: i32) -> c_long; + /* 33 */ + #[link_name = "SYS_dup2"] + pub fn __syscall_SYS_dup2(a1: i32, a2: i32) -> c_long; + /* 35 */ + #[link_name = "SYS_nanosleep"] + pub fn __syscall_SYS_nanosleep(a1: i32, a2: i32) -> c_long; + /* 37 */ + #[link_name = "SYS_alarm"] + pub fn __syscall_SYS_alarm(a1: i32) -> c_long; + /* 38 */ + #[link_name = "SYS_setitimer"] + pub fn __syscall_SYS_setitimer(a1: i32, a2: i32, a3: i32) -> c_long; + /* 39 */ + #[link_name = "SYS_getpid"] + pub fn __syscall_SYS_getpid() -> c_long; + /* 41 */ + #[link_name = "SYS_socket"] + pub fn __syscall_SYS_socket(a1: i32, a2: i32, a3: i32) -> c_long; + /* 42 */ + #[link_name = "SYS_connect"] + pub fn __syscall_SYS_connect(a1: i32, a2: i32, a3: u32) -> c_long; + /* 43 */ + #[link_name = "SYS_accept"] + pub fn __syscall_SYS_accept(a1: i32, a2: i32, a3: i32) -> c_long; + /* 44 */ + #[link_name = "SYS_sendto"] + pub fn __syscall_SYS_sendto(a1: i32, a2: i32, a3: u32, a4: i32, a5: i32, a6: u32) -> c_long; + /* 45 */ + #[link_name = "SYS_recvfrom"] + pub fn __syscall_SYS_recvfrom(a1: i32, a2: i32, a3: u32, a4: i32, a5: i32, a6: i32) -> c_long; + /* 46 */ + #[link_name = "SYS_sendmsg"] + pub fn __syscall_SYS_sendmsg(a1: i32, a2: i32, a3: i32) -> c_long; + /* 47 */ + #[link_name = "SYS_recvmsg"] + pub fn __syscall_SYS_recvmsg(a1: i32, a2: i32, a3: i32) -> c_long; + /* 48 */ + #[link_name = "SYS_shutdown"] + pub fn __syscall_SYS_shutdown(a1: i32, a2: i32) -> c_long; + /* 49 */ + #[link_name = "SYS_bind"] + pub fn __syscall_SYS_bind(a1: i32, a2: i32, a3: u32) -> c_long; + /* 50 */ + #[link_name = "SYS_listen"] + pub fn __syscall_SYS_listen(a1: i32, a2: i32) -> c_long; + /* 51 */ + #[link_name = "SYS_getsockname"] + pub fn __syscall_SYS_getsockname(a1: i32, a2: i32, a3: i32) -> c_long; + /* 52 */ + #[link_name = "SYS_getpeername"] + pub fn __syscall_SYS_getpeername(a1: i32, a2: i32, a3: i32) -> c_long; + /* 53 */ + #[link_name = "SYS_socketpair"] + pub fn __syscall_SYS_socketpair(a1: i32, a2: i32, a3: i32, a4: i32) -> c_long; + /* 54 */ + #[link_name = "SYS_setsockopt"] + pub fn __syscall_SYS_setsockopt(a1: i32, a2: i32, a3: i32, a4: i32, a5: u32) -> c_long; + /* 55 */ + #[link_name = "SYS_getsockopt"] + pub fn __syscall_SYS_getsockopt(a1: i32, a2: i32, a3: i32, a4: i32, a5: i32) -> c_long; + /* 57 */ + #[link_name = "SYS_fork"] + pub fn __syscall_SYS_fork() -> c_long; + /* 59 */ + #[link_name = "SYS_execve"] + pub fn __syscall_SYS_execve(a1: i32, a2: i32, a3: i32) -> c_long; + /* 60 */ + #[link_name = "SYS_exit"] + pub fn __syscall_SYS_exit(a1: i32) -> c_long; + /* 61 */ + #[link_name = "SYS_wait4"] + pub fn __syscall_SYS_wait4(a1: i32, a2: i32, a3: i32, a4: i32) -> c_long; + /* 62 */ + #[link_name = "SYS_kill"] + pub fn __syscall_SYS_kill(a1: i32, a2: i32) -> c_long; + /* 63 */ + #[link_name = "SYS_uname"] + pub fn __syscall_SYS_uname(a1: i32) -> c_long; + /* 72 */ + #[link_name = "SYS_fcntl"] + pub fn __syscall_SYS_fcntl(a1: i32, a2: i32, a3: i32) -> c_long; + /* 73 */ + #[link_name = "SYS_flock"] + pub fn __syscall_SYS_flock(a1: i32, a2: i32) -> c_long; + /* 74 */ + #[link_name = "SYS_fsync"] + pub fn __syscall_SYS_fsync(a1: i32) -> c_long; + /* 75 */ + #[link_name = "SYS_fdatasync"] + pub fn __syscall_SYS_fdatasync(a1: i32) -> c_long; + /* 77 */ + #[link_name = "SYS_ftruncate"] + pub fn __syscall_SYS_ftruncate(a1: i32, a2: i64) -> c_long; + /* 78 */ + #[link_name = "SYS_getdents"] + pub fn __syscall_SYS_getdents(a1: i32, a2: i32, a3: i32) -> c_long; + /* 79 */ + #[link_name = "SYS_getcwd"] + pub fn __syscall_SYS_getcwd(a1: i32, a2: u32) -> c_long; + /* 80 */ + #[link_name = "SYS_chdir"] + pub fn __syscall_SYS_chdir(a1: i32) -> c_long; + /* 81 */ + #[link_name = "SYS_fchdir"] + pub fn __syscall_SYS_fchdir(a1: i32) -> c_long; + /* 82 */ + #[link_name = "SYS_rename"] + pub fn __syscall_SYS_rename(a1: i32, a2: i32) -> c_long; + /* 83 */ + #[link_name = "SYS_mkdir"] + pub fn __syscall_SYS_mkdir(a1: i32, a2: i32) -> c_long; + /* 84 */ + #[link_name = "SYS_rmdir"] + pub fn __syscall_SYS_rmdir(a1: i32) -> c_long; + /* 86 */ + #[link_name = "SYS_link"] + pub fn __syscall_SYS_link(a1: i32, a2: i32) -> c_long; + /* 87 */ + #[link_name = "SYS_unlink"] + pub fn __syscall_SYS_unlink(a1: i32) -> c_long; + /* 88 */ + #[link_name = "SYS_symlink"] + pub fn __syscall_SYS_symlink(a1: i32, a2: i32) -> c_long; + /* 89 */ + #[link_name = "SYS_readlink"] + pub fn __syscall_SYS_readlink(a1: i32, a2: i32, a3: u32) -> c_long; + /* 90 */ + #[link_name = "SYS_chmod"] + pub fn __syscall_SYS_chmod(a1: i32, a2: i32) -> c_long; + /* 91 */ + #[link_name = "SYS_fchmod"] + pub fn __syscall_SYS_fchmod(a1: i32, a2: i32) -> c_long; + /* 92 */ + #[link_name = "SYS_chown"] + pub fn __syscall_SYS_chown(a1: i32, a2: i32, a3: i32) -> c_long; + /* 93 */ + #[link_name = "SYS_fchown"] + pub fn __syscall_SYS_fchown(a1: i32, a2: i32, a3: i32) -> c_long; + /* 95 */ + #[link_name = "SYS_umask"] + pub fn __syscall_SYS_umask(a1: i32) -> c_long; + /* 97 */ + #[link_name = "SYS_getrlimit"] + pub fn __syscall_SYS_getrlimit(a1: i32, a2: i32) -> c_long; + /* 98 */ + #[link_name = "SYS_getrusage"] + pub fn __syscall_SYS_getrusage(a1: i32, a2: i32) -> c_long; + /* 99 */ + #[link_name = "SYS_sysinfo"] + pub fn __syscall_SYS_sysinfo(a1: i32) -> c_long; + /* 102 */ + #[link_name = "SYS_getuid"] + pub fn __syscall_SYS_getuid() -> c_long; + /* 104 */ + #[link_name = "SYS_getgid"] + pub fn __syscall_SYS_getgid() -> c_long; + /* 105 */ + #[link_name = "SYS_setuid"] + pub fn __syscall_SYS_setuid(a1: i32) -> c_long; + /* 106 */ + #[link_name = "SYS_setgid"] + pub fn __syscall_SYS_setgid(a1: i32) -> c_long; + /* 107 */ + #[link_name = "SYS_geteuid"] + pub fn __syscall_SYS_geteuid() -> c_long; + /* 108 */ + #[link_name = "SYS_getegid"] + pub fn __syscall_SYS_getegid() -> c_long; + /* 109 */ + #[link_name = "SYS_setpgid"] + pub fn __syscall_SYS_setpgid(a1: i32, a2: i32) -> c_long; + /* 110 */ + #[link_name = "SYS_getppid"] + pub fn __syscall_SYS_getppid() -> c_long; + /* 112 */ + #[link_name = "SYS_setsid"] + pub fn __syscall_SYS_setsid() -> c_long; + /* 113 */ + #[link_name = "SYS_setreuid"] + pub fn __syscall_SYS_setreuid(a1: i32, a2: i32) -> c_long; + /* 114 */ + #[link_name = "SYS_setregid"] + pub fn __syscall_SYS_setregid(a1: i32, a2: i32) -> c_long; + /* 115 */ + #[link_name = "SYS_getgroups"] + pub fn __syscall_SYS_getgroups(a1: u32, a2: i32) -> c_long; + /* 116 */ + #[link_name = "SYS_setgroups"] + pub fn __syscall_SYS_setgroups(a1: u32, a2: i32) -> c_long; + /* 117 */ + #[link_name = "SYS_setresuid"] + pub fn __syscall_SYS_setresuid(a1: i32, a2: i32, a3: i32) -> c_long; + /* 119 */ + #[link_name = "SYS_setresgid"] + pub fn __syscall_SYS_setresgid(a1: i32, a2: i32, a3: i32) -> c_long; + /* 121 */ + #[link_name = "SYS_getpgid"] + pub fn __syscall_SYS_getpgid(a1: i32) -> c_long; + /* 124 */ + #[link_name = "SYS_getsid"] + pub fn __syscall_SYS_getsid(a1: i32) -> c_long; + /* 127 */ + #[link_name = "SYS_rt_sigpending"] + pub fn __syscall_SYS_rt_sigpending(a1: i32, a2: u32) -> c_long; + /* 130 */ + #[link_name = "SYS_rt_sigsuspend"] + pub fn __syscall_SYS_rt_sigsuspend(a1: i32, a2: u32) -> c_long; + /* 131 */ + #[link_name = "SYS_sigaltstack"] + pub fn __syscall_SYS_sigaltstack(a1: i32, a2: i32) -> c_long; + /* 132 */ + #[link_name = "SYS_utime"] + pub fn __syscall_SYS_utime(a1: i32, a2: i32) -> c_long; + /* 137 */ + #[link_name = "SYS_statfs"] + pub fn __syscall_SYS_statfs(a1: i32, a2: i32) -> c_long; + /* 138 */ + #[link_name = "SYS_fstatfs"] + pub fn __syscall_SYS_fstatfs(a1: i32, a2: i32) -> c_long; + /* 157 */ + #[link_name = "SYS_prctl"] + pub fn __syscall_SYS_prctl(a1: i32, a2: u64, a3: u64, a4: u64, a5: u64) -> c_long; + /* 160 */ + #[link_name = "SYS_setrlimit"] + pub fn __syscall_SYS_setrlimit(a1: i32, a2: i32) -> c_long; + /* 161 */ + #[link_name = "SYS_chroot"] + pub fn __syscall_SYS_chroot(a1: i32) -> c_long; + /* 186 */ + #[link_name = "SYS_gettid"] + pub fn __syscall_SYS_gettid() -> c_long; + /* 200 */ + #[link_name = "SYS_tkill"] + pub fn __syscall_SYS_tkill(a1: i32, a2: i32) -> c_long; + /* 202 */ + #[link_name = "SYS_futex"] + pub fn __syscall_SYS_futex(a1: i32, a2: i32, a3: i32, a4: i32, a5: i32, a6: i32) -> c_long; + /* 204 */ + #[link_name = "SYS_sched_getaffinity"] + pub fn __syscall_SYS_sched_getaffinity(a1: i32, a2: u32, a3: i32) -> c_long; + /* 217 */ + #[link_name = "SYS_getdents64"] + pub fn __syscall_SYS_getdents64(a1: i32, a2: i32, a3: i32) -> c_long; + /* 218 */ + #[link_name = "SYS_set_tid_address"] + pub fn __syscall_SYS_set_tid_address(a1: i32) -> c_long; + /* 221 */ + #[link_name = "SYS_fadvise"] + pub fn __syscall_SYS_fadvise(a1: i32, a2: i64, a3: i64, a4: i32) -> c_long; + /* 228 */ + #[link_name = "SYS_clock_gettime"] + pub fn __syscall_SYS_clock_gettime(a1: i32, a2: i32) -> c_long; + /* 229 */ + #[link_name = "SYS_clock_getres"] + pub fn __syscall_SYS_clock_getres(a1: i32, a2: i32) -> c_long; + /* 230 */ + #[link_name = "SYS_clock_nanosleep"] + pub fn __syscall_SYS_clock_nanosleep(a1: i32, a2: i32, a3: i32, a4: i32) -> c_long; + /* 231 */ + #[link_name = "SYS_exit_group"] + pub fn __syscall_SYS_exit_group(a1: i32) -> c_long; + /* 233 */ + #[link_name = "SYS_epoll_ctl"] + pub fn __syscall_SYS_epoll_ctl(a1: i32, a2: i32, a3: i32, a4: i32) -> c_long; + /* 257 */ + #[link_name = "SYS_openat"] + pub fn __syscall_SYS_openat(a1: i32, a2: i32, a3: i32, a4: i32) -> c_long; + /* 258 */ + #[link_name = "SYS_mkdirat"] + pub fn __syscall_SYS_mkdirat(a1: i32, a2: i32, a3: i32) -> c_long; + /* 260 */ + #[link_name = "SYS_fchownat"] + pub fn __syscall_SYS_fchownat(a1: i32, a2: i32, a3: i32, a4: i32, a5: i32) -> c_long; + /* 262 */ + #[link_name = "SYS_fstatat"] + pub fn __syscall_SYS_fstatat(a1: i32, a2: i32, a3: i32, a4: i32) -> c_long; + /* 263 */ + #[link_name = "SYS_unlinkat"] + pub fn __syscall_SYS_unlinkat(a1: i32, a2: i32, a3: i32) -> c_long; + /* 265 */ + #[link_name = "SYS_linkat"] + pub fn __syscall_SYS_linkat(a1: i32, a2: i32, a3: i32, a4: i32, a5: i32) -> c_long; + /* 266 */ + #[link_name = "SYS_symlinkat"] + pub fn __syscall_SYS_symlinkat(a1: i32, a2: i32, a3: i32) -> c_long; + /* 267 */ + #[link_name = "SYS_readlinkat"] + pub fn __syscall_SYS_readlinkat(a1: i32, a2: i32, a3: i32, a4: u32) -> c_long; + /* 268 */ + #[link_name = "SYS_fchmodat"] + pub fn __syscall_SYS_fchmodat(a1: i32, a2: i32, a3: i32, a4: i32) -> c_long; + /* 269 */ + #[link_name = "SYS_faccessat"] + pub fn __syscall_SYS_faccessat(a1: i32, a2: i32, a3: i32, a4: i32) -> c_long; + /* 270 */ + #[link_name = "SYS_pselect6"] + pub fn __syscall_SYS_pselect6(a1: i32, a2: i32, a3: i32, a4: i32, a5: i32, a6: i32) -> c_long; + /* 271 */ + #[link_name = "SYS_ppoll"] + pub fn __syscall_SYS_ppoll(a1: i32, a2: u32, a3: i32, a4: i32, a5: u32) -> c_long; + /* 280 */ + #[link_name = "SYS_utimensat"] + pub fn __syscall_SYS_utimensat(a1: i32, a2: i32, a3: i32, a4: i32) -> c_long; + /* 281 */ + #[link_name = "SYS_epoll_pwait"] + pub fn __syscall_SYS_epoll_pwait( + a1: i32, + a2: i32, + a3: i32, + a4: i32, + a5: i32, + a6: u32, + ) -> c_long; + /* 284 */ + #[link_name = "SYS_eventfd"] + pub fn __syscall_SYS_eventfd(a1: i32) -> c_long; + /* 288 */ + #[link_name = "SYS_accept4"] + pub fn __syscall_SYS_accept4(a1: i32, a2: i32, a3: i32, a4: i32) -> c_long; + /* 290 */ + #[link_name = "SYS_eventfd2"] + pub fn __syscall_SYS_eventfd2(a1: i32, a2: i32) -> c_long; + /* 291 */ + #[link_name = "SYS_epoll_create1"] + pub fn __syscall_SYS_epoll_create1(a1: i32) -> c_long; + /* 292 */ + #[link_name = "SYS_dup3"] + pub fn __syscall_SYS_dup3(a1: i32, a2: i32, a3: i32) -> c_long; + /* 293 */ + #[link_name = "SYS_pipe2"] + pub fn __syscall_SYS_pipe2(a1: i32, a2: i32) -> c_long; + /* 302 */ + #[link_name = "SYS_prlimit64"] + pub fn __syscall_SYS_prlimit64(a1: i32, a2: i32, a3: i32, a4: i32) -> c_long; + /* 316 */ + #[link_name = "SYS_renameat2"] + pub fn __syscall_SYS_renameat2(a1: i32, a2: i32, a3: i32, a4: i32, a5: i32) -> c_long; + /* 318 */ + #[link_name = "SYS_getrandom"] + pub fn __syscall_SYS_getrandom(a1: i32, a2: u32, a3: i32) -> c_long; + /* 332 */ + #[link_name = "SYS_statx"] + pub fn __syscall_SYS_statx(a1: i32, a2: i32, a3: i32, a4: i32, a5: i32) -> c_long; + /* 439 */ + #[link_name = "SYS_faccessat2"] + pub fn __syscall_SYS_faccessat2(a1: i32, a2: i32, a3: i32, a4: i32) -> c_long; +} 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..805457f --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs @@ -0,0 +1,831 @@ +use crate::off_t; +use crate::prelude::*; + +pub type wchar_t = i32; +pub type nlink_t = u64; +pub type blksize_t = c_long; +pub type greg_t = i64; + +pub type stat64 = stat; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + __pad0: Padding, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + #[cfg(all(musl32_time64, target_pointer_width = "32"))] + pub st_atime_nsec: i64, + #[cfg(not(all(musl32_time64, target_pointer_width = "32")))] + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + #[cfg(all(musl32_time64, target_pointer_width = "32"))] + pub st_mtime_nsec: i64, + #[cfg(not(all(musl32_time64, target_pointer_width = "32")))] + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + #[cfg(all(musl32_time64, target_pointer_width = "32"))] + pub st_ctime_nsec: i64, + #[cfg(not(all(musl32_time64, target_pointer_width = "32")))] + pub st_ctime_nsec: c_long, + __unused: Padding<[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: Padding, + #[cfg(target_pointer_width = "32")] + __pad1: Padding, + pub u_ar0: *mut user_regs_struct, + #[cfg(target_pointer_width = "32")] + __pad2: Padding, + 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 { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] + pub __ipc_perm_key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: crate::mode_t, + pub __seq: c_int, + __unused1: Padding, + __unused2: Padding, + } + + #[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, + } + + 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: Padding<[c_uint; 24]>, + } + + pub struct ucontext_t { + pub uc_flags: c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: crate::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: crate::sigset_t, + __private: [u8; 512], + } +} + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4], + } +} + +// 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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_create_module: c_long = 174; +pub const SYS_init_module: c_long = 175; +pub const SYS_delete_module: c_long = 176; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +pub const SYS_get_kernel_syms: c_long = 177; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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_io_pgetevents: c_long = 333; +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; + +// 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 = 0o0100000; +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 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: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const CIBAUD: crate::tcflag_t = 0o02003600000; +pub const CBAUDEX: crate::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const NLDLY: crate::tcflag_t = 0o000400; +pub const CRDLY: crate::tcflag_t = 0o003000; +pub const TABDLY: crate::tcflag_t = 0o014000; +pub const BSDLY: crate::tcflag_t = 0o020000; +pub const FFDLY: crate::tcflag_t = 0o100000; +pub const VTDLY: crate::tcflag_t = 0o040000; +pub const XTABS: crate::tcflag_t = 0o014000; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::speed_t = 0o010017; + +pub const EDEADLK: c_int = 35; +pub const EDEADLOCK: c_int = EDEADLK; + +pub const EXTPROC: crate::tcflag_t = 0x00010000; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::tcflag_t = 0x00000100; +pub const FLUSHO: crate::tcflag_t = 0x00001000; 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..c74fb84 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/lfs64.rs @@ -0,0 +1,242 @@ +use crate::off64_t; +use crate::prelude::*; + +#[inline] +pub unsafe extern "C" fn creat64(path: *const c_char, mode: crate::mode_t) -> c_int { + crate::creat(path, mode) +} + +#[inline] +pub unsafe extern "C" fn fallocate64( + fd: c_int, + mode: c_int, + offset: off64_t, + len: off64_t, +) -> c_int { + crate::fallocate(fd, mode, offset, len) +} + +#[inline] +pub unsafe extern "C" fn fgetpos64(stream: *mut crate::FILE, pos: *mut crate::fpos64_t) -> c_int { + crate::fgetpos(stream, pos.cast()) +} + +#[inline] +pub unsafe extern "C" fn fopen64(pathname: *const c_char, mode: *const c_char) -> *mut crate::FILE { + crate::fopen(pathname, mode) +} + +#[inline] +pub unsafe extern "C" fn freopen64( + pathname: *const c_char, + mode: *const c_char, + stream: *mut crate::FILE, +) -> *mut crate::FILE { + crate::freopen(pathname, mode, stream) +} + +#[inline] +pub unsafe extern "C" fn fseeko64( + stream: *mut crate::FILE, + offset: off64_t, + whence: c_int, +) -> c_int { + crate::fseeko(stream, offset, whence) +} + +#[inline] +pub unsafe extern "C" fn fsetpos64(stream: *mut crate::FILE, pos: *const crate::fpos64_t) -> c_int { + crate::fsetpos(stream, pos.cast()) +} + +#[inline] +pub unsafe extern "C" fn fstat64(fildes: c_int, buf: *mut crate::stat64) -> c_int { + crate::fstat(fildes, buf.cast()) +} + +#[inline] +pub unsafe extern "C" fn fstatat64( + fd: c_int, + path: *const c_char, + buf: *mut crate::stat64, + flag: c_int, +) -> c_int { + crate::fstatat(fd, path, buf.cast(), flag) +} + +#[inline] +pub unsafe extern "C" fn fstatfs64(fd: c_int, buf: *mut crate::statfs64) -> c_int { + crate::fstatfs(fd, buf.cast()) +} + +#[inline] +pub unsafe extern "C" fn fstatvfs64(fd: c_int, buf: *mut crate::statvfs64) -> c_int { + crate::fstatvfs(fd, buf.cast()) +} + +#[inline] +pub unsafe extern "C" fn ftello64(stream: *mut crate::FILE) -> off64_t { + crate::ftello(stream) +} + +#[inline] +pub unsafe extern "C" fn ftruncate64(fd: c_int, length: off64_t) -> c_int { + crate::ftruncate(fd, length) +} + +#[inline] +pub unsafe extern "C" fn getrlimit64(resource: c_int, rlim: *mut crate::rlimit64) -> c_int { + crate::getrlimit(resource, rlim.cast()) +} + +#[inline] +pub unsafe extern "C" fn lseek64(fd: c_int, offset: off64_t, whence: c_int) -> off64_t { + crate::lseek(fd, offset, whence) +} + +#[inline] +pub unsafe extern "C" fn lstat64(path: *const c_char, buf: *mut crate::stat64) -> c_int { + crate::lstat(path, buf.cast()) +} + +#[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 { + crate::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 crate::{ + open as open64, + 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 { + crate::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 { + crate::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 { + crate::pread(fd, buf, count, offset) +} + +#[inline] +pub unsafe extern "C" fn preadv64( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: off64_t, +) -> ssize_t { + crate::preadv(fd, iov, iovcnt, offset) +} + +#[inline] +pub unsafe extern "C" fn prlimit64( + pid: crate::pid_t, + resource: c_int, + new_limit: *const crate::rlimit64, + old_limit: *mut crate::rlimit64, +) -> c_int { + crate::prlimit(pid, resource, new_limit.cast(), old_limit.cast()) +} + +#[inline] +pub unsafe extern "C" fn pwrite64( + fd: c_int, + buf: *const c_void, + count: size_t, + offset: off64_t, +) -> ssize_t { + crate::pwrite(fd, buf, count, offset) +} + +#[inline] +pub unsafe extern "C" fn pwritev64( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: off64_t, +) -> ssize_t { + crate::pwritev(fd, iov, iovcnt, offset) +} + +#[inline] +pub unsafe extern "C" fn readdir64(dirp: *mut crate::DIR) -> *mut crate::dirent64 { + crate::readdir(dirp).cast() +} + +#[inline] +pub unsafe extern "C" fn readdir64_r( + dirp: *mut crate::DIR, + entry: *mut crate::dirent64, + result: *mut *mut crate::dirent64, +) -> c_int { + crate::readdir_r(dirp, entry.cast(), result.cast()) +} + +#[inline] +pub unsafe extern "C" fn sendfile64( + out_fd: c_int, + in_fd: c_int, + offset: *mut off64_t, + count: size_t, +) -> ssize_t { + crate::sendfile(out_fd, in_fd, offset, count) +} + +#[inline] +pub unsafe extern "C" fn setrlimit64(resource: c_int, rlim: *const crate::rlimit64) -> c_int { + crate::setrlimit(resource, rlim.cast()) +} + +#[inline] +pub unsafe extern "C" fn stat64(pathname: *const c_char, statbuf: *mut crate::stat64) -> c_int { + crate::stat(pathname, statbuf.cast()) +} + +#[inline] +pub unsafe extern "C" fn statfs64(pathname: *const c_char, buf: *mut crate::statfs64) -> c_int { + crate::statfs(pathname, buf.cast()) +} + +#[inline] +pub unsafe extern "C" fn statvfs64(path: *const c_char, buf: *mut crate::statvfs64) -> c_int { + crate::statvfs(path, buf.cast()) +} + +#[inline] +pub unsafe extern "C" fn tmpfile64() -> *mut crate::FILE { + crate::tmpfile() +} + +#[inline] +pub unsafe extern "C" fn truncate64(path: *const c_char, length: off64_t) -> c_int { + crate::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..26a7248 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/mod.rs @@ -0,0 +1,919 @@ +use crate::off64_t; +use crate::prelude::*; + +pub type pthread_t = *mut c_void; +pub type clock_t = c_long; +#[cfg(musl32_time64)] +pub type time_t = i64; +#[cfg(not(musl32_time64))] +#[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; +#[cfg(musl32_time64)] +pub type suseconds_t = i64; +#[cfg(not(musl32_time64))] +#[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 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 fsblkcnt64_t = c_ulonglong; +pub type fsfilcnt_t = c_ulonglong; +pub type fsfilcnt64_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).cast::()).si_addr + } + + pub unsafe fn si_value(&self) -> crate::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: crate::sigval, + } + (*(self as *const siginfo_t).cast::()).si_value + } +} + +s_no_extra_traits! { + // Internal, for casts to access union fields + struct sifields_sigchld { + si_pid: crate::pid_t, + si_uid: crate::uid_t, + si_status: c_int, + si_utime: c_long, + si_stime: c_long, + } + + // Internal, for casts to access union fields + 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. + struct siginfo_f { + _siginfo_base: [c_int; 3], + sifields: sifields, + } +} + +impl siginfo_t { + unsafe fn sifields(&self) -> &sifields { + &(*(self as *const siginfo_t).cast::()).sifields + } + + pub unsafe fn si_pid(&self) -> crate::pid_t { + self.sifields().sigchld.si_pid + } + + pub unsafe fn si_uid(&self) -> crate::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: crate::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; 32 - 2 * size_of::<*const ()>()], + } + + #[repr(align(8))] + pub struct fanotify_event_metadata { + pub event_len: c_uint, + pub vers: c_uchar, + pub reserved: c_uchar, + pub metadata_len: c_ushort, + pub mask: c_ulonglong, + pub fd: c_int, + pub pid: c_int, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::sigset_t, + pub sa_flags: c_int, + pub sa_restorer: Option, + } + + // `mips*` targets swap the `s_errno` and `s_code` fields otherwise this struct is + // target-agnostic (see https://www.openwall.com/lists/musl/2016/01/27/1/2) + // + // FIXME(union): C implementation uses unions + pub struct siginfo_t { + pub si_signo: c_int, + #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] + pub si_errno: c_int, + pub si_code: c_int, + #[cfg(any(target_arch = "mips", target_arch = "mips64"))] + pub si_errno: 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 statvfs { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::fsfilcnt_t, + #[cfg(target_endian = "little")] + pub f_fsid: c_ulong, + #[cfg(target_pointer_width = "32")] + __pad: Padding, + #[cfg(target_endian = "big")] + pub f_fsid: c_ulong, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + __f_reserved: Padding<[c_int; 6]>, + } + + pub struct statvfs64 { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt64_t, + pub f_bfree: crate::fsblkcnt64_t, + pub f_bavail: crate::fsblkcnt64_t, + pub f_files: crate::fsfilcnt64_t, + pub f_ffree: crate::fsfilcnt64_t, + pub f_favail: crate::fsfilcnt64_t, + #[cfg(target_endian = "little")] + pub f_fsid: c_ulong, + #[cfg(target_pointer_width = "32")] + __pad: Padding, + #[cfg(target_endian = "big")] + pub f_fsid: c_ulong, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + __f_reserved: Padding<[c_int; 6]>, + } + + // PowerPC implementations are special, see the subfolders + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + pub struct termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; crate::NCCS], + pub __c_ispeed: crate::speed_t, + pub __c_ospeed: crate::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: crate::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: crate::pid_t, + } + + pub struct regex_t { + __re_nsub: size_t, + __opaque: *mut c_void, + __padding: Padding<[*mut c_void; 4usize]>, + __nsub2: size_t, + __padding2: Padding, + } + + pub struct rtentry { + pub rt_pad1: c_ulong, + pub rt_dst: crate::sockaddr, + pub rt_gateway: crate::sockaddr, + pub rt_genmask: crate::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: crate::Elf64_Word, + pub ch_reserved: crate::Elf64_Word, + pub ch_size: crate::Elf64_Xword, + pub ch_addralign: crate::Elf64_Xword, + } + + pub struct Elf32_Chdr { + pub ch_type: crate::Elf32_Word, + pub ch_size: crate::Elf32_Word, + pub ch_addralign: crate::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: crate::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: crate::timeval, + pub maxerror: c_long, + pub esterror: c_long, + } + + // 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, + /// 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, + pub tcpi_rcv_ooopack: u32, + pub tcpi_snd_wnd: u32, + } + + // MIPS/s390x implementation is special (see arch folders) + #[cfg(not(any(target_arch = "mips", target_arch = "mips64", target_arch = "s390x")))] + pub struct statfs { + pub f_type: c_ulong, + pub f_bsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::fsid_t, + pub f_namelen: c_ulong, + pub f_frsize: c_ulong, + pub f_flags: c_ulong, + pub f_spare: [c_ulong; 4], + } + + // MIPS/s390x implementation is special (see arch folders) + #[cfg(not(any(target_arch = "mips", target_arch = "mips64", target_arch = "s390x")))] + pub struct statfs64 { + pub f_type: c_ulong, + pub f_bsize: c_ulong, + pub f_blocks: crate::fsblkcnt64_t, + pub f_bfree: crate::fsblkcnt64_t, + pub f_bavail: crate::fsblkcnt64_t, + pub f_files: crate::fsfilcnt64_t, + pub f_ffree: crate::fsfilcnt64_t, + pub f_fsid: crate::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 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 utmpx { + pub ut_type: c_short, + __ut_pad1: Padding, + pub ut_pid: crate::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(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "The ABI of this field has changed from c_long to c_int with padding, \ + we'll follow that change in the future release. See #4443 for more info." + )] + pub ut_session: c_long, + + #[cfg(musl_v1_2_3)] + #[cfg(not(target_endian = "little"))] + __ut_pad2: Padding, + + #[cfg(musl_v1_2_3)] + pub ut_session: c_int, + + #[cfg(musl_v1_2_3)] + #[cfg(target_endian = "little")] + __ut_pad2: Padding, + + pub ut_tv: crate::timeval, + pub ut_addr_v6: [c_uint; 4], + __unused: Padding<[c_char; 20]>, + } +} + +// 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; + +// 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; +pub const ACCOUNTING: c_short = 9; + +pub const SFD_CLOEXEC: c_int = 0x080000; + +#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] +pub const NCCS: usize = 32; +#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] +pub const NCCS: usize = 19; + +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 = u32_cast_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: crate::socklen_t = 255; +pub const PTHREAD_STACK_MIN: size_t = 2048; + +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; +#[deprecated(since = "0.2.70", note = "AF_PACKET must be used instead")] +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 = crate::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; + +// Value was changed in 1.2.4 +pub const CPU_SETSIZE: c_int = if cfg!(musl_v1_2_3) { 1024 } else { 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 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 = crate::O_NONBLOCK; + +pub const SFD_NONBLOCK: c_int = crate::O_NONBLOCK; + +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: crate::clockid_t = 10; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const EXTA: crate::speed_t = B19200; +pub const EXTB: crate::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 _CS_V6_ENV: c_int = 1148; +pub const _CS_V7_ENV: c_int = 1149; + +pub const CLONE_NEWTIME: c_int = 0x80; + +pub const UT_HOSTSIZE: usize = 256; +pub const UT_LINESIZE: usize = 32; +pub const UT_NAMESIZE: usize = 32; + +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 getrlimit(resource: c_int, rlim: *mut crate::rlimit) -> c_int; + pub fn setrlimit(resource: c_int, rlim: *const crate::rlimit) -> c_int; + pub fn prlimit( + pid: crate::pid_t, + resource: c_int, + new_limit: *const crate::rlimit, + old_limit: *mut crate::rlimit, + ) -> c_int; + #[cfg_attr(musl_redir_time64, link_name = "__gettimeofday_time64")] + pub fn gettimeofday(tp: *mut crate::timeval, tz: *mut c_void) -> c_int; + pub fn ptrace(request: c_int, ...) -> c_long; + pub fn getpriority(which: c_int, who: crate::id_t) -> c_int; + pub fn setpriority(which: c_int, who: crate::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 crate::iovec, + iovcnt: c_int, + offset: off_t, + flags: c_int, + ) -> ssize_t; + pub fn pwritev2( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: off_t, + flags: c_int, + ) -> ssize_t; + pub fn getauxval(type_: c_ulong) -> c_ulong; + pub fn renameat2( + olddirfd: c_int, + oldpath: *const c_char, + newdirfd: c_int, + newpath: *const c_char, + flags: c_uint, + ) -> c_int; + + // 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; + + #[cfg_attr(musl_redir_time64, link_name = "__adjtimex_time64")] + pub fn adjtimex(buf: *mut crate::timex) -> c_int; + #[cfg_attr(musl_redir_time64, link_name = "__clock_adjtime64")] + pub fn clock_adjtime(clk_id: crate::clockid_t, buf: *mut crate::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 crate::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.20 + pub fn getrandom(buf: *mut c_void, buflen: size_t, flags: c_uint) -> ssize_t; + + // Added in `musl` 1.1.24 + pub fn posix_spawn_file_actions_addchdir_np( + actions: *mut crate::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 crate::posix_spawn_file_actions_t, + fd: c_int, + ) -> c_int; + + #[deprecated( + since = "0.2.172", + note = "musl provides `utmp` as stubs and an alternative should be preferred; see https://wiki.musl-libc.org/faq.html" + )] + pub fn getutxent() -> *mut utmpx; + #[deprecated( + since = "0.2.172", + note = "musl provides `utmp` as stubs and an alternative should be preferred; see https://wiki.musl-libc.org/faq.html" + )] + pub fn getutxid(ut: *const utmpx) -> *mut utmpx; + #[deprecated( + since = "0.2.172", + note = "musl provides `utmp` as stubs and an alternative should be preferred; see https://wiki.musl-libc.org/faq.html" + )] + pub fn getutxline(ut: *const utmpx) -> *mut utmpx; + #[deprecated( + since = "0.2.172", + note = "musl provides `utmp` as stubs and an alternative should be preferred; see https://wiki.musl-libc.org/faq.html" + )] + pub fn pututxline(ut: *const utmpx) -> *mut utmpx; + #[deprecated( + since = "0.2.172", + note = "musl provides `utmp` as stubs and an alternative should be preferred; see https://wiki.musl-libc.org/faq.html" + )] + pub fn setutxent(); + #[deprecated( + since = "0.2.172", + note = "musl provides `utmp` as stubs and an alternative should be preferred; see https://wiki.musl-libc.org/faq.html" + )] + pub fn endutxent(); + #[deprecated( + since = "0.2.172", + note = "musl provides `utmp` as stubs and an alternative should be preferred; see https://wiki.musl-libc.org/faq.html" + )] + pub fn utmpxname(file: *const c_char) -> c_int; + pub fn pthread_tryjoin_np(thread: crate::pthread_t, retval: *mut *mut c_void) -> c_int; + #[cfg_attr( + all(musl_redir_time64, target_pointer_width = "32"), + link_name = "__pthread_timedjoin_np_time64" + )] + pub fn pthread_timedjoin_np( + thread: crate::pthread_t, + retval: *mut *mut c_void, + abstime: *const crate::timespec, + ) -> 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", + // musl-linux ABI for wasm32 follows b64 convention + target_arch = "wasm32", + ))] { + 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/uclibc/arm/mod.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs new file mode 100644 index 0000000..9d255b7 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs @@ -0,0 +1,921 @@ +use crate::off64_t; +use crate::prelude::*; + +pub type wchar_t = c_uint; + +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 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; + +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: crate::socklen_t, + pub msg_iov: *mut crate::iovec, + pub msg_iovlen: c_int, + pub msg_control: *mut c_void, + pub msg_controllen: crate::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: Padding, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: c_ulonglong, + __pad2: Padding, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + __unused4: Padding, + __unused5: Padding, + } + + pub struct stat64 { + pub st_dev: c_ulonglong, + pub __pad1: c_uint, + pub __st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: c_ulonglong, + pub __pad2: c_uint, + pub st_size: off64_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_ino: crate::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: crate::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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + + pub f_fsid: crate::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: crate::fsblkcnt64_t, + pub f_bfree: crate::fsblkcnt64_t, + pub f_bavail: crate::fsblkcnt64_t, + pub f_files: crate::fsfilcnt64_t, + pub f_ffree: crate::fsfilcnt64_t, + pub f_fsid: crate::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: Padding, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + __f_spare: [c_int; 6], + } + + pub struct sigset_t { + __val: [c_ulong; 2], + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_flags: c_ulong, + pub sa_restorer: Option, + pub sa_mask: sigset_t, + } + + pub struct termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; crate::NCCS], + pub c_ispeed: crate::speed_t, + pub c_ospeed: crate::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: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_ushort, + __pad1: Padding, + pub __seq: c_ushort, + __pad2: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + pub msg_stime: crate::time_t, + __unused1: Padding, + pub msg_rtime: crate::time_t, + __unused2: Padding, + pub msg_ctime: crate::time_t, + __unused3: Padding, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __unused4: Padding, + __unused5: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + __unused1: Padding, + pub shm_dtime: crate::time_t, + __unused2: Padding, + pub shm_ctime: crate::time_t, + __unused3: Padding, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused4: Padding, + __unused5: Padding, + } + + // FIXME(1.0) 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], + } +} + +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: crate::speed_t = 0; +pub const B1000000: crate::speed_t = 0x1008; +pub const B110: crate::speed_t = 0x3; +pub const B115200: crate::speed_t = 0x1002; +pub const B1152000: crate::speed_t = 0x1009; +pub const B1200: crate::speed_t = 0x9; +pub const B134: crate::speed_t = 0x4; +pub const B150: crate::speed_t = 0x5; +pub const B1500000: crate::speed_t = 0x100a; +pub const B1800: crate::speed_t = 0xa; +pub const B19200: crate::speed_t = 0xe; +pub const B200: crate::speed_t = 0x6; +pub const B2000000: crate::speed_t = 0x100b; +pub const B230400: crate::speed_t = 0x1003; +pub const B2400: crate::speed_t = 0xb; +pub const B2500000: crate::speed_t = 0x100c; +pub const B300: crate::speed_t = 0x7; +pub const B3000000: crate::speed_t = 0x100d; +pub const B3500000: crate::speed_t = 0x100e; +pub const B38400: crate::speed_t = 0xf; +pub const B4000000: crate::speed_t = 0x100f; +pub const B460800: crate::speed_t = 0x1004; +pub const B4800: crate::speed_t = 0xc; +pub const B50: crate::speed_t = 0x1; +pub const B500000: crate::speed_t = 0x1005; +pub const B57600: crate::speed_t = 0x1001; +pub const B576000: crate::speed_t = 0x1006; +pub const B600: crate::speed_t = 0x8; +pub const B75: crate::speed_t = 0x2; +pub const B921600: crate::speed_t = 0x1007; +pub const B9600: crate::speed_t = 0xd; +pub const BS1: c_int = 0x2000; +pub const BSDLY: c_int = 0x2000; +pub const CBAUD: crate::tcflag_t = 0x100f; +pub const CBAUDEX: crate::tcflag_t = 0x1000; +pub const CIBAUD: crate::tcflag_t = 0x100f0000; +pub const CLOCAL: crate::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: crate::tcflag_t = 0x80; +pub const CS6: crate::tcflag_t = 0x10; +pub const CS7: crate::tcflag_t = 0x20; +pub const CS8: crate::tcflag_t = 0x30; +pub const CSIZE: crate::tcflag_t = 0x30; +pub const CSTOPB: crate::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: crate::tcflag_t = 0x200; +pub const ECHOE: crate::tcflag_t = 0x10; +pub const ECHOK: crate::tcflag_t = 0x20; +pub const ECHOKE: crate::tcflag_t = 0x800; +pub const ECHONL: crate::tcflag_t = 0x40; +pub const ECHOPRT: crate::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: crate::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: crate::tcflag_t = 0x400; +pub const ICANON: crate::tcflag_t = 0x2; +pub const IEXTEN: crate::tcflag_t = 0x8000; +pub const ISIG: crate::tcflag_t = 0x1; +pub const IXOFF: crate::tcflag_t = 0x1000; +pub const IXON: crate::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: crate::tcflag_t = 0x100; +pub const NOFLSH: crate::tcflag_t = 0x80; +pub const OLCUC: crate::tcflag_t = 0x2; +pub const ONLCR: crate::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: crate::tcflag_t = 0x100; +pub const PARODD: crate::tcflag_t = 0x200; +pub const PENDIN: crate::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; + +// 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: crate::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: crate::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(linux): 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; 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..b6c8559 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs @@ -0,0 +1,691 @@ +use crate::off64_t; +use crate::prelude::*; + +pub type clock_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 fsblkcnt64_t = u64; +pub type fsfilcnt64_t = u64; + +s! { + pub struct stat { + pub st_dev: crate::dev_t, + st_pad1: Padding<[c_long; 2]>, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub st_pad2: [c_long; 1], + pub st_size: off_t, + st_pad3: Padding, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + st_pad5: Padding<[c_long; 14]>, + } + + pub struct stat64 { + pub st_dev: crate::dev_t, + st_pad1: Padding<[c_long; 2]>, + pub st_ino: crate::ino64_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + st_pad2: Padding<[c_long; 2]>, + pub st_size: off64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_blksize: crate::blksize_t, + st_pad3: Padding, + pub st_blocks: crate::blkcnt64_t, + st_pad5: Padding<[c_long; 14]>, + } + + pub struct statvfs64 { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt64_t, + pub f_bfree: crate::fsblkcnt64_t, + pub f_bavail: crate::fsblkcnt64_t, + pub f_files: crate::fsfilcnt64_t, + pub f_ffree: crate::fsfilcnt64_t, + pub f_favail: crate::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: crate::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: Padding<*mut c_void>, + __unused2: Padding<*mut c_void>, + __unused3: Padding<*mut c_void>, + __unused4: Padding<*mut c_void>, + __unused5: Padding<*mut c_void>, + } + + pub struct ipc_perm { + pub __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_uint, + pub __seq: c_ushort, + __pad1: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused4: Padding, + __unused5: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + #[cfg(target_endian = "big")] + __glibc_reserved1: Padding, + pub msg_stime: crate::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved1: Padding, + #[cfg(target_endian = "big")] + __glibc_reserved2: Padding, + pub msg_rtime: crate::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved2: Padding, + #[cfg(target_endian = "big")] + __glibc_reserved3: Padding, + pub msg_ctime: crate::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved3: Padding, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __glibc_reserved4: Padding, + __glibc_reserved5: Padding, + } + + pub struct statfs { + pub f_type: c_long, + pub f_bsize: c_long, + pub f_frsize: c_long, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_files: crate::fsblkcnt_t, + pub f_ffree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_fsid: crate::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: crate::fsblkcnt64_t, + pub f_bfree: crate::fsblkcnt64_t, + pub f_files: crate::fsblkcnt64_t, + pub f_ffree: crate::fsblkcnt64_t, + pub f_bavail: crate::fsblkcnt64_t, + pub f_fsid: crate::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: crate::socklen_t, + pub msg_iov: *mut crate::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: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; crate::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: crate::pid_t, + pad: Padding<[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], + } + + // FIXME(1.0): 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], + } +} + +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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; +#[deprecated(since = "0.2.70", note = "Functional up to 2.6 kernel")] +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 crate::pthread_attr_t, + cpusetsize: size_t, + cpuset: *mut crate::cpu_set_t, + ) -> c_int; + pub fn pthread_attr_setaffinity_np( + attr: *mut crate::pthread_attr_t, + cpusetsize: size_t, + cpuset: *const crate::cpu_set_t, + ) -> c_int; +} diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs new file mode 100644 index 0000000..a6a63a3 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs @@ -0,0 +1,202 @@ +use crate::off64_t; +use crate::prelude::*; + +pub type blkcnt_t = i64; +pub type blksize_t = i64; +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 wchar_t = i32; + +s! { + pub struct stat { + pub st_dev: c_ulong, + st_pad1: Padding<[c_long; 2]>, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: c_ulong, + st_pad2: Padding<[c_ulong; 1]>, + pub st_size: off_t, + st_pad3: Padding, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_blksize: crate::blksize_t, + st_pad4: Padding, + pub st_blocks: crate::blkcnt_t, + st_pad5: Padding<[c_long; 7]>, + } + + pub struct stat64 { + pub st_dev: c_ulong, + st_pad1: Padding<[c_long; 2]>, + pub st_ino: crate::ino64_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: c_ulong, + st_pad2: Padding<[c_long; 2]>, + pub st_size: off64_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_blksize: crate::blksize_t, + st_pad3: Padding, + pub st_blocks: crate::blkcnt64_t, + st_pad5: Padding<[c_long; 7]>, + } + + pub struct pthread_attr_t { + __size: [c_ulong; 7], + } + + pub struct sigaction { + pub sa_flags: c_int, + pub sa_sigaction: crate::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: Padding, + _pad2: Padding<[c_long; 14]>, + } + + pub struct ipc_perm { + pub __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_uint, + pub __seq: c_ushort, + __pad1: Padding, + __unused1: Padding, + __unused2: Padding, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused4: Padding, + __unused5: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + pub msg_stime: crate::time_t, + pub msg_rtime: crate::time_t, + pub msg_ctime: crate::time_t, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __glibc_reserved4: Padding, + __glibc_reserved5: Padding, + } + + pub struct statfs { + pub f_type: c_long, + pub f_bsize: c_long, + pub f_frsize: c_long, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_files: crate::fsblkcnt_t, + pub f_ffree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_fsid: crate::fsid_t, + + pub f_namelen: c_long, + f_spare: [c_long; 6], + } + + pub struct msghdr { + pub msg_name: *mut c_void, + pub msg_namelen: crate::socklen_t, + pub msg_iov: *mut crate::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: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; crate::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], + } + + // FIXME(1.0): 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], + } +} + +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 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..8d17aa8 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mod.rs @@ -0,0 +1,312 @@ +use crate::prelude::*; + +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_uint = 0x40000000; +pub const SA_RESETHAND: c_uint = 0x80000000; +pub const SA_RESTART: c_uint = 0x10000000; +pub const SA_NOCLDSTOP: c_uint = 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 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: crate::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 SIGEMT: c_int = 7; +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: crate::tcflag_t = 0x00000100; +pub const TOSTOP: crate::tcflag_t = 0x00008000; +pub const FLUSHO: crate::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: crate::tcflag_t = 0o0010017; +pub const CBAUDEX: crate::tcflag_t = 0o0010000; +pub const CIBAUD: crate::tcflag_t = 0o002003600000; +pub const TAB1: crate::tcflag_t = 0x00000800; +pub const TAB2: crate::tcflag_t = 0x00001000; +pub const TAB3: crate::tcflag_t = 0x00001800; +pub const TABDLY: crate::tcflag_t = 0o0014000; +pub const CR1: crate::tcflag_t = 0x00000200; +pub const CR2: crate::tcflag_t = 0x00000400; +pub const CR3: crate::tcflag_t = 0x00000600; +pub const FF1: crate::tcflag_t = 0x00008000; +pub const BS1: crate::tcflag_t = 0x00002000; +pub const BSDLY: crate::tcflag_t = 0o0020000; +pub const VT1: crate::tcflag_t = 0x00004000; +pub const VWERASE: usize = 14; +pub const XTABS: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const OLCUC: crate::tcflag_t = 0o0000002; +pub const ONLCR: crate::tcflag_t = 0x4; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x00000010; +pub const CS7: crate::tcflag_t = 0x00000020; +pub const CS8: crate::tcflag_t = 0x00000030; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CRDLY: c_int = 0o0003000; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOPRT: crate::tcflag_t = 0x00000400; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const PENDIN: crate::tcflag_t = 0x00004000; +pub const NOFLSH: crate::tcflag_t = 0x00000080; + +pub const MAP_HUGETLB: c_int = 0x80000; + +pub const B0: crate::speed_t = 0o000000; +pub const B50: crate::speed_t = 0o000001; +pub const B75: crate::speed_t = 0o000002; +pub const B110: crate::speed_t = 0o000003; +pub const B134: crate::speed_t = 0o000004; +pub const B150: crate::speed_t = 0o000005; +pub const B200: crate::speed_t = 0o000006; +pub const B300: crate::speed_t = 0o000007; +pub const B600: crate::speed_t = 0o000010; +pub const B1200: crate::speed_t = 0o000011; +pub const B1800: crate::speed_t = 0o000012; +pub const B2400: crate::speed_t = 0o000013; +pub const B4800: crate::speed_t = 0o000014; +pub const B9600: crate::speed_t = 0o000015; +pub const B19200: crate::speed_t = 0o000016; +pub const B38400: crate::speed_t = 0o000017; +pub const B57600: crate::speed_t = 0o010001; +pub const B115200: crate::speed_t = 0o010002; +pub const B230400: crate::speed_t = 0o010003; +pub const B460800: crate::speed_t = 0o010004; +pub const B500000: crate::speed_t = 0o010005; +pub const B576000: crate::speed_t = 0o010006; +pub const B921600: crate::speed_t = 0o010007; +pub const B1000000: crate::speed_t = 0o010010; +pub const B1152000: crate::speed_t = 0o010011; +pub const B1500000: crate::speed_t = 0o010012; +pub const B2000000: crate::speed_t = 0o010013; +pub const B2500000: crate::speed_t = 0o010014; +pub const B3000000: crate::speed_t = 0o010015; +pub const B3500000: crate::speed_t = 0o010016; +pub const B4000000: crate::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..6c3d801 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs @@ -0,0 +1,426 @@ +// FIXME(ulibc): this module has definitions that are redundant with the parent +#![allow(dead_code)] + +use crate::off64_t; +use crate::prelude::*; + +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! { + // Set `--cfg=libc_unstable_uclibc_time64` in RUSTFLAGS if your uClibc has 64-bit `time_t`. + if #[cfg(linux_time_bits64)] { + pub type time_t = i64; + pub type suseconds_t = i64; + } else { + pub type time_t = c_long; + pub type suseconds_t = c_long; + } +} + +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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::fsfilcnt_t, + #[cfg(target_endian = "little")] + pub f_fsid: c_ulong, + #[cfg(target_pointer_width = "32")] + __f_unused: Padding, + #[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: crate::sockaddr, + pub rt_gateway: crate::sockaddr, + pub rt_genmask: crate::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: crate::__u64, + pub flags: crate::__u32, + pub nr: crate::__s32, + } + + 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, + } +} + +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).cast::()).si_addr + } + + pub unsafe fn si_value(&self) -> crate::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: crate::sigval, + } + (*(self as *const siginfo_t).cast::()).si_value + } +} + +s_no_extra_traits! { + // Internal, for casts to access union fields + struct sifields_sigchld { + si_pid: crate::pid_t, + si_uid: crate::uid_t, + si_status: c_int, + si_utime: c_long, + si_stime: c_long, + } + + // Internal, for casts to access union fields + 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. + struct siginfo_f { + _siginfo_base: [c_int; 3], + sifields: sifields, + } +} + +impl siginfo_t { + unsafe fn sifields(&self) -> &sifields { + &(*(self as *const siginfo_t).cast::()).sifields + } + + pub unsafe fn si_pid(&self) -> crate::pid_t { + self.sifields().sigchld.si_pid + } + + pub unsafe fn si_uid(&self) -> crate::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 + +pub const ENOTSUP: c_int = EOPNOTSUPP; + +pub const IPV6_JOIN_GROUP: c_int = 20; +pub const IPV6_LEAVE_GROUP: c_int = 21; + +// Different than Gnu. +pub const FILENAME_MAX: c_uint = 4095; + +pub const PRIO_PROCESS: crate::__priority_which_t = 0; +pub const PRIO_PGRP: crate::__priority_which_t = 1; +pub const PRIO_USER: crate::__priority_which_t = 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: crate::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: crate::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 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; +#[deprecated(since = "0.2.70", note = "AF_PACKET must be used instead")] +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; + +extern "C" { + pub fn gettimeofday(tp: *mut crate::timeval, tz: *mut crate::timezone) -> c_int; + + pub fn pthread_rwlockattr_getkind_np( + attr: *const crate::pthread_rwlockattr_t, + val: *mut c_int, + ) -> c_int; + pub fn pthread_rwlockattr_setkind_np( + attr: *mut crate::pthread_rwlockattr_t, + val: c_int, + ) -> c_int; + + pub fn ptrace(request: c_uint, ...) -> c_long; + + pub fn sendmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: c_uint, + flags: c_int, + ) -> c_int; + pub fn recvmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: c_uint, + flags: c_int, + timeout: *mut crate::timespec, + ) -> c_int; + + pub fn openpty( + amaster: *mut c_int, + aslave: *mut c_int, + name: *mut c_char, + termp: *mut termios, + winp: *mut crate::winsize, + ) -> c_int; + pub fn forkpty( + amaster: *mut c_int, + name: *mut c_char, + termp: *mut termios, + winp: *mut crate::winsize, + ) -> crate::pid_t; + + pub fn getnameinfo( + sa: *const crate::sockaddr, + salen: crate::socklen_t, + host: *mut c_char, + hostlen: crate::socklen_t, + serv: *mut c_char, + servlen: crate::socklen_t, + flags: c_int, + ) -> c_int; + + pub fn pwritev(fd: c_int, iov: *const crate::iovec, iovcnt: c_int, offset: off64_t) -> ssize_t; + pub fn preadv(fd: c_int, iov: *const crate::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: crate::__rlimit_resource_t, rlim: *mut crate::rlimit64) -> c_int; + pub fn setrlimit64(resource: crate::__rlimit_resource_t, rlim: *const crate::rlimit64) + -> c_int; + pub fn getrlimit(resource: crate::__rlimit_resource_t, rlim: *mut crate::rlimit) -> c_int; + pub fn setrlimit(resource: crate::__rlimit_resource_t, rlim: *const crate::rlimit) -> c_int; + pub fn getpriority(which: crate::__priority_which_t, who: crate::id_t) -> c_int; + pub fn setpriority(which: crate::__priority_which_t, who: crate::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/x86_64/mod.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs new file mode 100644 index 0000000..46f3439 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs @@ -0,0 +1,342 @@ +//! Definitions for uclibc on 64bit systems + +use crate::off64_t; +use crate::prelude::*; + +pub type blkcnt_t = i64; +pub type blksize_t = i64; +pub type clock_t = i64; +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 wchar_t = c_int; +pub type pthread_t = c_ulong; + +pub type fsblkcnt64_t = u64; +pub type fsfilcnt64_t = u64; + +s! { + pub struct ipc_perm { + pub __key: crate::key_t, + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: c_ushort, // read / write + __pad1: Padding, + pub __seq: c_ushort, + __pad2: Padding, + __unused1: Padding, + __unused2: Padding, + } + + 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: crate::ipc_perm, + pub shm_segsz: size_t, // segment size in bytes + pub shm_atime: crate::time_t, // time of last shmat() + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_cpid: crate::pid_t, + pub shm_lpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + __unused1: Padding, + __unused2: Padding, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + pub msg_stime: crate::time_t, + pub msg_rtime: crate::time_t, + pub msg_ctime: crate::time_t, + pub __msg_cbytes: c_ulong, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + __ignored1: c_ulong, + __ignored2: c_ulong, + } + + pub struct sockaddr { + pub sa_family: crate::sa_family_t, + pub sa_data: [c_char; 14], + } + + pub struct sockaddr_in { + pub sin_family: crate::sa_family_t, + pub sin_port: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_zero: [u8; 8], + } + + pub struct sockaddr_in6 { + pub sin6_family: crate::sa_family_t, + pub sin6_port: crate::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: crate::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], + // } + + pub struct stat { + pub st_dev: c_ulong, + pub st_ino: crate::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: crate::nlink_t, + pub st_mode: crate::mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: c_ulong, // dev_t + pub st_size: off_t, // file size + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_ulong, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_ulong, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_ulong, + st_pad4: Padding<[c_long; 3]>, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_handler: crate::sighandler_t, + pub sa_flags: c_ulong, + pub sa_restorer: Option, + pub sa_mask: crate::sigset_t, + } + + pub struct stack_t { + // FIXME(ulibc) + pub ss_sp: *mut c_void, + pub ss_flags: c_int, + pub ss_size: size_t, + } + + pub struct statfs { + // FIXME(ulibc) + pub f_type: fsword_t, + pub f_bsize: fsword_t, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_fsid: crate::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: crate::fsblkcnt64_t, + pub f_bfree: crate::fsblkcnt64_t, + pub f_bavail: crate::fsblkcnt64_t, + pub f_files: crate::fsfilcnt64_t, + pub f_ffree: crate::fsfilcnt64_t, + pub f_fsid: crate::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: Padding, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + __f_spare: [c_int; 6], + } + + pub struct msghdr { + // FIXME(ulibc) + pub msg_name: *mut c_void, + pub msg_namelen: crate::socklen_t, + pub msg_iov: *mut crate::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(ulibc) + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; crate::NCCS], + } + + pub struct sigset_t { + // FIXME(ulibc) + __val: [c_ulong; 16], + } + + pub struct sysinfo { + // FIXME(ulibc) + 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(ulibc) + pub gl_pathc: size_t, + pub gl_pathv: *mut *mut c_char, + pub gl_offs: size_t, + pub gl_flags: c_int, + __unused1: Padding<*mut c_void>, + __unused2: Padding<*mut c_void>, + __unused3: Padding<*mut c_void>, + __unused4: Padding<*mut c_void>, + __unused5: Padding<*mut c_void>, + } + + pub struct cpu_set_t { + // FIXME(ulibc) + #[cfg(target_pointer_width = "32")] + bits: [u32; 32], + #[cfg(target_pointer_width = "64")] + bits: [u64; 16], + } + + pub struct fsid_t { + // FIXME(ulibc) + __val: [c_int; 2], + } + + // FIXME(1.0): 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! { + pub struct dirent { + pub d_ino: crate::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 PTHREAD_STACK_MIN: usize = 16384; diff --git a/vendor/libc/src/unix/linux_like/linux_l4re_shared.rs b/vendor/libc/src/unix/linux_like/linux_l4re_shared.rs new file mode 100644 index 0000000..0674269 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux_l4re_shared.rs @@ -0,0 +1,1944 @@ +use crate::prelude::*; + +pub type Elf32_Half = u16; +pub type Elf32_Word = u32; +pub type Elf32_Off = u32; +pub type Elf32_Addr = u32; +pub type Elf32_Xword = 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_Sword = i32; + +pub type Elf32_Section = u16; +pub type Elf64_Section = u16; + +pub type Elf32_Relr = Elf32_Word; +pub type Elf64_Relr = Elf32_Xword; +pub type Elf32_Rel = __c_anonymous_elf32_rel; +pub type Elf64_Rel = __c_anonymous_elf64_rel; + +cfg_if! { + if #[cfg(not(target_arch = "sparc64"))] { + pub type Elf32_Rela = __c_anonymous_elf32_rela; + pub type Elf64_Rela = __c_anonymous_elf64_rela; + } +} + +pub type iconv_t = *mut c_void; + +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: Padding<*mut c_void>, + __unused2: Padding<*mut c_void>, + __unused3: Padding<*mut c_void>, + __unused4: Padding<*mut c_void>, + __unused5: Padding<*mut c_void>, + } + + pub struct passwd { + pub pw_name: *mut c_char, + pub pw_passwd: *mut c_char, + pub pw_uid: crate::uid_t, + pub pw_gid: crate::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: crate::timespec, + pub it_value: crate::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 sembuf { + pub sem_num: c_ushort, + pub sem_op: c_short, + pub sem_flg: c_short, + } + + 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 ucred { + pub pid: crate::pid_t, + pub uid: crate::uid_t, + pub gid: crate::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 in6_pktinfo { + pub ipi6_addr: crate::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; crate::MAX_ADDR_LEN], + } + + pub struct regmatch_t { + pub rm_so: crate::regoff_t, + pub rm_eo: crate::regoff_t, + } + + pub struct option { + pub name: *const c_char, + pub has_arg: c_int, + pub flag: *mut c_int, + pub val: c_int, + } + + pub struct rlimit64 { + pub rlim_cur: crate::rlim64_t, + pub rlim_max: crate::rlim64_t, + } + + 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 dirent { + pub d_ino: crate::ino_t, + pub d_off: crate::off_t, + pub d_reclen: c_ushort, + pub d_type: c_uchar, + pub d_name: [c_char; 256], + } + + pub struct dirent64 { + pub d_ino: crate::ino64_t, + pub d_off: crate::off64_t, + pub d_reclen: c_ushort, + pub d_type: c_uchar, + pub d_name: [c_char; 256], + } +} + +cfg_if! { + if #[cfg(not(target_arch = "sparc64"))] { + s! { + pub struct __c_anonymous_elf32_rela { + pub r_offset: crate::Elf32_Addr, + pub r_info: crate::Elf32_Word, + pub r_addend: crate::Elf32_Sword, + } + + pub struct __c_anonymous_elf64_rela { + pub r_offset: crate::Elf64_Addr, + pub r_info: crate::Elf64_Xword, + pub r_addend: crate::Elf64_Sxword, + } + } + } +} + +s_no_extra_traits! { + pub union __c_anonymous_ifr_ifru { + pub ifru_addr: crate::sockaddr, + pub ifru_dstaddr: crate::sockaddr, + pub ifru_broadaddr: crate::sockaddr, + pub ifru_netmask: crate::sockaddr, + pub ifru_hwaddr: crate::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; crate::IFNAMSIZ], + pub ifru_newname: [c_char; crate::IFNAMSIZ], + pub ifru_data: *mut c_char, + } + + pub struct ifreq { + /// interface name, e.g. "en0" + pub ifr_name: [c_char; crate::IFNAMSIZ], + pub ifr_ifru: __c_anonymous_ifr_ifru, + } + + pub union __c_anonymous_ifc_ifcu { + pub ifcu_buf: *mut c_char, + pub ifcu_req: *mut crate::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 { + /// Size of buffer + pub ifc_len: c_int, + pub ifc_ifcu: __c_anonymous_ifc_ifcu, + } +} + +cfg_if! { + if #[cfg(not(target_env = "uclibc"))] { + const DATE_BASE: crate::nl_item = 0x20000; + } else { + const DATE_BASE: crate::nl_item = 768; + } +} + +pub const ABDAY_1: crate::nl_item = DATE_BASE; +pub const ABDAY_2: crate::nl_item = DATE_BASE + 0x1; +pub const ABDAY_3: crate::nl_item = DATE_BASE + 0x2; +pub const ABDAY_4: crate::nl_item = DATE_BASE + 0x3; +pub const ABDAY_5: crate::nl_item = DATE_BASE + 0x4; +pub const ABDAY_6: crate::nl_item = DATE_BASE + 0x5; +pub const ABDAY_7: crate::nl_item = DATE_BASE + 0x6; + +pub const DAY_1: crate::nl_item = DATE_BASE + 0x7; +pub const DAY_2: crate::nl_item = DATE_BASE + 0x8; +pub const DAY_3: crate::nl_item = DATE_BASE + 0x9; +pub const DAY_4: crate::nl_item = DATE_BASE + 0xA; +pub const DAY_5: crate::nl_item = DATE_BASE + 0xB; +pub const DAY_6: crate::nl_item = DATE_BASE + 0xC; +pub const DAY_7: crate::nl_item = DATE_BASE + 0xD; + +pub const ABMON_1: crate::nl_item = DATE_BASE + 0xE; +pub const ABMON_2: crate::nl_item = DATE_BASE + 0xF; +pub const ABMON_3: crate::nl_item = DATE_BASE + 0x10; +pub const ABMON_4: crate::nl_item = DATE_BASE + 0x11; +pub const ABMON_5: crate::nl_item = DATE_BASE + 0x12; +pub const ABMON_6: crate::nl_item = DATE_BASE + 0x13; +pub const ABMON_7: crate::nl_item = DATE_BASE + 0x14; +pub const ABMON_8: crate::nl_item = DATE_BASE + 0x15; +pub const ABMON_9: crate::nl_item = DATE_BASE + 0x16; +pub const ABMON_10: crate::nl_item = DATE_BASE + 0x17; +pub const ABMON_11: crate::nl_item = DATE_BASE + 0x18; +pub const ABMON_12: crate::nl_item = DATE_BASE + 0x19; + +pub const MON_1: crate::nl_item = DATE_BASE + 0x1A; +pub const MON_2: crate::nl_item = DATE_BASE + 0x1B; +pub const MON_3: crate::nl_item = DATE_BASE + 0x1C; +pub const MON_4: crate::nl_item = DATE_BASE + 0x1D; +pub const MON_5: crate::nl_item = DATE_BASE + 0x1E; +pub const MON_6: crate::nl_item = DATE_BASE + 0x1F; +pub const MON_7: crate::nl_item = DATE_BASE + 0x20; +pub const MON_8: crate::nl_item = DATE_BASE + 0x21; +pub const MON_9: crate::nl_item = DATE_BASE + 0x22; +pub const MON_10: crate::nl_item = DATE_BASE + 0x23; +pub const MON_11: crate::nl_item = DATE_BASE + 0x24; +pub const MON_12: crate::nl_item = DATE_BASE + 0x25; + +pub const AM_STR: crate::nl_item = DATE_BASE + 0x26; +pub const PM_STR: crate::nl_item = DATE_BASE + 0x27; + +pub const D_T_FMT: crate::nl_item = DATE_BASE + 0x28; +pub const D_FMT: crate::nl_item = DATE_BASE + 0x29; +pub const T_FMT: crate::nl_item = DATE_BASE + 0x2A; +pub const T_FMT_AMPM: crate::nl_item = DATE_BASE + 0x2B; + +pub const ERA: crate::nl_item = DATE_BASE + 0x2C; +pub const ERA_D_FMT: crate::nl_item = DATE_BASE + 0x2E; +pub const ALT_DIGITS: crate::nl_item = DATE_BASE + 0x2F; +pub const ERA_D_T_FMT: crate::nl_item = DATE_BASE + 0x30; +pub const ERA_T_FMT: crate::nl_item = DATE_BASE + 0x31; + +cfg_if! { + if #[cfg(any( + target_env = "gnu", + target_env = "musl", + target_env = "ohos" + ))] { + pub const CODESET: crate::nl_item = 14; + pub const CRNCYSTR: crate::nl_item = 0x4000F; + pub const RADIXCHAR: crate::nl_item = 0x10000; + pub const THOUSEP: crate::nl_item = 0x10001; + pub const YESEXPR: crate::nl_item = 0x50000; + pub const NOEXPR: crate::nl_item = 0x50001; + pub const YESSTR: crate::nl_item = 0x50002; + pub const NOSTR: crate::nl_item = 0x50003; + } else if #[cfg(target_env = "uclibc")] { + pub const CODESET: crate::nl_item = 10; + pub const CRNCYSTR: crate::nl_item = 0x215; + pub const RADIXCHAR: crate::nl_item = 0x100; + pub const THOUSEP: crate::nl_item = 0x101; + pub const YESEXPR: crate::nl_item = 0x500; + pub const NOEXPR: crate::nl_item = 0x501; + pub const YESSTR: crate::nl_item = 0x502; + pub const NOSTR: crate::nl_item = 0x503; + } +} + +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 _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 _CS_PATH: c_int = 0; +pub const _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS: c_int = 1; +pub const _CS_POSIX_V5_WIDTH_RESTRICTED_ENVS: c_int = 4; +pub const _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS: c_int = 5; +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 RLIM_SAVED_MAX: crate::rlim_t = crate::RLIM_INFINITY; +pub const RLIM_SAVED_CUR: crate::rlim_t = crate::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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; +#[cfg(not(target_env = "uclibc"))] +pub const EM_OPENRISC: u16 = 92; +#[cfg(target_env = "uclibc")] +pub const EM_OR1K: 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_RISCV: u16 = 243; +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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_HWCAP3: c_ulong = 29; +pub const AT_HWCAP4: c_ulong = 30; +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; +#[cfg(not(target_env = "uclibc"))] +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_MADV_DONTNEED: c_int = 4; + +pub const S_IEXEC: crate::mode_t = 0o0100; +pub const S_IWRITE: crate::mode_t = 0o0200; +pub const S_IREAD: crate::mode_t = 0o0400; + +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 = ptr::null_mut(); +pub const RTLD_NODELETE: c_int = 0x1000; +pub const RTLD_NOW: c_int = 0x2; + +pub const AT_EACCESS: c_int = 0x200; + +pub const PTHREAD_BARRIER_SERIAL_THREAD: c_int = -1; +pub const PTHREAD_ONCE_INIT: crate::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; +#[cfg(not(target_os = "l4re"))] +pub const PTHREAD_MUTEX_STALLED: c_int = 0; +#[cfg(not(target_os = "l4re"))] +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; +#[cfg(not(target_os = "l4re"))] +pub const __SIZEOF_PTHREAD_COND_T: usize = 48; + +// 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: crate::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 = if cfg!(musl_redir_time64) { 0x102 } else { 2 }; +pub const IPC_INFO: c_int = 3; + +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 LOG_NFACILITIES: c_int = 24; + +pub const SEM_FAILED: *mut crate::sem_t = ptr::null_mut(); + +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; +#[cfg(not(target_env = "uclibc"))] +pub const NI_IDN: c_int = 32; + +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 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 = (-1 as c_long) as c_ulong; + +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 ITIMER_REAL: c_int = 0; +pub const ITIMER_VIRTUAL: c_int = 1; +pub const ITIMER_PROF: c_int = 2; + +pub const _POSIX_VDISABLE: crate::cc_t = 0; + +pub const IPV6_RTHDR_LOOSE: c_int = 0; +pub const IPV6_RTHDR_STRICT: c_int = 1; + +pub const IUTF8: crate::tcflag_t = 0x00004000; +#[cfg(not(all(target_env = "uclibc", target_arch = "mips")))] +pub const CMSPAR: crate::tcflag_t = 0o10000000000; + +cfg_if! { + if #[cfg(not(target_os = "l4re"))] { + 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; + } +} + +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; +cfg_if! { + if #[cfg(not(target_os = "l4re"))] { + 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 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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const RT_CLASS_MAX: u8 = 255; + +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; + +// 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/asm-generic/mman-common.h +pub const MAP_FIXED_NOREPLACE: c_int = 0x100000; +pub const MLOCK_ONFAULT: c_uint = 0x01; + +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; + +// 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 CSIGNAL: c_int = 0x000000ff; + +#[cfg(not(target_os = "l4re"))] +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; + +// elf.h +pub const NT_PRSTATUS: c_int = 1; +#[cfg(not(target_os = "l4re"))] +pub const NT_PRFPREG: c_int = 2; +pub const NT_FPREGSET: c_int = 2; +pub const NT_PRPSINFO: c_int = 3; +#[cfg(not(target_os = "l4re"))] +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; + +// FIXME(1.0): C uses an unsigned int here. +pub const MS_NOUSER: c_ulong = 1 << 31; + +f! { + pub unsafe fn CMSG_NXTHDR( + mhdr: *const crate::msghdr, + cmsg: *const crate::cmsghdr, + ) -> *mut crate::cmsghdr { + if ((*cmsg).cmsg_len as usize) < size_of::() { + return ptr::null_mut(); + } + + // FIXME(msrv): `.wrapping_byte_add()` stabilized in 1.75 + let next_cmsg = cmsg + .cast::() + .wrapping_add(super::CMSG_ALIGN((*cmsg).cmsg_len as usize)) + .cast::(); + + // In case the addition wrapped. `next_addr > max_addr` + // would otherwise not work as intended. + if (next_cmsg as usize) < (cmsg as usize) { + return ptr::null_mut(); + } + + let mut max_addr = (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize; + + if cfg!(any(target_env = "musl", target_env = "ohos")) { + // musl and some of its descendants do `>= max_addr` + // comparisons in the if statement below. + // https://www.openwall.com/lists/musl/2025/12/27/1 + max_addr -= 1; + } + + if next_cmsg as usize + size_of::() > max_addr { + ptr::null_mut() + } else { + next_cmsg as *mut crate::cmsghdr + } + } + + pub unsafe fn CPU_ALLOC_SIZE(count: c_int) -> size_t { + let _dummy: cpu_set_t = mem::zeroed(); + let size_in_bits = 8 * size_of_val(&_dummy.bits[0]); + ((count as size_t + size_in_bits - 1) / 8) as size_t + } + + pub unsafe fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + cpuset.bits.fill(0); + } + + pub unsafe fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits = 8 * 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 unsafe fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits = 8 * 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 unsafe fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + 0 != (cpuset.bits[idx] & (1 << offset)) + } + + pub unsafe fn CPU_COUNT_S(size: usize, cpuset: &cpu_set_t) -> c_int { + let mut s: u32 = 0; + let size_of_mask = size_of_val(&cpuset.bits[0]); + for i in &cpuset.bits[..(size / size_of_mask)] { + s += i.count_ones(); + } + s as c_int + } + + pub unsafe fn CPU_COUNT(cpuset: &cpu_set_t) -> c_int { + CPU_COUNT_S(size_of::(), cpuset) + } + + pub unsafe fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.bits == set2.bits + } + + pub unsafe fn IPTOS_TOS(tos: u8) -> u8 { + tos & IPTOS_TOS_MASK + } + + pub unsafe fn IPTOS_PREC(tos: u8) -> u8 { + tos & IPTOS_PREC_MASK + } + + pub unsafe fn RT_TOS(tos: u8) -> u8 { + tos & crate::IPTOS_TOS_MASK + } + + pub unsafe fn RT_ADDRCLASS(flags: u32) -> u32 { + flags >> 23 + } + + pub unsafe fn RT_LOCALADDR(flags: u32) -> bool { + (flags & RTF_ADDRCLASSMASK) == (RTF_LOCAL | RTF_INTERFACE) + } + + pub unsafe fn ELF32_R_SYM(val: Elf32_Word) -> Elf32_Word { + val >> 8 + } + + pub unsafe fn ELF32_R_TYPE(val: Elf32_Word) -> Elf32_Word { + val & 0xff + } + + pub unsafe fn ELF32_R_INFO(sym: Elf32_Word, t: Elf32_Word) -> Elf32_Word { + sym << (8 + t) & 0xff + } + + pub unsafe fn ELF64_R_SYM(val: Elf64_Xword) -> Elf64_Xword { + val >> 32 + } + + pub unsafe fn ELF64_R_TYPE(val: Elf64_Xword) -> Elf64_Xword { + val & 0xffffffff + } + + pub unsafe fn ELF64_R_INFO(sym: Elf64_Xword, t: Elf64_Xword) -> Elf64_Xword { + sym << (32 + t) + } +} + +safe_f! { + pub const safe fn makedev(major: c_uint, minor: c_uint) -> crate::dev_t { + let major = major as crate::dev_t; + let minor = minor as crate::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 safe fn major(dev: crate::dev_t) -> c_uint { + let mut major = 0; + major |= (dev & 0x00000000000fff00) >> 8; + major |= (dev & 0xfffff00000000000) >> 32; + major as c_uint + } + + pub const safe fn minor(dev: crate::dev_t) -> c_uint { + let mut minor = 0; + minor |= (dev & 0x00000000000000ff) >> 0; + minor |= (dev & 0x00000ffffff00000) >> 12; + minor as c_uint + } +} + +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(all(not(target_env = "uclibc"), not(target_env = "ohos")))] { + extern "C" { + #[cfg_attr(gnu_file_offset_bits64, link_name = "aio_read64")] + pub fn aio_read(aiocbp: *mut crate::aiocb) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "aio_write64")] + pub fn aio_write(aiocbp: *mut crate::aiocb) -> c_int; + pub fn aio_fsync(op: c_int, aiocbp: *mut crate::aiocb) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "aio_error64")] + pub fn aio_error(aiocbp: *const crate::aiocb) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "aio_return64")] + pub fn aio_return(aiocbp: *mut crate::aiocb) -> ssize_t; + #[cfg_attr( + any(musl_redir_time64, gnu_time_bits64), + link_name = "__aio_suspend_time64" + )] + pub fn aio_suspend( + aiocb_list: *const *const crate::aiocb, + nitems: c_int, + timeout: *const crate::timespec, + ) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "aio_cancel64")] + pub fn aio_cancel(fd: c_int, aiocbp: *mut crate::aiocb) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "lio_listio64")] + pub fn lio_listio( + mode: c_int, + aiocb_list: *const *mut crate::aiocb, + nitems: c_int, + sevp: *mut crate::sigevent, + ) -> c_int; + } + } +} + +cfg_if! { + if #[cfg(not(target_env = "uclibc"))] { + extern "C" { + #[cfg_attr(gnu_file_offset_bits64, link_name = "pwritev64")] + pub fn pwritev( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: crate::off_t, + ) -> ssize_t; + #[cfg_attr(gnu_file_offset_bits64, link_name = "preadv64")] + pub fn preadv( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: crate::off_t, + ) -> ssize_t; + pub fn getnameinfo( + sa: *const crate::sockaddr, + salen: crate::socklen_t, + host: *mut c_char, + hostlen: crate::socklen_t, + serv: *mut c_char, + servlen: crate::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: crate::pid_t, + local_iov: *const crate::iovec, + liovcnt: c_ulong, + remote_iov: *const crate::iovec, + riovcnt: c_ulong, + flags: c_ulong, + ) -> isize; + pub fn process_vm_writev( + pid: crate::pid_t, + local_iov: *const crate::iovec, + liovcnt: c_ulong, + remote_iov: *const crate::iovec, + riovcnt: c_ulong, + flags: c_ulong, + ) -> isize; + #[cfg_attr(gnu_time_bits64, link_name = "__futimes64")] + #[cfg_attr(musl_redir_time64, link_name = "__futimes_time64")] + pub fn futimes(fd: c_int, times: *const crate::timeval) -> 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 jrand48(xseed: *mut c_ushort) -> c_long; + pub fn srand48(seed: c_long); + + pub fn setpwent(); + pub fn endpwent(); + pub fn getpwent() -> *mut passwd; + pub fn setgrent(); + pub fn endgrent(); + pub fn getgrent() -> *mut crate::group; + #[cfg(not(target_os = "l4re"))] + pub fn setspent(); + #[cfg(not(target_os = "l4re"))] + pub fn endspent(); + #[cfg(not(target_os = "l4re"))] + pub fn getspent() -> *mut spwd; + + pub fn getspnam(name: *const c_char) -> *mut spwd; + + // System V IPC + pub fn shmget(key: crate::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; + #[cfg_attr(gnu_time_bits64, link_name = "__shmctl64")] + pub fn shmctl(shmid: c_int, cmd: c_int, buf: *mut crate::shmid_ds) -> c_int; + + pub fn mprotect(addr: *mut c_void, len: size_t, prot: c_int) -> c_int; + pub fn __errno_location() -> *mut c_int; + + #[cfg_attr(gnu_time_bits64, link_name = "__glob64_time64")] + #[cfg_attr( + all(not(gnu_time_bits64), gnu_file_offset_bits64), + link_name = "glob64" + )] + pub fn glob( + pattern: *const c_char, + flags: c_int, + errfunc: Option c_int>, + pglob: *mut crate::glob_t, + ) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__globfree64_time64")] + #[cfg_attr( + all(not(gnu_time_bits64), gnu_file_offset_bits64), + link_name = "globfree64" + )] + pub fn globfree(pglob: *mut crate::glob_t); + + pub fn seekdir(dirp: *mut crate::DIR, loc: c_long); + + pub fn telldir(dirp: *mut crate::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 crate::sockaddr, + addrlen: *mut crate::socklen_t, + ) -> ssize_t; + + pub fn nl_langinfo(item: crate::nl_item) -> *mut c_char; + pub fn nl_langinfo_l(item: crate::nl_item, locale: crate::locale_t) -> *mut c_char; + + pub fn sched_getaffinity( + pid: crate::pid_t, + cpusetsize: size_t, + cpuset: *mut cpu_set_t, + ) -> c_int; + pub fn sched_get_priority_max(policy: c_int) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__settimeofday64")] + #[cfg_attr(musl_redir_time64, link_name = "__settimeofday_time64")] + pub fn settimeofday(tv: *const crate::timeval, tz: *const crate::timezone) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__sem_timedwait64")] + #[cfg_attr(musl_redir_time64, link_name = "__sem_timedwait_time64")] + pub fn sem_timedwait(sem: *mut crate::sem_t, abstime: *const crate::timespec) -> c_int; + pub fn sem_getvalue(sem: *mut crate::sem_t, sval: *mut c_int) -> c_int; + pub fn mount( + src: *const c_char, + target: *const c_char, + fstype: *const c_char, + flags: c_ulong, + data: *const c_void, + ) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__prctl_time64")] + pub fn prctl(option: c_int, ...) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__ppoll64")] + #[cfg_attr(musl_redir_time64, link_name = "__ppoll_time64")] + pub fn ppoll( + fds: *mut crate::pollfd, + nfds: crate::nfds_t, + timeout: *const crate::timespec, + sigmask: *const crate::sigset_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 sysinfo(info: *mut crate::sysinfo) -> c_int; + pub fn sigsuspend(mask: *const crate::sigset_t) -> c_int; + pub fn getgrgid_r( + gid: crate::gid_t, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn sem_close(sem: *mut crate::sem_t) -> c_int; + pub fn getgrnam_r( + name: *const c_char, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn initgroups(user: *const c_char, group: crate::gid_t) -> c_int; + pub fn sem_open(name: *const c_char, oflag: c_int, ...) -> *mut crate::sem_t; + pub fn getgrnam(name: *const c_char) -> *mut crate::group; + pub fn sem_unlink(name: *const c_char) -> c_int; + pub fn daemon(nochdir: c_int, noclose: c_int) -> c_int; + pub fn sigwait(set: *const crate::sigset_t, sig: *mut c_int) -> c_int; + pub fn getgrgid(gid: crate::gid_t) -> *mut crate::group; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut crate::FILE; + pub fn faccessat(dirfd: c_int, pathname: *const c_char, mode: c_int, flags: c_int) -> c_int; + pub fn dl_iterate_phdr( + callback: Option< + unsafe extern "C" fn( + info: *mut crate::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 crate::FILE; + pub fn getmntent(stream: *mut crate::FILE) -> *mut crate::mntent; + pub fn addmntent(stream: *mut crate::FILE, mnt: *const crate::mntent) -> c_int; + pub fn endmntent(streamp: *mut crate::FILE) -> c_int; + pub fn hasmntopt(mnt: *const crate::mntent, opt: *const c_char) -> *mut c_char; + + pub fn regcomp(preg: *mut crate::regex_t, pattern: *const c_char, cflags: c_int) -> c_int; + + pub fn regexec( + preg: *const crate::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 crate::regex_t, + errbuf: *mut c_char, + errbuf_size: size_t, + ) -> size_t; + + pub fn regfree(preg: *mut crate::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() -> crate::pid_t; + + pub fn timer_create( + clockid: crate::clockid_t, + sevp: *mut crate::sigevent, + timerid: *mut crate::timer_t, + ) -> c_int; + pub fn timer_delete(timerid: crate::timer_t) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn timer_getoverrun(timerid: crate::timer_t) -> c_int; + #[cfg_attr( + any(gnu_time_bits64, musl_redir_time64), + link_name = "__timer_gettime64" + )] + pub fn timer_gettime(timerid: crate::timer_t, curr_value: *mut crate::itimerspec) -> c_int; + #[cfg_attr( + any(gnu_time_bits64, musl_redir_time64), + link_name = "__timer_settime64" + )] + pub fn timer_settime( + timerid: crate::timer_t, + flags: c_int, + new_value: *const crate::itimerspec, + old_value: *mut crate::itimerspec, + ) -> 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 getopt_long( + argc: c_int, + argv: *const *mut c_char, + optstring: *const c_char, + longopts: *const option, + longindex: *mut c_int, + ) -> c_int; + + #[cfg(not(target_env = "uclibc"))] + pub fn copy_file_range( + fd_in: c_int, + off_in: *mut crate::off64_t, + fd_out: c_int, + off_out: *mut crate::off64_t, + len: size_t, + flags: c_uint, + ) -> ssize_t; +} + +cfg_if! { + if #[cfg(not(any(target_env = "musl", target_env = "ohos")))] { + extern "C" { + pub fn freopen64( + filename: *const c_char, + mode: *const c_char, + file: *mut crate::FILE, + ) -> *mut crate::FILE; + pub fn fseeko64( + stream: *mut crate::FILE, + offset: crate::off64_t, + whence: c_int, + ) -> c_int; + pub fn fsetpos64(stream: *mut crate::FILE, ptr: *const crate::fpos64_t) -> c_int; + pub fn ftello64(stream: *mut crate::FILE) -> crate::off64_t; + } + } +} 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..9081f84 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/mod.rs @@ -0,0 +1,2234 @@ +use crate::prelude::*; + +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 useconds_t = u32; +pub type key_t = c_int; +pub type id_t = c_uint; + +extern_ty! { + pub type timezone; +} + +s! { + pub struct in_addr { + pub s_addr: crate::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: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_zero: [u8; 8], + } + + pub struct sockaddr_in6 { + pub sin6_family: sa_family_t, + pub sin6_port: crate::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: crate::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(not(target_os = "android"))] + pub ai_addr: *mut crate::sockaddr, + + pub ai_canonname: *mut c_char, + + #[cfg(target_os = "android")] + pub ai_addr: *mut crate::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 as usize / 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, + } + + #[cfg(not(any(target_env = "musl", target_os = "emscripten", target_env = "ohos")))] + 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 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: crate::in_addr, + pub ipi_addr: crate::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 crate::sockaddr, + pub ifa_netmask: *mut crate::sockaddr, + pub ifa_ifu: *mut crate::sockaddr, // FIXME(union) This should be a union + pub ifa_data: *mut c_void, + } + + pub struct in6_rtmsg { + rtmsg_dst: crate::in6_addr, + rtmsg_src: crate::in6_addr, + rtmsg_gateway: crate::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: crate::sockaddr, + pub arp_ha: crate::sockaddr, + pub arp_flags: c_int, + pub arp_netmask: crate::sockaddr, + pub arp_dev: [c_char; 16], + } + + pub struct arpreq_old { + pub arp_pa: crate::sockaddr, + pub arp_ha: crate::sockaddr, + pub arp_flags: c_int, + pub arp_netmask: crate::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: crate::msghdr, + pub msg_len: c_uint, + } + + 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: Padding<[u8; 128 - 2 - 4]>, + #[cfg(target_pointer_width = "64")] + __ss_pad2: Padding<[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 if_nameindex { + pub if_index: c_uint, + pub if_name: *mut c_char, + } +} + +cfg_if! { + if #[cfg(not(any(target_os = "emscripten", target_os = "l4re")))] { + s! { + pub struct file_clone_range { + pub src_fd: crate::__s64, + pub src_offset: crate::__u64, + pub src_length: crate::__u64, + pub dest_offset: crate::__u64, + } + + // linux/filter.h + pub struct sock_filter { + pub code: crate::__u16, + pub jt: crate::__u8, + pub jf: crate::__u8, + pub k: crate::__u32, + } + + pub struct sock_fprog { + pub len: c_ushort, + pub filter: *mut sock_filter, + } + } + } +} + +cfg_if! { + if #[cfg(any( + target_env = "gnu", + target_os = "android", + all(target_env = "musl", musl_v1_2_3) + ))] { + s! { + pub struct statx { + pub stx_mask: crate::__u32, + pub stx_blksize: crate::__u32, + pub stx_attributes: crate::__u64, + pub stx_nlink: crate::__u32, + pub stx_uid: crate::__u32, + pub stx_gid: crate::__u32, + pub stx_mode: crate::__u16, + __statx_pad1: Padding<[crate::__u16; 1]>, + pub stx_ino: crate::__u64, + pub stx_size: crate::__u64, + pub stx_blocks: crate::__u64, + pub stx_attributes_mask: crate::__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: crate::__u32, + pub stx_rdev_minor: crate::__u32, + pub stx_dev_major: crate::__u32, + pub stx_dev_minor: crate::__u32, + pub stx_mnt_id: crate::__u64, + pub stx_dio_mem_align: crate::__u32, + pub stx_dio_offset_align: crate::__u32, + // The following fields are not available on Android as of + // 2026-06. + #[cfg(target_os = "linux")] + pub stx_subvol: crate::__u64, + #[cfg(target_os = "linux")] + pub stx_atomic_write_unit_min: crate::__u32, + #[cfg(target_os = "linux")] + pub stx_atomic_write_unit_max: crate::__u32, + #[cfg(target_os = "linux")] + pub stx_atomic_write_segments_max: crate::__u32, + #[cfg(target_os = "linux")] + pub stx_dio_read_offset_align: crate::__u32, + #[cfg(target_os = "linux")] + pub stx_atomic_write_unit_max_opt: crate::__u32, + #[cfg(target_os = "linux")] + __statx_pad2: Padding<[crate::__u32; 1]>, + #[cfg(target_os = "linux")] + __statx_pad3: Padding<[crate::__u64; 8]>, + #[cfg(not(target_os = "linux"))] + __statx_pad3: Padding<[crate::__u64; 12]>, + } + + pub struct statx_timestamp { + pub tv_sec: crate::__s64, + pub tv_nsec: crate::__u32, + __statx_timestamp_pad1: Padding<[crate::__s32; 1]>, + } + } + } +} + +s_no_extra_traits! { + #[cfg_attr( + any(target_arch = "x86_64", all(target_arch = "x86", target_env = "gnu")), + repr(packed) + )] + pub struct epoll_event { + pub events: u32, + pub u64: u64, + } + + pub struct sigevent { + pub sigev_value: crate::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: Padding<[c_int; 11]>, + #[cfg(target_pointer_width = "32")] + __unused1: Padding<[c_int; 12]>, + } +} + +cfg_if! { + if #[cfg(all(feature = "extra_traits", not(target_os = "l4re")))] { + 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 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 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 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: crate::clockid_t = 0; +pub const CLOCK_MONOTONIC: crate::clockid_t = 1; +pub const CLOCK_PROCESS_CPUTIME_ID: crate::clockid_t = 2; +pub const CLOCK_THREAD_CPUTIME_ID: crate::clockid_t = 3; +pub const CLOCK_MONOTONIC_RAW: crate::clockid_t = 4; +pub const CLOCK_REALTIME_COARSE: crate::clockid_t = 5; +pub const CLOCK_MONOTONIC_COARSE: crate::clockid_t = 6; +pub const CLOCK_BOOTTIME: crate::clockid_t = 7; +pub const CLOCK_REALTIME_ALARM: crate::clockid_t = 8; +pub const CLOCK_BOOTTIME_ALARM: crate::clockid_t = 9; +pub const CLOCK_TAI: crate::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 = 0o1_0000; +pub const S_IFCHR: mode_t = 0o2_0000; +pub const S_IFBLK: mode_t = 0o6_0000; +pub const S_IFDIR: mode_t = 0o4_0000; +pub const S_IFREG: mode_t = 0o10_0000; +pub const S_IFLNK: mode_t = 0o12_0000; +pub const S_IFSOCK: mode_t = 0o14_0000; +pub const S_IFMT: mode_t = 0o17_0000; +pub const S_IRWXU: mode_t = 0o0700; +pub const S_IXUSR: mode_t = 0o0100; +pub const S_IWUSR: mode_t = 0o0200; +pub const S_IRUSR: mode_t = 0o0400; +pub const S_IRWXG: mode_t = 0o0070; +pub const S_IXGRP: mode_t = 0o0010; +pub const S_IWGRP: mode_t = 0o0020; +pub const S_IRGRP: mode_t = 0o0040; +pub const S_IRWXO: mode_t = 0o0007; +pub const S_IXOTH: mode_t = 0o0001; +pub const S_IWOTH: mode_t = 0o0002; +pub const S_IROTH: mode_t = 0o0004; +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 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; + +#[cfg(not(target_os = "l4re"))] +pub const XATTR_CREATE: c_int = 0x1; +#[cfg(not(target_os = "l4re"))] +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: crate::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_NOSYMFOLLOW: c_ulong = 0x100; +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; +// MS_VERBOSE is deprecated +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; +#[cfg(not(target_os = "l4re"))] +pub const MADV_COLD: c_int = 20; +#[cfg(not(target_os = "l4re"))] +pub const MADV_PAGEOUT: c_int = 21; +pub const MADV_HWPOISON: c_int = 100; +cfg_if! { + if #[cfg(not(any(target_os = "emscripten", target_os = "l4re")))] { + 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; +#[cfg(not(target_os = "l4re"))] +pub const IP_NODEFRAG: c_int = 22; +#[cfg(not(target_os = "l4re"))] +pub const IP_CHECKSUM: c_int = 23; +#[cfg(not(target_os = "l4re"))] +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; +#[cfg(not(target_os = "l4re"))] +pub const IP_PMTUDISC_INTERFACE: c_int = 4; +#[cfg(not(target_os = "l4re"))] +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 +#[cfg(not(target_os = "l4re"))] +pub const IPPROTO_MPTCP: c_int = 262; +/// Ethernet-within-IPv6 encapsulation. +#[cfg(not(target_os = "l4re"))] +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; +#[cfg(not(target_os = "l4re"))] +pub const IPV6_RECVPATHMTU: c_int = 60; +#[cfg(not(target_os = "l4re"))] +pub const IPV6_PATHMTU: c_int = 61; +#[cfg(not(target_os = "l4re"))] +pub const IPV6_DONTFRAG: c_int = 62; +pub const IPV6_RECVTCLASS: c_int = 66; +pub const IPV6_TCLASS: c_int = 67; +cfg_if! { + if #[cfg(not(target_os = "l4re"))] { + 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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const NAME_MAX: c_int = 255; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 = u32_cast_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; + +cfg_if! { + if #[cfg(not(target_os = "l4re"))] { + 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: crate::tcflag_t = 0x00000000; +pub const NL1: crate::tcflag_t = 0x00000100; +pub const TAB0: crate::tcflag_t = 0x00000000; +pub const CR0: crate::tcflag_t = 0x00000000; +pub const FF0: crate::tcflag_t = 0x00000000; +pub const BS0: crate::tcflag_t = 0x00000000; +pub const VT0: crate::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: crate::tcflag_t = 0x00000001; +pub const BRKINT: crate::tcflag_t = 0x00000002; +pub const IGNPAR: crate::tcflag_t = 0x00000004; +pub const PARMRK: crate::tcflag_t = 0x00000008; +pub const INPCK: crate::tcflag_t = 0x00000010; +pub const ISTRIP: crate::tcflag_t = 0x00000020; +pub const INLCR: crate::tcflag_t = 0x00000040; +pub const IGNCR: crate::tcflag_t = 0x00000080; +pub const ICRNL: crate::tcflag_t = 0x00000100; +pub const IXANY: crate::tcflag_t = 0x00000800; +pub const IMAXBEL: crate::tcflag_t = 0x00002000; +pub const OPOST: crate::tcflag_t = 0x1; +pub const CS5: crate::tcflag_t = 0x00000000; +pub const CRTSCTS: crate::tcflag_t = 0x80000000; +pub const ECHO: crate::tcflag_t = 0x00000008; +pub const OCRNL: crate::tcflag_t = 0o000010; +pub const ONOCR: crate::tcflag_t = 0o000020; +pub const ONLRET: crate::tcflag_t = 0o000040; +pub const OFILL: crate::tcflag_t = 0o000100; +pub const OFDEL: crate::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; +#[cfg(not(target_os = "l4re"))] +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 = u32_cast_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; + +cfg_if! { + if #[cfg(not(target_os = "l4re"))] { + // 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 = u32_cast_int(0x80000000); + +cfg_if! { + if #[cfg(not(target_os = "l4re"))] { + 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; + +#[cfg(not(target_os = "l4re"))] +pub const PIPE_BUF: usize = 4096; + +pub const SI_LOAD_SHIFT: c_uint = 16; + +// si_code values +pub const SI_USER: c_int = 0; +pub const SI_KERNEL: c_int = 0x80; +pub const SI_QUEUE: c_int = -1; +cfg_if! { + if #[cfg(not(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64" + )))] { + pub const SI_TIMER: c_int = -2; + pub const SI_MESGQ: c_int = -3; + pub const SI_ASYNCIO: c_int = -4; + } else { + pub const SI_TIMER: c_int = -3; + pub const SI_MESGQ: c_int = -4; + pub const SI_ASYNCIO: c_int = -2; + } +} +pub const SI_SIGIO: c_int = -5; +pub const SI_TKILL: c_int = -6; +pub const SI_ASYNCNL: c_int = -60; + +// 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 +#[cfg(not(target_os = "l4re"))] +pub const BUS_MCEERR_AR: c_int = 4; +#[cfg(not(target_os = "l4re"))] +pub const BUS_MCEERR_AO: c_int = 5; + +// si_code values for SIGTRAP +pub const TRAP_BRKPT: c_int = 1; +pub const TRAP_TRACE: c_int = 2; +#[cfg(not(target_os = "l4re"))] +pub const TRAP_BRANCH: c_int = 3; +#[cfg(not(target_os = "l4re"))] +pub const TRAP_HWBKPT: c_int = 4; +#[cfg(not(target_os = "l4re"))] +pub const TRAP_UNK: 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(not(any(target_os = "emscripten", target_os = "l4re")))] { + // linux/if_tun.h + /* TUNSETIFF ifr flags */ + 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 = crate::IFF_TUN as c_short; + pub const TUN_TAP_DEV: c_short = crate::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; + // Ioctl operation codes + const T_TYPE: u32 = b'T' as u32; + pub const TUNSETNOCSUM: Ioctl = _IOW::(T_TYPE, 200); + pub const TUNSETDEBUG: Ioctl = _IOW::(T_TYPE, 201); + pub const TUNSETIFF: Ioctl = _IOW::(T_TYPE, 202); + pub const TUNSETPERSIST: Ioctl = _IOW::(T_TYPE, 203); + pub const TUNSETOWNER: Ioctl = _IOW::(T_TYPE, 204); + pub const TUNSETLINK: Ioctl = _IOW::(T_TYPE, 205); + pub const TUNSETGROUP: Ioctl = _IOW::(T_TYPE, 206); + pub const TUNGETFEATURES: Ioctl = _IOR::(T_TYPE, 207); + pub const TUNSETOFFLOAD: Ioctl = _IOW::(T_TYPE, 208); + pub const TUNSETTXFILTER: Ioctl = _IOW::(T_TYPE, 209); + pub const TUNGETIFF: Ioctl = _IOR::(T_TYPE, 210); + pub const TUNGETSNDBUF: Ioctl = _IOR::(T_TYPE, 211); + pub const TUNSETSNDBUF: Ioctl = _IOW::(T_TYPE, 212); + pub const TUNATTACHFILTER: Ioctl = _IOW::(T_TYPE, 213); + pub const TUNDETACHFILTER: Ioctl = _IOW::(T_TYPE, 214); + pub const TUNGETVNETHDRSZ: Ioctl = _IOR::(T_TYPE, 215); + pub const TUNSETVNETHDRSZ: Ioctl = _IOW::(T_TYPE, 216); + pub const TUNSETQUEUE: Ioctl = _IOW::(T_TYPE, 217); + pub const TUNSETIFINDEX: Ioctl = _IOW::(T_TYPE, 218); + pub const TUNGETFILTER: Ioctl = _IOR::(T_TYPE, 219); + pub const TUNSETVNETLE: Ioctl = _IOW::(T_TYPE, 220); + pub const TUNGETVNETLE: Ioctl = _IOR::(T_TYPE, 221); + pub const TUNSETVNETBE: Ioctl = _IOW::(T_TYPE, 222); + pub const TUNGETVNETBE: Ioctl = _IOR::(T_TYPE, 223); + pub const TUNSETSTEERINGEBPF: Ioctl = _IOR::(T_TYPE, 224); + pub const TUNSETFILTEREBPF: Ioctl = _IOR::(T_TYPE, 225); + pub const TUNSETCARRIER: Ioctl = _IOW::(T_TYPE, 226); + pub const TUNGETDEVNETNS: Ioctl = _IO(T_TYPE, 227); + + // linux/fs.h + pub const FS_IOC_GETFLAGS: Ioctl = _IOR::('f' as u32, 1); + pub const FS_IOC_SETFLAGS: Ioctl = _IOW::('f' as u32, 2); + pub const FS_IOC_GETVERSION: Ioctl = _IOR::('v' as u32, 1); + pub const FS_IOC_SETVERSION: Ioctl = _IOW::('v' as u32, 2); + pub const FS_IOC32_GETFLAGS: Ioctl = _IOR::('f' as u32, 1); + pub const FS_IOC32_SETFLAGS: Ioctl = _IOW::('f' as u32, 2); + pub const FS_IOC32_GETVERSION: Ioctl = _IOR::('v' as u32, 1); + pub const FS_IOC32_SETVERSION: Ioctl = _IOW::('v' as u32, 2); + + pub const FICLONE: Ioctl = _IOW::(0x94, 9); + pub const FICLONERANGE: Ioctl = _IOW::(0x94, 13); + } +} + +cfg_if! { + if #[cfg(any(target_os = "emscripten", target_os = "l4re"))] { + // 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 = u32_cast_long(0xcafe4a11); + pub const BTRFS_SUPER_MAGIC: c_long = u32_cast_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 = u32_cast_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 = u32_cast_long(0xf995e849); + pub const HUGETLBFS_MAGIC: c_long = u32_cast_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 = u32_cast_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 = u32_cast_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; + } +} + +cfg_if! { + if #[cfg(any( + target_env = "gnu", + target_os = "android", + all(target_env = "musl", musl_v1_2_3), + target_os = "l4re" + ))] { + 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_ALL: c_uint = 0x0fff; + pub const STATX_MNT_ID: c_uint = 0x1000; + pub const STATX_DIOALIGN: c_uint = 0x2000; + pub const STATX__RESERVED: c_int = u32_cast_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 = 0x100000; + pub const STATX_ATTR_DAX: c_int = 0x200000; + } +} + +// https://github.com/search?q=repo%3Atorvalds%2Flinux+%22%23define+_IOC_NONE%22&type=code +cfg_if! { + if #[cfg(not(target_os = "emscripten"))] { + const _IOC_NRBITS: u32 = 8; + const _IOC_TYPEBITS: u32 = 8; + + cfg_if! { + if #[cfg(any( + any(target_arch = "powerpc", target_arch = "powerpc64"), + any(target_arch = "sparc", target_arch = "sparc64"), + any(target_arch = "mips", target_arch = "mips64"), + ))] { + // https://github.com/torvalds/linux/blob/b311c1b497e51a628aa89e7cb954481e5f9dced2/arch/powerpc/include/uapi/asm/ioctl.h + // https://github.com/torvalds/linux/blob/b311c1b497e51a628aa89e7cb954481e5f9dced2/arch/sparc/include/uapi/asm/ioctl.h + // https://github.com/torvalds/linux/blob/b311c1b497e51a628aa89e7cb954481e5f9dced2/arch/mips/include/uapi/asm/ioctl.h + + const _IOC_SIZEBITS: u32 = 13; + const _IOC_DIRBITS: u32 = 3; + + const _IOC_NONE: u32 = 1; + const _IOC_READ: u32 = 2; + const _IOC_WRITE: u32 = 4; + } else { + // https://github.com/torvalds/linux/blob/b311c1b497e51a628aa89e7cb954481e5f9dced2/include/uapi/asm-generic/ioctl.h + + const _IOC_SIZEBITS: u32 = 14; + const _IOC_DIRBITS: u32 = 2; + + const _IOC_NONE: u32 = 0; + const _IOC_WRITE: u32 = 1; + const _IOC_READ: u32 = 2; + } + } + const _IOC_NRMASK: u32 = (1 << _IOC_NRBITS) - 1; + const _IOC_TYPEMASK: u32 = (1 << _IOC_TYPEBITS) - 1; + const _IOC_SIZEMASK: u32 = (1 << _IOC_SIZEBITS) - 1; + const _IOC_DIRMASK: u32 = (1 << _IOC_DIRBITS) - 1; + + const _IOC_NRSHIFT: u32 = 0; + const _IOC_TYPESHIFT: u32 = _IOC_NRSHIFT + _IOC_NRBITS; + const _IOC_SIZESHIFT: u32 = _IOC_TYPESHIFT + _IOC_TYPEBITS; + const _IOC_DIRSHIFT: u32 = _IOC_SIZESHIFT + _IOC_SIZEBITS; + + // adapted from https://github.com/torvalds/linux/blob/8a696a29c6905594e4abf78eaafcb62165ac61f1/rust/kernel/ioctl.rs + + /// Build an ioctl number, analogous to the C macro of the same name. + const fn _IOC(dir: u32, ty: u32, nr: u32, size: usize) -> Ioctl { + core::debug_assert!(dir <= _IOC_DIRMASK); + core::debug_assert!(ty <= _IOC_TYPEMASK); + core::debug_assert!(nr <= _IOC_NRMASK); + core::debug_assert!(size <= (_IOC_SIZEMASK as usize)); + + ((dir << _IOC_DIRSHIFT) + | (ty << _IOC_TYPESHIFT) + | (nr << _IOC_NRSHIFT) + | ((size as u32) << _IOC_SIZESHIFT)) as Ioctl + } + + /// Build an ioctl number for an argumentless ioctl. + pub const fn _IO(ty: u32, nr: u32) -> Ioctl { + _IOC(_IOC_NONE, ty, nr, 0) + } + + /// Build an ioctl number for an read-only ioctl. + pub const fn _IOR(ty: u32, nr: u32) -> Ioctl { + _IOC(_IOC_READ, ty, nr, size_of::()) + } + + /// Build an ioctl number for an write-only ioctl. + pub const fn _IOW(ty: u32, nr: u32) -> Ioctl { + _IOC(_IOC_WRITE, ty, nr, size_of::()) + } + + /// Build an ioctl number for a read-write ioctl. + pub const fn _IOWR(ty: u32, nr: u32) -> Ioctl { + _IOC(_IOC_READ | _IOC_WRITE, ty, nr, size_of::()) + } + + extern "C" { + #[cfg_attr(gnu_time_bits64, link_name = "__ioctl_time64")] + pub fn ioctl(fd: c_int, request: Ioctl, ...) -> c_int; + } + } +} + +const fn CMSG_ALIGN(len: usize) -> usize { + (len + size_of::() - 1) & !(size_of::() - 1) +} + +f! { + pub unsafe fn CMSG_FIRSTHDR(mhdr: *const crate::msghdr) -> *mut crate::cmsghdr { + if (*mhdr).msg_controllen as usize >= size_of::() { + (*mhdr).msg_control.cast() + } else { + ptr::null_mut() + } + } + + pub unsafe fn CMSG_DATA(cmsg: *const crate::cmsghdr) -> *mut c_uchar { + cmsg.offset(1) as *mut c_uchar + } + + pub const unsafe fn CMSG_SPACE(length: c_uint) -> c_uint { + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(size_of::())) as c_uint + } + + pub const unsafe fn CMSG_LEN(length: c_uint) -> c_uint { + CMSG_ALIGN(size_of::()) as c_uint + length + } + + pub unsafe fn FD_CLR(fd: c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] &= !(1 << (fd % size)); + return; + } + + pub unsafe fn FD_ISSET(fd: c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0; + } + + pub unsafe fn FD_SET(fd: c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] |= 1 << (fd % size); + return; + } + + pub unsafe fn FD_ZERO(set: *mut fd_set) -> () { + (*set).fds_bits.fill(0); + } +} + +safe_f! { + pub safe fn SIGRTMAX() -> c_int { + unsafe { __libc_current_sigrtmax() } + } + + pub safe fn SIGRTMIN() -> c_int { + unsafe { __libc_current_sigrtmin() } + } + + pub const safe fn WIFSTOPPED(status: c_int) -> bool { + (status & 0xff) == 0x7f + } + + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + (status >> 8) & 0xff + } + + pub const safe fn WIFCONTINUED(status: c_int) -> bool { + status == 0xffff + } + + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + ((status & 0x7f) + 1) as i8 >= 2 + } + + pub const safe fn WTERMSIG(status: c_int) -> c_int { + status & 0x7f + } + + pub const safe fn WIFEXITED(status: c_int) -> bool { + (status & 0x7f) == 0 + } + + pub const safe fn WEXITSTATUS(status: c_int) -> c_int { + (status >> 8) & 0xff + } + + pub const safe fn WCOREDUMP(status: c_int) -> bool { + (status & 0x80) != 0 + } + + pub const safe fn W_EXITCODE(ret: c_int, sig: c_int) -> c_int { + (ret << 8) | sig + } + + pub const safe fn W_STOPCODE(sig: c_int) -> c_int { + (sig << 8) | 0x7f + } + + pub const safe fn QCMD(cmd: c_int, type_: c_int) -> c_int { + (cmd << 8) | (type_ & 0x00ff) + } + + pub const safe fn IPOPT_COPIED(o: u8) -> u8 { + o & IPOPT_COPY + } + + pub const safe fn IPOPT_CLASS(o: u8) -> u8 { + o & IPOPT_CLASS_MASK + } + + pub const safe fn IPOPT_NUMBER(o: u8) -> u8 { + o & IPOPT_NUMBER_MASK + } + + pub const safe fn IPTOS_ECN(x: u8) -> u8 { + x & crate::IPTOS_ECN_MASK + } + + #[allow(ellipsis_inclusive_range_patterns)] + pub const safe fn KERNEL_VERSION(a: u32, b: u32, c: u32) -> u32 { + ((a << 16) + (b << 8)) + if c > 255 { 255 } else { c } + } +} + +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; + #[cfg(not(target_os = "l4re"))] + pub fn mincore(addr: *mut c_void, len: size_t, vec: *mut c_uchar) -> c_int; + + #[cfg_attr(gnu_time_bits64, link_name = "__clock_getres64")] + #[cfg_attr(musl_redir_time64, link_name = "__clock_getres_time64")] + pub fn clock_getres(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + #[cfg_attr( + any(gnu_time_bits64, musl_redir_time64), + link_name = "__clock_gettime64" + )] + pub fn clock_gettime(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + #[cfg_attr( + any(gnu_time_bits64, musl_redir_time64), + link_name = "__clock_settime64" + )] + pub fn clock_settime(clk_id: crate::clockid_t, tp: *const crate::timespec) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn clock_getcpuclockid(pid: crate::pid_t, clk_id: *mut crate::clockid_t) -> c_int; + + #[cfg_attr(gnu_time_bits64, link_name = "__getitimer64")] + #[cfg_attr(musl_redir_time64, link_name = "__getitimer_time64")] + pub fn getitimer(which: c_int, curr_value: *mut crate::itimerval) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__setitimer64")] + #[cfg_attr(musl_redir_time64, link_name = "__setitimer_time64")] + pub fn setitimer( + which: c_int, + new_value: *const crate::itimerval, + old_value: *mut crate::itimerval, + ) -> c_int; + + pub fn dirfd(dirp: *mut crate::DIR) -> c_int; + + pub fn memalign(align: size_t, size: size_t) -> *mut c_void; + pub fn setgroups(ngroups: size_t, ptr: *const crate::gid_t) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn pipe2(fds: *mut c_int, flags: c_int) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "statfs64")] + pub fn statfs(path: *const c_char, buf: *mut statfs) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "fstatfs64")] + 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; + #[cfg_attr(gnu_file_offset_bits64, link_name = "posix_fadvise64")] + pub fn posix_fadvise(fd: c_int, offset: off_t, len: off_t, advise: c_int) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__futimens64")] + #[cfg_attr(musl_redir_time64, link_name = "__futimens_time64")] + #[cfg(not(target_os = "l4re"))] + pub fn futimens(fd: c_int, times: *const crate::timespec) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__utimensat64")] + #[cfg_attr(musl_redir_time64, link_name = "__utimensat_time64")] + pub fn utimensat( + dirfd: c_int, + path: *const c_char, + times: *const crate::timespec, + flag: c_int, + ) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn duplocale(base: crate::locale_t) -> crate::locale_t; + pub fn freelocale(loc: crate::locale_t); + pub fn newlocale(mask: c_int, locale: *const c_char, base: crate::locale_t) -> crate::locale_t; + pub fn uselocale(loc: crate::locale_t) -> crate::locale_t; + #[cfg(not(target_os = "l4re"))] + pub fn mknodat(dirfd: c_int, pathname: *const c_char, mode: mode_t, dev: dev_t) -> c_int; + + #[cfg(not(target_os = "l4re"))] + pub fn ptsname_r(fd: c_int, buf: *mut c_char, buflen: size_t) -> c_int; + pub fn clearenv() -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn waitid( + idtype: idtype_t, + id: id_t, + infop: *mut crate::siginfo_t, + options: c_int, + ) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn getresuid( + ruid: *mut crate::uid_t, + euid: *mut crate::uid_t, + suid: *mut crate::uid_t, + ) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn getresgid( + rgid: *mut crate::gid_t, + egid: *mut crate::gid_t, + sgid: *mut crate::gid_t, + ) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn acct(filename: *const c_char) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn brk(addr: *mut c_void) -> c_int; + #[cfg(not(target_os = "l4re"))] + 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() -> crate::pid_t; + #[cfg(not(target_os = "l4re"))] + pub fn setresgid(rgid: crate::gid_t, egid: crate::gid_t, sgid: crate::gid_t) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn setresuid(ruid: crate::uid_t, euid: crate::uid_t, suid: crate::uid_t) -> c_int; + #[cfg_attr(any(gnu_time_bits64, musl_redir_time64), link_name = "__wait4_time64")] + #[cfg(not(target_os = "l4re"))] + pub fn wait4( + pid: crate::pid_t, + status: *mut c_int, + options: c_int, + rusage: *mut crate::rusage, + ) -> crate::pid_t; + #[cfg(not(target_os = "l4re"))] + pub fn login_tty(fd: c_int) -> c_int; + + // DIFF(main): changed to `*const *mut` in e77f551de9 + #[cfg(not(target_os = "l4re"))] + pub fn execvpe( + file: *const c_char, + argv: *const *const c_char, + envp: *const *const c_char, + ) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn fexecve(fd: c_int, argv: *const *const c_char, envp: *const *const c_char) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn getifaddrs(ifap: *mut *mut crate::ifaddrs) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn freeifaddrs(ifa: *mut crate::ifaddrs); + pub fn bind( + socket: c_int, + address: *const crate::sockaddr, + address_len: crate::socklen_t, + ) -> c_int; + + pub fn writev(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + pub fn readv(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + + #[cfg_attr(gnu_time_bits64, link_name = "__sendmsg64")] + pub fn sendmsg(fd: c_int, msg: *const crate::msghdr, flags: c_int) -> ssize_t; + #[cfg_attr(gnu_time_bits64, link_name = "__recvmsg64")] + pub fn recvmsg(fd: c_int, msg: *mut crate::msghdr, flags: c_int) -> ssize_t; + pub fn uname(buf: *mut crate::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 crate::tm, + ) -> size_t; + pub fn strftime_l( + s: *mut c_char, + max: size_t, + format: *const c_char, + tm: *const crate::tm, + locale: crate::locale_t, + ) -> size_t; + pub fn strptime(s: *const c_char, format: *const c_char, tm: *mut crate::tm) -> *mut c_char; + + #[cfg_attr(gnu_file_offset_bits64, link_name = "mkostemp64")] + pub fn mkostemp(template: *mut c_char, flags: c_int) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "mkostemps64")] + #[cfg(not(target_os = "l4re"))] + pub fn mkostemps(template: *mut c_char, suffixlen: c_int, flags: c_int) -> c_int; + + #[cfg(not(target_os = "l4re"))] + pub fn getdomainname(name: *mut c_char, len: size_t) -> c_int; + #[cfg(not(target_os = "l4re"))] + 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 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: crate::uid_t, + pwd: *mut passwd, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut passwd, + ) -> c_int; +} + +// 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_env = "ohos", + 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; + #[cfg_attr(gnu_time_bits64, link_name = "__fstat64_time64")] + pub fn fstat64(fildes: c_int, buf: *mut stat64) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__fstatat64_time64")] + #[cfg(not(target_os = "l4re"))] + 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; + #[cfg_attr(gnu_time_bits64, link_name = "__lstat64_time64")] + #[cfg(not(target_os = "l4re"))] + 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 crate::DIR) -> *mut crate::dirent64; + pub fn readdir64_r( + dirp: *mut crate::DIR, + entry: *mut crate::dirent64, + result: *mut *mut crate::dirent64, + ) -> c_int; + #[cfg_attr(gnu_time_bits64, link_name = "__stat64_time64")] + #[cfg(not(target_os = "l4re"))] + 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_env = "ohos", + target_os = "emscripten", + )))] { + extern "C" { + pub fn preadv64( + fd: c_int, + iov: *const crate::iovec, + iovcnt: c_int, + offset: off64_t, + ) -> ssize_t; + pub fn pwritev64( + fd: c_int, + iov: *const crate::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 crate::winsize, + ) -> crate::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 crate::winsize, + ) -> c_int; + } + } +} + +// The statx syscall, available on some libcs. +cfg_if! { + if #[cfg(any( + target_env = "gnu", + target_os = "android", + all(target_env = "musl", musl_v1_2_3) + ))] { + extern "C" { + pub fn statx( + dirfd: c_int, + pathname: *const c_char, + flags: c_int, + mask: c_uint, + statxbuf: *mut statx, + ) -> 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::*; + mod linux_l4re_shared; + pub use self::linux_l4re_shared::*; + } else if #[cfg(target_os = "l4re")] { + mod l4re; + pub use self::l4re::*; + mod linux_l4re_shared; + pub use self::linux_l4re_shared::*; + } 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..6c64020 --- /dev/null +++ b/vendor/libc/src/unix/mod.rs @@ -0,0 +1,2520 @@ +//! 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. + +use crate::prelude::*; + +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; + +#[cfg(not(target_os = "nuttx"))] +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(any(target_os = "nto", target_os = "qnx"))] { + pub type uid_t = i32; + pub type gid_t = i32; + } else { + pub type uid_t = u32; + pub type gid_t = u32; + } +} + +extern_ty! { + pub type DIR; +} + +// Deprecated impls: see #5296 +unsafe impl Send for DIR {} +unsafe impl Sync for DIR {} + +#[cfg(not(target_os = "nuttx"))] +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: crate::gid_t, + pub gr_mem: *mut *mut c_char, + } + + pub struct utimbuf { + pub actime: time_t, + pub modtime: time_t, + } + + #[derive(Default)] + pub struct timeval { + pub tv_sec: time_t, + #[cfg(not(gnu_time_bits64))] + pub tv_usec: crate::suseconds_t, + // For 64 bit time on 32 bit linux glibc, suseconds_t is still + // a 32 bit type. Use __suseconds64_t instead + #[cfg(gnu_time_bits64)] + pub tv_usec: __suseconds64_t, + } + + // linux x32 compatibility + // See https://sourceware.org/bugzilla/show_bug.cgi?id=16437 + #[derive(Default)] + #[cfg(not(target_env = "gnu"))] + pub struct timespec { + pub tv_sec: time_t, + #[cfg(all(musl32_time64, target_endian = "big"))] + __pad0: Padding, + #[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, + #[cfg(all(musl32_time64, target_endian = "little"))] + __pad0: Padding, + } + + 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: Padding, + pub ru_ixrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad2: Padding, + pub ru_idrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad3: Padding, + pub ru_isrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad4: Padding, + pub ru_minflt: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad5: Padding, + pub ru_majflt: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad6: Padding, + pub ru_nswap: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad7: Padding, + pub ru_inblock: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad8: Padding, + pub ru_oublock: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad9: Padding, + pub ru_msgsnd: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad10: Padding, + pub ru_msgrcv: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad11: Padding, + pub ru_nsignals: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad12: Padding, + pub ru_nvcsw: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad13: Padding, + pub ru_nivcsw: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad14: Padding, + + #[cfg(any(target_env = "musl", target_env = "ohos", target_os = "emscripten"))] + __reserved: Padding<[c_long; 16]>, + } + + #[cfg(not(target_os = "nuttx"))] + 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, + } + + #[cfg(all(not(target_os = "cygwin"), not(target_os = "horizon")))] + 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, + } + + #[cfg(not(target_os = "horizon"))] + 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, + } + + #[cfg(not(target_os = "cygwin"))] + 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: crate::timeval, + pub it_value: crate::timeval, + } + + // + pub struct tms { + pub tms_utime: crate::clock_t, + pub tms_stime: crate::clock_t, + pub tms_cutime: crate::clock_t, + pub tms_cstime: crate::clock_t, + } + + pub struct servent { + pub s_name: *mut c_char, + pub s_aliases: *mut *mut c_char, + #[cfg(target_os = "cygwin")] + pub s_port: c_short, + #[cfg(not(target_os = "cygwin"))] + 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, + #[cfg(not(target_os = "cygwin"))] + pub p_proto: c_int, + #[cfg(target_os = "cygwin")] + pub p_proto: c_short, + } + + #[repr(align(4))] + pub struct in6_addr { + pub s6_addr: [u8; 16], + } +} + +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(all( + not(any(target_os = "nto", target_os = "qnx")), + not(target_os = "aix"), + not(target_os = "espidf") + ))] { + 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(any( + target_os = "nto", + target_os = "qnx", + target_os = "l4re" + )))] { + 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; + +cfg_if! { + if #[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "solaris", + target_os = "cygwin" + )))] { + 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(any(target_os = "nto", target_os = "qnx")))] { + 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 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], +}; + +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; + +cfg_if! { + if #[cfg(any(target_os = "nto", target_os = "qnx", target_os = "aix"))] { + pub const FNM_PERIOD: c_int = 1 << 1; + } else { + pub const FNM_PERIOD: c_int = 1 << 2; + } +} +pub const FNM_NOMATCH: c_int = 1; + +cfg_if! { + if #[cfg(any( + target_os = "illumos", + target_os = "solaris", + target_os = "netbsd" + ))] { + pub const FNM_CASEFOLD: c_int = 1 << 3; + } else if #[cfg(not(target_os = "aix"))] { + pub const FNM_CASEFOLD: c_int = 1 << 4; + } +} + +cfg_if! { + if #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "android", + target_os = "openbsd", + target_os = "cygwin", + target_os = "netbsd", + ))] { + pub const FNM_PATHNAME: c_int = 1 << 1; + } else { + pub const FNM_PATHNAME: c_int = 1 << 0; + } +} + +cfg_if! { + if #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "android", + target_os = "openbsd", + target_os = "netbsd", + target_os = "cygwin", + ))] { + pub const FNM_NOESCAPE: c_int = 1 << 0; + } else if #[cfg(any(target_os = "nto", target_os = "qnx"))] { + pub const FNM_NOESCAPE: c_int = 1 << 2; + } else if #[cfg(target_os = "aix")] { + pub const FNM_NOESCAPE: c_int = 1 << 3; + } else { + pub const FNM_NOESCAPE: c_int = 1 << 1; + } +} + +extern "C" { + pub static in6addr_loopback: in6_addr; + pub static in6addr_any: in6_addr; +} + +// FIXME(1.0): We want to remove these directives and instead expect that no-std users add their +// own link configuration when required, rather than unconditionally linking everything that may +// possibly be needed. +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( + any( + all( + target_os = "linux", + any(target_env = "gnu", target_env = "uclibc") + ), + target_os = "cygwin" + ), + 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 "C" {} + } else if #[cfg(libc_pauthtest)] { + #[link(name = "c")] + #[link(name = "m")] + #[link(name = "rt")] + #[link(name = "pthread")] + #[link(name = "dl")] + extern "C" {} + } else if #[cfg(any( + all(target_env = "musl", not(libc_pauthtest)), + 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 "C" {} + } else if #[cfg(target_os = "emscripten")] { + // Don't pass -lc to Emscripten, it breaks. See: + // https://github.com/emscripten-core/emscripten/issues/22758 + } 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 "C" {} + } 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", + target_os = "qnx", + ))] { + #[link(name = "c")] + #[link(name = "m")] + extern "C" {} + } else if #[cfg(target_os = "haiku")] { + #[link(name = "root")] + #[link(name = "network")] + extern "C" {} + } else if #[cfg(target_env = "newlib")] { + #[link(name = "c")] + #[link(name = "m")] + extern "C" {} + } else if #[cfg(target_env = "illumos")] { + #[link(name = "c")] + #[link(name = "m")] + extern "C" {} + } 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 "C" {} + } else if #[cfg(target_os = "aix")] { + #[link(name = "c")] + #[link(name = "m")] + #[link(name = "bsd")] + #[link(name = "pthread")] + extern "C" {} + } else { + #[link(name = "c")] + #[link(name = "m")] + #[link(name = "rt")] + #[link(name = "pthread")] + extern "C" {} + } +} + +cfg_if! { + if #[cfg(not(all(target_os = "linux", target_env = "gnu")))] { + extern_ty! { + pub type fpos_t; // FIXME(unix): fill this out with a struct + } + } +} + +extern_ty! { + pub type FILE; +} + +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" + )] + #[cfg_attr(gnu_file_offset_bits64, link_name = "fopen64")] + 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" + )] + #[cfg_attr(gnu_file_offset_bits64, link_name = "freopen64")] + 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; + #[cfg_attr(gnu_file_offset_bits64, link_name = "tmpfile64")] + 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")] + #[cfg_attr(gnu_file_offset_bits64, link_name = "fgetpos64")] + pub fn fgetpos(stream: *mut FILE, ptr: *mut fpos_t) -> c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__fsetpos50")] + #[cfg_attr(gnu_file_offset_bits64, link_name = "fsetpos64")] + 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; + #[cfg_attr(target_os = "aix", link_name = "vec_calloc")] + pub fn calloc(nobj: size_t, size: size_t) -> *mut c_void; + #[cfg_attr(target_os = "aix", link_name = "vec_malloc")] + 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; + pub fn memccpy(dest: *mut c_void, src: *const 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: crate::uid_t) -> *mut passwd; + + pub fn fprintf(stream: *mut crate::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 crate::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(target_arch = "powerpc", target_vendor = "nintendo")))] + #[cfg_attr(target_os = "netbsd", link_name = "__socket30")] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_socket")] + #[cfg_attr(target_os = "solaris", link_name = "__xnet7_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(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(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")] + #[cfg_attr(target_os = "aix", link_name = "naccept")] + pub fn accept(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int; + #[cfg(not(all(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")] + #[cfg_attr(target_os = "aix", link_name = "ngetpeername")] + pub fn getpeername(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) + -> c_int; + #[cfg(not(all(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")] + #[cfg_attr(target_os = "aix", link_name = "ngetsockname")] + 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")] + #[cfg_attr(gnu_time_bits64, link_name = "__setsockopt64")] + 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(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" + )] + #[cfg_attr(gnu_time_bits64, link_name = "__fstat64_time64")] + #[cfg_attr( + all(not(gnu_time_bits64), gnu_file_offset_bits64), + link_name = "fstat64" + )] + #[cfg_attr(musl_redir_time64, link_name = "__fstat_time64")] + 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" + )] + #[cfg_attr(gnu_time_bits64, link_name = "__stat64_time64")] + #[cfg_attr( + all(not(gnu_time_bits64), gnu_file_offset_bits64), + link_name = "stat64" + )] + #[cfg_attr(musl_redir_time64, link_name = "__stat_time64")] + pub fn stat(path: *const c_char, buf: *mut stat) -> c_int; + + pub fn pclose(stream: *mut crate::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 crate::FILE; + pub fn fileno(stream: *mut crate::FILE) -> c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "open$UNIX2003" + )] + #[cfg_attr(gnu_file_offset_bits64, link_name = "open64")] + 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" + )] + #[cfg_attr(gnu_file_offset_bits64, link_name = "creat64")] + 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" + )] + #[cfg_attr(gnu_time_bits64, link_name = "__fcntl_time64")] + #[cfg_attr( + all(not(gnu_time_bits64), gnu_file_offset_bits64), + link_name = "__fcntl_time64" + )] + 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 crate::DIR; + #[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 crate::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" + )] + #[cfg_attr(gnu_file_offset_bits64, link_name = "readdir64")] + pub fn readdir(dirp: *mut crate::DIR) -> *mut crate::dirent; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "closedir$UNIX2003" + )] + pub fn closedir(dirp: *mut crate::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 crate::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: crate::uid_t, group: crate::gid_t) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn fchownat( + dirfd: c_int, + pathname: *const c_char, + owner: crate::uid_t, + group: crate::gid_t, + flags: c_int, + ) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "openat64")] + pub fn openat(dirfd: c_int, pathname: *const c_char, 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" + )] + #[cfg_attr(gnu_time_bits64, link_name = "__fstatat64_time64")] + #[cfg_attr( + all(not(gnu_time_bits64), gnu_file_offset_bits64), + link_name = "fstatat64" + )] + #[cfg(not(target_os = "l4re"))] + #[cfg_attr(musl_redir_time64, link_name = "__fstatat_time64")] + pub fn fstatat(dirfd: c_int, pathname: *const c_char, buf: *mut stat, flags: c_int) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn linkat( + olddirfd: c_int, + oldpath: *const c_char, + newdirfd: c_int, + newpath: *const c_char, + flags: c_int, + ) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn mkdirat(dirfd: c_int, pathname: *const c_char, mode: mode_t) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn renameat( + olddirfd: c_int, + oldpath: *const c_char, + newdirfd: c_int, + newpath: *const c_char, + ) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn symlinkat(target: *const c_char, newdirfd: c_int, linkpath: *const c_char) -> c_int; + #[cfg(not(target_os = "l4re"))] + 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; + + // DIFF(main): changed to `*const *mut` in e77f551de9 + 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; + #[cfg_attr(target_os = "solaris", link_name = "__link_xpg4")] + pub fn link(src: *const c_char, dst: *const c_char) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "lseek64")] + 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; + pub fn aligned_alloc(alignment: size_t, size: size_t) -> *mut c_void; + #[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")] + #[cfg_attr(gnu_time_bits64, link_name = "__nanosleep64")] + #[cfg_attr(musl_redir_time64, link_name = "__nanosleep_time64")] + 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: crate::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( + any(target_os = "illumos", target_os = "solaris"), + 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" + )] + #[cfg_attr(gnu_file_offset_bits64, link_name = "pread64")] + 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" + )] + #[cfg_attr(gnu_file_offset_bits64, link_name = "pwrite64")] + 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")] + #[cfg_attr(any(gnu_time_bits64, musl_redir_time64), link_name = "__utime64")] + 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" + )] + #[cfg_attr(gnu_file_offset_bits64, link_name = "mmap64")] + 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" + )] + #[cfg_attr(gnu_time_bits64, link_name = "__lstat64_time64")] + #[cfg_attr( + all(not(gnu_time_bits64), gnu_file_offset_bits64), + link_name = "lstat64" + )] + #[cfg_attr(musl_redir_time64, link_name = "__lstat_time64")] + 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; + + #[cfg_attr(gnu_file_offset_bits64, link_name = "truncate64")] + pub fn truncate(path: *const c_char, length: off_t) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "ftruncate64")] + 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")] + #[cfg_attr(gnu_time_bits64, link_name = "__getrusage64")] + #[cfg_attr(musl_redir_time64, link_name = "__getrusage_time64")] + 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; + + #[cfg_attr(target_os = "netbsd", link_name = "__times13")] + pub fn times(buf: *mut crate::tms) -> crate::clock_t; + + pub fn pthread_self() -> crate::pthread_t; + pub fn pthread_equal(t1: crate::pthread_t, t2: crate::pthread_t) -> c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_join$UNIX2003" + )] + pub fn pthread_join(native: crate::pthread_t, value: *mut *mut c_void) -> c_int; + pub fn pthread_exit(value: *mut c_void) -> !; + pub fn pthread_attr_init(attr: *mut crate::pthread_attr_t) -> c_int; + pub fn pthread_attr_destroy(attr: *mut crate::pthread_attr_t) -> c_int; + pub fn pthread_attr_getstacksize( + attr: *const crate::pthread_attr_t, + stacksize: *mut size_t, + ) -> c_int; + pub fn pthread_attr_setstacksize(attr: *mut crate::pthread_attr_t, stack_size: size_t) + -> c_int; + pub fn pthread_attr_setdetachstate(attr: *mut crate::pthread_attr_t, state: c_int) -> c_int; + pub fn pthread_detach(thread: crate::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 crate::pthread_key_t, + dtor: Option, + ) -> c_int; + pub fn pthread_key_delete(key: crate::pthread_key_t) -> c_int; + pub fn pthread_getspecific(key: crate::pthread_key_t) -> *mut c_void; + pub fn pthread_setspecific(key: crate::pthread_key_t, value: *const c_void) -> c_int; + pub fn pthread_mutex_init( + lock: *mut crate::pthread_mutex_t, + attr: *const crate::pthread_mutexattr_t, + ) -> c_int; + pub fn pthread_mutex_destroy(lock: *mut crate::pthread_mutex_t) -> c_int; + pub fn pthread_mutex_lock(lock: *mut crate::pthread_mutex_t) -> c_int; + pub fn pthread_mutex_trylock(lock: *mut crate::pthread_mutex_t) -> c_int; + pub fn pthread_mutex_unlock(lock: *mut crate::pthread_mutex_t) -> c_int; + + pub fn pthread_mutexattr_init(attr: *mut crate::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 crate::pthread_mutexattr_t) -> c_int; + pub fn pthread_mutexattr_settype(attr: *mut crate::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 crate::pthread_cond_t, + attr: *const crate::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 crate::pthread_cond_t, + lock: *mut crate::pthread_mutex_t, + ) -> c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_cond_timedwait$UNIX2003" + )] + #[cfg_attr(gnu_time_bits64, link_name = "__pthread_cond_timedwait64")] + #[cfg_attr(musl_redir_time64, link_name = "__pthread_cond_timedwait_time64")] + pub fn pthread_cond_timedwait( + cond: *mut crate::pthread_cond_t, + lock: *mut crate::pthread_mutex_t, + abstime: *const crate::timespec, + ) -> c_int; + pub fn pthread_cond_signal(cond: *mut crate::pthread_cond_t) -> c_int; + pub fn pthread_cond_broadcast(cond: *mut crate::pthread_cond_t) -> c_int; + pub fn pthread_cond_destroy(cond: *mut crate::pthread_cond_t) -> c_int; + pub fn pthread_condattr_init(attr: *mut crate::pthread_condattr_t) -> c_int; + pub fn pthread_condattr_destroy(attr: *mut crate::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 crate::pthread_rwlock_t, + attr: *const crate::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 crate::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 crate::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 crate::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 crate::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 crate::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 crate::pthread_rwlock_t) -> c_int; + pub fn pthread_rwlockattr_init(attr: *mut crate::pthread_rwlockattr_t) -> c_int; + pub fn pthread_rwlockattr_destroy(attr: *mut crate::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")] + #[cfg_attr(gnu_time_bits64, link_name = "__getsockopt64")] + pub fn getsockopt( + sockfd: c_int, + level: c_int, + optname: c_int, + optval: *mut c_void, + optlen: *mut crate::socklen_t, + ) -> c_int; + pub fn raise(signum: c_int) -> c_int; + + #[cfg_attr(target_os = "netbsd", link_name = "__utimes50")] + #[cfg_attr(gnu_time_bits64, link_name = "__utimes64")] + #[cfg_attr(musl_redir_time64, link_name = "__utimes_time64")] + pub fn utimes(filename: *const c_char, times: *const crate::timeval) -> c_int; + pub fn dlopen(filename: *const c_char, flag: c_int) -> *mut c_void; + pub fn dlerror() -> *mut c_char; + #[cfg_attr(musl_redir_time64, link_name = "__dlsym_time64")] + 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(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(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 = "cygwin", + 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" + )] + #[cfg_attr(target_os = "aix", link_name = "_res_init")] + #[cfg(not(target_os = "l4re"))] + pub fn res_init() -> c_int; + + #[cfg_attr(target_os = "netbsd", link_name = "__gmtime_r50")] + #[cfg_attr(gnu_time_bits64, link_name = "__gmtime64_r")] + #[cfg_attr(not(musl32_time64), allow(deprecated))] + #[cfg_attr(musl_redir_time64, link_name = "__gmtime64_r")] + 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(gnu_time_bits64, link_name = "__localtime64_r")] + #[cfg_attr(not(musl32_time64), allow(deprecated))] + #[cfg_attr(musl_redir_time64, link_name = "__localtime64_r")] + 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(gnu_time_bits64, musl_redir_time64), link_name = "__mktime64")] + #[cfg_attr(not(musl32_time64), allow(deprecated))] + pub fn mktime(tm: *mut tm) -> time_t; + #[cfg_attr(target_os = "netbsd", link_name = "__time50")] + #[cfg_attr(any(gnu_time_bits64, musl_redir_time64), link_name = "__time64")] + #[cfg_attr(not(musl32_time64), allow(deprecated))] + pub fn time(time: *mut time_t) -> time_t; + #[cfg_attr(target_os = "netbsd", link_name = "__gmtime50")] + #[cfg_attr(any(gnu_time_bits64, musl_redir_time64), link_name = "__gmtime64")] + #[cfg_attr(not(musl32_time64), allow(deprecated))] + pub fn gmtime(time_p: *const time_t) -> *mut tm; + #[cfg_attr(target_os = "netbsd", link_name = "__locatime50")] + #[cfg_attr(any(gnu_time_bits64, musl_redir_time64), link_name = "__localtime64")] + #[cfg_attr(not(musl32_time64), allow(deprecated))] + pub fn localtime(time_p: *const time_t) -> *mut tm; + #[cfg_attr(target_os = "netbsd", link_name = "__difftime50")] + #[cfg_attr(any(gnu_time_bits64, musl_redir_time64), link_name = "__difftime64")] + #[cfg_attr(not(musl32_time64), allow(deprecated))] + pub fn difftime(time1: time_t, time0: time_t) -> c_double; + #[cfg(not(target_os = "aix"))] + #[cfg_attr(target_os = "netbsd", link_name = "__timegm50")] + #[cfg_attr(gnu_time_bits64, link_name = "__timegm64")] + #[cfg_attr(not(musl32_time64), allow(deprecated))] + #[cfg_attr(musl_redir_time64, link_name = "__timegm_time64")] + pub fn timegm(tm: *mut crate::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: crate::dev_t) -> c_int; + #[cfg(not(target_os = "espidf"))] + 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(target_os = "cygwin")] + pub fn usleep(secs: useconds_t) -> c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "usleep$UNIX2003" + )] + #[cfg(not(target_os = "cygwin"))] + 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")] + #[cfg_attr(target_os = "aix", link_name = "__fd_select")] + #[cfg_attr(gnu_time_bits64, link_name = "__select64")] + #[cfg_attr(musl_redir_time64, link_name = "__select_time64")] + 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; + #[cfg_attr(gnu_file_offset_bits64, link_name = "statvfs64")] + pub fn statvfs(path: *const c_char, buf: *mut crate::statvfs) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "fstatvfs64")] + pub fn fstatvfs(fd: c_int, buf: *mut crate::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; + + #[cfg_attr(target_os = "solaris", link_name = "__sysconf_xpg7")] + pub fn sysconf(name: c_int) -> c_long; + + pub fn mkfifo(path: *const c_char, mode: mode_t) -> c_int; + + #[cfg_attr(gnu_file_offset_bits64, link_name = "fseeko64")] + pub fn fseeko(stream: *mut crate::FILE, offset: off_t, whence: c_int) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "ftello64")] + pub fn ftello(stream: *mut crate::FILE) -> off_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "tcdrain$UNIX2003" + )] + pub fn tcdrain(fd: c_int) -> c_int; + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "arm"), + link_name = "cfgetispeed@GLIBC_2.4" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "csky"), + link_name = "cfgetispeed@GLIBC_2.29" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "m68k"), + link_name = "cfgetispeed@GLIBC_2.0" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + any(target_arch = "mips", target_arch = "mips32r6") + ), + link_name = "cfgetispeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "powerpc"), + link_name = "cfgetispeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "riscv32"), + link_name = "cfgetispeed@GLIBC_2.33" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "sparc"), + link_name = "cfgetispeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "x86"), + link_name = "cfgetispeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "aarch64"), + link_name = "cfgetispeed@GLIBC_2.17" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "loongarch64"), + link_name = "cfgetispeed@GLIBC_2.36" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + any(target_arch = "mips64", target_arch = "mips64r6") + ), + link_name = "cfgetispeed@GLIBC_2.0" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "powerpc64", + target_endian = "big" + ), + link_name = "cfgetispeed@GLIBC_2.3" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "powerpc64", + target_endian = "little" + ), + link_name = "cfgetispeed@GLIBC_2.17" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "riscv64"), + link_name = "cfgetispeed@GLIBC_2.27" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "s390x"), + link_name = "cfgetispeed@GLIBC_2.2" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "sparc64"), + link_name = "cfgetispeed@GLIBC_2.2" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "x86_64", + target_pointer_width = "64" + ), + link_name = "cfgetispeed@GLIBC_2.2.5" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "x86_64", + target_pointer_width = "32" + ), + link_name = "cfgetispeed@GLIBC_2.16" + )] + pub fn cfgetispeed(termios: *const crate::termios) -> crate::speed_t; + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "arm"), + link_name = "cfgetospeed@GLIBC_2.4" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "csky"), + link_name = "cfgetospeed@GLIBC_2.29" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "m68k"), + link_name = "cfgetospeed@GLIBC_2.0" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + any(target_arch = "mips", target_arch = "mips32r6") + ), + link_name = "cfgetospeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "powerpc"), + link_name = "cfgetospeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "riscv32"), + link_name = "cfgetospeed@GLIBC_2.33" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "sparc"), + link_name = "cfgetospeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "x86"), + link_name = "cfgetospeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "aarch64"), + link_name = "cfgetospeed@GLIBC_2.17" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "loongarch64"), + link_name = "cfgetospeed@GLIBC_2.36" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + any(target_arch = "mips64", target_arch = "mips64r6") + ), + link_name = "cfgetospeed@GLIBC_2.0" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "powerpc64", + target_endian = "big" + ), + link_name = "cfgetospeed@GLIBC_2.3" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "powerpc64", + target_endian = "little" + ), + link_name = "cfgetospeed@GLIBC_2.17" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "riscv64"), + link_name = "cfgetospeed@GLIBC_2.27" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "s390x"), + link_name = "cfgetospeed@GLIBC_2.2" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "sparc64"), + link_name = "cfgetospeed@GLIBC_2.2" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "x86_64", + target_pointer_width = "64" + ), + link_name = "cfgetospeed@GLIBC_2.2.5" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "x86_64", + target_pointer_width = "32" + ), + link_name = "cfgetospeed@GLIBC_2.16" + )] + pub fn cfgetospeed(termios: *const crate::termios) -> crate::speed_t; + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "arm"), + link_name = "cfsetispeed@GLIBC_2.4" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "csky"), + link_name = "cfsetispeed@GLIBC_2.29" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "m68k"), + link_name = "cfsetispeed@GLIBC_2.0" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + any(target_arch = "mips", target_arch = "mips32r6") + ), + link_name = "cfsetispeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "powerpc"), + link_name = "cfsetispeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "riscv32"), + link_name = "cfsetispeed@GLIBC_2.33" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "sparc"), + link_name = "cfsetispeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "x86"), + link_name = "cfsetispeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "aarch64"), + link_name = "cfsetispeed@GLIBC_2.17" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "loongarch64"), + link_name = "cfsetispeed@GLIBC_2.36" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + any(target_arch = "mips64", target_arch = "mips64r6") + ), + link_name = "cfsetispeed@GLIBC_2.0" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "powerpc64", + target_endian = "big" + ), + link_name = "cfsetispeed@GLIBC_2.3" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "powerpc64", + target_endian = "little" + ), + link_name = "cfsetispeed@GLIBC_2.17" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "riscv64"), + link_name = "cfsetispeed@GLIBC_2.27" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "s390x"), + link_name = "cfsetispeed@GLIBC_2.2" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "sparc64"), + link_name = "cfsetispeed@GLIBC_2.2" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "x86_64", + target_pointer_width = "64" + ), + link_name = "cfsetispeed@GLIBC_2.2.5" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "x86_64", + target_pointer_width = "32" + ), + link_name = "cfsetispeed@GLIBC_2.16" + )] + pub fn cfsetispeed(termios: *mut crate::termios, speed: crate::speed_t) -> c_int; + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "arm"), + link_name = "cfsetospeed@GLIBC_2.4" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "csky"), + link_name = "cfsetospeed@GLIBC_2.29" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "m68k"), + link_name = "cfsetospeed@GLIBC_2.0" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + any(target_arch = "mips", target_arch = "mips32r6") + ), + link_name = "cfsetospeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "powerpc"), + link_name = "cfsetospeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "riscv32"), + link_name = "cfsetospeed@GLIBC_2.33" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "sparc"), + link_name = "cfsetospeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "x86"), + link_name = "cfsetospeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "aarch64"), + link_name = "cfsetospeed@GLIBC_2.17" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "loongarch64"), + link_name = "cfsetospeed@GLIBC_2.36" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + any(target_arch = "mips64", target_arch = "mips64r6") + ), + link_name = "cfsetospeed@GLIBC_2.0" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "powerpc64", + target_endian = "big" + ), + link_name = "cfsetospeed@GLIBC_2.3" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "powerpc64", + target_endian = "little" + ), + link_name = "cfsetospeed@GLIBC_2.17" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "riscv64"), + link_name = "cfsetospeed@GLIBC_2.27" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "s390x"), + link_name = "cfsetospeed@GLIBC_2.2" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "sparc64"), + link_name = "cfsetospeed@GLIBC_2.2" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "x86_64", + target_pointer_width = "64" + ), + link_name = "cfsetospeed@GLIBC_2.2.5" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "x86_64", + target_pointer_width = "32" + ), + link_name = "cfsetospeed@GLIBC_2.16" + )] + pub fn cfsetospeed(termios: *mut crate::termios, speed: crate::speed_t) -> c_int; + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "sparc" + ), + ), + link_name = "tcgetattr@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "sparc64"), + link_name = "tcgetattr@GLIBC_2.2" + )] + pub fn tcgetattr(fd: c_int, termios: *mut crate::termios) -> c_int; + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "sparc" + ), + ), + link_name = "tcsetattr@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "sparc64"), + link_name = "tcsetattr@GLIBC_2.2" + )] + pub fn tcsetattr(fd: c_int, optional_actions: c_int, termios: *const crate::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) -> crate::pid_t; + pub fn tcsendbreak(fd: c_int, duration: c_int) -> c_int; + #[cfg_attr(gnu_file_offset_bits64, link_name = "mkstemp64")] + 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; + + #[cfg(not(target_os = "l4re"))] + pub fn grantpt(fd: c_int) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn posix_openpt(flags: c_int) -> c_int; + #[cfg(not(target_os = "l4re"))] + pub fn ptsname(fd: c_int) -> *mut c_char; + #[cfg(not(target_os = "l4re"))] + pub fn unlockpt(fd: c_int) -> c_int; + + #[cfg(not(target_os = "aix"))] + 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; + + #[cfg_attr(gnu_file_offset_bits64, link_name = "lockf64")] + pub fn lockf(fd: c_int, cmd: c_int, len: off_t) -> c_int; + +} + +safe_f! { + // It seems htonl, etc are macros on macOS. So we have to reimplement them. So let's + // reimplement them for all UNIX platforms + pub const safe fn htonl(hostlong: u32) -> u32 { + u32::to_be(hostlong) + } + pub const safe fn htons(hostshort: u16) -> u16 { + u16::to_be(hostshort) + } + pub const safe fn ntohl(netlong: u32) -> u32 { + u32::from_be(netlong) + } + pub const safe fn ntohs(netshort: u16) -> u16 { + u16::from_be(netshort) + } +} + +cfg_if! { + if #[cfg(not(any( + target_os = "emscripten", + target_os = "android", + target_os = "haiku", + target_os = "nto", + target_os = "qnx", + target_os = "solaris", + target_os = "cygwin", + target_os = "aix", + target_os = "l4re", + )))] { + extern "C" { + #[cfg_attr(target_os = "netbsd", link_name = "__adjtime50")] + #[cfg_attr(any(gnu_time_bits64, musl_redir_time64), link_name = "__adjtime64")] + pub fn adjtime(delta: *const timeval, olddelta: *mut timeval) -> c_int; + } + } else if #[cfg(target_os = "solaris")] { + extern "C" { + pub fn adjtime(delta: *mut 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(any( + target_os = "dragonfly", + target_os = "emscripten", + target_os = "hurd", + target_os = "macos", + target_os = "openbsd", + target_os = "l4re", + )))] { + extern "C" { + pub fn sigqueue(pid: pid_t, sig: c_int, value: crate::sigval) -> c_int; + } + } +} + +cfg_if! { + if #[cfg(not(target_os = "android"))] { + extern "C" { + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "confstr$UNIX2003" + )] + #[cfg_attr(target_os = "solaris", link_name = "__confstr_xpg7")] + pub fn confstr(name: c_int, buf: *mut c_char, len: size_t) -> size_t; + } + } +} + +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(target_os = "solaris"))] { + extern "C" { + pub fn flock(fd: c_int, operation: c_int) -> 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 "C" { + 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; + #[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" + )] + #[cfg_attr( + all(target_os = "freebsd", not(any(freebsd11, freebsd10))), + link_name = "readdir_r@FBSD_1.5" + )] + /// 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: + /// + /// * + /// * + /// * + #[cfg_attr(gnu_file_offset_bits64, link_name = "readdir64_r")] + pub fn readdir_r( + dirp: *mut crate::DIR, + entry: *mut crate::dirent, + result: *mut *mut crate::dirent, + ) -> c_int; + } + } +} + +cfg_if! { + if #[cfg(any(target_os = "nto", target_os = "qnx"))] { + extern "C" { + 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 "C" { + #[cfg(not(target_os = "l4re"))] + pub fn readlinkat( + dirfd: c_int, + pathname: *const c_char, + buf: *mut c_char, + bufsiz: size_t, + ) -> ssize_t; + #[cfg(not(target_os = "l4re"))] + pub fn fmemopen(buf: *mut c_void, size: size_t, mode: *const c_char) -> *mut FILE; + #[cfg(not(target_os = "l4re"))] + 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")] + #[cfg_attr(gnu_time_bits64, link_name = "__pselect64")] + #[cfg_attr(musl_redir_time64, link_name = "__pselect_time64")] + 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(any(target_os = "aix", target_os = "nto"))] { + extern "C" { + pub fn cfmakeraw(termios: *mut crate::termios) -> c_int; + } + } else if #[cfg(not(any(target_os = "solaris", target_os = "illumos",)))] { + extern "C" { + pub fn cfmakeraw(termios: *mut crate::termios); + } + } +} + +cfg_if! { + if #[cfg(any(target_os = "aix", target_os = "qnx",))] { + extern "C" { + pub fn cfsetspeed(termios: *mut crate::termios, speed: crate::speed_t) -> c_int; + } + } else if #[cfg(not(any( + target_os = "solaris", + target_os = "illumos", + target_os = "nto" + )))] { + extern "C" { + #[cfg(not(target_os = "l4re"))] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "arm"), + link_name = "cfsetspeed@GLIBC_2.4" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "csky"), + link_name = "cfsetspeed@GLIBC_2.29" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "m68k"), + link_name = "cfsetspeed@GLIBC_2.0" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + any(target_arch = "mips", target_arch = "mips32r6") + ), + link_name = "cfsetspeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "powerpc"), + link_name = "cfsetspeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "riscv32"), + link_name = "cfsetspeed@GLIBC_2.33" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "sparc"), + link_name = "cfsetspeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "x86"), + link_name = "cfsetspeed@GLIBC_2.0" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "aarch64"), + link_name = "cfsetspeed@GLIBC_2.17" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "loongarch64"), + link_name = "cfsetspeed@GLIBC_2.36" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + any(target_arch = "mips64", target_arch = "mips64r6") + ), + link_name = "cfsetspeed@GLIBC_2.0" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "powerpc64", + target_endian = "big" + ), + link_name = "cfsetspeed@GLIBC_2.3" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "powerpc64", + target_endian = "little" + ), + link_name = "cfsetspeed@GLIBC_2.17" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "riscv64"), + link_name = "cfsetspeed@GLIBC_2.27" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "s390x"), + link_name = "cfsetspeed@GLIBC_2.2" + )] + #[cfg_attr( + all(target_os = "linux", target_env = "gnu", target_arch = "sparc64"), + link_name = "cfsetspeed@GLIBC_2.2" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "x86_64", + target_pointer_width = "64" + ), + link_name = "cfsetspeed@GLIBC_2.2.5" + )] + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_arch = "x86_64", + target_pointer_width = "32" + ), + link_name = "cfsetspeed@GLIBC_2.16" + )] + pub fn cfsetspeed(termios: *mut crate::termios, speed: crate::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 = "cygwin")] { + mod cygwin; + pub use self::cygwin::*; + } else if #[cfg(any(target_os = "nto", target_os = "qnx"))] { + 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 + } +} 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..56c268f --- /dev/null +++ b/vendor/libc/src/unix/newlib/aarch64/mod.rs @@ -0,0 +1,56 @@ +use crate::prelude::*; + +pub type clock_t = c_long; +pub type wchar_t = u32; + +s! { + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: crate::sa_family_t, + pub sa_data: [c_char; 14], + } + + pub struct sockaddr_in6 { + pub sin6_len: u8, + pub sin6_family: crate::sa_family_t, + pub sin6_port: crate::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: crate::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: crate::sa_family_t, + pub sin_port: crate::in_port_t, + pub sin_addr: crate::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/arm/mod.rs b/vendor/libc/src/unix/newlib/arm/mod.rs new file mode 100644 index 0000000..9b5978f --- /dev/null +++ b/vendor/libc/src/unix/newlib/arm/mod.rs @@ -0,0 +1,58 @@ +use crate::prelude::*; + +pub type clock_t = c_long; +pub type wchar_t = u32; + +s! { + pub struct sockaddr { + pub sa_family: crate::sa_family_t, + pub sa_data: [c_char; 14], + } + + pub struct sockaddr_in6 { + pub sin6_family: crate::sa_family_t, + pub sin6_port: crate::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: crate::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct sockaddr_in { + pub sin_family: crate::sa_family_t, + pub sin_port: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_zero: [u8; 8], + } + + pub struct sockaddr_storage { + pub ss_family: crate::sa_family_t, + __ss_padding: 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..b791bbe --- /dev/null +++ b/vendor/libc/src/unix/newlib/espidf/mod.rs @@ -0,0 +1,137 @@ +use crate::prelude::*; + +pub type clock_t = c_ulong; +pub type wchar_t = u32; + +s! { + pub struct cmsghdr { + pub cmsg_len: crate::socklen_t, + pub cmsg_level: c_int, + pub cmsg_type: c_int, + } + + pub struct msghdr { + pub msg_name: *mut c_void, + pub msg_namelen: crate::socklen_t, + pub msg_iov: *mut crate::iovec, + pub msg_iovlen: c_int, + pub msg_control: *mut c_void, + pub msg_controllen: crate::socklen_t, + pub msg_flags: c_int, + } + + pub struct sockaddr_un { + pub sun_family: crate::sa_family_t, + pub sun_path: [c_char; 108], + } + + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: crate::sa_family_t, + pub sa_data: [c_char; 14], + } + + pub struct sockaddr_in6 { + pub sin6_len: u8, + pub sin6_family: crate::sa_family_t, + pub sin6_port: crate::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: crate::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: crate::sa_family_t, + pub sin_port: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_zero: [c_char; 8], + } + + pub struct sockaddr_storage { + pub s2_len: u8, + pub ss_family: crate::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; + +pub const SOMAXCONN: c_int = 128; + +pub const DT_UNKNOWN: u8 = 0; +pub const DT_REG: u8 = 1; +pub const DT_DIR: u8 = 2; +// Not used by esp-idf, but still defined in headers. +pub const DT_CHR: u8 = 4; +pub const DT_BLK: u8 = 6; +pub const DT_FIFO: u8 = 8; +pub const DT_LNK: u8 = 10; +pub const DT_SOCK: u8 = 12; +pub const DT_WHT: u8 = 14; + +extern "C" { + pub fn pthread_create( + native: *mut crate::pthread_t, + attr: *const crate::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; + + pub fn gethostname(name: *mut c_char, namelen: ssize_t); + + #[link_name = "lwip_sendmsg"] + pub fn sendmsg(s: c_int, msg: *const crate::msghdr, flags: c_int) -> ssize_t; + #[link_name = "lwip_recvmsg"] + pub fn recvmsg(s: c_int, msg: *mut crate::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..303de80 --- /dev/null +++ b/vendor/libc/src/unix/newlib/generic.rs @@ -0,0 +1,39 @@ +//! Common types used by most newlib platforms + +#[allow(unused_imports)] // needed for platforms that don't use the prelude here +use crate::prelude::*; + +s! { + #[cfg(all(not(target_os = "vita"), not(target_os = "horizon")))] + pub struct sigset_t { + __val: u32, + } + + #[cfg(all(not(target_os = "vita"), not(target_os = "horizon")))] + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub st_size: crate::off_t, + pub st_atime: crate::time_t, + pub st_spare1: c_long, + pub st_mtime: crate::time_t, + pub st_spare2: c_long, + pub st_ctime: crate::time_t, + pub st_spare3: c_long, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_spare4: [c_long; 2usize], + } + + #[cfg(not(target_os = "vita"))] + pub struct dirent { + pub d_ino: crate::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..0e92ccd --- /dev/null +++ b/vendor/libc/src/unix/newlib/horizon/mod.rs @@ -0,0 +1,286 @@ +//! ARMv6K Nintendo 3DS C Newlib definitions + +use crate::off_t; +use crate::prelude::*; + +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 pollfd { + pub fd: c_int, + pub events: c_int, + pub revents: c_int, + } + + pub struct sockaddr { + pub sa_family: crate::sa_family_t, + pub sa_data: [c_char; 26usize], + } + + pub struct sockaddr_storage { + pub ss_family: crate::sa_family_t, + __ss_padding: Padding<[c_char; 26usize]>, + } + + pub struct sockaddr_in { + pub sin_family: crate::sa_family_t, + pub sin_port: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_zero: [c_char; 8], + } + + pub struct sockaddr_in6 { + pub sin6_family: crate::sa_family_t, + pub sin6_port: crate::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: crate::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct sockaddr_un { + pub sun_len: c_uchar, + pub sun_family: crate::sa_family_t, + pub sun_path: [c_char; 104usize], + } + + pub struct sched_param { + pub sched_priority: c_int, + } + + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_atim: crate::timespec, + pub st_mtim: crate::timespec, + pub st_ctim: crate::timespec, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::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 PTHREAD_STACK_MIN: size_t = 4096; +pub const WNOHANG: c_int = 1; + +pub const POLLIN: c_int = 0x0001; +pub const POLLPRI: c_int = 0x0002; +pub const POLLOUT: c_int = 0x0008; +pub const POLLRDNORM: c_int = 0x0040; +pub const POLLWRNORM: c_int = POLLOUT; +pub const POLLRDBAND: c_int = 0x0080; +pub const POLLWRBAND: c_int = 0x0100; +/// POLLERR behavior on 3DS+HorizonOS is unclear, and it may be unsupported. +pub const POLLERR: c_int = 0x0008; +/// POLLHUP behavior on 3DS+HorizonOS is unclear, and it may be unsupported. +pub const POLLHUP: c_int = 0x0010; +pub const POLLNVAL: c_int = 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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 = ptr::null_mut(); + +// 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 safe fn WIFSTOPPED(_status: c_int) -> bool { + false + } + + pub const safe fn WSTOPSIG(_status: c_int) -> c_int { + 0 + } + + pub const safe fn WIFCONTINUED(_status: c_int) -> bool { + true + } + + pub const safe fn WIFSIGNALED(_status: c_int) -> bool { + false + } + + pub const safe fn WTERMSIG(_status: c_int) -> c_int { + 0 + } + + pub const safe fn WIFEXITED(_status: c_int) -> bool { + true + } + + pub const safe fn WEXITSTATUS(_status: c_int) -> c_int { + 0 + } + + pub const safe fn WCOREDUMP(_status: c_int) -> bool { + false + } +} + +extern "C" { + pub fn pthread_create( + native: *mut crate::pthread_t, + attr: *const crate::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 crate::pthread_attr_t, + param: *mut sched_param, + ) -> c_int; + + pub fn pthread_attr_setschedparam( + attr: *mut crate::pthread_attr_t, + param: *const sched_param, + ) -> c_int; + + pub fn pthread_attr_getprocessorid_np( + attr: *const crate::pthread_attr_t, + processor_id: *mut c_int, + ) -> c_int; + + pub fn pthread_attr_setprocessorid_np( + attr: *mut crate::pthread_attr_t, + processor_id: c_int, + ) -> c_int; + + pub fn pthread_getschedparam( + native: crate::pthread_t, + policy: *mut c_int, + param: *mut crate::sched_param, + ) -> c_int; + + pub fn pthread_setschedparam( + native: crate::pthread_t, + policy: c_int, + param: *const crate::sched_param, + ) -> c_int; + + pub fn pthread_condattr_getclock( + attr: *const crate::pthread_condattr_t, + clock_id: *mut crate::clockid_t, + ) -> c_int; + + pub fn pthread_condattr_setclock( + attr: *mut crate::pthread_condattr_t, + clock_id: crate::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..d5f8bc5 --- /dev/null +++ b/vendor/libc/src/unix/newlib/mod.rs @@ -0,0 +1,975 @@ +use crate::prelude::*; + +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", not(espidf_time32)) + ))] { + pub type time_t = c_longlong; + } else { + pub type time_t = i32; + } +} + +s! { + // The order of the `ai_addr` field in this struct is crucial + // for converting between the Rust and C types. + 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(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 in_addr { + pub s_addr: crate::in_addr_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_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, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_handler: extern "C" 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 as usize / ULONG_SIZE], + } + + pub struct passwd { + // Unverified + pub pw_name: *mut c_char, + pub pw_passwd: *mut c_char, + pub pw_uid: crate::uid_t, + pub pw_gid: crate::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: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; crate::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 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], + } + + #[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; crate::__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; crate::__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; crate::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[repr(align(8))] + pub struct pthread_cond_t { + // Unverified + size: [u8; crate::__SIZEOF_PTHREAD_COND_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + // Unverified + size: [u8; crate::__SIZEOF_PTHREAD_CONDATTR_T], + } +} + +// unverified constants +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; +cfg_if! { + if #[cfg(espidf_picolibc)] { + pub const O_APPEND: c_int = 1024; + pub const O_CREAT: c_int = 64; + pub const O_TRUNC: c_int = 512; + } else { + 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 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 = 0o0400; +pub const S_IWRITE: mode_t = 0o0200; +pub const S_IEXEC: mode_t = 0o0100; +pub const S_ENFMT: mode_t = 0o2000; +pub const S_IFMT: mode_t = 0o17_0000; +pub const S_IFDIR: mode_t = 0o4_0000; +pub const S_IFCHR: mode_t = 0o2_0000; +pub const S_IFBLK: mode_t = 0o6_0000; +pub const S_IFREG: mode_t = 0o10_0000; +pub const S_IFLNK: mode_t = 0o12_0000; +pub const S_IFSOCK: mode_t = 0o14_0000; +pub const S_IFIFO: mode_t = 0o1_0000; +pub const S_IRUSR: mode_t = 0o0400; +pub const S_IWUSR: mode_t = 0o0200; +pub const S_IXUSR: mode_t = 0o0100; +pub const S_IRGRP: mode_t = 0o0040; +pub const S_IWGRP: mode_t = 0o0020; +pub const S_IXGRP: mode_t = 0o0010; +pub const S_IROTH: mode_t = 0o0004; +pub const S_IWOTH: mode_t = 0o0002; +pub const S_IXOTH: mode_t = 0o0001; + +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: crate::clockid_t = 1; +pub const CLOCK_MONOTONIC: crate::clockid_t = 4; +pub const CLOCK_BOOTTIME: crate::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 = u32_cast_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 unsafe fn FD_CLR(fd: c_int, set: *mut fd_set) -> () { + let bits = size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); + return; + } + + pub unsafe fn FD_ISSET(fd: c_int, set: *const fd_set) -> bool { + let bits = size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0; + } + + pub unsafe fn FD_SET(fd: c_int, set: *mut fd_set) -> () { + let bits = size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] |= 1 << (fd % bits); + return; + } + + pub unsafe fn FD_ZERO(set: *mut fd_set) -> () { + (*set).fds_bits.fill(0); + } +} + +extern "C" { + pub fn getrlimit(resource: c_int, rlim: *mut crate::rlimit) -> c_int; + pub fn setrlimit(resource: c_int, rlim: *const crate::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(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: crate::clockid_t, tp: *const crate::timespec) -> c_int; + pub fn clock_gettime(clock_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_getres(clock_id: crate::clockid_t, res: *mut crate::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(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(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; + + // DIFF(main): changed to `*const *mut` in e77f551de9 + pub fn fexecve(fd: c_int, argv: *const *const c_char, envp: *const *const c_char) -> c_int; + + pub fn gettimeofday(tp: *mut crate::timeval, tz: *mut c_void) -> c_int; + pub fn getgrgid_r( + gid: crate::gid_t, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::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 crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::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 crate::group; + pub fn pthread_kill(thread: crate::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: crate::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: crate::gid_t) -> *mut crate::group; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut crate::FILE; + pub fn uname(buf: *mut crate::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::*; + } +} 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..f51a1b2 --- /dev/null +++ b/vendor/libc/src/unix/newlib/powerpc/mod.rs @@ -0,0 +1,18 @@ +use crate::prelude::*; + +pub type clock_t = c_ulong; +pub type wchar_t = c_int; + +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..c889f6d --- /dev/null +++ b/vendor/libc/src/unix/newlib/rtems/mod.rs @@ -0,0 +1,148 @@ +// defined in architecture specific module + +use crate::prelude::*; + +s! { + pub struct sockaddr_un { + pub sun_family: crate::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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 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 safe fn WIFSTOPPED(status: c_int) -> bool { + (status & 0xff) == 0x7f + } + + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + // (status >> 8) & 0xff + WEXITSTATUS(status) + } + + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + ((status & 0x7f) > 0) && ((status & 0x7f) < 0x7f) + } + + pub const safe fn WTERMSIG(status: c_int) -> c_int { + status & 0x7f + } + + pub const safe fn WIFEXITED(status: c_int) -> bool { + (status & 0xff) == 0 + } + + pub const safe fn WEXITSTATUS(status: c_int) -> c_int { + (status >> 8) & 0xff + } + + // RTEMS doesn't have native WIFCONTINUED. + pub const safe fn WIFCONTINUED(_status: c_int) -> bool { + true + } + + // RTEMS doesn't have native WCOREDUMP. + pub const safe fn WCOREDUMP(_status: c_int) -> bool { + false + } +} + +extern "C" { + pub fn futimens(fd: c_int, times: *const crate::timespec) -> c_int; + pub fn writev(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + pub fn readv(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + + pub fn pthread_create( + native: *mut crate::pthread_t, + attr: *const crate::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 crate::pthread_condattr_t, + clock_id: crate::clockid_t, + ) -> c_int; + + pub fn getentropy(buf: *mut c_void, buflen: size_t) -> c_int; + + pub fn arc4random_buf(buf: *mut core::ffi::c_void, nbytes: size_t); + + pub fn setgroups(ngroups: c_int, grouplist: *const crate::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..95abf90 --- /dev/null +++ b/vendor/libc/src/unix/newlib/vita/mod.rs @@ -0,0 +1,233 @@ +use crate::off_t; +use crate::prelude::*; + +pub type clock_t = c_long; + +pub type wchar_t = u32; + +pub type sigset_t = c_ulong; + +s! { + pub struct msghdr { + pub msg_name: *mut c_void, + pub msg_namelen: crate::socklen_t, + pub msg_iov: *mut crate::iovec, + pub msg_iovlen: c_int, + pub msg_control: *mut c_void, + pub msg_controllen: crate::socklen_t, + pub msg_flags: c_int, + } + + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: crate::sa_family_t, + pub sa_data: [c_char; 14], + } + + pub struct sockaddr_in6 { + pub sin6_len: u8, + pub sin6_family: crate::sa_family_t, + pub sin6_port: crate::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: crate::in6_addr, + pub sin6_vport: crate::in_port_t, + pub sin6_scope_id: u32, + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: crate::sa_family_t, + pub sin_port: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_vport: crate::in_port_t, + pub sin_zero: [u8; 6], + } + + pub struct sockaddr_un { + pub ss_len: u8, + pub sun_family: crate::sa_family_t, + pub sun_path: [c_char; 108usize], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: crate::sa_family_t, + __ss_pad1: Padding<[u8; 2]>, + __ss_align: i64, + __ss_pad2: Padding<[u8; 116]>, + } + + pub struct sched_param { + pub sched_priority: c_int, + } + + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: crate::mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_atime: crate::time_t, + pub st_mtime: crate::time_t, + pub st_ctime: crate::time_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_spare4: [c_long; 2usize], + } + + #[repr(align(8))] + pub struct dirent { + __offset: [u8; 88], + pub d_name: [c_char; 256usize], + __pad: Padding<[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 = ptr::null_mut(); + +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 PTHREAD_STACK_MIN: size_t = 32 * 1024; + +pub const IP_HDRINCL: c_int = 2; + +extern "C" { + pub fn futimens(fd: c_int, times: *const crate::timespec) -> c_int; + pub fn writev(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + pub fn readv(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + + pub fn sendmsg(s: c_int, msg: *const crate::msghdr, flags: c_int) -> ssize_t; + pub fn recvmsg(s: c_int, msg: *mut crate::msghdr, flags: c_int) -> ssize_t; + + pub fn pthread_create( + native: *mut crate::pthread_t, + attr: *const crate::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 crate::pthread_attr_t, + param: *mut sched_param, + ) -> c_int; + + pub fn pthread_attr_setschedparam( + attr: *mut crate::pthread_attr_t, + param: *const sched_param, + ) -> c_int; + + pub fn pthread_attr_getprocessorid_np( + attr: *const crate::pthread_attr_t, + processor_id: *mut c_int, + ) -> c_int; + + pub fn pthread_attr_setprocessorid_np( + attr: *mut crate::pthread_attr_t, + processor_id: c_int, + ) -> c_int; + + pub fn pthread_getschedparam( + native: crate::pthread_t, + policy: *mut c_int, + param: *mut crate::sched_param, + ) -> c_int; + + pub fn pthread_setschedparam( + native: crate::pthread_t, + policy: c_int, + param: *const crate::sched_param, + ) -> c_int; + + pub fn pthread_condattr_getclock( + attr: *const crate::pthread_condattr_t, + clock_id: *mut crate::clockid_t, + ) -> c_int; + + pub fn pthread_condattr_setclock( + attr: *mut crate::pthread_condattr_t, + clock_id: crate::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/nto/arch/aarch64.rs b/vendor/libc/src/unix/nto/arch/aarch64.rs new file mode 100644 index 0000000..8662169 --- /dev/null +++ b/vendor/libc/src/unix/nto/arch/aarch64.rs @@ -0,0 +1,44 @@ +//! Definitions specific to QNX on AArch64 +//! +//! This module applies to: +//! +//! * `aarch64-unknown-nto-qnx700` +//! * `aarch64-unknown-nto-qnx710` +//! * `aarch64-unknown-nto-qnx710_iosock` +//! * `aarch64-unknown-qnx` + +use crate::prelude::*; + +pub type wchar_t = u32; +pub type time_t = i64; + +s! { + pub struct aarch64_qreg_t { + pub qlo: u64, + pub qhi: u64, + } + + pub struct aarch64_fpu_registers { + pub reg: [crate::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: crate::aarch64_cpu_registers, + pub fpu: crate::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/arch/i686.rs b/vendor/libc/src/unix/nto/arch/i686.rs new file mode 100644 index 0000000..489b047 --- /dev/null +++ b/vendor/libc/src/unix/nto/arch/i686.rs @@ -0,0 +1,10 @@ +//! Definitions specific to QNX on x86 +//! +//! This module applies to: +//! +//! * `i686-pc-nto-qnx700` + +use crate::prelude::*; + +pub type wchar_t = u32; +pub type time_t = i64; diff --git a/vendor/libc/src/unix/nto/arch/mod.rs b/vendor/libc/src/unix/nto/arch/mod.rs new file mode 100644 index 0000000..e671716 --- /dev/null +++ b/vendor/libc/src/unix/nto/arch/mod.rs @@ -0,0 +1,13 @@ +//! Architecture-specific definitions for QNX + +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"); + } +} diff --git a/vendor/libc/src/unix/nto/arch/x86_64.rs b/vendor/libc/src/unix/nto/arch/x86_64.rs new file mode 100644 index 0000000..fa2c028 --- /dev/null +++ b/vendor/libc/src/unix/nto/arch/x86_64.rs @@ -0,0 +1,119 @@ +//! Definitions specific to QNX on x86-64 +//! +//! This module applies to: +//! +//! * `x86_64-pc-nto-qnx710` +//! * `x86_64-pc-nto-qnx710_iosock` +//! * `x86_64-pc-qnx` + +use crate::prelude::*; + +pub type wchar_t = u32; +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: Padding, + pub rflags: u64, + pub rsp: u64, + pub ss: u32, + rsvd2: Padding, + } + + #[repr(align(8))] + pub struct mcontext_t { + pub cpu: x86_64_cpu_registers, + pub fpu: x86_64_fpu_registers, + } + + 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: Padding<[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! { + 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")] { + impl Eq for x86_64_fpu_registers {} + + 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 + } + } + } + + 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/nto/io_pkt/mod.rs b/vendor/libc/src/unix/nto/io_pkt/mod.rs new file mode 100644 index 0000000..928e0a3 --- /dev/null +++ b/vendor/libc/src/unix/nto/io_pkt/mod.rs @@ -0,0 +1,160 @@ +//! Definitions specific to QNX versions using io-pkt networking +//! +//! This module applies to: +//! +//! * `aarch64-unknown-nto-qnx700` +//! * `i686-pc-nto-qnx700` +//! * `aarch64-unknown-nto-qnx710` +//! * `x86_64-pc-nto-qnx710` + +use crate::prelude::*; + +s! { + #[repr(packed)] + pub struct in_addr { + pub s_addr: crate::in_addr_t, + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: crate::sa_family_t, + pub sin_port: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_zero: [i8; 8], + } + + pub struct in_pktinfo { + pub ipi_addr: crate::in_addr, + pub ipi_ifindex: c_uint, + } + + #[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 unpcbid { + pub unp_pid: crate::pid_t, + pub unp_euid: crate::uid_t, + pub unp_egid: crate::gid_t, + } + + pub struct mmsghdr { + pub msg_hdr: crate::msghdr, + pub msg_len: c_uint, + } + + pub struct bpf_stat { + pub bs_recv: u64, + pub bs_drop: u64, + pub bs_capt: u64, + bs_padding: Padding<[u64; 13]>, + } + + pub struct sockaddr_dl { + pub sdl_len: c_uchar, + pub sdl_family: crate::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 const SCM_CREDS: c_int = 0x04; +pub const IFF_NOTRAILERS: c_int = 0x00000020; +pub const AF_INET6: c_int = 24; +pub const AF_BLUETOOTH: c_int = 31; +pub const pseudo_AF_KEY: c_int = 29; +pub const MSG_NOSIGNAL: c_int = 0x0800; +pub const MSG_WAITFORONE: c_int = 0x2000; +pub const IP_IPSEC_POLICY_COMPAT: c_int = 22; +pub const IP_PKTINFO: c_int = 25; +pub const IPPROTO_DIVERT: c_int = 259; +pub const IPV6_IPSEC_POLICY_COMPAT: c_int = 28; +pub const TCP_KEEPALIVE: c_int = 0x04; +pub const ARPHRD_ARCNET: u16 = 7; +pub const SO_BINDTODEVICE: c_int = 0x0800; +pub const EAI_NODATA: c_int = 7; +pub const IPTOS_ECN_NOT_ECT: u8 = 0x00; +pub const RTF_BROADCAST: u32 = 0x80000; +pub const UDP_ENCAP: c_int = 100; +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_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 AF_ARP: c_int = 28; +pub const AF_IEEE80211: c_int = 32; +pub const AF_NATM: c_int = 27; +pub const AF_NS: c_int = 6; +pub const BIOCGDLTLIST: c_int = -1072676233; +pub const BIOCGETIF: c_int = 1083196011; +pub const BIOCGSEESENT: c_int = 1074020984; +pub const BIOCGSTATS: c_int = 1082147439; +pub const BIOCSDLT: c_int = -2147204490; +pub const BIOCSETIF: c_int = -2138029460; +pub const BIOCSSEESENT: c_int = -2147204487; +pub const FIONSPACE: c_int = 1074030200; +pub const FIONWRITE: c_int = 1074030201; +pub const IFF_ACCEPTRTADV: c_int = 0x40000000; +pub const IFF_IP6FORWARDING: c_int = 0x20000000; +pub const IFF_SHIM: c_int = u32_cast_int(0x80000000); +pub const KERN_ARND: c_int = 81; +pub const KERN_IOV_MAX: c_int = 38; +pub const KERN_LOGSIGEXIT: c_int = 46; +pub const KERN_MAXID: c_int = 83; +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_RGID: c_int = 8; +pub const LOCAL_CONNWAIT: c_int = 0x0002; +pub const LOCAL_CREDS: c_int = 0x0001; +pub const LOCAL_PEEREID: c_int = 0x0003; +pub const MSG_NOTIFICATION: c_int = 0x0400; +pub const NET_RT_IFLIST: c_int = 4; +pub const NI_NUMERICSCOPE: c_int = 0x00000040; +pub const PF_ARP: c_int = 28; +pub const PF_NATM: c_int = 27; +pub const pseudo_AF_HDRCMPLT: c_int = 30; +pub const SIOCGIFADDR: c_int = -1064277727; +pub const SO_FIB: c_int = 0x100a; +pub const SO_TXPRIO: c_int = 0x100b; +pub const SO_SETFIB: c_int = 0x100a; +pub const SO_VLANPRIO: c_int = 0x100c; +pub const USER_ATEXIT_MAX: c_int = 21; +pub const USER_MAXID: c_int = 22; +pub const SO_OVERFLOWED: c_int = 0x1009; + +extern "C" { + pub fn sendmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: c_uint, + flags: c_uint, + ) -> c_int; + + pub fn recvmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: c_uint, + flags: c_uint, + timeout: *mut crate::timespec, + ) -> c_int; +} diff --git a/vendor/libc/src/unix/nto/io_sock/mod.rs b/vendor/libc/src/unix/nto/io_sock/mod.rs new file mode 100644 index 0000000..303f5ca --- /dev/null +++ b/vendor/libc/src/unix/nto/io_sock/mod.rs @@ -0,0 +1,108 @@ +//! Definitions specific to QNX versions using io-sock networking +//! +//! This module applies to: +//! +//! * `aarch64-unknown-nto-qnx710` +//! * `x86_64-pc-nto-qnx710` +//! * `aarch64-unknown-qnx` +//! * `x86_64-pc-qnx` + +use crate::prelude::*; + +s! { + pub struct in_addr { + pub s_addr: crate::in_addr_t, + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: crate::sa_family_t, + pub sin_port: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_zero: [c_char; 8], + } + + 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: crate::msghdr, + pub msg_len: ssize_t, + } + + pub struct bpf_stat { + pub bs_recv: c_uint, + pub bs_drop: c_uint, + } + + 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 const SCM_CREDS: c_int = 0x03; +pub const AF_INET6: c_int = 28; +pub const AF_BLUETOOTH: c_int = 36; +pub const pseudo_AF_KEY: c_int = 27; +pub const MSG_NOSIGNAL: c_int = 0x20000; +pub const MSG_WAITFORONE: c_int = 0x00080000; +pub const IPPROTO_DIVERT: c_int = 258; +pub const RTF_BROADCAST: u32 = 0x400000; +pub const UDP_ENCAP: c_int = 1; +pub const HW_MACHINE_ARCH: c_int = 11; +pub const AF_ARP: c_int = 35; +pub const AF_IEEE80211: c_int = 37; +pub const AF_NATM: c_int = 29; +pub const BIOCGDLTLIST: c_ulong = 0xffffffffc0104279; +pub const BIOCGETIF: c_int = 0x4020426b; +pub const BIOCGSEESENT: c_int = 0x40044276; +pub const BIOCGSTATS: c_int = 0x4008426f; +pub const BIOCSDLT: c_int = u32_cast_int(0x80044278); +pub const BIOCSETIF: c_int = u32_cast_int(0x8020426c); +pub const BIOCSSEESENT: c_int = u32_cast_int(0x80044277); +pub const KERN_ARND: c_int = 37; +pub const KERN_IOV_MAX: c_int = 35; +pub const KERN_LOGSIGEXIT: c_int = 34; +pub const KERN_PROC_ARGS: c_int = 7; +pub const KERN_PROC_ENV: c_int = 35; +pub const KERN_PROC_GID: c_int = 11; +pub const KERN_PROC_RGID: c_int = 10; +pub const LOCAL_CONNWAIT: c_int = 4; +pub const LOCAL_CREDS: c_int = 2; +pub const MSG_NOTIFICATION: c_int = 0x00002000; +pub const NET_RT_IFLIST: c_int = 3; +pub const NI_NUMERICSCOPE: c_int = 0x00000020; +pub const PF_ARP: c_int = AF_ARP; +pub const PF_NATM: c_int = AF_NATM; +pub const pseudo_AF_HDRCMPLT: c_int = 31; +pub const SIOCGIFADDR: c_int = u32_cast_int(0xc0206921); +pub const SO_SETFIB: c_int = 0x1014; + +extern "C" { + pub fn sendmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: size_t, + flags: c_int, + ) -> ssize_t; + + pub fn recvmmsg( + sockfd: c_int, + msgvec: *mut crate::mmsghdr, + vlen: size_t, + flags: c_int, + timeout: *const crate::timespec, + ) -> ssize_t; +} diff --git a/vendor/libc/src/unix/nto/mod.rs b/vendor/libc/src/unix/nto/mod.rs new file mode 100644 index 0000000..6aa400a --- /dev/null +++ b/vendor/libc/src/unix/nto/mod.rs @@ -0,0 +1,3021 @@ +//! Definitions for QNX Software Development Platform +//! +//! This module applies to: +//! +//! * `aarch64-unknown-nto-qnx700` +//! * `aarch64-unknown-nto-qnx710` +//! * `aarch64-unknown-nto-qnx710_iosock` +//! * `aarch64-unknown-qnx` +//! * `i686-pc-nto-qnx700` +//! * `x86_64-pc-nto-qnx710` +//! * `x86_64-pc-nto-qnx710_iosock` +//! * `x86_64-pc-qnx` +//! +//! There are sub-modules for the target architecture, and sub-modules for the +//! kind of networking library used. QNX SDP 7.0 uses `io-pkt`, QNX SDP 8.0 +//! uses `io-sock`, and QNX SDP 7.1 comes with both (so you can pick). + +use crate::prelude::*; + +// QNX definitions of common UNIX things + +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 = crate::uintptr_t; + +pub type pthread_mutex_t = crate::sync_t; +pub type pthread_mutexattr_t = crate::_sync_attr; +pub type pthread_cond_t = crate::sync_t; +pub type pthread_condattr_t = crate::_sync_attr; +pub type pthread_rwlockattr_t = crate::_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; + +extern_ty! { + pub type timezone; +} + +s! { + pub struct dirent_extra { + pub d_datalen: u16, + pub d_type: u16, + d_reserved: Padding, + } + + pub struct stat { + pub st_ino: crate::ino_t, + pub st_size: off_t, + pub st_dev: crate::dev_t, + pub st_rdev: crate::dev_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub __old_st_mtime: crate::_Time32t, + pub __old_st_atime: crate::_Time32t, + pub __old_st_ctime: crate::_Time32t, + pub st_mode: mode_t, + pub st_nlink: crate::nlink_t, + pub st_blocksize: crate::blksize_t, + pub st_nblocks: i32, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_mtim: crate::timespec, + pub st_atim: crate::timespec, + pub st_ctim: crate::timespec, + } + + 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: [c_char; 14], + } + + pub struct sockaddr_in6 { + pub sin6_len: u8, + pub sin6_family: sa_family_t, + pub sin6_port: crate::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: crate::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 crate::sockaddr, + pub ai_next: *mut addrinfo, + } + + pub struct fd_set { + fds_bits: [c_uint; 2 * FD_SETSIZE as usize / 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, + reserved: Padding<[c_int; 10]>, + } + + #[repr(align(8))] + pub struct __sched_param { + pub __sched_priority: c_int, + pub __sched_curpriority: c_int, + reserved: Padding<[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, + _Reserved: Padding<[*mut c_char; 8]>, + } + + pub struct ifaddrs { + pub ifa_next: *mut ifaddrs, + pub ifa_name: *mut c_char, + pub ifa_flags: c_uint, + pub ifa_addr: *mut crate::sockaddr, + pub ifa_netmask: *mut crate::sockaddr, + pub ifa_dstaddr: *mut crate::sockaddr, + pub ifa_data: *mut c_void, + } + + pub struct arpreq { + pub arp_pa: crate::sockaddr, + pub arp_ha: crate::sockaddr, + pub arp_flags: c_int, + } + + #[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: crate::sighandler_t, + pub sa_flags: c_int, + pub sa_mask: crate::sigset_t, + } + + pub struct _sync { + _union: c_uint, + __owner: c_uint, + } + pub struct rlimit64 { + pub rlim_cur: rlim64_t, + pub rlim_max: rlim64_t, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + 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: Padding<*mut c_void>, + __unused2: Padding<*mut c_void>, + __unused3: Padding<*mut c_void>, + __unused4: Padding<*mut c_void>, + __unused5: Padding<*mut c_void>, + } + + pub struct passwd { + pub pw_name: *mut c_char, + pub pw_passwd: *mut c_char, + pub pw_uid: crate::uid_t, + pub pw_gid: crate::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: crate::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: crate::socklen_t, + pub msg_iov: *mut crate::iovec, + pub msg_iovlen: c_int, + pub msg_control: *mut c_void, + pub msg_controllen: crate::socklen_t, + pub msg_flags: c_int, + } + + pub struct cmsghdr { + pub cmsg_len: crate::socklen_t, + pub cmsg_level: c_int, + pub cmsg_type: c_int, + } + + pub struct termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_cc: [crate::cc_t; crate::NCCS], + __reserved: Padding<[c_uint; 3]>, + pub c_ispeed: crate::speed_t, + pub c_ospeed: crate::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: crate::pid_t, + pub l_sysid: u32, + } + + pub struct statvfs { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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: crate::sigevent, + pub aio_lio_opcode: c_int, + pub _aio_lio_state: *mut c_void, + _aio_pad: Padding<[c_int; 3]>, + pub _aio_next: *mut crate::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: crate::__sched_param, + } + + pub struct pthread_attr_t { + __data1: c_long, + __data2: [u8; 96], + } + + pub struct ipc_perm { + pub uid: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: mode_t, + pub seq: c_uint, + pub key: crate::key_t, + _reserved: Padding<[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, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + 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: crate::__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: Padding<[c_int; 3]>, + } + + pub struct sockcred { + pub sc_uid: crate::uid_t, + pub sc_euid: crate::uid_t, + pub sc_gid: crate::gid_t, + pub sc_egid: crate::gid_t, + pub sc_ngroups: c_int, + pub sc_groups: [crate::gid_t; 1], + } + + pub struct bpf_program { + pub bf_len: c_uint, + pub bf_insns: *mut crate::bpf_insn, + } + + pub struct bpf_version { + pub bv_major: c_ushort, + pub bv_minor: c_ushort, + } + + pub struct bpf_hdr { + pub bh_tstamp: crate::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 dl_phdr_info { + pub dlpi_addr: crate::Elf64_Addr, + pub dlpi_name: *const c_char, + pub dlpi_phdr: *const crate::Elf64_Phdr, + pub dlpi_phnum: crate::Elf64_Half, + } + + #[repr(align(8))] + pub struct ucontext_t { + pub uc_link: *mut ucontext_t, + pub uc_sigmask: crate::sigset_t, + pub uc_stack: stack_t, + pub uc_mcontext: mcontext_t, + } + 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: Padding<[c_char; 6]>, + __ss_align: i64, + __ss_pad2: Padding<[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, + __padding1: Padding, + pub sigev_signo: c_int, // union + __padding2: Padding, + pub sigev_value: crate::sigval, + __sigev_un2: usize, // union + } + pub struct dirent { + pub d_ino: crate::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, + } +} + +s_no_extra_traits! { + pub struct msg { + pub msg_next: *mut crate::msg, + pub msg_type: c_long, + pub msg_ts: c_ushort, + pub msg_spot: c_short, + _pad: Padding<[u8; 4]>, + } + + pub struct msqid_ds { + pub msg_perm: crate::ipc_perm, + pub msg_first: *mut crate::msg, + pub msg_last: *mut crate::msg, + pub msg_cbytes: crate::msglen_t, + pub msg_qnum: crate::msgqnum_t, + pub msg_qbytes: crate::msglen_t, + pub msg_lspid: crate::pid_t, + pub msg_lrpid: crate::pid_t, + pub msg_stime: crate::time_t, + msg_pad1: Padding, + pub msg_rtime: crate::time_t, + msg_pad2: Padding, + pub msg_ctime: crate::time_t, + msg_pad3: Padding, + msg_pad4: Padding<[c_long; 4]>, + } + + pub struct sync_t { + __u: c_uint, // union + pub __owner: c_uint, + } + + #[repr(align(4))] + pub struct pthread_barrier_t { + // union + __pad: Padding<[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: crate::pthread_mutex_t, // union + pub __rcond: crate::pthread_cond_t, // union + pub __wcond: crate::pthread_cond_t, // union + pub __owner: c_uint, + pub __spare: c_uint, + } + + // There is no canonical definition of c_longdouble in Rust. For both AArch64 and x86_64, + // however, the size and alignment properties are that of the gcc __int128 which corresponds (at + // least on rustc 1.78+ with LLVM 18, see + // https://blog.rust-lang.org/2024/03/30/i128-layout-update/) to i128. Use this instead until we + // get native f128 support. + // + // The definition was taken from the definition of the _Maxalignt struct in the QNX SDK. + // However, on QNX SDP 7, there is a different definition of std::max_align_t (the C++ version of + // this type). In practice, this doesn't make a difference for the _alignment_ properties of the + // type - however, it changes the size, so using in in any other form than the zero-sized array + // form would be bogus and it would potentially change the size of the data type. On QNX SDP 8, this + // got fixed and both C and C++ are using the same definition. + pub struct max_align_t { + _ll: crate::c_longlong, + _ld: i128, + } +} + +pub const _SYSNAME_SIZE: usize = 256 + 1; +pub const RLIM_INFINITY: crate::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: crate::clockid_t = 0; +pub const CLOCK_MONOTONIC: crate::clockid_t = 2; +pub const CLOCK_PROCESS_CPUTIME_ID: crate::clockid_t = 3; +pub const CLOCK_THREAD_CPUTIME_ID: crate::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 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 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_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_ROUTE: c_int = 17; +pub const AF_SNA: c_int = 11; + +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 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 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_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_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_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 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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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: crate::tcflag_t = 0x000; +pub const NL1: crate::tcflag_t = 0x100; +pub const TAB0: crate::tcflag_t = 0x0000; +pub const CR0: crate::tcflag_t = 0x000; +pub const FF0: crate::tcflag_t = 0x0000; +pub const BS0: crate::tcflag_t = 0x0000; +pub const VT0: crate::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: crate::tcflag_t = 0x00000001; +pub const BRKINT: crate::tcflag_t = 0x00000002; +pub const IGNPAR: crate::tcflag_t = 0x00000004; +pub const PARMRK: crate::tcflag_t = 0x00000008; +pub const INPCK: crate::tcflag_t = 0x00000010; +pub const ISTRIP: crate::tcflag_t = 0x00000020; +pub const INLCR: crate::tcflag_t = 0x00000040; +pub const IGNCR: crate::tcflag_t = 0x00000080; +pub const ICRNL: crate::tcflag_t = 0x00000100; +pub const IXANY: crate::tcflag_t = 0x00000800; +pub const IMAXBEL: crate::tcflag_t = 0x00002000; +pub const OPOST: crate::tcflag_t = 0x00000001; +pub const CS5: crate::tcflag_t = 0x00; +pub const ECHO: crate::tcflag_t = 0x00000008; +pub const OCRNL: crate::tcflag_t = 0x00000008; +pub const ONOCR: crate::tcflag_t = 0x00000010; +pub const ONLRET: crate::tcflag_t = 0x00000020; +pub const OFILL: crate::tcflag_t = 0x00000040; +pub const OFDEL: crate::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_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_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: crate::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 crate::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_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; + +// DIFF(main): changed to `c_short` in f62eb023ab +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 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 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 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 = crate::S_IXUSR; +pub const S_IWRITE: mode_t = crate::S_IWUSR; +pub const S_IREAD: mode_t = crate::S_IRUSR; + +pub const S_IFIFO: mode_t = 0o1_0000; +pub const S_IFCHR: mode_t = 0o2_0000; +pub const S_IFDIR: mode_t = 0o4_0000; +pub const S_IFBLK: mode_t = 0o6_0000; +pub const S_IFREG: mode_t = 0o10_0000; +pub const S_IFLNK: mode_t = 0o12_0000; +pub const S_IFSOCK: mode_t = 0o14_0000; +pub const S_IFMT: mode_t = 0o17_0000; + +pub const S_IXOTH: mode_t = 0o0001; +pub const S_IWOTH: mode_t = 0o0002; +pub const S_IROTH: mode_t = 0o0004; +pub const S_IRWXO: mode_t = 0o0007; +pub const S_IXGRP: mode_t = 0o0010; +pub const S_IWGRP: mode_t = 0o0020; +pub const S_IRGRP: mode_t = 0o0040; +pub const S_IRWXG: mode_t = 0o0070; +pub const S_IXUSR: mode_t = 0o0100; +pub const S_IWUSR: mode_t = 0o0200; +pub const S_IRUSR: mode_t = 0o0400; +pub const S_IRWXU: mode_t = 0o0700; + +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: crate::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 = crate::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: crate::tcflag_t = 15; +pub const CBAUD: crate::tcflag_t = _TIO_CBAUD; +pub const TAB1: crate::tcflag_t = 0x0800; +pub const TAB2: crate::tcflag_t = 0x1000; +pub const TAB3: crate::tcflag_t = 0x1800; +pub const CR1: crate::tcflag_t = 0x200; +pub const CR2: crate::tcflag_t = 0x400; +pub const CR3: crate::tcflag_t = 0x600; +pub const FF1: crate::tcflag_t = 0x8000; +pub const BS1: crate::tcflag_t = 0x2000; +pub const VT1: crate::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: crate::tcflag_t = 0x00000400; +pub const IXOFF: crate::tcflag_t = 0x00001000; +pub const ONLCR: crate::tcflag_t = 0x00000004; +pub const CSIZE: crate::tcflag_t = 0x00000030; +pub const CS6: crate::tcflag_t = 0x10; +pub const CS7: crate::tcflag_t = 0x20; +pub const CS8: crate::tcflag_t = 0x30; +pub const CSTOPB: crate::tcflag_t = 0x00000040; +pub const CREAD: crate::tcflag_t = 0x00000080; +pub const PARENB: crate::tcflag_t = 0x00000100; +pub const PARODD: crate::tcflag_t = 0x00000200; +pub const HUPCL: crate::tcflag_t = 0x00000400; +pub const CLOCAL: crate::tcflag_t = 0x00000800; +pub const ECHOKE: crate::tcflag_t = 0x00000800; +pub const ECHOE: crate::tcflag_t = 0x00000010; +pub const ECHOK: crate::tcflag_t = 0x00000020; +pub const ECHONL: crate::tcflag_t = 0x00000040; +pub const ECHOCTL: crate::tcflag_t = 0x00000200; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const NOFLSH: crate::tcflag_t = 0x00000080; +pub const OLCUC: crate::tcflag_t = 0x00000002; +pub const NLDLY: crate::tcflag_t = 0x00000100; +pub const CRDLY: crate::tcflag_t = 0x00000600; +pub const TABDLY: crate::tcflag_t = 0x00001800; +pub const BSDLY: crate::tcflag_t = 0x00002000; +pub const FFDLY: crate::tcflag_t = 0x00008000; +pub const VTDLY: crate::tcflag_t = 0x00004000; +pub const XTABS: crate::tcflag_t = 0x1800; + +pub const B0: crate::speed_t = 0; +pub const B50: crate::speed_t = 1; +pub const B75: crate::speed_t = 2; +pub const B110: crate::speed_t = 3; +pub const B134: crate::speed_t = 4; +pub const B150: crate::speed_t = 5; +pub const B200: crate::speed_t = 6; +pub const B300: crate::speed_t = 7; +pub const B600: crate::speed_t = 8; +pub const B1200: crate::speed_t = 9; +pub const B1800: crate::speed_t = 10; +pub const B2400: crate::speed_t = 11; +pub const B4800: crate::speed_t = 12; +pub const B9600: crate::speed_t = 13; +pub const B19200: crate::speed_t = 14; +pub const B38400: crate::speed_t = 15; +pub const EXTA: crate::speed_t = 14; +pub const EXTB: crate::speed_t = 15; +pub const B57600: crate::speed_t = 57600; +pub const B115200: crate::speed_t = 115200; + +pub const VEOL: usize = 5; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 16; +pub const IEXTEN: crate::tcflag_t = 0x00008000; +pub const TOSTOP: crate::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 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 DAY_1: crate::nl_item = 8; +pub const DAY_2: crate::nl_item = 9; +pub const DAY_3: crate::nl_item = 10; +pub const DAY_4: crate::nl_item = 11; +pub const DAY_5: crate::nl_item = 12; +pub const DAY_6: crate::nl_item = 13; +pub const DAY_7: crate::nl_item = 14; + +pub const MON_1: crate::nl_item = 22; +pub const MON_2: crate::nl_item = 23; +pub const MON_3: crate::nl_item = 24; +pub const MON_4: crate::nl_item = 25; +pub const MON_5: crate::nl_item = 26; +pub const MON_6: crate::nl_item = 27; +pub const MON_7: crate::nl_item = 28; +pub const MON_8: crate::nl_item = 29; +pub const MON_9: crate::nl_item = 30; +pub const MON_10: crate::nl_item = 31; +pub const MON_11: crate::nl_item = 32; +pub const MON_12: crate::nl_item = 33; + +pub const ABDAY_1: crate::nl_item = 15; +pub const ABDAY_2: crate::nl_item = 16; +pub const ABDAY_3: crate::nl_item = 17; +pub const ABDAY_4: crate::nl_item = 18; +pub const ABDAY_5: crate::nl_item = 19; +pub const ABDAY_6: crate::nl_item = 20; +pub const ABDAY_7: crate::nl_item = 21; + +pub const ABMON_1: crate::nl_item = 34; +pub const ABMON_2: crate::nl_item = 35; +pub const ABMON_3: crate::nl_item = 36; +pub const ABMON_4: crate::nl_item = 37; +pub const ABMON_5: crate::nl_item = 38; +pub const ABMON_6: crate::nl_item = 39; +pub const ABMON_7: crate::nl_item = 40; +pub const ABMON_8: crate::nl_item = 41; +pub const ABMON_9: crate::nl_item = 42; +pub const ABMON_10: crate::nl_item = 43; +pub const ABMON_11: crate::nl_item = 44; +pub const ABMON_12: crate::nl_item = 45; + +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_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_OSI: c_int = 7; +pub const AF_PUP: c_int = 4; +pub const ALT_DIGITS: crate::nl_item = 50; +pub const AM_STR: crate::nl_item = 6; +pub const B76800: crate::speed_t = 76800; + +pub const BIOCFLUSH: c_int = 17000; +pub const BIOCGBLEN: c_int = 1074020966; +pub const BIOCGDLT: c_int = 1074020970; +pub const BIOCGHDRCMPLT: c_int = 1074020980; +pub const BIOCGRTIMEOUT: c_int = 1074807406; +pub const BIOCIMMEDIATE: c_int = -2147204496; +pub const BIOCPROMISC: c_int = 17001; +pub const BIOCSBLEN: c_int = -1073462682; +pub const BIOCSETF: c_int = -2146418073; +pub const BIOCSHDRCMPLT: c_int = -2147204491; +pub const BIOCSRTIMEOUT: c_int = -2146418067; +pub const BIOCVERSION: c_int = 1074020977; + +pub const BPF_ALIGNMENT: usize = size_of::(); +pub const CHAR_BIT: usize = 8; +pub const CODESET: crate::nl_item = 1; +pub const CRNCYSTR: crate::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: crate::nl_item = 3; +pub const D_GETFLAG: c_int = 1; +pub const D_SETFLAG: c_int = 2; +pub const D_T_FMT: crate::nl_item = 2; +pub const ERA: crate::nl_item = 46; +pub const ERA_D_FMT: crate::nl_item = 47; +pub const ERA_D_T_FMT: crate::nl_item = 48; +pub const ERA_T_FMT: crate::nl_item = 49; +pub const RADIXCHAR: crate::nl_item = 51; +pub const THOUSEP: crate::nl_item = 52; +pub const YESEXPR: crate::nl_item = 53; +pub const NOEXPR: crate::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 FIOSETOWN: c_int = -2147195268; + +pub const F_SETOWN: c_int = 36; +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_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_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_JOB_CONTROL: c_int = 19; +pub const KERN_MAXFILES: c_int = 7; +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_PGRP: c_int = 2; +pub const KERN_PROC_PID: c_int = 1; +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 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 NET_RT_DUMP: c_int = 1; +pub const NET_RT_FLAGS: c_int = 2; +pub const OHFLOW: tcflag_t = 0x00000002; +pub const P_ALL: idtype_t = 0; +pub const PARSTK: tcflag_t = 0x00000004; +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_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: crate::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_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 SO_USELOOPBACK: c_int = 0x0040; +pub const _SS_ALIGNSIZE: usize = 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: crate::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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_BASE_MAX: c_int = 2; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_DIM_MAX: c_int = 3; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_SCALE_MAX: c_int = 4; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_BC_STRING_MAX: c_int = 5; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_COLL_WEIGHTS_MAX: c_int = 6; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_EXPR_NEST_MAX: c_int = 7; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const USER_LINE_MAX: c_int = 8; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 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; + +#[cfg(not(any(target_env = "nto71", target_env = "nto71_iosock", target_os = "qnx")))] +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + __u: 0x80000000, + __owner: 0xffffffff, +}; +#[cfg(any(target_env = "nto71", target_env = "nto71_iosock"))] +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + __u: 0x82000000, + __owner: 0, +}; +#[cfg(target_os = "qnx")] +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + __u: 0x80000000, + __owner: 0, +}; +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 _CMSG_ALIGN(len: usize) -> usize { + len + size_of::() - 1 & !(size_of::() - 1) +} + +const fn _ALIGN(p: usize, b: usize) -> usize { + (p + b - 1) & !(b - 1) +} + +f! { + pub unsafe fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize >= size_of::() { + (*mhdr).msg_control.cast() + } else { + ptr::null_mut() + } + } + + pub unsafe fn CMSG_NXTHDR(mhdr: *const crate::msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { + let msg = _CMSG_ALIGN((*cmsg).cmsg_len as usize); + let next = cmsg as usize + msg + _CMSG_ALIGN(size_of::()); + if next > (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize { + ptr::null_mut() + } else { + (cmsg as usize + msg) as *mut cmsghdr + } + } + + pub unsafe fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + (cmsg as *mut c_uchar).offset(_CMSG_ALIGN(size_of::()) as isize) + } + + pub const unsafe fn CMSG_LEN(length: c_uint) -> c_uint { + _CMSG_ALIGN(size_of::()) as c_uint + length + } + + pub const unsafe fn CMSG_SPACE(length: c_uint) -> c_uint { + (_CMSG_ALIGN(size_of::()) + _CMSG_ALIGN(length as usize)) as c_uint + } + + pub unsafe fn FD_CLR(fd: c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] &= !(1 << (fd % size)); + return; + } + + pub unsafe fn FD_ISSET(fd: c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0; + } + + pub unsafe fn FD_SET(fd: c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] |= 1 << (fd % size); + return; + } + + pub unsafe fn FD_ZERO(set: *mut fd_set) -> () { + (*set).fds_bits.fill(0); + } + + pub unsafe fn _DEXTRA_FIRST(_d: *const dirent) -> *mut crate::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 crate::dirent_extra + } + + pub unsafe fn _DEXTRA_VALID(_x: *const crate::dirent_extra, _d: *const dirent) -> bool { + let sz = _x as usize - _d as usize + size_of::(); + let rsz = (*_d).d_reclen as usize; + + if sz > rsz || sz + (*_x).d_datalen as usize > rsz { + false + } else { + true + } + } + + pub unsafe fn _DEXTRA_NEXT(_x: *const crate::dirent_extra) -> *mut crate::dirent_extra { + _ALIGN( + _x as usize + size_of::() + (*_x).d_datalen as usize, + 8, + ) as *mut crate::dirent_extra + } + + pub unsafe fn SOCKCREDSIZE(ngrps: usize) -> usize { + let ngrps = if ngrps > 0 { ngrps - 1 } else { 0 }; + size_of::() + size_of::() * ngrps + } +} + +safe_f! { + pub const safe fn WIFSTOPPED(status: c_int) -> bool { + (status & 0xff) == 0x7f + } + + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + (status >> 8) & 0xff + } + + pub const safe fn WIFCONTINUED(status: c_int) -> bool { + status == 0xffff + } + + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + ((status & 0x7f) + 1) as i8 >= 2 + } + + pub const safe fn WTERMSIG(status: c_int) -> c_int { + status & 0x7f + } + + pub const safe fn WIFEXITED(status: c_int) -> bool { + (status & 0x7f) == 0 + } + + pub const safe fn WEXITSTATUS(status: c_int) -> c_int { + (status >> 8) & 0xff + } + + pub const safe fn WCOREDUMP(status: c_int) -> bool { + (status & 0x80) != 0 + } + + pub const safe fn IPTOS_ECN(x: u8) -> u8 { + x & crate::IPTOS_ECN_MASK + } + + pub const safe fn makedev(major: c_uint, minor: c_uint) -> crate::dev_t { + ((major << 10) | (minor)) as crate::dev_t + } + + pub const safe fn major(dev: crate::dev_t) -> c_uint { + ((dev as c_uint) >> 10) & 0x3f + } + + pub const safe fn minor(dev: crate::dev_t) -> c_uint { + (dev as c_uint) & 0x3ff + } +} + +// 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: crate::id_t) -> c_int; + pub fn setpriority(which: c_int, who: crate::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: crate::dev_t) -> c_int; + + pub fn clock_getres(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_gettime(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_settime(clk_id: crate::clockid_t, tp: *const crate::timespec) -> c_int; + pub fn clock_getcpuclockid(pid: crate::pid_t, clk_id: *mut crate::clockid_t) -> c_int; + + pub fn pthread_attr_getstack( + attr: *const crate::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 crate::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 crate::timespec) -> c_int; + pub fn nl_langinfo(item: crate::nl_item) -> *mut c_char; + + pub fn utimensat( + dirfd: c_int, + path: *const c_char, + times: *const crate::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: crate::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 crate::siginfo_t, + options: c_int, + ) -> c_int; + pub fn wait4( + pid: crate::pid_t, + status: *mut c_int, + options: c_int, + rusage: *mut crate::rusage, + ) -> crate::pid_t; + + // DIFF(main): changed to `*const *mut` in e77f551de9 + 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 crate::ifaddrs) -> c_int; + pub fn freeifaddrs(ifa: *mut crate::ifaddrs); + pub fn bind( + socket: c_int, + address: *const crate::sockaddr, + address_len: crate::socklen_t, + ) -> c_int; + + pub fn writev(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + pub fn readv(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + + pub fn sendmsg(fd: c_int, msg: *const crate::msghdr, flags: c_int) -> ssize_t; + pub fn recvmsg(fd: c_int, msg: *mut crate::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 crate::winsize, + ) -> c_int; + pub fn forkpty( + amaster: *mut c_int, + name: *mut c_char, + termp: *mut termios, + winp: *mut crate::winsize, + ) -> crate::pid_t; + pub fn login_tty(fd: c_int) -> c_int; + + pub fn uname(buf: *mut crate::utsname) -> c_int; + + pub fn getpeereid(socket: c_int, euid: *mut crate::uid_t, egid: *mut crate::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 crate::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) -> crate::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 crate::timespec, + ) -> c_int; + pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> c_int; + pub fn pthread_setschedprio(native: crate::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 crate::glob_t, + ) -> c_int; + pub fn globfree(pglob: *mut crate::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 crate::DIR, loc: c_long); + + pub fn telldir(dirp: *mut crate::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 crate::sockaddr, + addrlen: *mut crate::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: crate::pthread_t, + policy: *mut c_int, + param: *mut crate::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 crate::timeval, tz: *const c_void) -> c_int; + pub fn sched_rr_get_interval(pid: crate::pid_t, tp: *mut crate::timespec) -> c_int; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const crate::timespec) -> c_int; + pub fn sem_getvalue(sem: *mut sem_t, sval: *mut c_int) -> c_int; + pub fn sched_setparam(pid: crate::pid_t, param: *const crate::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: crate::pid_t, param: *mut crate::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 crate::timespec, + ) -> c_int; + pub fn pthread_spin_init(lock: *mut crate::pthread_spinlock_t, pshared: c_int) -> c_int; + pub fn pthread_spin_destroy(lock: *mut crate::pthread_spinlock_t) -> c_int; + pub fn pthread_spin_lock(lock: *mut crate::pthread_spinlock_t) -> c_int; + pub fn pthread_spin_trylock(lock: *mut crate::pthread_spinlock_t) -> c_int; + pub fn pthread_spin_unlock(lock: *mut crate::pthread_spinlock_t) -> c_int; + pub fn pthread_barrierattr_init(__attr: *mut crate::pthread_barrierattr_t) -> c_int; + pub fn pthread_barrierattr_destroy(__attr: *mut crate::pthread_barrierattr_t) -> c_int; + pub fn pthread_barrierattr_getpshared( + __attr: *const crate::pthread_barrierattr_t, + __pshared: *mut c_int, + ) -> c_int; + pub fn pthread_barrierattr_setpshared( + __attr: *mut crate::pthread_barrierattr_t, + __pshared: c_int, + ) -> c_int; + pub fn pthread_barrier_init( + __barrier: *mut crate::pthread_barrier_t, + __attr: *const crate::pthread_barrierattr_t, + __count: c_uint, + ) -> c_int; + pub fn pthread_barrier_destroy(__barrier: *mut crate::pthread_barrier_t) -> c_int; + pub fn pthread_barrier_wait(__barrier: *mut crate::pthread_barrier_t) -> c_int; + + pub fn sched_getscheduler(pid: crate::pid_t) -> c_int; + pub fn clock_nanosleep( + clk_id: crate::clockid_t, + flags: c_int, + rqtp: *const crate::timespec, + rmtp: *mut crate::timespec, + ) -> c_int; + pub fn pthread_attr_getguardsize( + attr: *const crate::pthread_attr_t, + guardsize: *mut size_t, + ) -> c_int; + pub fn pthread_attr_setguardsize(attr: *mut crate::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: crate::pthread_t, + policy: c_int, + param: *const crate::sched_param, + ) -> c_int; + pub fn sched_setscheduler( + pid: crate::pid_t, + policy: c_int, + param: *const crate::sched_param, + ) -> c_int; + pub fn sigsuspend(mask: *const crate::sigset_t) -> c_int; + pub fn getgrgid_r( + gid: crate::gid_t, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::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 crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn initgroups(user: *const c_char, group: crate::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 crate::group; + pub fn pthread_cancel(thread: crate::pthread_t) -> c_int; + pub fn pthread_kill(thread: crate::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: crate::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: crate::gid_t) -> *mut crate::group; + pub fn getgrouplist( + user: *const c_char, + group: crate::gid_t, + groups: *mut crate::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 crate::pthread_t, + attr: *const crate::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 crate::itimerval) -> c_int; + pub fn setitimer( + which: c_int, + value: *const crate::itimerval, + ovalue: *mut crate::itimerval, + ) -> c_int; + pub fn posix_spawn( + pid: *mut crate::pid_t, + path: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::posix_spawnattr_t, + argv: *const *mut c_char, + envp: *const *mut c_char, + ) -> c_int; + pub fn posix_spawnp( + pid: *mut crate::pid_t, + file: *const c_char, + file_actions: *const crate::posix_spawn_file_actions_t, + attrp: *const crate::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 crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + default: *const crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + default: *mut crate::sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + default: *const crate::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 crate::pid_t, + ) -> c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: crate::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 crate::sched_param, + ) -> c_int; + pub fn posix_spawnattr_setschedparam( + attr: *mut posix_spawnattr_t, + param: *const crate::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 crate::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() -> crate::pid_t; + + pub fn pthread_getcpuclockid(thread: crate::pthread_t, clk_id: *mut crate::clockid_t) -> c_int; + + pub fn getnameinfo( + sa: *const crate::sockaddr, + salen: crate::socklen_t, + host: *mut c_char, + hostlen: crate::socklen_t, + serv: *mut c_char, + servlen: crate::socklen_t, + flags: c_int, + ) -> c_int; + + pub fn mallopt(param: c_int, value: i64) -> c_int; + pub fn gettimeofday(tp: *mut crate::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() -> crate::mallinfo; + pub fn getpwent_r( + pwd: *mut crate::passwd, + buf: *mut c_char, + __bufsize: c_int, + __result: *mut *mut crate::passwd, + ) -> c_int; + pub fn pthread_getname_np(thread: crate::pthread_t, name: *mut c_char, len: c_int) -> c_int; + pub fn pthread_setname_np(thread: crate::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 crate::rlimit) -> c_int; + pub fn setrlimit(resource: c_int, rlp: *const crate::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 crate::regex_t, __pattern: *const c_char, __cflags: c_int) + -> c_int; + pub fn regexec( + __preg: *const crate::regex_t, + __str: *const c_char, + __nmatch: size_t, + __pmatch: *mut crate::regmatch_t, + __eflags: c_int, + ) -> c_int; + pub fn regerror( + __errcode: c_int, + __preg: *const crate::regex_t, + __errbuf: *mut c_char, + __errbuf_size: size_t, + ) -> size_t; + pub fn regfree(__preg: *mut crate::regex_t); + pub fn dirfd(__dirp: *mut crate::DIR) -> c_int; + pub fn dircntl(dir: *mut crate::DIR, cmd: c_int, ...) -> c_int; + + pub fn aio_cancel(__fd: c_int, __aiocbp: *mut crate::aiocb) -> c_int; + pub fn aio_error(__aiocbp: *const crate::aiocb) -> c_int; + pub fn aio_fsync(__operation: c_int, __aiocbp: *mut crate::aiocb) -> c_int; + pub fn aio_read(__aiocbp: *mut crate::aiocb) -> c_int; + pub fn aio_return(__aiocpb: *mut crate::aiocb) -> ssize_t; + pub fn aio_suspend( + __list: *const *const crate::aiocb, + __nent: c_int, + __timeout: *const crate::timespec, + ) -> c_int; + pub fn aio_write(__aiocpb: *mut crate::aiocb) -> c_int; + + pub fn mq_close(__mqdes: crate::mqd_t) -> c_int; + pub fn mq_getattr(__mqdes: crate::mqd_t, __mqstat: *mut crate::mq_attr) -> c_int; + pub fn mq_notify(__mqdes: crate::mqd_t, __notification: *const crate::sigevent) -> c_int; + pub fn mq_open(__name: *const c_char, __oflag: c_int, ...) -> crate::mqd_t; + pub fn mq_receive( + __mqdes: crate::mqd_t, + __msg_ptr: *mut c_char, + __msg_len: size_t, + __msg_prio: *mut c_uint, + ) -> ssize_t; + pub fn mq_send( + __mqdes: crate::mqd_t, + __msg_ptr: *const c_char, + __msg_len: size_t, + __msg_prio: c_uint, + ) -> c_int; + pub fn mq_setattr( + __mqdes: crate::mqd_t, + __mqstat: *const mq_attr, + __omqstat: *mut mq_attr, + ) -> c_int; + pub fn mq_timedreceive( + __mqdes: crate::mqd_t, + __msg_ptr: *mut c_char, + __msg_len: size_t, + __msg_prio: *mut c_uint, + __abs_timeout: *const crate::timespec, + ) -> ssize_t; + pub fn mq_timedsend( + __mqdes: crate::mqd_t, + __msg_ptr: *const c_char, + __msg_len: size_t, + __msg_prio: c_uint, + __abs_timeout: *const crate::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, ptr::null_mut(), __dso_handle) +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut c_void { + #[repr(C)] + struct siginfo_si_addr { + _pad: Padding<[u8; 32]>, + si_addr: *mut c_void, + } + (*(self as *const siginfo_t).cast::()).si_addr + } + + pub unsafe fn si_value(&self) -> crate::sigval { + #[repr(C)] + struct siginfo_si_value { + _pad: Padding<[u8; 32]>, + si_value: crate::sigval, + } + (*(self as *const siginfo_t).cast::()).si_value + } + + pub unsafe fn si_pid(&self) -> crate::pid_t { + #[repr(C)] + struct siginfo_si_pid { + _pad: Padding<[u8; 16]>, + si_pid: crate::pid_t, + } + (*(self as *const siginfo_t).cast::()).si_pid + } + + pub unsafe fn si_uid(&self) -> crate::uid_t { + #[repr(C)] + struct siginfo_si_uid { + _pad: Padding<[u8; 24]>, + si_uid: crate::uid_t, + } + (*(self as *const siginfo_t).cast::()).si_uid + } + + pub unsafe fn si_status(&self) -> c_int { + #[repr(C)] + struct siginfo_si_status { + _pad: Padding<[u8; 28]>, + si_status: c_int, + } + (*(self as *const siginfo_t).cast::()).si_status + } +} + +// Things that are QNX specific + +mod neutrino; +pub use self::neutrino::*; + +// Things that are architecture specific + +mod arch; +pub use self::arch::*; + +// Things that are network-stack specific + +cfg_if! { + if #[cfg(any(target_env = "nto70", target_env = "nto71"))] { + mod io_pkt; + pub use self::io_pkt::*; + } else if #[cfg(any(target_env = "nto71_iosock", target_os = "qnx"))] { + mod io_sock; + pub use self::io_sock::*; + } else { + panic!("Unsupported arch"); + } +} diff --git a/vendor/libc/src/unix/nto/neutrino.rs b/vendor/libc/src/unix/nto/neutrino.rs new file mode 100644 index 0000000..f360605 --- /dev/null +++ b/vendor/libc/src/unix/nto/neutrino.rs @@ -0,0 +1,1272 @@ +//! APIs that are specific to QNX Neutrino and not found in other operating systems + +use crate::prelude::*; + +pub type nto_job_t = crate::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: crate::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: Padding, + } + + pub struct _cred_info { + pub ruid: crate::uid_t, + pub euid: crate::uid_t, + pub suid: crate::uid_t, + pub rgid: crate::gid_t, + pub egid: crate::gid_t, + pub sgid: crate::gid_t, + pub ngroups: u32, + pub grouplist: [crate::gid_t; 8], + } + + pub struct _client_info { + pub nd: u32, + pub pid: crate::pid_t, + pub sid: crate::pid_t, + pub flags: u32, + pub cred: crate::_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: crate::sigevent, + pub num_pulses: c_uint, + pub rearm_threshold: c_uint, + pub options: c_uint, + reserved: Padding<[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 crate::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: crate::_itimer, + // reserve: Padding, + //} + + //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: crate::sigevent, + // pub num_curmsg: c_uint, + // pub ttimer: crate::timer_t, + // pub block_con: crate::pthread_cond_t, + // pub mu: crate::pthread_mutex_t, + // reserved: Padding, + // pub attr: crate::_asyncmsg_connection_attr, + // reserves: Padding<[c_uint; 3]>, + // pub sendq: [crate::_asyncmsg_put_header; 1], // flexarray + //} + + pub struct __c_anonymous_struct_ev { + pub event: crate::sigevent, + pub coid: c_int, + } + + pub struct _channel_connect_attr { + // union + pub ev: crate::__c_anonymous_struct_ev, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct _sighandler_info { + pub siginfo: crate::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: crate::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: Padding<[c_int; 11]>, + } + + pub struct _timer_info { + pub itime: crate::_itimer, + pub otime: crate::_itimer, + pub flags: u32, + pub tid: i32, + pub notify: i32, + pub clockid: crate::clockid_t, + pub overruns: u32, + pub event: crate::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: Padding<[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: crate::mode_t, + __bufsize: usize, + __maxnumbuf: c_uint, + __ev: *const crate::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: crate::pid_t, + __chid: c_int, + __index: c_uint, + __flags: c_int, + ) -> c_int; + pub fn ConnectAttach_r( + __nd: u32, + __pid: crate::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: crate::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: crate::pid_t, __coid: c_int, __info: *mut _msg_info64) + -> c_int; + pub fn ConnectServerInfo_r( + __pid: crate::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: crate::pid_t, + __coid: c_int, + __mask: c_uint, + __bits: c_uint, + ) -> c_int; + pub fn ConnectFlags_r( + __pid: crate::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 crate::iovec, + __rparts: usize, + ) -> c_long; + pub fn MsgSendsv_r( + __coid: c_int, + __smsg: *const c_void, + __sbytes: usize, + __riov: *const crate::iovec, + __rparts: usize, + ) -> c_long; + pub fn MsgSendsvnc( + __coid: c_int, + __smsg: *const c_void, + __sbytes: usize, + __riov: *const crate::iovec, + __rparts: usize, + ) -> c_long; + pub fn MsgSendsvnc_r( + __coid: c_int, + __smsg: *const c_void, + __sbytes: usize, + __riov: *const crate::iovec, + __rparts: usize, + ) -> c_long; + pub fn MsgSendvs( + __coid: c_int, + __siov: *const crate::iovec, + __sparts: usize, + __rmsg: *mut c_void, + __rbytes: usize, + ) -> c_long; + pub fn MsgSendvs_r( + __coid: c_int, + __siov: *const crate::iovec, + __sparts: usize, + __rmsg: *mut c_void, + __rbytes: usize, + ) -> c_long; + pub fn MsgSendvsnc( + __coid: c_int, + __siov: *const crate::iovec, + __sparts: usize, + __rmsg: *mut c_void, + __rbytes: usize, + ) -> c_long; + pub fn MsgSendvsnc_r( + __coid: c_int, + __siov: *const crate::iovec, + __sparts: usize, + __rmsg: *mut c_void, + __rbytes: usize, + ) -> c_long; + pub fn MsgSendv( + __coid: c_int, + __siov: *const crate::iovec, + __sparts: usize, + __riov: *const crate::iovec, + __rparts: usize, + ) -> c_long; + pub fn MsgSendv_r( + __coid: c_int, + __siov: *const crate::iovec, + __sparts: usize, + __riov: *const crate::iovec, + __rparts: usize, + ) -> c_long; + pub fn MsgSendvnc( + __coid: c_int, + __siov: *const crate::iovec, + __sparts: usize, + __riov: *const crate::iovec, + __rparts: usize, + ) -> c_long; + pub fn MsgSendvnc_r( + __coid: c_int, + __siov: *const crate::iovec, + __sparts: usize, + __riov: *const crate::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 crate::iovec, + __parts: usize, + __info: *mut _msg_info64, + ) -> c_int; + pub fn MsgReceivev_r( + __chid: c_int, + __iov: *const crate::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 crate::iovec, + __parts: usize, + __info: *mut _msg_info64, + ) -> c_int; + pub fn MsgReceivePulsev_r( + __chid: c_int, + __iov: *const crate::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 crate::iovec, + __parts: usize, + ) -> c_int; + pub fn MsgReplyv_r( + __rcvid: c_int, + __status: c_long, + __iov: *const crate::iovec, + __parts: usize, + ) -> c_int; + pub fn MsgReadiov( + __rcvid: c_int, + __iov: *const crate::iovec, + __parts: usize, + __offset: usize, + __flags: c_int, + ) -> isize; + pub fn MsgReadiov_r( + __rcvid: c_int, + __iov: *const crate::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 crate::iovec, + __parts: usize, + __offset: usize, + ) -> isize; + pub fn MsgReadv_r( + __rcvid: c_int, + __iov: *const crate::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 crate::iovec, + __parts: usize, + __offset: usize, + ) -> isize; + pub fn MsgWritev_r( + __rcvid: c_int, + __iov: *const crate::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 crate::sigevent) -> c_int; + pub fn MsgDeliverEvent_r(__rcvid: c_int, __event: *const crate::sigevent) -> c_int; + pub fn MsgVerifyEvent(__rcvid: c_int, __event: *const crate::sigevent) -> c_int; + pub fn MsgVerifyEvent_r(__rcvid: c_int, __event: *const crate::sigevent) -> c_int; + pub fn MsgRegisterEvent(__event: *mut crate::sigevent, __coid: c_int) -> c_int; + pub fn MsgRegisterEvent_r(__event: *mut crate::sigevent, __coid: c_int) -> c_int; + pub fn MsgUnregisterEvent(__event: *const crate::sigevent) -> c_int; + pub fn MsgUnregisterEvent_r(__event: *const crate::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 crate::iovec, + __parts: c_int, + ) -> c_int; + pub fn MsgKeyData_r( + __rcvid: c_int, + __oper: c_int, + __key: u32, + __newkey: *mut u32, + __iov: *const crate::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 crate::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: crate::pid_t, + __tid: c_int, + __signo: c_int, + __code: c_int, + __value: c_int, + ) -> c_int; + pub fn SignalKill_r( + __nd: u32, + __pid: crate::pid_t, + __tid: c_int, + __signo: c_int, + __code: c_int, + __value: c_int, + ) -> c_int; + pub fn SignalKillSigval( + __nd: u32, + __pid: crate::pid_t, + __tid: c_int, + __signo: c_int, + __code: c_int, + __value: *const crate::sigval, + ) -> c_int; + pub fn SignalKillSigval_r( + __nd: u32, + __pid: crate::pid_t, + __tid: c_int, + __signo: c_int, + __code: c_int, + __value: *const crate::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: crate::pid_t, + __sigstub: unsafe extern "C" fn(), + __signo: c_int, + __act: *const crate::sigaction, + __oact: *mut crate::sigaction, + ) -> c_int; + pub fn SignalAction_r( + __pid: crate::pid_t, + __sigstub: unsafe extern "C" fn(), + __signo: c_int, + __act: *const crate::sigaction, + __oact: *mut crate::sigaction, + ) -> c_int; + pub fn SignalProcmask( + __pid: crate::pid_t, + __tid: c_int, + __how: c_int, + __set: *const crate::sigset_t, + __oldset: *mut crate::sigset_t, + ) -> c_int; + pub fn SignalProcmask_r( + __pid: crate::pid_t, + __tid: c_int, + __how: c_int, + __set: *const crate::sigset_t, + __oldset: *mut crate::sigset_t, + ) -> c_int; + pub fn SignalSuspend(__set: *const crate::sigset_t) -> c_int; + pub fn SignalSuspend_r(__set: *const crate::sigset_t) -> c_int; + pub fn SignalWaitinfo(__set: *const crate::sigset_t, __info: *mut crate::siginfo_t) -> c_int; + pub fn SignalWaitinfo_r(__set: *const crate::sigset_t, __info: *mut crate::siginfo_t) -> c_int; + pub fn SignalWaitinfoMask( + __set: *const crate::sigset_t, + __info: *mut crate::siginfo_t, + __mask: *const crate::sigset_t, + ) -> c_int; + pub fn SignalWaitinfoMask_r( + __set: *const crate::sigset_t, + __info: *mut crate::siginfo_t, + __mask: *const crate::sigset_t, + ) -> c_int; + pub fn ThreadCreate( + __pid: crate::pid_t, + __func: unsafe extern "C" fn(__arg: *mut c_void) -> *mut c_void, + __arg: *mut c_void, + __attr: *const crate::_thread_attr, + ) -> c_int; + pub fn ThreadCreate_r( + __pid: crate::pid_t, + __func: unsafe extern "C" fn(__arg: *mut c_void) -> *mut c_void, + __arg: *mut c_void, + __attr: *const crate::_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: crate::pid_t, + __tid: c_int, + __cmd: c_int, + __data: *mut c_void, + ) -> c_int; + pub fn ThreadCtlExt_r( + __pid: crate::pid_t, + __tid: c_int, + __cmd: c_int, + __data: *mut c_void, + ) -> c_int; + + pub fn InterruptHookTrace( + __handler: Option *const crate::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 crate::sigevent, __flags: c_uint) -> c_int; + pub fn InterruptAttachEvent( + __intr: c_int, + __event: *const crate::sigevent, + __flags: c_uint, + ) -> c_int; + pub fn InterruptAttachEvent_r( + __intr: c_int, + __event: *const crate::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 crate::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 crate::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 crate::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 crate::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: crate::pid_t, __tid: c_int, __param: *mut crate::sched_param) -> c_int; + pub fn SchedGet_r(__pid: crate::pid_t, __tid: c_int, __param: *mut crate::sched_param) + -> c_int; + pub fn SchedGetCpuNum() -> c_uint; + pub fn SchedSet( + __pid: crate::pid_t, + __tid: c_int, + __algorithm: c_int, + __param: *const crate::sched_param, + ) -> c_int; + pub fn SchedSet_r( + __pid: crate::pid_t, + __tid: c_int, + __algorithm: c_int, + __param: *const crate::sched_param, + ) -> c_int; + pub fn SchedInfo( + __pid: crate::pid_t, + __algorithm: c_int, + __info: *mut crate::_sched_info, + ) -> c_int; + pub fn SchedInfo_r( + __pid: crate::pid_t, + __algorithm: c_int, + __info: *mut crate::_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: crate::clockid_t, __notify: *const crate::sigevent) -> c_int; + pub fn TimerCreate_r(__id: crate::clockid_t, __notify: *const crate::sigevent) -> c_int; + pub fn TimerDestroy(__id: crate::timer_t) -> c_int; + pub fn TimerDestroy_r(__id: crate::timer_t) -> c_int; + pub fn TimerSettime( + __id: crate::timer_t, + __flags: c_int, + __itime: *const crate::_itimer, + __oitime: *mut crate::_itimer, + ) -> c_int; + pub fn TimerSettime_r( + __id: crate::timer_t, + __flags: c_int, + __itime: *const crate::_itimer, + __oitime: *mut crate::_itimer, + ) -> c_int; + pub fn TimerInfo( + __pid: crate::pid_t, + __id: crate::timer_t, + __flags: c_int, + __info: *mut crate::_timer_info, + ) -> c_int; + pub fn TimerInfo_r( + __pid: crate::pid_t, + __id: crate::timer_t, + __flags: c_int, + __info: *mut crate::_timer_info, + ) -> c_int; + pub fn TimerAlarm( + __id: crate::clockid_t, + __itime: *const crate::_itimer, + __otime: *mut crate::_itimer, + ) -> c_int; + pub fn TimerAlarm_r( + __id: crate::clockid_t, + __itime: *const crate::_itimer, + __otime: *mut crate::_itimer, + ) -> c_int; + pub fn TimerTimeout( + __id: crate::clockid_t, + __flags: c_int, + __notify: *const crate::sigevent, + __ntime: *const u64, + __otime: *mut u64, + ) -> c_int; + pub fn TimerTimeout_r( + __id: crate::clockid_t, + __flags: c_int, + __notify: *const crate::sigevent, + __ntime: *const u64, + __otime: *mut u64, + ) -> c_int; + + pub fn SyncTypeCreate( + __type: c_uint, + __sync: *mut crate::sync_t, + __attr: *const crate::_sync_attr, + ) -> c_int; + pub fn SyncTypeCreate_r( + __type: c_uint, + __sync: *mut crate::sync_t, + __attr: *const crate::_sync_attr, + ) -> c_int; + pub fn SyncDestroy(__sync: *mut crate::sync_t) -> c_int; + pub fn SyncDestroy_r(__sync: *mut crate::sync_t) -> c_int; + pub fn SyncCtl(__cmd: c_int, __sync: *mut crate::sync_t, __data: *mut c_void) -> c_int; + pub fn SyncCtl_r(__cmd: c_int, __sync: *mut crate::sync_t, __data: *mut c_void) -> c_int; + pub fn SyncMutexEvent(__sync: *mut crate::sync_t, event: *const crate::sigevent) -> c_int; + pub fn SyncMutexEvent_r(__sync: *mut crate::sync_t, event: *const crate::sigevent) -> c_int; + pub fn SyncMutexLock(__sync: *mut crate::sync_t) -> c_int; + pub fn SyncMutexLock_r(__sync: *mut crate::sync_t) -> c_int; + pub fn SyncMutexUnlock(__sync: *mut crate::sync_t) -> c_int; + pub fn SyncMutexUnlock_r(__sync: *mut crate::sync_t) -> c_int; + pub fn SyncMutexRevive(__sync: *mut crate::sync_t) -> c_int; + pub fn SyncMutexRevive_r(__sync: *mut crate::sync_t) -> c_int; + pub fn SyncCondvarWait(__sync: *mut crate::sync_t, __mutex: *mut crate::sync_t) -> c_int; + pub fn SyncCondvarWait_r(__sync: *mut crate::sync_t, __mutex: *mut crate::sync_t) -> c_int; + pub fn SyncCondvarSignal(__sync: *mut crate::sync_t, __all: c_int) -> c_int; + pub fn SyncCondvarSignal_r(__sync: *mut crate::sync_t, __all: c_int) -> c_int; + pub fn SyncSemPost(__sync: *mut crate::sync_t) -> c_int; + pub fn SyncSemPost_r(__sync: *mut crate::sync_t) -> c_int; + pub fn SyncSemWait(__sync: *mut crate::sync_t, __tryto: c_int) -> c_int; + pub fn SyncSemWait_r(__sync: *mut crate::sync_t, __tryto: c_int) -> c_int; + + pub fn ClockTime(__id: crate::clockid_t, _new: *const u64, __old: *mut u64) -> c_int; + pub fn ClockTime_r(__id: crate::clockid_t, _new: *const u64, __old: *mut u64) -> c_int; + pub fn ClockAdjust( + __id: crate::clockid_t, + _new: *const crate::_clockadjust, + __old: *mut crate::_clockadjust, + ) -> c_int; + pub fn ClockAdjust_r( + __id: crate::clockid_t, + _new: *const crate::_clockadjust, + __old: *mut crate::_clockadjust, + ) -> c_int; + pub fn ClockPeriod( + __id: crate::clockid_t, + _new: *const crate::_clockperiod, + __old: *mut crate::_clockperiod, + __reserved: c_int, + ) -> c_int; + pub fn ClockPeriod_r( + __id: crate::clockid_t, + _new: *const crate::_clockperiod, + __old: *mut crate::_clockperiod, + __reserved: c_int, + ) -> c_int; + pub fn ClockId(__pid: crate::pid_t, __tid: c_int) -> c_int; + pub fn ClockId_r(__pid: crate::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/nuttx/mod.rs b/vendor/libc/src/unix/nuttx/mod.rs new file mode 100644 index 0000000..b110034 --- /dev/null +++ b/vendor/libc/src/unix/nuttx/mod.rs @@ -0,0 +1,699 @@ +///! Definitions for Apache NuttX RTOS. +///! +///! Following definitions are based on NuttX 13.0.0. +///! See https://github.com/apache/nuttx/tree/releases/13.0 for more details. +use crate::prelude::*; +use crate::{ + in6_addr, + in_addr_t, + timespec, + DIR, +}; + +pub type pid_t = c_int; +pub type nlink_t = u16; +pub type ino_t = u16; +pub type blkcnt_t = u64; +pub type blksize_t = i16; +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 = c_uint; +pub type speed_t = usize; +pub type suseconds_t = i32; +pub type tcflag_t = u32; +pub type clockid_t = c_int; +pub type time_t = i64; + +cfg_if! { + if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] { + pub type wchar_t = c_int; + } else if #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] { + pub type wchar_t = c_uint; + } +} + +s! { + // sys/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: 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: Padding<[usize; __DEFAULT_RESERVED_SIZE__]>, + } + + // sys/socket.h + pub struct sockaddr { + pub sa_family: sa_family_t, + pub sa_data: [u8; 14], + } + + pub struct msghdr { + pub msg_name: *mut c_void, + pub msg_namelen: socklen_t, + pub msg_iov: *mut crate::iovec, + pub msg_iovlen: c_ulong, + pub msg_control: *mut c_void, + pub msg_controllen: c_ulong, + pub msg_flags: c_int, + } + + // pwd.h + pub struct passwd { + pub pw_name: *const c_char, + pub pw_passwd: *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: Padding<[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: Padding<[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 c_char, + __reserved: Padding<[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: Padding<[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: Padding<[usize; __DEFAULT_RESERVED_SIZE__]>, + } + + pub struct dirent { + pub d_type: u8, + pub d_name: [c_char; __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: Padding<[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: Padding<[usize; __DEFAULT_RESERVED_SIZE__]>, + } + + // netinet/in.h + pub struct in_addr { + pub s_addr: in_addr_t, + } + + pub struct sockaddr_in { + pub sin_family: sa_family_t, + pub sin_port: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_zero: [u8; 8], + } + + pub struct sockaddr_in6 { + pub sin6_family: sa_family_t, + pub sin6_port: crate::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: crate::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 ip_mreqn { + pub imr_multiaddr: in_addr, + pub imr_address: in_addr, + pub imr_ifindex: c_uint, + } + + pub struct ipv6_mreq { + pub ipv6mr_multiaddr: in6_addr, + pub ipv6mr_interface: u32, + } + + pub struct ip_mreq_source { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + pub imr_sourceaddr: in_addr, + } +} + +// 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. +// char *pw_passwd Encrypted password. +// 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 = ptr::null_mut(); + +// 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 +// fcntl() commands +pub const FIOCLEX: i32 = 0x30b; +pub const F_DUPFD_CLOEXEC: i32 = 0x12; +pub const F_GETFD: i32 = 0x1; +pub const F_GETFL: i32 = 0x2; +pub const F_SETFD: i32 = 8; +pub const F_SETFL: i32 = 9; +// open flag settings for open() (and related APIs) +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 POLLRDNORM: i16 = 0x01; +pub const POLLRDBAND: i16 = 0x01; +pub const POLLPRI: i16 = 0x02; +pub const POLLOUT: i16 = 0x04; +pub const POLLWRNORM: i16 = 0x04; +pub const POLLWRBAND: i16 = 0x04; +pub const POLLHUP: i16 = 0x10; +pub const POLLRDHUP: i16 = 0x10; +pub const POLLERR: i16 = 0x08; +pub const POLLNVAL: i16 = 0x20; + +// sys/socket.h +// Supported Protocol Families +pub const AF_UNSPEC: i32 = 0; +pub const AF_UNIX: i32 = 1; +pub const AF_INET: i32 = 2; +pub const AF_INET6: i32 = 10; +// The socket created by socket() has the indicated type, which specifies +// the communication semantics. +pub const SOCK_STREAM: i32 = 1; +pub const SOCK_DGRAM: i32 = 2; +pub const SOCK_RAW: i32 = 3; +pub const SOCK_RDM: i32 = 4; +pub const SOCK_SEQPACKET: i32 = 5; +pub const SOCK_CLOEXEC: i32 = 0o02000000; +pub const SOCK_NONBLOCK: i32 = 0o00004000; +// Bits in the FLAGS argument to `send', `recv', et al. These are the bits +// recognized by Linux, not all are supported by NuttX. +pub const MSG_OOB: i32 = 0x000001; +pub const MSG_PEEK: i32 = 0x000002; +pub const MSG_TRUNC: i32 = 0x000020; +pub const MSG_EOR: i32 = 0x000080; +// Protocol levels supported by get/setsockopt(): +pub const SOL_SOCKET: i32 = 1; +// Socket-level options +pub const SO_BROADCAST: i32 = 1; +pub const SO_ERROR: i32 = 4; +pub const SO_KEEPALIVE: i32 = 5; +pub const SO_LINGER: i32 = 6; +pub const SO_OOBINLINE: i32 = 7; +pub const SO_RCVBUF: i32 = 8; +pub const SO_RCVTIMEO: i32 = 10; +pub const SO_REUSEADDR: i32 = 11; +pub const SO_SNDBUF: i32 = 12; +pub const SO_SNDTIMEO: i32 = 14; +pub const SO_TYPE: i32 = 15; +// Protocol-level socket options may begin with this value +pub const __SO_PROTOCOL: i32 = 16; +// Values for the 'how' argument of shutdown() +pub const SHUT_RD: i32 = 1; +pub const SHUT_WR: i32 = 2; +pub const SHUT_RDWR: i32 = 3; +// The maximum backlog queue length +pub const SOMAXCONN: i32 = 8; + +// netinet/tcp.h +pub const TCP_NODELAY: i32 = __SO_PROTOCOL + 0; +pub const TCP_KEEPIDLE: i32 = __SO_PROTOCOL + 1; +pub const TCP_KEEPINTVL: i32 = __SO_PROTOCOL + 2; +pub const TCP_KEEPCNT: i32 = __SO_PROTOCOL + 3; +pub const TCP_MAXSEG: i32 = __SO_PROTOCOL + 4; + +// nuttx/fs/ioctl.h +pub const FIONBIO: i32 = 0x30a; + +// unistd.h +pub const _SC_PAGESIZE: i32 = 0x36; +pub const _SC_THREAD_STACK_MIN: i32 = 0x58; +pub const _SC_GETPW_R_SIZE_MAX: i32 = 0x25; +pub const _SC_HOST_NAME_MAX: i32 = 0x26; + +// sys/eventfd.h +pub const EFD_NONBLOCK: i32 = O_NONBLOCK; +pub const EFD_CLOEXEC: i32 = O_CLOEXEC; + +// signal.h +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 SIGPOLL: c_int = SIGIO; +pub const SIGPWR: c_int = 30; +pub const SIGSYS: c_int = 31; + +// pthread.h +pub const PTHREAD_MUTEX_NORMAL: i32 = 0; + +// netinet/in.h +// SOL_IP protocol-level socket options. +pub const IP_MULTICAST_IF: i32 = __SO_PROTOCOL + 1; +pub const IP_MULTICAST_TTL: i32 = __SO_PROTOCOL + 2; +pub const IP_MULTICAST_LOOP: i32 = __SO_PROTOCOL + 3; +pub const IP_ADD_MEMBERSHIP: i32 = __SO_PROTOCOL + 4; +pub const IP_DROP_MEMBERSHIP: i32 = __SO_PROTOCOL + 5; +pub const IP_ADD_SOURCE_MEMBERSHIP: i32 = __SO_PROTOCOL + 8; +pub const IP_DROP_SOURCE_MEMBERSHIP: i32 = __SO_PROTOCOL + 9; +pub const IP_TOS: i32 = __SO_PROTOCOL + 13; +pub const IP_TTL: i32 = __SO_PROTOCOL + 14; +// SOL_IPV6 protocol-level socket options. +pub const IPV6_JOIN_GROUP: i32 = __SO_PROTOCOL + 1; +pub const IPV6_LEAVE_GROUP: i32 = __SO_PROTOCOL + 2; +pub const IPV6_MULTICAST_HOPS: i32 = __SO_PROTOCOL + 3; +pub const IPV6_MULTICAST_IF: i32 = __SO_PROTOCOL + 4; +pub const IPV6_MULTICAST_LOOP: i32 = __SO_PROTOCOL + 5; +pub const IPV6_UNICAST_HOPS: i32 = __SO_PROTOCOL + 6; +pub const IPV6_V6ONLY: i32 = __SO_PROTOCOL + 7; +pub const IPV6_RECVHOPLIMIT: i32 = __SO_PROTOCOL + 11; + +extern "C" { + pub fn __errno() -> *mut c_int; + 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_setname_np(thread: pthread_t, name: *const c_char) -> i32; + pub fn pthread_getname_np(thread: pthread_t, name: *mut c_char, len: usize) -> i32; + pub fn getrandom(buf: *mut c_void, buflen: usize, flags: u32) -> isize; + pub fn arc4random() -> u32; + pub fn arc4random_buf(bytes: *mut c_void, nbytes: usize); + // string.h + pub fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t) -> c_int; + // sys/socket.h + pub fn accept4( + sockfd: c_int, + addr: *mut sockaddr, + addrlen: *mut socklen_t, + flags: c_int, + ) -> c_int; + pub fn recvmsg(sockfd: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t; + pub fn sendmsg(sockfd: c_int, msg: *const msghdr, flags: c_int) -> ssize_t; + // sys/eventfd.h + pub fn eventfd(count: c_uint, flags: c_int) -> c_int; + // unistd.h + pub fn pipe2(fds: *mut c_int, flags: c_int) -> c_int; +} diff --git a/vendor/libc/src/unix/redox/mod.rs b/vendor/libc/src/unix/redox/mod.rs new file mode 100644 index 0000000..774d7b0 --- /dev/null +++ b/vendor/libc/src/unix/redox/mod.rs @@ -0,0 +1,1450 @@ +use crate::prelude::*; + +pub type wchar_t = i32; + +pub type blkcnt_t = c_longlong; +pub type blksize_t = c_long; +pub type clock_t = c_long; +pub type clockid_t = c_int; +pub type dev_t = c_ulonglong; +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 uid_t = c_int; +pub type gid_t = c_int; + +extern_ty! { + pub type timezone; +} + +s! { + #[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: crate::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: crate::sa_family_t, + pub sun_path: [c_char; 108], + } + + pub struct sockaddr_storage { + pub ss_family: crate::sa_family_t, + __ss_padding: Padding<[u8; 128 - size_of::() - size_of::()]>, + __ss_align: 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: size_t, + pub ai_canonname: *mut c_char, + pub ai_addr: *mut crate::sockaddr, + pub ai_next: *mut crate::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; crate::FD_SETSIZE as usize / ULONG_SIZE], + } + + pub struct in_addr { + pub s_addr: crate::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: crate::in_addr, + pub imr_interface: crate::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 msghdr { + pub msg_name: *mut c_void, + pub msg_namelen: crate::socklen_t, + pub msg_iov: *mut crate::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 passwd { + pub pw_name: *mut c_char, + pub pw_passwd: *mut c_char, + pub pw_uid: crate::uid_t, + pub pw_gid: crate::gid_t, + pub pw_gecos: *mut c_char, + pub pw_dir: *mut c_char, + pub pw_shell: *mut c_char, + } + + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] + pub struct sigaction { + pub sa_sigaction: crate::sighandler_t, + pub sa_flags: c_int, + pub sa_restorer: Option, + pub sa_mask: crate::sigset_t, + } + + pub struct siginfo_t { + pub si_signo: c_int, + pub si_errno: c_int, + pub si_code: c_int, + _pad: Padding<[c_int; 29]>, + _align: [usize; 0], + } + + pub struct sockaddr { + pub sa_family: crate::sa_family_t, + pub sa_data: [c_char; 14], + } + + pub struct sockaddr_in { + pub sin_family: crate::sa_family_t, + pub sin_port: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_zero: [c_char; 8], + } + + pub struct sockaddr_in6 { + pub sin6_family: crate::sa_family_t, + pub sin6_port: crate::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: crate::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_nlink: crate::nlink_t, + pub st_mode: mode_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + _pad: Padding<[c_char; 24]>, + } + + pub struct statvfs { + pub f_bsize: c_ulong, + pub f_frsize: c_ulong, + pub f_blocks: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::fsfilcnt_t, + pub f_fsid: c_ulong, + pub f_flag: c_ulong, + pub f_namemax: c_ulong, + } + + pub struct termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_line: crate::cc_t, + pub c_cc: [crate::cc_t; crate::NCCS], + pub c_ispeed: crate::speed_t, + pub c_ospeed: crate::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: crate::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 +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; + +pub const AT_FDCWD: c_int = -100; +pub const AT_SYMLINK_NOFOLLOW: c_int = 0x200; +pub const AT_REMOVEDIR: c_int = 0x200; +pub const AT_SYMLINK_FOLLOW: c_int = 0x2000; +pub const AT_EMPTY_PATH: c_int = 0x4000; +pub const AT_EACCESS: c_int = 0x400; + +// FIXME(redox): relibc { +pub const RTLD_DEFAULT: *mut c_void = ptr::null_mut(); +// } + +// dlfcn.h +pub const RTLD_LAZY: c_int = 0x0001; +pub const RTLD_NOW: c_int = 0x0002; +pub const RTLD_NOLOAD: c_int = 0x0004; +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; +pub const F_DUPFD_CLOEXEC: c_int = 1030; +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_NDELAY: c_int = O_NONBLOCK; +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_SYNC: c_int = O_FSYNC; +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(redox): Fix negative values missing from includes +pub const O_NOFOLLOW: c_int = -0x8000_0000; +pub const O_NOCTTY: c_int = 0x00000200; + +// locale.h +pub const LC_COLLATE: c_int = 0; +pub const LC_CTYPE: c_int = 1; +pub const LC_MESSAGES: 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_ALL: 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(redox): 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_JOIN_GROUP: c_int = 20; +pub const IPV6_DROP_MEMBERSHIP: c_int = 21; +pub const IPV6_LEAVE_GROUP: 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 IP_TOS: c_int = 1; +pub const IP_RECVTOS: c_int = 13; +pub const IPPROTO_IGMP: c_int = 2; +pub const IPPROTO_PUP: c_int = 12; +pub const IPPROTO_IDP: c_int = 22; +pub const IPPROTO_RAW: c_int = 255; +pub const IPPROTO_MAX: c_int = 255; +// } + +// netinet/tcp.h +pub const TCP_NODELAY: c_int = 1; +pub const TCP_MAXSEG: c_int = 2; +pub const TCP_KEEPIDLE: c_int = 4; +pub const TCP_KEEPINTVL: c_int = 5; +pub const TCP_KEEPCNT: c_int = 6; + +// 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_DEFAULT: c_int = 0; +pub const PTHREAD_MUTEX_ERRORCHECK: c_int = 1; +pub const PTHREAD_MUTEX_NORMAL: c_int = 2; +pub const PTHREAD_MUTEX_RECURSIVE: c_int = 3; + +pub const PTHREAD_MUTEX_ROBUST: c_int = 0; +pub const PTHREAD_MUTEX_STALLED: c_int = 1; + +pub const PTHREAD_MUTEX_INITIALIZER: crate::pthread_mutex_t = crate::pthread_mutex_t { + bytes: [0; _PTHREAD_MUTEX_SIZE], +}; +pub const PTHREAD_COND_INITIALIZER: crate::pthread_cond_t = crate::pthread_cond_t { + bytes: [0; _PTHREAD_COND_SIZE], +}; +pub const PTHREAD_RWLOCK_INITIALIZER: crate::pthread_rwlock_t = crate::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_NOCLDWAIT: c_int = 0x0000_0002; +pub const SA_RESTORER: c_int = 0x0000_0004; // FIXME(redox): remove after relibc removes it +pub const SA_SIGINFO: c_int = 0x0200_0000; +pub const SA_ONSTACK: c_int = 0x0400_0000; +pub const SA_RESTART: c_int = 0x0800_0000; +pub const SA_NODEFER: c_int = 0x1000_0000; +pub const SA_RESETHAND: c_int = 0x2000_0000; +pub const SA_NOCLDSTOP: c_int = 0x4000_0000; + +// 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 = 0o17_0000; +pub const S_IFDIR: c_int = 0o4_0000; +pub const S_IFCHR: c_int = 0o2_0000; +pub const S_IFBLK: c_int = 0o6_0000; +pub const S_IFREG: c_int = 0o10_0000; +pub const S_IFIFO: c_int = 0o1_0000; +pub const S_IFLNK: c_int = 0o12_0000; +pub const S_IFSOCK: c_int = 0o14_0000; +pub const S_IRWXU: c_int = 0o0700; +pub const S_IRUSR: c_int = 0o0400; +pub const S_IWUSR: c_int = 0o0200; +pub const S_IXUSR: c_int = 0o0100; +pub const S_IRWXG: c_int = 0o0070; +pub const S_IRGRP: c_int = 0o0040; +pub const S_IWGRP: c_int = 0o0020; +pub const S_IXGRP: c_int = 0o0010; +pub const S_IRWXO: c_int = 0o0007; +pub const S_IROTH: c_int = 0o0004; +pub const S_IWOTH: c_int = 0o0002; +pub const S_IXOTH: c_int = 0o0001; +pub const UTIME_NOW: c_long = u32_cast_long(0xffffffff); +pub const UTIME_OMIT: c_long = u32_cast_long(0xfffffffe); + +// stdlib.h +pub const EXIT_SUCCESS: c_int = 0; +pub const EXIT_FAILURE: c_int = 1; + +// sys/ioctl.h +// FIXME(redox): 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 = 0x0004; +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/resource.h +pub const RLIM_INFINITY: rlim_t = !0; +pub const RLIM_SAVED_CUR: rlim_t = RLIM_INFINITY; +pub const RLIM_SAVED_MAX: rlim_t = RLIM_INFINITY; +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_NLIMITS: c_int = 15; + +pub const RUSAGE_SELF: c_int = 0; +pub const RUSAGE_CHILDREN: c_int = -1; +pub const RUSAGE_BOTH: c_int = -2; +pub const RUSAGE_THREAD: c_int = 1; + +// 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 SCM_RIGHTS: 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 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_RAW: c_int = 3; +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: crate::tcflag_t = 0o000_001; +pub const BRKINT: crate::tcflag_t = 0o000_002; +pub const IGNPAR: crate::tcflag_t = 0o000_004; +pub const PARMRK: crate::tcflag_t = 0o000_010; +pub const INPCK: crate::tcflag_t = 0o000_020; +pub const ISTRIP: crate::tcflag_t = 0o000_040; +pub const INLCR: crate::tcflag_t = 0o000_100; +pub const IGNCR: crate::tcflag_t = 0o000_200; +pub const ICRNL: crate::tcflag_t = 0o000_400; +pub const IXON: crate::tcflag_t = 0o001_000; +pub const IXOFF: crate::tcflag_t = 0o002_000; + +pub const OPOST: crate::tcflag_t = 0o000_001; +pub const ONLCR: crate::tcflag_t = 0o000_002; +pub const OLCUC: crate::tcflag_t = 0o000_004; +pub const OCRNL: crate::tcflag_t = 0o000_010; +pub const ONOCR: crate::tcflag_t = 0o000_020; +pub const ONLRET: crate::tcflag_t = 0o000_040; +pub const OFILL: crate::tcflag_t = 0o0000_100; +pub const OFDEL: crate::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: crate::tcflag_t = 0o001_400; +pub const CS5: crate::tcflag_t = 0o000_000; +pub const CS6: crate::tcflag_t = 0o000_400; +pub const CS7: crate::tcflag_t = 0o001_000; +pub const CS8: crate::tcflag_t = 0o001_400; + +pub const CSTOPB: crate::tcflag_t = 0o002_000; +pub const CREAD: crate::tcflag_t = 0o004_000; +pub const PARENB: crate::tcflag_t = 0o010_000; +pub const PARODD: crate::tcflag_t = 0o020_000; +pub const HUPCL: crate::tcflag_t = 0o040_000; + +pub const CLOCAL: crate::tcflag_t = 0o0100000; + +pub const ISIG: crate::tcflag_t = 0x0000_0080; +pub const ICANON: crate::tcflag_t = 0x0000_0100; +pub const ECHO: crate::tcflag_t = 0x0000_0008; +pub const ECHOE: crate::tcflag_t = 0x0000_0002; +pub const ECHOK: crate::tcflag_t = 0x0000_0004; +pub const ECHONL: crate::tcflag_t = 0x0000_0010; +pub const NOFLSH: crate::tcflag_t = 0x8000_0000; +pub const TOSTOP: crate::tcflag_t = 0x0040_0000; +pub const IEXTEN: crate::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; + +pub const _POSIX_VDISABLE: crate::cc_t = 0; + +// 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; +pub const __WCLONE: c_int = u32_cast_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: crate::clockid_t = 2; +pub const CLOCKS_PER_SEC: crate::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_NPROCESSORS_CONF: c_int = 57; +pub const _SC_NPROCESSORS_ONLN: c_int = 58; + +// ... +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_SYMLOOP_MAX: c_int = 173; +// ... +pub const _SC_HOST_NAME_MAX: c_int = 180; +// ... +pub const _SC_SIGQUEUE_MAX: c_int = 190; +pub const _SC_REALTIME_SIGNALS: c_int = 191; +// } POSIX.1 + +// confstr +pub const _CS_PATH: c_int = 0; +pub const _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS: c_int = 1; +pub const _CS_POSIX_V5_WIDTH_RESTRICTED_ENVS: c_int = 4; +pub const _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS: c_int = 5; +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 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; + +// stdio.h +pub const BUFSIZ: c_uint = 1024; +pub const _IOFBF: c_int = 0; +pub const _IOLBF: c_int = 1; +pub const _IONBF: 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 _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; + +pub const RENAME_NOREPLACE: c_uint = 1; + +f! { + //sys/socket.h + pub const unsafe fn CMSG_ALIGN(len: size_t) -> size_t { + (len + size_of::() - 1) & !(size_of::() - 1) + } + pub const unsafe fn CMSG_LEN(length: c_uint) -> c_uint { + (CMSG_ALIGN(size_of::()) + length as usize) as c_uint + } + pub const unsafe fn CMSG_SPACE(len: c_uint) -> c_uint { + (CMSG_ALIGN(len as size_t) + CMSG_ALIGN(size_of::())) as c_uint + } + + // wait.h + pub unsafe fn FD_CLR(fd: c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] &= !(1 << (fd % size)); + return; + } + + pub unsafe fn FD_ISSET(fd: c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0; + } + + pub unsafe fn FD_SET(fd: c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] |= 1 << (fd % size); + return; + } + + pub unsafe fn FD_ZERO(set: *mut fd_set) -> () { + (*set).fds_bits.fill(0); + } +} + +safe_f! { + pub const safe fn WIFSTOPPED(status: c_int) -> bool { + (status & 0xff) == 0x7f + } + + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + (status >> 8) & 0xff + } + + pub const safe fn WIFCONTINUED(status: c_int) -> bool { + status == 0xffff + } + + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + ((status & 0x7f) + 1) as i8 >= 2 + } + + pub const safe fn WTERMSIG(status: c_int) -> c_int { + status & 0x7f + } + + pub const safe fn WIFEXITED(status: c_int) -> bool { + (status & 0x7f) == 0 + } + + pub const safe fn WEXITSTATUS(status: c_int) -> c_int { + (status >> 8) & 0xff + } + + pub const safe fn WCOREDUMP(status: c_int) -> bool { + (status & 0x80) != 0 + } + + pub const safe 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 safe fn major(dev: dev_t) -> c_uint { + let mut major = 0; + major |= (dev & 0x00000000000fff00) >> 8; + major |= (dev & 0xfffff00000000000) >> 32; + major as c_uint + } + + pub const safe fn minor(dev: dev_t) -> c_uint { + let mut minor = 0; + minor |= (dev & 0x00000000000000ff) >> 0; + minor |= (dev & 0x00000ffffff00000) >> 12; + minor as c_uint + } +} + +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; + + // dirent.h + pub fn dirfd(dirp: *mut crate::DIR) -> c_int; + pub fn seekdir(dirp: *mut crate::DIR, loc: c_long); + + // unistd.h + pub fn faccessat(dirfd: c_int, pathname: *const c_char, mode: c_int, flags: c_int) -> c_int; + pub fn pipe2(fds: *mut c_int, flags: c_int) -> c_int; + pub fn getdtablesize() -> c_int; + pub fn getresgid( + rgid: *mut crate::gid_t, + egid: *mut crate::gid_t, + sgid: *mut crate::gid_t, + ) -> c_int; + pub fn getresuid( + ruid: *mut crate::uid_t, + euid: *mut crate::uid_t, + suid: *mut crate::uid_t, + ) -> c_int; + pub fn setresgid(rgid: crate::gid_t, egid: crate::gid_t, sgid: crate::gid_t) -> c_int; + pub fn setresuid(ruid: crate::uid_t, euid: crate::uid_t, suid: crate::uid_t) -> c_int; + + // grp.h + pub fn getgrent() -> *mut crate::group; + pub fn setgrent(); + pub fn endgrent(); + pub fn getgrgid(gid: crate::gid_t) -> *mut crate::group; + pub fn getgrgid_r( + gid: crate::gid_t, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn getgrnam(name: *const c_char) -> *mut crate::group; + pub fn getgrnam_r( + name: *const c_char, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn getgrouplist( + user: *const c_char, + group: crate::gid_t, + groups: *mut crate::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 crate::sockaddr, + addrlen: crate::socklen_t, + host: *mut c_char, + hostlen: crate::socklen_t, + serv: *mut c_char, + servlen: crate::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 crate::pthread_t, + attr: *const crate::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: crate::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 crate::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: crate::uid_t, + pwd: *mut passwd, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut passwd, + ) -> c_int; + + // semaphore.h + 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 sem_clockwait( + sem: *mut sem_t, + clock_id: clockid_t, + abstime: *const crate::timespec, + ) -> c_int; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const crate::timespec) -> c_int; + pub fn sem_getvalue(sem: *mut sem_t, sval: *mut c_int) -> c_int; + + // signal.h + pub fn pthread_sigmask( + how: c_int, + set: *const crate::sigset_t, + oldset: *mut crate::sigset_t, + ) -> c_int; + pub fn pthread_cancel(thread: crate::pthread_t) -> c_int; + pub fn pthread_kill(thread: crate::pthread_t, sig: c_int) -> c_int; + pub fn sigtimedwait( + set: *const sigset_t, + sig: *mut siginfo_t, + timeout: *const crate::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 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 reallocarray(ptr: *mut c_void, nmemb: size_t, size: size_t) -> *mut c_void; + + // stdio.h + pub fn renameat2( + olddirfd: c_int, + oldpath: *const c_char, + newdirfd: c_int, + newpath: *const c_char, + flags: c_uint, + ) -> c_int; + + // 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 crate::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 crate::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: crate::id_t) -> c_int; + pub fn setpriority(which: c_int, who: crate::id_t, prio: c_int) -> c_int; + pub fn getrlimit(resource: c_int, rlim: *mut crate::rlimit) -> c_int; + pub fn setrlimit(resource: c_int, rlim: *const crate::rlimit) -> c_int; + + // sys/socket.h + pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar; + pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr; + pub fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr; + pub fn bind( + socket: c_int, + address: *const crate::sockaddr, + address_len: crate::socklen_t, + ) -> c_int; + pub fn recvfrom( + socket: c_int, + buf: *mut c_void, + len: size_t, + flags: c_int, + addr: *mut crate::sockaddr, + addrlen: *mut crate::socklen_t, + ) -> ssize_t; + pub fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t; + pub fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> ssize_t; + + // sys/stat.h + pub fn futimens(fd: c_int, times: *const crate::timespec) -> c_int; + pub fn mknodat(dirfd: c_int, pathname: *const c_char, mode: mode_t, dev: dev_t) -> c_int; + pub fn utimensat( + dirfd: c_int, + path: *const c_char, + times: *const crate::timespec, + flag: c_int, + ) -> c_int; + + // sys/uio.h + pub fn preadv(fd: c_int, iov: *const crate::iovec, iovcnt: c_int, offset: off_t) -> ssize_t; + pub fn pwritev(fd: c_int, iov: *const crate::iovec, iovcnt: c_int, offset: off_t) -> ssize_t; + pub fn readv(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + pub fn writev(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + + // sys/utsname.h + pub fn uname(utsname: *mut utsname) -> c_int; + + // time.h + pub fn gettimeofday(tp: *mut crate::timeval, tz: *mut crate::timezone) -> c_int; + pub fn clock_getres(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_gettime(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn strftime( + s: *mut c_char, + max: size_t, + format: *const c_char, + tm: *const crate::tm, + ) -> size_t; + + // utmp.h + pub fn login_tty(fd: c_int) -> c_int; +} diff --git a/vendor/libc/src/unix/solarish/compat.rs b/vendor/libc/src/unix/solarish/compat.rs new file mode 100644 index 0000000..6876a9d --- /dev/null +++ b/vendor/libc/src/unix/solarish/compat.rs @@ -0,0 +1,222 @@ +// Common functions that are unfortunately missing on illumos and +// Solaris, but often needed by other crates. +use core::cmp::min; + +use crate::unix::solarish::*; +use crate::{ + c_char, + c_int, + size_t, +}; + +pub unsafe fn cfmakeraw(termios: *mut crate::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 crate::termios, speed: crate::speed_t) -> c_int { + // Neither of these functions on illumos or Solaris actually ever + // return an error + crate::cfsetispeed(termios, speed); + crate::cfsetospeed(termios, speed); + 0 +} + +#[cfg(target_os = "illumos")] +unsafe fn bail(fdm: c_int, fds: c_int) -> c_int { + let e = *___errno(); + if fds >= 0 { + crate::close(fds); + } + if fdm >= 0 { + crate::close(fdm); + } + *___errno() = e; + -1 +} + +#[cfg(target_os = "illumos")] +pub unsafe fn openpty( + amain: *mut c_int, + asubord: *mut c_int, + name: *mut c_char, + termp: *const termios, + winp: *const crate::winsize, +) -> c_int { + const PTEM: &[u8] = b"ptem\0"; + const LDTERM: &[u8] = b"ldterm\0"; + + // Open the main pseudo-terminal device, making sure not to set it as the + // controlling terminal for this process: + let fdm = crate::posix_openpt(O_RDWR | O_NOCTTY); + if fdm < 0 { + return -1; + } + + // Set permissions and ownership on the subordinate device and unlock it: + if crate::grantpt(fdm) < 0 || crate::unlockpt(fdm) < 0 { + return bail(fdm, -1); + } + + // Get the path name of the subordinate device: + let subordpath = crate::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 = crate::open(subordpath, O_RDWR | O_NOCTTY); + if fds < 0 { + return bail(fdm, -1); + } + + // Check if the STREAMS modules are already pushed: + let setup = crate::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 crate::ioctl(fds, I_PUSH, PTEM.as_ptr()) < 0 + || crate::ioctl(fds, I_PUSH, LDTERM.as_ptr()) < 0 + { + return bail(fdm, fds); + } + } + + // If provided, set the terminal parameters: + if !termp.is_null() && crate::tcsetattr(fds, TCSAFLUSH, termp) != 0 { + return bail(fdm, fds); + } + + // If provided, set the window size: + if !winp.is_null() && crate::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() { + crate::strcpy(name, subordpath); + } + + *amain = fdm; + *asubord = fds; + 0 +} + +#[cfg(target_os = "illumos")] +pub unsafe fn forkpty( + amain: *mut c_int, + name: *mut c_char, + termp: *const termios, + winp: *const crate::winsize, +) -> crate::pid_t { + let mut fds = -1; + + if openpty(amain, &mut fds, name, termp, winp) != 0 { + return -1; + } + + let pid = crate::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: + crate::close(fds); + return pid; + } + + // The rest of this function executes in the child process. + + // Close the main side of the pseudo-terminal pair: + crate::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 crate::setsid() < 0 + || crate::ioctl(fds, TIOCSCTTY, 0) < 0 + || crate::dup2(fds, 0) < 0 + || crate::dup2(fds, 1) < 0 + || crate::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. + crate::_exit(EXIT_FAILURE); + } + // Close the inherited descriptor, taking care to avoid closing the standard + // descriptors by mistake: + if fds > 2 { + crate::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 = *crate::___errno(); + *crate::___errno() = 0; + *result = native_getpwent_r(pwd, buf, min(buflen, c_int::MAX as size_t) as c_int); + + let ret = if (*result).is_null() { + *crate::___errno() + } else { + 0 + }; + *crate::___errno() = old_errno; + + ret +} + +pub unsafe fn getgrent_r( + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, +) -> c_int { + let old_errno = *crate::___errno(); + *crate::___errno() = 0; + *result = native_getgrent_r(grp, buf, min(buflen, c_int::MAX as size_t) as c_int); + + let ret = if (*result).is_null() { + *crate::___errno() + } else { + 0 + }; + *crate::___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..7b8ce2c --- /dev/null +++ b/vendor/libc/src/unix/solarish/illumos.rs @@ -0,0 +1,305 @@ +use crate::prelude::*; +use crate::{ + exit_status, + off_t, + NET_MAC_AWARE, + NET_MAC_AWARE_INHERIT, + PRIV_AWARE_RESET, + PRIV_DEBUG, + PRIV_PFEXEC, + PRIV_XPOLICY, +}; + +pub type lgrp_rsrc_t = c_int; +pub type lgrp_affinity_t = c_int; + +s! { + pub struct aiocb { + pub aio_fildes: c_int, + pub aio_buf: *mut c_void, + pub aio_nbytes: size_t, + pub aio_offset: off_t, + pub aio_reqprio: c_int, + pub aio_sigevent: crate::sigevent, + pub aio_lio_opcode: c_int, + pub aio_resultp: crate::aio_result_t, + pub aio_state: c_int, + pub aio__pad: [c_int; 1], + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_amp: *mut c_void, + pub shm_lkcnt: c_ushort, + pub shm_lpid: crate::pid_t, + pub shm_cpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + pub shm_cnattch: c_ulong, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::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; crate::FILNAME_MAX as usize], + } + + #[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), repr(packed(4)))] + 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: crate::pid_t, + pub ut_type: c_short, + pub ut_exit: exit_status, + pub ut_tv: crate::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 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 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_DUPFD_CLOFORK: c_int = 58; +pub const F_DUP2FD_CLOEXEC: c_int = 36; +pub const F_DUP2FD_CLOFORK: c_int = 57; +pub const F_DUP3FD: c_int = 59; + +pub const FD_CLOFORK: c_int = 2; + +pub const FIL_ATTACH: c_int = 0x1; +pub const FIL_DETACH: c_int = 0x2; +pub const FIL_LIST: c_int = 0x3; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 POSIX_SPAWN_SETSID: c_short = 0x40; + +pub const SIGINFO: c_int = 41; + +pub const O_DIRECT: c_int = 0x2000000; +pub const O_CLOFORK: c_int = 0x4000000; + +pub const MSG_CMSG_CLOEXEC: c_int = 0x1000; +pub const MSG_CMSG_CLOFORK: c_int = 0x2000; + +pub const PBIND_HARD: crate::processorid_t = -3; +pub const PBIND_SOFT: crate::processorid_t = -4; + +pub const PS_SYSTEM: c_int = 1; + +pub const MAP_FILE: c_int = 0; + +pub const MAP_32BIT: c_int = 0x80; + +pub const AF_NCA: c_int = 28; + +pub const PF_NCA: c_int = AF_NCA; + +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const _PC_LAST: c_int = 101; + +pub const _CS_PATH: c_int = 65; + +pub const VSTATUS: usize = 16; +pub const VERASE2: usize = 17; + +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 = u32_cast_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; + +pub const PRIV_USER: c_uint = PRIV_DEBUG + | NET_MAC_AWARE + | NET_MAC_AWARE_INHERIT + | PRIV_XPOLICY + | PRIV_AWARE_RESET + | PRIV_PFEXEC; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const LGRP_RSRC_COUNT: crate::lgrp_rsrc_t = 2; + +pub const LGRP_RSRC_CPU: crate::lgrp_rsrc_t = 0; +pub const LGRP_RSRC_MEM: crate::lgrp_rsrc_t = 1; + +pub const P_DISABLED: c_int = 0x008; + +pub const AT_SUN_HWCAP2: c_uint = 2023; +pub const AT_SUN_FPTYPE: c_uint = 2027; + +pub const B1000000: crate::speed_t = 24; +pub const B1152000: crate::speed_t = 25; +pub const B1500000: crate::speed_t = 26; +pub const B2000000: crate::speed_t = 27; +pub const B2500000: crate::speed_t = 28; +pub const B3000000: crate::speed_t = 29; +pub const B3500000: crate::speed_t = 30; +pub const B4000000: crate::speed_t = 31; + +// sys/systeminfo.h +pub const SI_ADDRESS_WIDTH: c_int = 520; + +// netinet/in.h +pub const IP_MINTTL: c_int = 0x1c; +pub const IPV6_MINHOPCOUNT: c_int = 0x2f; + +// sys/timerfd.h +pub const TFD_CLOEXEC: i32 = 0o2000000; +pub const TFD_NONBLOCK: i32 = 0o4000; +pub const TFD_TIMER_ABSTIME: i32 = 1 << 0; +pub const TFD_TIMER_CANCEL_ON_SET: i32 = 1 << 1; + +extern "C" { + pub fn eventfd(initval: c_uint, flags: c_int) -> c_int; + + pub fn epoll_pwait( + epfd: c_int, + events: *mut crate::epoll_event, + maxevents: c_int, + timeout: c_int, + sigmask: *const crate::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 crate::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 crate::epoll_event) -> c_int; + + pub fn mincore(addr: crate::caddr_t, len: size_t, vec: *mut c_char) -> c_int; + + pub fn pset_bind_lwp( + pset: crate::psetid_t, + id: crate::id_t, + pid: crate::pid_t, + opset: *mut crate::psetid_t, + ) -> c_int; + pub fn pset_getloadavg(pset: crate::psetid_t, load: *mut c_double, num: c_int) -> c_int; + + pub fn pthread_attr_get_np(thread: crate::pthread_t, attr: *mut crate::pthread_attr_t) + -> c_int; + pub fn pthread_attr_getstackaddr( + attr: *const crate::pthread_attr_t, + stackaddr: *mut *mut c_void, + ) -> c_int; + pub fn pthread_attr_setstack( + attr: *mut crate::pthread_attr_t, + stackaddr: *mut c_void, + stacksize: size_t, + ) -> c_int; + pub fn pthread_attr_setstackaddr( + attr: *mut crate::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 crate::iovec, iovcnt: c_int, offset: off_t) -> ssize_t; + pub fn pwritev(fd: c_int, iov: *const crate::iovec, iovcnt: c_int, offset: off_t) -> ssize_t; + pub fn getpagesizes2(pagesize: *mut size_t, nelem: c_int) -> c_int; + + pub fn posix_spawn_file_actions_addfchdir_np( + file_actions: *mut crate::posix_spawn_file_actions_t, + fd: c_int, + ) -> c_int; + + pub fn ptsname_r(fildes: c_int, name: *mut c_char, namelen: size_t) -> c_int; + + pub fn syncfs(fd: c_int) -> c_int; + + pub fn strcasecmp_l(s1: *const c_char, s2: *const c_char, loc: crate::locale_t) -> c_int; + pub fn strncasecmp_l( + s1: *const c_char, + s2: *const c_char, + n: size_t, + loc: crate::locale_t, + ) -> c_int; + + pub fn timerfd_create(clockid: c_int, flags: c_int) -> c_int; + pub fn timerfd_gettime(fd: c_int, curr_value: *mut crate::itimerspec) -> c_int; + pub fn timerfd_settime( + fd: c_int, + flags: c_int, + new_value: *const crate::itimerspec, + old_value: *mut crate::itimerspec, + ) -> 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..b08e8a4 --- /dev/null +++ b/vendor/libc/src/unix/solarish/mod.rs @@ -0,0 +1,3058 @@ +use crate::prelude::*; + +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 = crate::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_id_t = crate::id_t; +pub type lgrp_mem_size_t = c_longlong; +pub type lgrp_cookie_t = crate::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; + +pub type posix_spawnattr_t = *mut c_void; +pub type posix_spawn_file_actions_t = *mut c_void; + +extern_ty! { + pub type timezone; + pub type ucred_t; +} + +s! { + pub struct in_addr { + pub s_addr: crate::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: crate::uid_t, + pub gid: crate::gid_t, + pub cuid: crate::uid_t, + pub cgid: crate::gid_t, + pub mode: mode_t, + pub seq: c_uint, + pub key: crate::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: crate::in_port_t, + pub sin_addr: crate::in_addr, + pub sin_zero: [c_char; 8], + } + + pub struct sockaddr_in6 { + pub sin6_family: sa_family_t, + pub sin6_port: crate::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: crate::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: crate::in_addr, + pub ipi_addr: crate::in_addr, + } + + pub struct in6_pktinfo { + pub ipi6_addr: crate::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: crate::uid_t, + pub pw_gid: crate::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 crate::sockaddr, + pub ifa_netmask: *mut crate::sockaddr, + pub ifa_dstaddr: *mut crate::sockaddr, + pub ifa_data: *mut c_void, + } + + pub struct itimerspec { + pub it_interval: crate::timespec, + pub it_value: crate::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: crate::socklen_t, + pub msg_iov: *mut crate::iovec, + pub msg_iovlen: c_int, + pub msg_control: *mut c_void, + pub msg_controllen: crate::socklen_t, + pub msg_flags: c_int, + } + + pub struct cmsghdr { + pub cmsg_len: crate::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: crate::pthread_mutex_t, + __pthread_rwlock_readercv: crate::pthread_cond_t, + __pthread_rwlock_writercv: crate::pthread_cond_t, + } + + pub struct pthread_rwlockattr_t { + __pthread_rwlockattrp: *mut c_void, + } + + pub struct dirent { + pub d_ino: crate::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: Padding<*mut c_void>, + __unused2: Padding, + #[cfg(target_os = "illumos")] + __unused3: Padding, + #[cfg(target_os = "illumos")] + __unused4: Padding, + #[cfg(target_os = "illumos")] + __unused5: Padding<*mut c_void>, + #[cfg(target_os = "illumos")] + __unused6: Padding<*mut c_void>, + #[cfg(target_os = "illumos")] + __unused7: Padding<*mut c_void>, + #[cfg(target_os = "illumos")] + __unused8: Padding<*mut c_void>, + #[cfg(target_os = "illumos")] + __unused9: Padding<*mut c_void>, + #[cfg(target_os = "illumos")] + __unused10: Padding<*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: Padding, + pub ai_addrlen: crate::socklen_t, + pub ai_canonname: *mut c_char, + pub ai_addr: *mut crate::sockaddr, + pub ai_next: *mut addrinfo, + } + + pub struct sigset_t { + bits: [u32; 4], + } + + pub struct sigaction { + pub sa_flags: c_int, + pub sa_sigaction: crate::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: crate::fsblkcnt_t, + pub f_bfree: crate::fsblkcnt_t, + pub f_bavail: crate::fsblkcnt_t, + pub f_files: crate::fsfilcnt_t, + pub f_ffree: crate::fsfilcnt_t, + pub f_favail: crate::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: Padding<[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: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + pub st_atime: crate::time_t, + pub st_atime_nsec: c_long, + pub st_mtime: crate::time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: crate::time_t, + pub st_ctime_nsec: c_long, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_fstype: [c_char; _ST_FSTYPSZ as usize], + } + + pub struct termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_cc: [crate::cc_t; crate::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: crate::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: Padding<[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: crate::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 aio_result_t { + pub aio_return: ssize_t, + pub aio_errno: c_int, + } + + 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: crate::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: crate::timeval, + pub maxerror: i32, + pub esterror: i32, + } + + pub struct mmapobj_result_t { + pub mr_addr: crate::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_t { + pub idtype: crate::idtype_t, + pub id: crate::id_t, + pub lgrp: crate::lgrp_id_t, + pub aff: crate::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, + } + + 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 as usize / 64], + #[cfg(target_pointer_width = "32")] + fds_bits: [i32; FD_SETSIZE as usize / 32], + } + + pub struct sockaddr_storage { + pub ss_family: crate::sa_family_t, + __ss_pad1: Padding<[u8; 6]>, + __ss_align: i64, + __ss_pad2: Padding<[u8; 240]>, + } + + 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: crate::sigval, + pub ss_sp: *mut c_void, + pub sigev_notify_attributes: *const crate::pthread_attr_t, + __sigev_pad2: Padding, + } +} + +s_no_extra_traits! { + #[cfg_attr(target_pointer_width = "64", 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], + } + + #[repr(align(16))] + pub union pad128_t { + // pub _q in this structure would be a "long double", of 16 bytes + pub _l: [i32; 4], + } + + #[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 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 => { + size_of::() / size_of::() + } + SIGCLD => size_of::() / size_of::(), + SIGHUP + | SIGINT + | SIGQUIT + | SIGABRT + | SIGSYS + | SIGPIPE + | SIGALRM + | SIGTERM + | crate::SIGUSR1 + | crate::SIGUSR2 + | SIGPWR + | SIGWINCH + | SIGURG => size_of::() / size_of::(), + _ => 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(solarish): 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 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(solarish): 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 pad128_t { + fn eq(&self, other: &pad128_t) -> bool { + unsafe { + // FIXME(solarish): self._q == other._q || + self._l == other._l + } + } + } + impl Eq for pad128_t {} + impl hash::Hash for pad128_t { + fn hash(&self, state: &mut H) { + unsafe { + // FIXME(solarish): state.write_i64(self._q as i64); + self._l.hash(state); + } + } + } + impl PartialEq for upad128_t { + fn eq(&self, other: &upad128_t) -> bool { + unsafe { + // FIXME(solarish): self._q == other._q || + self._l == other._l + } + } + } + impl Eq for upad128_t {} + impl hash::Hash for upad128_t { + fn hash(&self, state: &mut H) { + unsafe { + // FIXME(solarish): 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; + } +} + +s_no_extra_traits! { + struct siginfo_fault { + addr: *mut c_void, + trapno: c_int, + pc: *mut crate::caddr_t, + } + + struct siginfo_cldval { + utime: crate::clock_t, + status: c_int, + stime: crate::clock_t, + } + + struct siginfo_killval { + uid: crate::uid_t, + value: crate::sigval, + // Pad out to match the SIGCLD value size + _pad: Padding<*mut c_void>, + } + + struct siginfo_sigcld { + pid: crate::pid_t, + val: siginfo_cldval, + ctid: crate::ctid_t, + zoneid: crate::zoneid_t, + } + + struct siginfo_kill { + pid: crate::pid_t, + val: siginfo_killval, + ctid: crate::ctid_t, + zoneid: crate::zoneid_t, + } +} + +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) -> crate::uid_t { + let kill: siginfo_kill = self.sidata(); + kill.val.uid + } + pub unsafe fn si_value(&self) -> crate::sigval { + let kill: siginfo_kill = self.sidata(); + kill.val.value + } + pub unsafe fn si_pid(&self) -> crate::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: crate::nl_item = 1; +pub const DAY_2: crate::nl_item = 2; +pub const DAY_3: crate::nl_item = 3; +pub const DAY_4: crate::nl_item = 4; +pub const DAY_5: crate::nl_item = 5; +pub const DAY_6: crate::nl_item = 6; +pub const DAY_7: crate::nl_item = 7; + +pub const ABDAY_1: crate::nl_item = 8; +pub const ABDAY_2: crate::nl_item = 9; +pub const ABDAY_3: crate::nl_item = 10; +pub const ABDAY_4: crate::nl_item = 11; +pub const ABDAY_5: crate::nl_item = 12; +pub const ABDAY_6: crate::nl_item = 13; +pub const ABDAY_7: crate::nl_item = 14; + +pub const MON_1: crate::nl_item = 15; +pub const MON_2: crate::nl_item = 16; +pub const MON_3: crate::nl_item = 17; +pub const MON_4: crate::nl_item = 18; +pub const MON_5: crate::nl_item = 19; +pub const MON_6: crate::nl_item = 20; +pub const MON_7: crate::nl_item = 21; +pub const MON_8: crate::nl_item = 22; +pub const MON_9: crate::nl_item = 23; +pub const MON_10: crate::nl_item = 24; +pub const MON_11: crate::nl_item = 25; +pub const MON_12: crate::nl_item = 26; + +pub const ABMON_1: crate::nl_item = 27; +pub const ABMON_2: crate::nl_item = 28; +pub const ABMON_3: crate::nl_item = 29; +pub const ABMON_4: crate::nl_item = 30; +pub const ABMON_5: crate::nl_item = 31; +pub const ABMON_6: crate::nl_item = 32; +pub const ABMON_7: crate::nl_item = 33; +pub const ABMON_8: crate::nl_item = 34; +pub const ABMON_9: crate::nl_item = 35; +pub const ABMON_10: crate::nl_item = 36; +pub const ABMON_11: crate::nl_item = 37; +pub const ABMON_12: crate::nl_item = 38; + +pub const RADIXCHAR: crate::nl_item = 39; +pub const THOUSEP: crate::nl_item = 40; +pub const YESSTR: crate::nl_item = 41; +pub const NOSTR: crate::nl_item = 42; +pub const CRNCYSTR: crate::nl_item = 43; + +pub const D_T_FMT: crate::nl_item = 44; +pub const D_FMT: crate::nl_item = 45; +pub const T_FMT: crate::nl_item = 46; +pub const AM_STR: crate::nl_item = 47; +pub const PM_STR: crate::nl_item = 48; + +pub const CODESET: crate::nl_item = 49; +pub const T_FMT_AMPM: crate::nl_item = 50; +pub const ERA: crate::nl_item = 51; +pub const ERA_D_FMT: crate::nl_item = 52; +pub const ERA_D_T_FMT: crate::nl_item = 53; +pub const ERA_T_FMT: crate::nl_item = 54; +pub const ALT_DIGITS: crate::nl_item = 55; +pub const YESEXPR: crate::nl_item = 56; +pub const NOEXPR: crate::nl_item = 57; +pub const _DATE_FMT: crate::nl_item = 58; +pub const MAXSTRMSG: crate::nl_item = 58; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 = u32_cast_int(0x8004667e); +pub const FIOASYNC: c_int = u32_cast_int(0x8004667d); +pub const FIOSETOWN: c_int = u32_cast_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 SIG_BLOCK: c_int = 1; +pub const SIG_UNBLOCK: c_int = 2; +pub const SIG_SETMASK: c_int = 3; + +pub const AIO_CANCELED: c_int = 0; +pub const AIO_ALLDONE: c_int = 1; +pub const AIO_NOTCANCELED: c_int = 2; +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 SIGEV_NONE: c_int = 1; +pub const SIGEV_SIGNAL: c_int = 2; +pub const SIGEV_THREAD: c_int = 3; +pub const SIGEV_PORT: c_int = 4; + +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_HOPLIMIT: c_int = 0xc; +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; +pub const IPV6_BOUND_IF: c_int = 0x41; + +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: crate::socklen_t = 1025; +pub const NI_MAXSERV: crate::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 S_IFIFO: mode_t = 0o1_0000; +pub const S_IFCHR: mode_t = 0o2_0000; +pub const S_IFBLK: mode_t = 0o6_0000; +pub const S_IFDIR: mode_t = 0o4_0000; +pub const S_IFREG: mode_t = 0o10_0000; +pub const S_IFLNK: mode_t = 0o12_0000; +pub const S_IFSOCK: mode_t = 0o14_0000; +pub const S_IFMT: mode_t = 0o17_0000; +pub const S_IEXEC: mode_t = 0o0100; +pub const S_IWRITE: mode_t = 0o0200; +pub const S_IREAD: mode_t = 0o0400; +pub const S_IRWXU: mode_t = 0o0700; +pub const S_IXUSR: mode_t = 0o0100; +pub const S_IWUSR: mode_t = 0o0200; +pub const S_IRUSR: mode_t = 0o0400; +pub const S_IRWXG: mode_t = 0o0070; +pub const S_IXGRP: mode_t = 0o0010; +pub const S_IWGRP: mode_t = 0o0020; +pub const S_IRGRP: mode_t = 0o0040; +pub const S_IRWXO: mode_t = 0o0007; +pub const S_IXOTH: mode_t = 0o0001; +pub const S_IWOTH: mode_t = 0o0002; +pub const S_IROTH: mode_t = 0o0004; +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 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 = u32_cast_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: crate::processorid_t = -1; +pub const PBIND_QUERY: crate::processorid_t = -2; + +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_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_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_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 AI_CANONNAME: c_int = 0x0010; + +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 POSIX_SPAWN_RESETIDS: c_short = 0x1; +pub const POSIX_SPAWN_SETPGROUP: c_short = 0x2; +pub const POSIX_SPAWN_SETSIGDEF: c_short = 0x4; +pub const POSIX_SPAWN_SETSIGMASK: c_short = 0x8; +pub const POSIX_SPAWN_SETSCHEDPARAM: c_short = 0x10; +pub const POSIX_SPAWN_SETSCHEDULER: c_short = 0x20; +pub const POSIX_SPAWN_SETSIGIGN_NP: c_short = 0x800; +pub const POSIX_SPAWN_NOSIGCHLD_NP: c_short = 0x1000; +pub const POSIX_SPAWN_WAITPID_NP: c_short = 0x2000; +pub const POSIX_SPAWN_NOEXECERR_NP: c_short = 0x4000; + +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 +// +// 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 +// CLOCK_PROF==CLOCK_THREAD_CPUTIME_ID==2 (distinct from CLOCK_VIRTUAL==1) +pub const CLOCK_REALTIME: crate::clockid_t = 3; +pub const CLOCK_MONOTONIC: crate::clockid_t = 4; +pub const CLOCK_PROCESS_CPUTIME_ID: crate::clockid_t = 5; +pub const CLOCK_THREAD_CPUTIME_ID: crate::clockid_t = 2; +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_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_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; +pub const IP_BOUND_IF: c_int = 0x41; + +// 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 = u32_cast_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 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_XATTR_EXISTS: c_int = 101; + +pub const _POSIX_VDISABLE: crate::cc_t = 0; + +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 _ST_FSTYPSZ: c_int = 16; + +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 = crate::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 PORT_ALERT_SET: c_int = 0x01; +pub const PORT_ALERT_UPDATE: c_int = 0x02; +pub const PORT_ALERT_INVALID: c_int = PORT_ALERT_SET | PORT_ALERT_UPDATE; + +pub const NONROOT_USR: c_short = 2; + +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; + +/* 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: crate::tcflag_t = 0o21; +pub const CSTOP: crate::tcflag_t = 0o23; +pub const CSWTCH: crate::tcflag_t = 0o32; +pub const CBAUD: crate::tcflag_t = 0o17; +pub const CIBAUD: crate::tcflag_t = 0o3600000; +pub const CBAUDEXT: crate::tcflag_t = 0o10000000; +pub const CIBAUDEXT: crate::tcflag_t = 0o20000000; +pub const CSIZE: crate::tcflag_t = 0o000060; +pub const CS5: crate::tcflag_t = 0; +pub const CS6: crate::tcflag_t = 0o000020; +pub const CS7: crate::tcflag_t = 0o000040; +pub const CS8: crate::tcflag_t = 0o000060; +pub const CSTOPB: crate::tcflag_t = 0o000100; +pub const ECHO: crate::tcflag_t = 0o000010; +pub const ECHOE: crate::tcflag_t = 0o000020; +pub const ECHOK: crate::tcflag_t = 0o000040; +pub const ECHONL: crate::tcflag_t = 0o000100; +pub const ECHOCTL: crate::tcflag_t = 0o001000; +pub const ECHOPRT: crate::tcflag_t = 0o002000; +pub const ECHOKE: crate::tcflag_t = 0o004000; +pub const EXTPROC: crate::tcflag_t = 0o200000; +pub const IGNBRK: crate::tcflag_t = 0o000001; +pub const BRKINT: crate::tcflag_t = 0o000002; +pub const IGNPAR: crate::tcflag_t = 0o000004; +pub const PARMRK: crate::tcflag_t = 0o000010; +pub const INPCK: crate::tcflag_t = 0o000020; +pub const ISTRIP: crate::tcflag_t = 0o000040; +pub const INLCR: crate::tcflag_t = 0o000100; +pub const IGNCR: crate::tcflag_t = 0o000200; +pub const ICRNL: crate::tcflag_t = 0o000400; +pub const IUCLC: crate::tcflag_t = 0o001000; +pub const IXON: crate::tcflag_t = 0o002000; +pub const IXOFF: crate::tcflag_t = 0o010000; +pub const IXANY: crate::tcflag_t = 0o004000; +pub const IMAXBEL: crate::tcflag_t = 0o020000; +pub const DOSMODE: crate::tcflag_t = 0o100000; +pub const OPOST: crate::tcflag_t = 0o000001; +pub const OLCUC: crate::tcflag_t = 0o000002; +pub const ONLCR: crate::tcflag_t = 0o000004; +pub const OCRNL: crate::tcflag_t = 0o000010; +pub const ONOCR: crate::tcflag_t = 0o000020; +pub const ONLRET: crate::tcflag_t = 0o000040; +pub const OFILL: crate::tcflag_t = 0o0000100; +pub const OFDEL: crate::tcflag_t = 0o0000200; +pub const CREAD: crate::tcflag_t = 0o000200; +pub const PARENB: crate::tcflag_t = 0o000400; +pub const PARODD: crate::tcflag_t = 0o001000; +pub const HUPCL: crate::tcflag_t = 0o002000; +pub const CLOCAL: crate::tcflag_t = 0o004000; +pub const CRTSXOFF: crate::tcflag_t = 0o10000000000; +pub const CRTSCTS: crate::tcflag_t = 0o20000000000; +pub const ISIG: crate::tcflag_t = 0o000001; +pub const ICANON: crate::tcflag_t = 0o000002; +pub const IEXTEN: crate::tcflag_t = 0o100000; +pub const TOSTOP: crate::tcflag_t = 0o000400; +pub const FLUSHO: crate::tcflag_t = 0o020000; +pub const PENDIN: crate::tcflag_t = 0o040000; +pub const NOFLSH: crate::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; + +// +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; + +// 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: crate::lgrp_cookie_t = 0; +pub const LGRP_AFF_NONE: crate::lgrp_affinity_t = 0x0; +pub const LGRP_AFF_WEAK: crate::lgrp_affinity_t = 0x10; +pub const LGRP_AFF_STRONG: crate::lgrp_affinity_t = 0x100; +pub const LGRP_CONTENT_ALL: crate::lgrp_content_t = 0; +pub const LGRP_CONTENT_HIERARCHY: crate::lgrp_content_t = LGRP_CONTENT_ALL; +pub const LGRP_CONTENT_DIRECT: crate::lgrp_content_t = 1; +pub const LGRP_LAT_CPU_TO_MEM: crate::lgrp_lat_between_t = 0; +pub const LGRP_MEM_SZ_FREE: crate::lgrp_mem_size_flag_t = 0; +pub const LGRP_MEM_SZ_INSTALLED: crate::lgrp_mem_size_flag_t = 1; +pub const LGRP_VIEW_CALLER: crate::lgrp_view_t = 0; +pub const LGRP_VIEW_OS: crate::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_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; + +// 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 = size_of::(); + +const NEWDEV: c_int = 1; + +// sys/sendfile.h +pub const SFV_FD_SELF: c_int = -2; + +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 unsafe fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + _CMSG_DATA_ALIGN(cmsg.offset(1) as usize) as *mut c_uchar + } + + pub const unsafe fn CMSG_LEN(length: c_uint) -> c_uint { + _CMSG_DATA_ALIGN(size_of::()) as c_uint + length + } + + pub unsafe fn CMSG_FIRSTHDR(mhdr: *const crate::msghdr) -> *mut cmsghdr { + if ((*mhdr).msg_controllen as usize) < size_of::() { + ptr::null_mut() + } else { + (*mhdr).msg_control.cast::() + } + } + + pub unsafe fn CMSG_NXTHDR(mhdr: *const crate::msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { + if cmsg.is_null() { + return crate::CMSG_FIRSTHDR(mhdr); + } + let next = + _CMSG_HDR_ALIGN(cmsg as usize + (*cmsg).cmsg_len as usize + size_of::()); + let max = (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize; + if next > max { + ptr::null_mut() + } else { + _CMSG_HDR_ALIGN(cmsg as usize + (*cmsg).cmsg_len as usize) as *mut cmsghdr + } + } + + pub const unsafe fn CMSG_SPACE(length: c_uint) -> c_uint { + _CMSG_HDR_ALIGN(size_of::() as usize + length as usize) as c_uint + } + + pub unsafe fn FD_CLR(fd: c_int, set: *mut fd_set) -> () { + let bits = size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); + return; + } + + pub unsafe fn FD_ISSET(fd: c_int, set: *const fd_set) -> bool { + let bits = size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0; + } + + pub unsafe fn FD_SET(fd: c_int, set: *mut fd_set) -> () { + let bits = size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] |= 1 << (fd % bits); + return; + } + + pub unsafe fn FD_ZERO(set: *mut fd_set) -> () { + (*set).fds_bits.fill(0); + } +} + +safe_f! { + pub safe fn SIGRTMAX() -> c_int { + unsafe { crate::sysconf(_SC_SIGRT_MAX) as c_int } + } + + pub safe fn SIGRTMIN() -> c_int { + unsafe { crate::sysconf(_SC_SIGRT_MIN) as c_int } + } + + pub const safe fn WIFEXITED(status: c_int) -> bool { + (status & 0xFF) == 0 + } + + pub const safe fn WEXITSTATUS(status: c_int) -> c_int { + (status >> 8) & 0xFF + } + + pub const safe fn WTERMSIG(status: c_int) -> c_int { + status & 0x7F + } + + pub const safe fn WIFCONTINUED(status: c_int) -> bool { + (status & 0xffff) == 0xffff + } + + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + (status & 0xff00) >> 8 + } + + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + ((status & 0xff) > 0) && (status & 0xff00 == 0) + } + + pub const safe fn WIFSTOPPED(status: c_int) -> bool { + ((status & 0xff) == 0x7f) && ((status & 0xff00) != 0) + } + + pub const safe fn WCOREDUMP(status: c_int) -> bool { + (status & 0x80) != 0 + } + + pub const safe fn MR_GET_TYPE(flags: c_uint) -> c_uint { + flags & 0x0000ffff + } +} + +extern "C" { + pub fn getrlimit(resource: c_int, rlim: *mut crate::rlimit) -> c_int; + pub fn setrlimit(resource: c_int, rlim: *const crate::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 crate::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 crate::timeval, tz: *mut c_void) -> c_int; + pub fn settimeofday(tp: *const crate::timeval, tz: *const c_void) -> c_int; + pub fn getifaddrs(ifap: *mut *mut crate::ifaddrs) -> c_int; + pub fn freeifaddrs(ifa: *mut crate::ifaddrs); + + pub fn stack_getbounds(sp: *mut crate::stack_t) -> c_int; + pub fn getgrouplist( + name: *const c_char, + basegid: crate::gid_t, + groups: *mut crate::gid_t, + ngroups: *mut c_int, + ) -> c_int; + pub fn initgroups(name: *const c_char, basegid: crate::gid_t) -> c_int; + pub fn setgroups(ngroups: c_int, ptr: *const crate::gid_t) -> c_int; + pub fn ioctl(fildes: c_int, request: c_int, ...) -> c_int; + pub fn mprotect(addr: *mut c_void, len: size_t, prot: c_int) -> c_int; + pub fn ___errno() -> *mut c_int; + pub fn clock_getres(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_gettime(clk_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + pub fn clock_nanosleep( + clk_id: crate::clockid_t, + flags: c_int, + rqtp: *const crate::timespec, + rmtp: *mut crate::timespec, + ) -> c_int; + pub fn clock_settime(clk_id: crate::clockid_t, tp: *const crate::timespec) -> c_int; + pub fn getnameinfo( + sa: *const crate::sockaddr, + salen: crate::socklen_t, + host: *mut c_char, + hostlen: crate::socklen_t, + serv: *mut c_char, + servlen: crate::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: crate::nl_item, locale: crate::locale_t) -> *mut c_char; + pub fn duplocale(base: crate::locale_t) -> crate::locale_t; + pub fn freelocale(loc: crate::locale_t); + pub fn newlocale(mask: c_int, locale: *const c_char, base: crate::locale_t) -> crate::locale_t; + pub fn uselocale(loc: crate::locale_t) -> crate::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 crate::pthread_t, + attr: *const crate::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 crate::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: crate::clockid_t, + ) -> c_int; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const crate::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 crate::timespec, + ) -> c_int; + pub fn pthread_getname_np(tid: crate::pthread_t, name: *mut c_char, len: size_t) -> c_int; + pub fn pthread_setname_np(tid: crate::pthread_t, name: *const c_char) -> c_int; + pub fn waitid( + idtype: idtype_t, + id: id_t, + infop: *mut crate::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 crate::glob_t, + ) -> c_int; + + #[cfg_attr(target_os = "illumos", link_name = "_globfree_ext")] + pub fn globfree(pglob: *mut crate::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 posix_spawn( + pid: *mut crate::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 crate::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_spawn_file_actions_addclosefrom_np( + file_actions: *mut posix_spawn_file_actions_t, + lowfiledes: c_int, + ) -> c_int; + pub fn posix_spawn_file_actions_addchdir( + file_actions: *mut posix_spawn_file_actions_t, + path: *const c_char, + ) -> c_int; + pub fn posix_spawn_file_actions_addchdir_np( + file_actions: *mut posix_spawn_file_actions_t, + path: *const c_char, + ) -> c_int; + pub fn posix_spawn_file_actions_addfchdir( + file_actions: *mut posix_spawn_file_actions_t, + fd: 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_setflags(attr: *mut posix_spawnattr_t, flags: c_short) -> c_int; + pub fn posix_spawnattr_getflags(attr: *const posix_spawnattr_t, flags: *mut c_short) -> c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, pgroup: crate::pid_t) -> c_int; + pub fn posix_spawnattr_getpgroup( + attr: *const posix_spawnattr_t, + _pgroup: *mut crate::pid_t, + ) -> c_int; + pub fn posix_spawnattr_setschedparam( + attr: *mut posix_spawnattr_t, + param: *const crate::sched_param, + ) -> c_int; + pub fn posix_spawnattr_getschedparam( + attr: *const posix_spawnattr_t, + param: *mut crate::sched_param, + ) -> c_int; + pub fn posix_spawnattr_setschedpolicy(attr: *mut posix_spawnattr_t, policy: c_int) -> c_int; + pub fn posix_spawnattr_getschedpolicy( + attr: *const posix_spawnattr_t, + _policy: *mut c_int, + ) -> c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + sigdefault: *const sigset_t, + ) -> c_int; + pub fn posix_spawnattr_getsigdefault( + attr: *const posix_spawnattr_t, + sigdefault: *mut sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigignore_np( + attr: *mut posix_spawnattr_t, + sigignore: *const sigset_t, + ) -> c_int; + pub fn posix_spawnattr_getsigignore_np( + attr: *const posix_spawnattr_t, + sigignore: *mut sigset_t, + ) -> c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + sigmask: *const sigset_t, + ) -> c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + sigmask: *mut sigset_t, + ) -> 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 crate::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 crate::DIR, loc: c_long); + + pub fn telldir(dirp: *mut crate::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 crate::sockaddr, + addrlen: *mut crate::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 crate::timeval) -> c_int; + pub fn futimens(dirfd: c_int, times: *const crate::timespec) -> c_int; + pub fn utimensat( + dirfd: c_int, + path: *const c_char, + times: *const crate::timespec, + flag: c_int, + ) -> c_int; + pub fn nl_langinfo(item: crate::nl_item) -> *mut c_char; + + #[link_name = "__xnet_bind"] + pub fn bind( + socket: c_int, + address: *const crate::sockaddr, + address_len: crate::socklen_t, + ) -> c_int; + + pub fn writev(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + pub fn readv(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + + #[link_name = "__xnet_sendmsg"] + pub fn sendmsg(fd: c_int, msg: *const crate::msghdr, flags: c_int) -> ssize_t; + #[link_name = "__xnet_recvmsg"] + pub fn recvmsg(fd: c_int, msg: *mut crate::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, ...) -> crate::mqd_t; + pub fn mq_close(mqd: crate::mqd_t) -> c_int; + pub fn mq_unlink(name: *const c_char) -> c_int; + pub fn mq_receive( + mqd: crate::mqd_t, + msg_ptr: *mut c_char, + msg_len: size_t, + msg_prio: *mut c_uint, + ) -> ssize_t; + pub fn mq_timedreceive( + mqd: crate::mqd_t, + msg_ptr: *mut c_char, + msg_len: size_t, + msg_prio: *mut c_uint, + abs_timeout: *const crate::timespec, + ) -> ssize_t; + pub fn mq_send( + mqd: crate::mqd_t, + msg_ptr: *const c_char, + msg_len: size_t, + msg_prio: c_uint, + ) -> c_int; + pub fn mq_timedsend( + mqd: crate::mqd_t, + msg_ptr: *const c_char, + msg_len: size_t, + msg_prio: c_uint, + abs_timeout: *const crate::timespec, + ) -> c_int; + pub fn mq_getattr(mqd: crate::mqd_t, attr: *mut crate::mq_attr) -> c_int; + pub fn mq_setattr( + mqd: crate::mqd_t, + newattr: *const crate::mq_attr, + oldattr: *mut crate::mq_attr, + ) -> c_int; + pub fn port_create() -> c_int; + pub fn port_associate( + port: c_int, + source: c_int, + object: crate::uintptr_t, + events: c_int, + user: *mut c_void, + ) -> c_int; + pub fn port_dissociate(port: c_int, source: c_int, object: crate::uintptr_t) -> c_int; + pub fn port_get(port: c_int, pe: *mut port_event, timeout: *mut crate::timespec) -> c_int; + pub fn port_getn( + port: c_int, + pe_list: *mut port_event, + max: c_uint, + nget: *mut c_uint, + timeout: *mut crate::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; + pub fn port_alert(port: c_int, flags: c_int, 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: crate::gid_t, + grp: *mut crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> c_int; + pub fn sigsuspend(mask: *const crate::sigset_t) -> c_int; + pub fn sem_close(sem: *mut sem_t) -> c_int; + pub fn getdtablesize() -> 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 crate::group, + buf: *mut c_char, + buflen: size_t, + result: *mut *mut crate::group, + ) -> c_int; + pub fn thr_self() -> crate::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 crate::group; + #[cfg_attr(target_os = "solaris", link_name = "__pthread_kill_xpg7")] + pub fn pthread_kill(thread: crate::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: crate::pid_t, param: *mut sched_param) -> c_int; + pub fn sched_setparam(pid: crate::pid_t, param: *const sched_param) -> c_int; + pub fn sched_getscheduler(pid: crate::pid_t) -> c_int; + pub fn sched_setscheduler( + pid: crate::pid_t, + policy: c_int, + param: *const crate::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: crate::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 crate::group, + buf: *mut c_char, + buflen: c_int, + ) -> *mut crate::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: crate::gid_t) -> *mut crate::group; + pub fn setgrent(); + pub fn endgrent(); + pub fn getgrent() -> *mut crate::group; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut crate::FILE; + + pub fn dup3(src: c_int, dst: c_int, flags: c_int) -> c_int; + pub fn uname(buf: *mut crate::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: *mut utmpx); + 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: crate::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) -> crate::uid_t; + pub fn ucred_getruid(ucred: *const ucred_t) -> crate::uid_t; + pub fn ucred_getsuid(ucred: *const ucred_t) -> crate::uid_t; + pub fn ucred_getegid(ucred: *const ucred_t) -> crate::gid_t; + pub fn ucred_getrgid(ucred: *const ucred_t) -> crate::gid_t; + pub fn ucred_getsgid(ucred: *const ucred_t) -> crate::gid_t; + pub fn ucred_getgroups(ucred: *const ucred_t, groups: *mut *const crate::gid_t) -> c_int; + pub fn ucred_getpid(ucred: *const ucred_t) -> crate::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 crate::psetid_t) -> c_int; + pub fn pset_destroy(pset: crate::psetid_t) -> c_int; + pub fn pset_assign( + pset: crate::psetid_t, + cpu: crate::processorid_t, + opset: *mut psetid_t, + ) -> c_int; + pub fn pset_info( + pset: crate::psetid_t, + tpe: *mut c_int, + numcpus: *mut c_uint, + cpulist: *mut processorid_t, + ) -> c_int; + pub fn pset_bind( + pset: crate::psetid_t, + idtype: crate::idtype_t, + id: crate::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: crate::idtype_t, + id: crate::id_t, + new_binding: crate::processorid_t, + old_binding: *mut processorid_t, + ) -> c_int; + pub fn p_online(processorid: crate::processorid_t, flag: c_int) -> c_int; + pub fn processor_info(processorid: crate::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 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 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 crate::timespec, + ) -> c_int; + pub fn aio_waitn( + aiocb_list: *mut *mut aiocb, + nent: c_uint, + nwait: *mut c_uint, + timeout: *const crate::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 __major(version: c_int, devnum: crate::dev_t) -> crate::major_t; + pub fn __minor(version: c_int, devnum: crate::dev_t) -> crate::minor_t; + pub fn __makedev( + version: c_int, + majdev: crate::major_t, + mindev: crate::minor_t, + ) -> crate::dev_t; + + pub fn arc4random() -> u32; + pub fn arc4random_buf(buf: *mut c_void, nbytes: size_t); + pub fn arc4random_uniform(upper_bound: u32) -> u32; + + pub fn secure_getenv(name: *const c_char) -> *mut c_char; + + #[cfg_attr(target_os = "solaris", link_name = "__strftime_xpg7")] + pub fn strftime( + s: *mut c_char, + maxsize: size_t, + format: *const c_char, + timeptr: *const crate::tm, + ) -> size_t; + pub fn strftime_l( + s: *mut c_char, + maxsize: size_t, + format: *const c_char, + timeptr: *const crate::tm, + loc: crate::locale_t, + ) -> size_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: crate::idtype_t, + id: crate::id_t, + lgrp: crate::lgrp_id_t, + ) -> crate::lgrp_affinity_t; + pub fn lgrp_affinity_set( + idtype: crate::idtype_t, + id: crate::id_t, + lgrp: crate::lgrp_id_t, + aff: lgrp_affinity_t, + ) -> c_int; + pub fn lgrp_cpus( + cookie: crate::lgrp_cookie_t, + lgrp: crate::lgrp_id_t, + cpuids: *mut crate::processorid_t, + count: c_uint, + content: crate::lgrp_content_t, + ) -> c_int; + pub fn lgrp_mem_size( + cookie: crate::lgrp_cookie_t, + lgrp: crate::lgrp_id_t, + tpe: crate::lgrp_mem_size_flag_t, + content: crate::lgrp_content_t, + ) -> crate::lgrp_mem_size_t; + pub fn lgrp_nlgrps(cookie: crate::lgrp_cookie_t) -> c_int; + pub fn lgrp_view(cookie: crate::lgrp_cookie_t) -> crate::lgrp_view_t; + pub fn lgrp_home(idtype: crate::idtype_t, id: crate::id_t) -> crate::lgrp_id_t; + pub fn lgrp_version(version: c_int) -> c_int; + pub fn lgrp_resources( + cookie: crate::lgrp_cookie_t, + lgrp: crate::lgrp_id_t, + lgrps: *mut crate::lgrp_id_t, + count: c_uint, + tpe: crate::lgrp_rsrc_t, + ) -> c_int; + pub fn lgrp_root(cookie: crate::lgrp_cookie_t) -> crate::lgrp_id_t; +} + +pub unsafe fn major(device: crate::dev_t) -> crate::major_t { + __major(NEWDEV, device) +} + +pub unsafe fn minor(device: crate::dev_t) -> crate::minor_t { + __minor(NEWDEV, device) +} + +pub unsafe fn makedev(maj: crate::major_t, min: crate::minor_t) -> crate::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..b336c31 --- /dev/null +++ b/vendor/libc/src/unix/solarish/solaris.rs @@ -0,0 +1,206 @@ +use crate::prelude::*; +use crate::{ + exit_status, + off_t, + termios, + NET_MAC_AWARE, + NET_MAC_AWARE_INHERIT, + PRIV_AWARE_RESET, + PRIV_DEBUG, + PRIV_PFEXEC, + PRIV_XPOLICY, +}; + +pub type door_attr_t = c_uint; +pub type door_id_t = c_ulonglong; +pub type lgrp_affinity_t = c_uint; + +e! { + #[repr(u32)] + pub enum lgrp_rsrc_t { + LGRP_RSRC_CPU = 0, + LGRP_RSRC_MEM = 1, + LGRP_RSRC_TYPES = 2, + } +} + +s! { + pub struct aiocb { + pub aio_fildes: c_int, + pub aio_buf: *mut c_void, + pub aio_nbytes: size_t, + pub aio_offset: off_t, + pub aio_reqprio: c_int, + pub aio_sigevent: crate::sigevent, + pub aio_lio_opcode: c_int, + pub aio_resultp: crate::aio_result_t, + pub aio_state: c_char, + pub aio_returned: c_char, + pub aio__pad1: [c_char; 2], + pub aio_flags: c_int, + } + + pub struct shmid_ds { + pub shm_perm: crate::ipc_perm, + pub shm_segsz: size_t, + pub shm_flags: crate::uintptr_t, + pub shm_lkcnt: c_ushort, + pub shm_lpid: crate::pid_t, + pub shm_cpid: crate::pid_t, + pub shm_nattch: crate::shmatt_t, + pub shm_cnattch: c_ulong, + pub shm_atime: crate::time_t, + pub shm_dtime: crate::time_t, + pub shm_ctime: crate::time_t, + pub shm_amp: *mut c_void, + pub shm_gransize: u64, + pub shm_allocated: u64, + pub shm_pad4: [i64; 1], + } + + pub struct xrs_t { + pub xrs_id: c_ulong, + pub xrs_ptr: *mut c_char, + } + + pub struct utmpx { + pub ut_user: [c_char; _UTMP_USER_LEN], + pub ut_id: [c_char; _UTMP_ID_LEN], + pub ut_line: [c_char; _UTMP_LINE_LEN], + pub ut_pid: crate::pid_t, + pub ut_type: c_short, + pub ut_exit: exit_status, + pub ut_tv: crate::timeval, + pub ut_session: c_int, + pub pad: [c_int; 5], + pub ut_syslen: c_short, + pub ut_host: [c_char; 257], + } +} + +s_no_extra_traits! { + #[repr(packed)] + pub struct door_desc_t__d_data__d_desc { + pub d_descriptor: c_int, + pub d_id: crate::door_id_t, + } + + 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 */ + } + + pub struct door_desc_t { + pub d_attributes: door_attr_t, + pub d_data: door_desc_t__d_data, + } + + 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, + } +} + +// FIXME(solaris): O_DIRECT and SIGINFO are NOT available on Solaris. +// But in past they were defined here and thus other crates expected them. +// Latest version v0.29.0 of Nix crate still expects this. Since last +// version of Nix crate is almost one year ago let's define these two +// temporarily before new Nix version is released. +pub const O_DIRECT: c_int = 0x2000000; +pub const SIGINFO: c_int = 41; + +pub const _UTMP_USER_LEN: usize = 32; +pub const _UTMP_LINE_LEN: usize = 32; +pub const _UTMP_ID_LEN: usize = 4; + +pub const PORT_SOURCE_POSTWAIT: c_int = 8; +pub const PORT_SOURCE_SIGNAL: c_int = 9; + +pub const AF_LOCAL: c_int = 1; // AF_UNIX +pub const AF_FILE: c_int = 1; // AF_UNIX + +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const _PC_LAST: c_int = 102; + +pub const PRIV_PROC_SENSITIVE: c_uint = 0x0008; +pub const PRIV_PFEXEC_AUTH: c_uint = 0x0200; +pub const PRIV_PROC_TPD: c_uint = 0x0400; +pub const PRIV_TPD_UNSAFE: c_uint = 0x0800; +pub const PRIV_PROC_TPD_RESET: c_uint = 0x1000; +pub const PRIV_TPD_KILLABLE: c_uint = 0x2000; + +pub const POSIX_SPAWN_SETSID: c_short = 0x400; + +pub const PRIV_USER: c_uint = PRIV_DEBUG + | PRIV_PROC_SENSITIVE + | NET_MAC_AWARE + | NET_MAC_AWARE_INHERIT + | PRIV_XPOLICY + | PRIV_AWARE_RESET + | PRIV_PFEXEC + | PRIV_PFEXEC_AUTH + | PRIV_PROC_TPD + | PRIV_TPD_UNSAFE + | PRIV_TPD_KILLABLE + | PRIV_PROC_TPD_RESET; + +extern "C" { + // DIFF(main): changed to `*const *mut` in e77f551de9 + pub fn fexecve(fd: c_int, argv: *const *const c_char, envp: *const *const c_char) -> c_int; + + pub fn mincore(addr: *mut c_void, len: size_t, vec: *mut c_char) -> c_int; + + pub fn door_call(d: c_int, params: *mut door_arg_t) -> c_int; + pub fn door_return( + data_ptr: *mut c_char, + data_size: size_t, + desc_ptr: *mut door_desc_t, + num_desc: c_uint, + ) -> c_int; + pub fn door_create( + server_procedure: extern "C" fn( + cookie: *mut c_void, + argp: *mut c_char, + arg_size: size_t, + dp: *mut door_desc_t, + n_desc: c_uint, + ), + cookie: *mut 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: crate::pthread_t, attr: *mut crate::pthread_attr_t) -> c_int; + + pub fn euidaccess(path: *const c_char, amode: c_int) -> c_int; + + pub fn openpty( + amain: *mut c_int, + asubord: *mut c_int, + name: *mut c_char, + termp: *mut termios, + winp: *mut crate::winsize, + ) -> c_int; + + pub fn forkpty( + amain: *mut c_int, + name: *mut c_char, + termp: *mut termios, + winp: *mut crate::winsize, + ) -> crate::pid_t; +} diff --git a/vendor/libc/src/unix/solarish/x86.rs b/vendor/libc/src/unix/solarish/x86.rs new file mode 100644 index 0000000..a37ed3d --- /dev/null +++ b/vendor/libc/src/unix/solarish/x86.rs @@ -0,0 +1,31 @@ +use crate::prelude::*; + +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..a4c4806 --- /dev/null +++ b/vendor/libc/src/unix/solarish/x86_64.rs @@ -0,0 +1,154 @@ +use crate::prelude::*; + +cfg_if! { + if #[cfg(target_os = "solaris")] { + use crate::unix::solarish::solaris; + } +} + +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: [crate::upad128_t; 8], + pub xmm: [crate::upad128_t; 16], + pub __fx_ign: [crate::upad128_t; 6], + pub status: u32, + pub xstatus: u32, + } + + pub struct __c_anonymous_Elf64_Phdr { + pub p_type: crate::Elf64_Word, + pub p_flags: crate::Elf64_Word, + pub p_offset: crate::Elf64_Off, + pub p_vaddr: crate::Elf64_Addr, + pub p_paddr: crate::Elf64_Addr, + pub p_filesz: crate::Elf64_Xword, + pub p_memsz: crate::Elf64_Xword, + pub p_align: crate::Elf64_Xword, + } + + pub struct dl_phdr_info { + pub dlpi_addr: crate::Elf64_Addr, + pub dlpi_name: *const c_char, + pub dlpi_phdr: *const crate::Elf64_Phdr, + pub dlpi_phnum: crate::Elf64_Half, + pub dlpi_adds: c_ulonglong, + pub dlpi_subs: c_ulonglong, + #[cfg(target_os = "solaris")] + pub dlpi_tls_modid: c_ulong, + #[cfg(target_os = "solaris")] + pub dlpi_tls_data: *mut c_void, + } + + pub struct fpregset_t { + pub fp_reg_set: __c_anonymous_fp_reg_set, + } + + pub struct mcontext_t { + pub gregs: [crate::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: crate::sigset_t, + pub uc_stack: crate::stack_t, + pub uc_mcontext: mcontext_t, + #[cfg(target_os = "illumos")] + pub uc_brand_data: [*mut c_void; 3], + #[cfg(target_os = "illumos")] + pub uc_xsave: c_long, + #[cfg(target_os = "illumos")] + pub uc_filler: c_long, + #[cfg(target_os = "solaris")] + pub uc_xrs: solaris::xrs_t, + #[cfg(target_os = "solaris")] + pub uc_lwpid: c_uint, + #[cfg(target_os = "solaris")] + pub uc_filler: [c_long; 2], + } +} + +s_no_extra_traits! { + pub union __c_anonymous_fp_reg_set { + pub fpchip_state: __c_anonymous_fpchip_state, + pub f_fpregs: [[u32; 13]; 10], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + 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) + } + } + } + impl Eq for __c_anonymous_fp_reg_set {} + impl hash::Hash for __c_anonymous_fp_reg_set { + fn hash(&self, state: &mut H) { + unsafe { + self.f_fpregs.hash(state); + } + } + } + } +} + +// 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..e72a22a --- /dev/null +++ b/vendor/libc/src/unix/solarish/x86_common.rs @@ -0,0 +1,69 @@ +// 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; +cfg_if! { + if #[cfg(target_os = "illumos")] { + 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..376783c --- /dev/null +++ b/vendor/libc/src/vxworks/aarch64.rs @@ -0,0 +1 @@ +pub type wchar_t = u32; diff --git a/vendor/libc/src/vxworks/arm.rs b/vendor/libc/src/vxworks/arm.rs new file mode 100644 index 0000000..376783c --- /dev/null +++ b/vendor/libc/src/vxworks/arm.rs @@ -0,0 +1 @@ +pub type wchar_t = u32; diff --git a/vendor/libc/src/vxworks/mod.rs b/vendor/libc/src/vxworks/mod.rs new file mode 100644 index 0000000..27e0c12 --- /dev/null +++ b/vendor/libc/src/vxworks/mod.rs @@ -0,0 +1,2491 @@ +//! Interface to VxWorks C library + +use crate::prelude::*; + +extern_ty! { + pub type DIR; +} + +// Deprecated impls: see #5296 +unsafe impl Send for DIR {} +unsafe impl Sync for DIR {} + +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 = crate::uintptr_t; +pub type ssize_t = intptr_t; +pub type speed_t = c_uint; +pub type tcflag_t = c_uint; +pub type clock_t = c_long; +pub type cc_t = c_uchar; + +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_longlong; + +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 = crate::stat; + +pub type pthread_key_t = c_ulong; + +// From b_off_t.h +pub type off_t = c_longlong; + +#[deprecated( + since = "0.2.187", + note = "Kernel mode definitions are unsupported. Use `off_t` instead." +)] +pub type off64_t = c_longlong; + +// From b_BOOL.h +pub type BOOL = c_int; + +// From vxWind.h .. +pub type _Vx_OBJ_HANDLE = c_int; +pub type _Vx_TASK_ID = crate::_Vx_OBJ_HANDLE; +pub type _Vx_MSG_Q_ID = crate::_Vx_OBJ_HANDLE; +pub type _Vx_SEM_ID_KERNEL = crate::_Vx_OBJ_HANDLE; +pub type _Vx_RTP_ID = crate::_Vx_OBJ_HANDLE; +pub type _Vx_SD_ID = crate::_Vx_OBJ_HANDLE; +pub type _Vx_CONDVAR_ID = crate::_Vx_OBJ_HANDLE; +pub type _Vx_SEM_ID = *mut crate::_Vx_semaphore; +pub type OBJ_HANDLE = crate::_Vx_OBJ_HANDLE; +pub type TASK_ID = crate::OBJ_HANDLE; +pub type MSG_Q_ID = crate::OBJ_HANDLE; +pub type SEM_ID_KERNEL = crate::OBJ_HANDLE; +pub type RTP_ID = crate::OBJ_HANDLE; +pub type SD_ID = crate::OBJ_HANDLE; +pub type CONDVAR_ID = crate::OBJ_HANDLE; +pub type STATUS = crate::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; + +extern_ty! { + pub type _Vx_semaphore; +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut c_void { + self.si_addr + } + + pub unsafe fn si_value(&self) -> crate::sigval { + self.si_value + } + + pub unsafe fn si_pid(&self) -> crate::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> crate::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: crate::clockid_t, + } + + // b_pthread_cond_t.h + pub struct pthread_cond_t { + pub condSemId: crate::_Vx_SEM_ID, + pub condValid: c_int, + pub condInitted: c_int, + pub condRefCount: c_int, + pub condMutex: *mut crate::pthread_mutex_t, + pub condAttr: crate::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: crate::_Vx_SEM_ID, + pub rwlockReadersRefCount: c_uint, + pub rwlockValid: c_int, + pub rwlockInitted: c_int, + pub rwlockAttr: crate::pthread_rwlockattr_t, + pub rwlockSemName: [c_char; _PTHREAD_SHARED_SEM_NAME_MAX], + } + + // b_struct_timeval.h + #[derive(Default)] + pub struct timeval { + pub tv_sec: crate::time_t, + pub tv_usec: crate::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: crate::rlim_t, + pub rlim_max: crate::rlim_t, + } + + // stat.h + pub struct stat { + pub st_dev: crate::dev_t, + pub st_ino: crate::ino_t, + pub st_mode: mode_t, + pub st_nlink: crate::nlink_t, + pub st_uid: crate::uid_t, + pub st_gid: crate::gid_t, + pub st_rdev: crate::dev_t, + pub st_size: off_t, + #[cfg(not(vxworks_lt_25_09))] + pub st_atim: timespec, + #[cfg(vxworks_lt_25_09)] + pub st_atime: crate::time_t, + #[cfg(not(vxworks_lt_25_09))] + pub st_mtim: timespec, + #[cfg(vxworks_lt_25_09)] + pub st_mtime: crate::time_t, + #[cfg(not(vxworks_lt_25_09))] + pub st_ctim: timespec, + #[cfg(vxworks_lt_25_09)] + pub st_ctime: crate::time_t, + pub st_blksize: crate::blksize_t, + pub st_blocks: crate::blkcnt_t, + pub st_attrib: c_uchar, + st_reserved1: Padding, + st_reserved2: Padding, + st_reserved3: Padding, + st_reserved4: Padding, + } + + pub struct fsid_t { + val: [c_long; 2], + } + + pub struct statfs { + pub f_type: c_long, + pub f_bsize: 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: crate::fsid_t, + f_spare: Padding<[c_long; 7]>, + } + + //b_struct__Timespec.h + pub struct _Timespec { + pub tv_sec: crate::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: crate::timespec, /* replenishment period */ + pub sched_ss_init_budget: crate::timespec, /* initial budget */ + pub sched_ss_max_repl: c_int, /* max pending replenishment */ + } + + // 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: crate::_Timespec, /* replenishment period */ + pub sched_ss_init_budget: crate::_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: crate::_Sched_param, + } + + // signal.h + + pub struct sigaction { + #[cfg(vxworks_lt_25_09)] + pub sa_u: crate::sa_u_t, + #[cfg(not(vxworks_lt_25_09))] + pub sa_sigaction: crate::sighandler_t, + pub sa_mask: crate::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: crate::sigval, + pub si_errno: c_int, + pub si_status: c_int, + pub si_addr: *mut c_void, + pub si_uid: crate::uid_t, + pub si_pid: crate::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: crate::_Vx_SEM_ID, /*_Vx_SEM_ID ..*/ + pub mutexValid: c_int, + pub mutexInitted: c_int, + pub mutexCondRefCount: c_int, + pub mutexSavPriority: c_int, + pub mutexAttr: crate::pthread_mutexattr_t, + pub mutexSemName: [c_char; _PTHREAD_SHARED_SEM_NAME_MAX], + } + + // b_struct_timespec.h + #[derive(Default)] + pub struct timespec { + pub tv_sec: crate::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, + } + + // sys/times.h + pub struct tms { + pub tms_utime: crate::clock_t, + pub tms_stime: crate::clock_t, + pub tms_cutime: crate::clock_t, + pub tms_cstime: crate::clock_t, + } + + // utime.h + pub struct utimbuf { + pub actime: time_t, + pub modtime: time_t, + } + + // 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 crate::sockaddr, + pub ai_next: *mut crate::addrinfo, + } + + // netdb.h + 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, + } + + // netdb.h + pub struct protoent { + pub p_name: *mut c_char, + pub p_aliases: *mut *mut c_char, + pub p_proto: c_int, + } + + // netdb.h + 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, + } + + // in.h + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: u8, + pub sin_port: u16, + pub sin_addr: crate::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: crate::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, + } + + pub struct flock { + pub l_type: c_short, + pub l_whence: c_short, + pub l_start: c_longlong, + pub l_len: c_longlong, + pub l_pid: c_long, + } + + 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 termios { + pub c_iflag: crate::tcflag_t, + pub c_oflag: crate::tcflag_t, + pub c_cflag: crate::tcflag_t, + pub c_lflag: crate::tcflag_t, + pub c_cc: [crate::cc_t; crate::NCCS], + pub c_ispeed: crate::speed_t, + pub c_ospeed: crate::speed_t, + } + + pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + pub ru_maxrss: c_long, + pub ru_ixrss: c_long, + pub ru_idrss: c_long, + pub ru_isrss: c_long, + pub ru_minflt: c_long, + pub ru_majflt: c_long, + pub ru_nswap: c_long, + pub ru_inblock: c_long, + pub ru_oublock: c_long, + pub ru_msgsnd: c_long, + pub ru_msgrcv: c_long, + pub ru_nsignals: c_long, + pub ru_nvcsw: c_long, + pub ru_nivcsw: c_long, + } + + 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 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_frac_digits: 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, + } + + // grp.h + pub struct group { + pub gr_name: *mut c_char, + pub gr_passwd: *mut c_char, + pub gr_gid: c_int, + pub gr_mem: *mut *mut c_char, + } + + pub struct utsname { + pub sysname: [c_char; 80], + pub nodename: [c_char; 256], + pub release: [c_char; 80], + pub version: [c_char; 256], + pub machine: [c_char; 256], + pub endian: [c_char; 80], + pub kernelversion: [c_char; 80], + pub releaseversion: [c_char; 80], + pub processor: [c_char; 80], + pub bsprevision: [c_char; 80], + pub builddate: [c_char; 80], + } +} + +s_no_extra_traits! { + // dirent.h + pub struct dirent { + pub d_ino: crate::ino_t, + pub d_name: [c_char; _PARM_NAME_MAX as usize + 1], + pub d_type: c_uchar, + } + + 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: crate::TASK_ID, + pub parentId: crate::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: crate::sa_family_t, + __ss_pad1: Padding<[c_char; _SS_PAD1SIZE]>, + __ss_align: i32, + __ss_pad2: Padding<[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 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 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 hash::Hash for sigval { + fn hash(&self, state: &mut H) { + unsafe { (self.sival_ptr as usize).hash(state) }; + } + } + } +} + +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; + +pub const INT_MAX: c_int = 0x7fffffff; +pub const INT_MIN: c_int = -INT_MAX - 1; + +// FIXME(vxworks): 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 = ptr::null_mut(); + +//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 = u32_cast_int(0xF70990EF); +pub const PTHREAD_DESTROYED_OBJ: c_int = -1; +pub const PTHREAD_VALID_OBJ: c_int = u32_cast_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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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 ENFILE: c_int = 23; +pub const EMFILE: c_int = 24; +pub const ENOTTY: c_int = 25; +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 ENOLCK: c_int = 34; +pub const ENOTSUP: c_int = 35; +pub const EMSGSIZE: c_int = 36; +pub const EDOM: c_int = 37; +pub const ERANGE: c_int = 38; +pub const EDOOM: c_int = 39; +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 ENOTBLK: c_int = 66; +pub const EHOSTDOWN: c_int = 67; +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 ECANCELED: c_int = 72; +pub const ENOSR: c_int = 74; +pub const ENOSTR: c_int = 75; +pub const EPROTO: c_int = 76; +pub const EBADMSG: c_int = 77; +pub const ENODATA: c_int = 78; +pub const ETIME: c_int = 79; +pub const ENOMSG: c_int = 80; +pub const EFPOS: c_int = 81; +pub const EILSEQ: c_int = 82; +pub const EDQUOT: c_int = 83; +pub const EIDRM: c_int = 84; +pub const EOVERFLOW: c_int = 85; +pub const EMULTIHOP: c_int = 86; +pub const ENOLINK: c_int = 87; +pub const ESTALE: c_int = 88; +pub const EOWNERDEAD: c_int = 89; +pub const ENOTRECOVERABLE: c_int = 90; + +// 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 + 0x006D; + +// FIXME(vxworks): could also be useful for TASK_DESC type +pub const VX_TASK_NAME_LENGTH: c_int = 31; +pub const VX_TASK_RENAME_LENGTH: c_int = 16; + +pub const TCIFLUSH: c_int = 0; + +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 VMIN: usize = 16; +pub const VTIME: usize = 17; + +// 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; + +// netinet/in.h +pub const IPPROTO_IP: c_int = 0; +pub const IPPROTO_ICMP: c_int = 1; +pub const IPPROTO_TCP: c_int = 6; +pub const IPPROTO_IPV6: c_int = 41; +pub const IPPROTO_ICMPV6: c_int = 58; + +pub const INADDR_ANY: in_addr_t = 0; +pub const INADDR_LOOPBACK: in_addr_t = 2130706433; +pub const INADDR_BROADCAST: in_addr_t = 4294967295; +pub const INADDR_NONE: in_addr_t = 4294967295; + +// netinet6/in6.h +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], +}; + +// udp.h +pub const IPPROTO_UDP: c_int = 17; + +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; + +// netdb.h +pub const NI_MAXHOST: c_int = 1025; + +// 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 = 0o17_0000; +pub const S_IFIFO: c_int = 0o1_0000; +pub const S_IFCHR: c_int = 0o2_0000; +pub const S_IFDIR: c_int = 0o4_0000; +pub const S_IFBLK: c_int = 0o6_0000; +pub const S_IFREG: c_int = 0o10_0000; +pub const S_IFLNK: c_int = 0o12_0000; +pub const S_IFSHM: c_int = 0o13_0000; +pub const S_IFSOCK: c_int = 0o14_0000; +pub const S_ISUID: c_int = 0o4000; +pub const S_ISGID: c_int = 0o2000; +pub const S_ISTXT: c_int = 0o1000; +pub const S_ISVTX: c_int = 0o1000; +pub const S_IRUSR: c_int = 0o0400; +pub const S_IWUSR: c_int = 0o0200; +pub const S_IXUSR: c_int = 0o0100; +pub const S_IRWXU: c_int = 0o0700; +pub const S_IRGRP: c_int = 0o0040; +pub const S_IWGRP: c_int = 0o0020; +pub const S_IXGRP: c_int = 0o0010; +pub const S_IRWXG: c_int = 0o0070; +pub const S_IROTH: c_int = 0o0004; +pub const S_IWOTH: c_int = 0o0002; +pub const S_IXOTH: c_int = 0o0001; +pub const S_IRWXO: c_int = 0o0007; + +pub const UTIME_OMIT: c_long = 0x3ffffffe; +pub const UTIME_NOW: c_long = 0x3fffffff; + +// 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::() - size_of::(); +pub const _SS_PAD2SIZE: usize = _SS_MAXSIZE + - size_of::() + - size_of::() + - _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 PF_LOCAL: c_int = AF_LOCAL; +pub const PF_UNIX: c_int = PF_LOCAL; +pub const PF_UNSPEC: c_int = AF_UNSPEC; +pub const AF_UNIX: c_int = AF_LOCAL; +pub const AF_INET: c_int = 2; +pub const PF_INET: c_int = AF_INET; +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 PF_INET6: c_int = AF_INET6; +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; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const AF_MAX: c_int = 39; + +// termios.h +pub const B0: crate::speed_t = 0; +pub const B50: crate::speed_t = 50; +pub const B75: crate::speed_t = 75; +pub const B110: crate::speed_t = 110; +pub const B134: crate::speed_t = 134; +pub const B150: crate::speed_t = 150; +pub const B200: crate::speed_t = 200; +pub const B300: crate::speed_t = 300; +pub const B600: crate::speed_t = 600; +pub const B1200: crate::speed_t = 1200; +pub const B1800: crate::speed_t = 1800; +pub const B2400: crate::speed_t = 2400; +pub const B4800: crate::speed_t = 4800; +pub const B9600: crate::speed_t = 9600; +pub const B19200: crate::speed_t = 19200; +pub const B38400: crate::speed_t = 38400; +pub const B57600: crate::speed_t = 57600; +pub const B115200: crate::speed_t = 115200; +pub const B230400: crate::speed_t = 230400; + +pub const IGNBRK: crate::tcflag_t = 0x00000001; +pub const BRKINT: crate::tcflag_t = 0x00000002; +pub const IGNCR: crate::tcflag_t = 0x00000200; +pub const IGNPAR: crate::tcflag_t = 0x00000000; +pub const INPCK: crate::tcflag_t = 0x00000020; +pub const ISTRIP: crate::tcflag_t = 0x00000040; +pub const INLCR: crate::tcflag_t = 0x00000100; +pub const ISIG: crate::tcflag_t = 0x00000001; +pub const IXOFF: crate::tcflag_t = 0x00010000; +pub const IXON: crate::tcflag_t = 0x00002000; +pub const PARMRK: crate::tcflag_t = 0x00000000; +pub const NOFLSH: crate::tcflag_t = 0x00000000; +pub const NCCS: usize = 20; + +pub const OPOST: crate::tcflag_t = 0x00000001; +pub const ONLCR: crate::tcflag_t = 0x00000004; +pub const ECHO: crate::tcflag_t = 0x00000010; +pub const OCRNL: crate::tcflag_t = 0x00000010; +pub const ECHOE: crate::tcflag_t = 0x00000020; +pub const ECHOK: crate::tcflag_t = 0x00000040; +pub const ECHONL: crate::tcflag_t = 0x00000100; + +// net/if.h +pub const IFNAMSIZ: size_t = 16; +pub const IF_NAMESIZE: size_t = IFNAMSIZ; + +// sioLibCommon.h +pub const CLOCAL: crate::tcflag_t = 0x1; +pub const CREAD: crate::tcflag_t = 0x2; +pub const CS5: crate::tcflag_t = 0x0; +pub const CS6: crate::tcflag_t = 0x4; +pub const CS7: crate::tcflag_t = 0x8; +pub const CS8: crate::tcflag_t = 0xc; +pub const CSTOPB: crate::tcflag_t = 0x20; +pub const CSIZE: crate::tcflag_t = 0xc; + +pub const PARODD: crate::tcflag_t = 0x80; +pub const PARENB: crate::tcflag_t = 0x40; + +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 FNM_NOMATCH: c_int = 1; +pub const FNM_NOESCAPE: c_int = 1; +pub const FNM_PATHNAME: c_int = 2; +pub const FNM_PERIOD: c_int = 4; +pub const FNM_CASEFOLD: c_int = 16; + +pub const F_OK: c_int = 0; +pub const X_OK: c_int = 1; +pub const W_OK: c_int = 2; + +pub const _PC_CHOWN_RESTRICTED: c_int = 4; +pub const _PC_LINK_MAX: c_int = 6; +pub const _PC_MAX_CANON: c_int = 7; +pub const _PC_MAX_INPUT: c_int = 8; +pub const _PC_NAME_MAX: c_int = 9; +pub const _PC_NO_TRUNC: c_int = 10; +pub const _PC_PATH_MAX: c_int = 11; +pub const _PC_PIPE_BUF: c_int = 12; +pub const _PC_VDISABLE: c_int = 20; + +pub const HUPCL: crate::tcflag_t = 0x10; + +pub const SHUT_RD: c_int = 0; +pub const SHUT_WR: c_int = 1; +pub const SHUT_RDWR: c_int = 2; + +pub const ICANON: crate::tcflag_t = 0x00000002; +pub const ICRNL: crate::tcflag_t = 0x00000400; +pub const IEXTEN: crate::tcflag_t = 0x00000000; + +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; + +pub const TCSANOW: c_int = 0; +pub const TCSADRAIN: c_int = 1; +pub const TCSAFLUSH: c_int = 2; + +// 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 = u32_cast_int(0x90040010); + +// limits.h +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +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; +pub const F_RDLCK: c_int = 1; +pub const F_WRLCK: c_int = 2; +pub const F_UNLCK: c_int = 3; + +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 << 3; +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 = 0x7; +pub const LOG_FACMASK: c_int = 0x3f8; + +// dlfcn.h +pub const RTLD_LOCAL: c_int = 0; +pub const RTLD_LAZY: c_int = 1; +pub const RTLD_NOW: c_int = 2; +pub const RTLD_GLOBAL: c_int = 256; + +// 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 SIGUSR1: c_int = 30; +pub const SIGUSR2: c_int = 31; +pub const SIGPOLL: c_int = 32; +pub const SIGPROF: c_int = 33; +pub const SIGSYS: c_int = 34; +pub const SIGURG: c_int = 35; +pub const SIGVTALRM: c_int = 36; +pub const SIGXCPU: c_int = 37; +pub const SIGXFSZ: c_int = 38; +pub const SIGRTMIN: c_int = 48; + +pub const SIGIO: c_int = SIGRTMIN; +pub const SIGWINCH: c_int = SIGRTMIN + 5; +pub const SIGLOST: c_int = SIGRTMIN + 6; + +pub const SIG_BLOCK: c_int = 1; +pub const SIG_UNBLOCK: c_int = 2; +pub const SIG_SETMASK: c_int = 3; + +pub const SA_NOCLDSTOP: c_int = 0x0001; +pub const SA_SIGINFO: c_int = 0x0002; +pub const SA_ONSTACK: c_int = 0x0004; +pub const SA_INTERRUPT: c_int = 0x0008; +pub const SA_RESETHAND: c_int = 0x0010; +pub const SA_RESTART: c_int = 0x0020; +pub const SA_NODEFER: c_int = 0x0040; +pub const SA_NOCLDWAIT: c_int = 0x0080; + +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; + +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; + +// vxParams.h definitions +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const _PARM_NAME_MAX: c_int = 255; + +/// Constants may change across releases. See the [usage guidelines](crate#usage-guidelines) +/// for details. +pub const _PARM_PATH_MAX: c_int = 1024; + +// WAIT STUFF +pub const WNOHANG: c_int = 0x01; +pub const WUNTRACED: c_int = 0x02; +pub const WCONTINUED: c_int = 0x04; + +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: ptr::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: u32_cast_int(0xf70990ef), + condAttrPshared: 1, + condAttrClockId: CLOCK_REALTIME, +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + condSemId: ptr::null_mut(), + condValid: PTHREAD_VALID_OBJ, + condInitted: PTHREAD_UNUSED_YET_OBJ, + condRefCount: 0, + condMutex: ptr::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: ptr::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: crate::RTP_ID = -1; + +// h/public/unistd.h +// h/public/unistd.h +pub const R_OK: c_int = 4; +pub const _SC_ARG_MAX: c_int = 4; // Via unistd.h +pub const _SC_CHILD_MAX: c_int = 12; +pub const _SC_CLK_TCK: c_int = 13; +pub const _SC_GETPW_R_SIZE_MAX: c_int = 21; +pub const _SC_HOST_NAME_MAX: c_int = 22; +pub const _SC_NGROUPS_MAX: c_int = 36; +pub const _SC_OPEN_MAX: c_int = 37; +pub const _SC_PAGE_SIZE: c_int = 38; +pub const _SC_PAGESIZE: c_int = 39; +pub const _SC_STREAM_MAX: c_int = 59; +pub const _SC_SYMLOOP_MAX: c_int = 60; +pub const _SC_TTY_NAME_MAX: c_int = 87; +pub const _SC_TZNAME_MAX: c_int = 89; +pub const _SC_VERSION: c_int = 94; +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_SYNC: c_int = 0x2000; +pub const O_ASYNC: c_int = 0x0040; +pub const O_DSYNC: c_int = 0x10000; +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 MS_SYNC: c_int = 0x0001; +pub const MS_ASYNC: c_int = 0x0002; +pub const MS_INVALIDATE: c_int = 0x0004; + +pub const MAP_FAILED: *mut c_void = !0 as *mut c_void; + +// sys/ttycom.h +pub const TIOCGWINSZ: i64 = 0x1740087468; +pub const TIOCSWINSZ: c_int = -0x7ff78b99; + +extern_ty! { + pub type FILE; + pub type fpos_t; // FIXME(vxworks): fill this out with a struct +} + +f! { + pub const unsafe fn CMSG_ALIGN(len: usize) -> usize { + len + size_of::() - 1 & !(size_of::() - 1) + } + + pub unsafe 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(size_of::()); + 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 { + ptr::null_mut() + } + } + + pub unsafe fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize > 0 { + (*mhdr).msg_control.cast() + } else { + ptr::null_mut() + } + } + + pub unsafe fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + (cmsg as *mut c_uchar).offset(CMSG_ALIGN(size_of::()) as isize) + } + + pub const unsafe fn CMSG_SPACE(length: c_uint) -> c_uint { + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(size_of::())) as c_uint + } + + pub const unsafe fn CMSG_LEN(length: c_uint) -> c_uint { + CMSG_ALIGN(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 cfgetospeed(termios: *const crate::termios) -> crate::speed_t; + pub fn cfmakeraw(termios: *mut crate::termios) -> c_int; + pub fn cfsetispeed(termios: *mut crate::termios, speed: crate::speed_t) -> c_int; + pub fn cfsetospeed(termios: *mut crate::termios, speed: crate::speed_t) -> c_int; + 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 strnlen(cs: *const c_char, n: 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 memccpy(dest: *mut c_void, src: *const c_void, c: c_int, 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 aligned_alloc(alignment: size_t, size: size_t) -> *mut c_void; + pub fn uname(buf: *mut crate::utsname) -> c_int; + pub fn times(buf: *mut crate::tms) -> crate::clock_t; + pub fn tcflush(fd: c_int, action: c_int) -> c_int; + pub fn pclose(stream: *mut crate::FILE) -> c_int; + pub fn mkdtemp(template: *mut c_char) -> *mut c_char; + + 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 unlinkat(dirfd: c_int, pathname: *const c_char, flags: c_int) -> c_int; + + // netdb.h + pub fn getprotobyname(name: *const c_char) -> *mut protoent; + pub fn getprotobynumber(proto: c_int) -> *mut protoent; + pub fn getservbyname(name: *const c_char, proto: *const c_char) -> *mut servent; + + pub fn fchownat( + dirfd: c_int, + pathname: *const c_char, + owner: crate::uid_t, + group: crate::gid_t, + flags: c_int, + ) -> c_int; +} + +extern "C" { + pub fn fprintf(stream: *mut crate::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 crate::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 crate::FILE; + pub fn fileno(stream: *mut crate::FILE) -> c_int; + pub fn creat(path: *const c_char, mode: mode_t) -> c_int; + pub fn rewinddir(dirp: *mut crate::DIR); + pub fn fchown(fd: c_int, owner: crate::uid_t, group: crate::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 statfs(path: *const c_char, buf: *mut statfs) -> 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 munlock(addr: *const c_void, len: size_t) -> 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 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 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 crate::timeval, tz: *mut c_void) -> c_int; + pub fn pthread_exit(value: *mut c_void) -> !; + pub fn pthread_attr_setdetachstate(attr: *mut crate::pthread_attr_t, state: c_int) -> c_int; + pub fn pthread_equal(t1: crate::pthread_t, t2: crate::pthread_t) -> 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 crate::timeval) -> c_int; + + pub fn futimens(fd: c_int, times: *const crate::timespec) -> c_int; + + pub fn utimensat( + dirfd: c_int, + path: *const c_char, + times: *const crate::timespec, + flag: c_int, + ) -> 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: crate::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 localeconv() -> *mut lconv; + + 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 crate::FILE, offset: off_t, whence: c_int) -> c_int; + pub fn ftello(stream: *mut crate::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; + pub fn tcsetattr(fd: c_int, optional_actions: c_int, termios: *const crate::termios) -> c_int; + pub fn tcgetattr(fd: c_int, termios: *mut crate::termios) -> c_int; + pub fn tcsendbreak(fd: c_int, duration: c_int) -> c_int; + pub fn confstr(name: c_int, buf: *mut c_char, len: size_t) -> size_t; + pub fn fnmatch(pattern: *const c_char, name: *const c_char, flags: c_int) -> c_int; + + pub fn symlinkat(target: *const c_char, newdirfd: c_int, linkpath: *const c_char) -> c_int; + + // sys/stat.h + pub fn fchmodat(dirfd: c_int, pathname: *const c_char, mode: mode_t, flags: c_int) -> c_int; + + // utime.h + pub fn utime(file: *const c_char, buf: *const utimbuf) -> c_int; +} + +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 crate::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 crate::pthread_attr_t, name: *mut c_char) -> c_int; + + // pthread.h + pub fn pthread_attr_setstacksize(attr: *mut crate::pthread_attr_t, stacksize: size_t) -> c_int; + + // pthread.h + pub fn pthread_attr_getstacksize( + attr: *const crate::pthread_attr_t, + size: *mut size_t, + ) -> c_int; + + // pthread.h + pub fn pthread_attr_init(attr: *mut crate::pthread_attr_t) -> c_int; + + // pthread.h + pub fn pthread_create( + pThread: *mut crate::pthread_t, + pAttr: *const crate::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: crate::pthread_t, + policy: c_int, + param: *const crate::sched_param, + ) -> c_int; + + //pthread.h + pub fn pthread_getschedparam( + native: crate::pthread_t, + policy: *mut c_int, + param: *mut crate::sched_param, + ) -> c_int; + + //pthread.h + pub fn pthread_attr_setinheritsched( + attr: *mut crate::pthread_attr_t, + inheritsched: c_int, + ) -> c_int; + + //pthread.h + pub fn pthread_attr_setschedpolicy(attr: *mut crate::pthread_attr_t, policy: c_int) -> c_int; + + // pthread.h + pub fn pthread_attr_destroy(thread: *mut crate::pthread_attr_t) -> c_int; + + // pthread.h + pub fn pthread_detach(thread: crate::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; + + // sys/statfs.h + pub fn fstatfs(fd: c_int, buf: *mut statfs) -> 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 crate::DIR, + entry: *mut crate::dirent, + result: *mut *mut crate::dirent, + ) -> c_int; + + // dirent.h + pub fn readdir(pDir: *mut crate::DIR) -> *mut crate::dirent; + + // dirent.h + pub fn fdopendir(fd: c_int) -> *mut crate::DIR; + + // dirent.h + pub fn dirfd(dirp: *mut crate::DIR) -> c_int; + + // fcntl.h or + // ioLib.h + pub fn open(path: *const c_char, oflag: c_int, ...) -> c_int; + + // fcntl.h + pub fn openat(dirfd: c_int, pathname: *const c_char, flags: 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 crate::pthread_condattr_t) -> c_int; + + // pthread.h + pub fn pthread_condattr_destroy(attr: *mut crate::pthread_condattr_t) -> c_int; + + // pthread.h + pub fn pthread_condattr_getclock( + pAttr: *const crate::pthread_condattr_t, + pClockId: *mut crate::clockid_t, + ) -> c_int; + + // pthread.h + pub fn pthread_condattr_setclock( + pAttr: *mut crate::pthread_condattr_t, + clockId: crate::clockid_t, + ) -> c_int; + + // pthread.h + pub fn pthread_cond_init( + cond: *mut crate::pthread_cond_t, + attr: *const crate::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 crate::pthread_cond_t) -> c_int; + + // pthread.h + pub fn pthread_cond_broadcast(cond: *mut crate::pthread_cond_t) -> c_int; + + // pthread.h + pub fn pthread_cond_wait( + cond: *mut crate::pthread_cond_t, + mutex: *mut crate::pthread_mutex_t, + ) -> c_int; + + // pthread.h + pub fn pthread_rwlockattr_init(attr: *mut crate::pthread_rwlockattr_t) -> c_int; + + // pthread.h + pub fn pthread_rwlockattr_destroy(attr: *mut crate::pthread_rwlockattr_t) -> c_int; + + // pthread.h + pub fn pthread_rwlockattr_setmaxreaders( + attr: *mut crate::pthread_rwlockattr_t, + attr2: c_uint, + ) -> c_int; + + // pthread.h + pub fn pthread_rwlock_init( + attr: *mut crate::pthread_rwlock_t, + host: *const crate::pthread_rwlockattr_t, + ) -> c_int; + + // pthread.h + pub fn pthread_rwlock_destroy(attr: *mut crate::pthread_rwlock_t) -> c_int; + + // pthread.h + pub fn pthread_rwlock_rdlock(attr: *mut crate::pthread_rwlock_t) -> c_int; + + // pthread.h + pub fn pthread_rwlock_tryrdlock(attr: *mut crate::pthread_rwlock_t) -> c_int; + + // pthread.h + pub fn pthread_rwlock_timedrdlock( + attr: *mut crate::pthread_rwlock_t, + host: *const crate::timespec, + ) -> c_int; + + // pthread.h + pub fn pthread_rwlock_wrlock(attr: *mut crate::pthread_rwlock_t) -> c_int; + + // pthread.h + pub fn pthread_rwlock_trywrlock(attr: *mut crate::pthread_rwlock_t) -> c_int; + + // pthread.h + pub fn pthread_rwlock_timedwrlock( + attr: *mut crate::pthread_rwlock_t, + host: *const crate::timespec, + ) -> c_int; + + // pthread.h + pub fn pthread_rwlock_unlock(attr: *mut crate::pthread_rwlock_t) -> c_int; + + // pthread.h + pub fn pthread_key_create( + key: *mut crate::pthread_key_t, + dtor: Option, + ) -> c_int; + + // pthread.h + pub fn pthread_key_delete(key: crate::pthread_key_t) -> c_int; + + // pthread.h + pub fn pthread_setspecific(key: crate::pthread_key_t, value: *const c_void) -> c_int; + + // pthread.h + pub fn pthread_getspecific(key: crate::pthread_key_t) -> *mut c_void; + + // pthread.h + pub fn pthread_cond_timedwait( + cond: *mut crate::pthread_cond_t, + mutex: *mut crate::pthread_mutex_t, + abstime: *const crate::timespec, + ) -> c_int; + + // pthread.h + pub fn pthread_attr_getname(attr: *mut crate::pthread_attr_t, name: *mut *mut c_char) -> c_int; + + // pthread.h + pub fn pthread_join(thread: crate::pthread_t, status: *mut *mut c_void) -> c_int; + + // pthread.h + pub fn pthread_self() -> crate::pthread_t; + + // clockLib.h + pub fn clock_gettime(clock_id: crate::clockid_t, tp: *mut crate::timespec) -> c_int; + + // clockLib.h + pub fn clock_settime(clock_id: crate::clockid_t, tp: *const crate::timespec) -> c_int; + + // clockLib.h + pub fn clock_getres(clock_id: crate::clockid_t, res: *mut crate::timespec) -> c_int; + + // clockLib.h + pub fn clock_nanosleep( + clock_id: crate::clockid_t, + flags: c_int, + rqtp: *const crate::timespec, + rmtp: *mut crate::timespec, + ) -> c_int; + + // timerLib.h + pub fn nanosleep(rqtp: *const crate::timespec, rmtp: *mut crate::timespec) -> c_int; + + // socket.h + pub fn accept(s: c_int, addr: *mut crate::sockaddr, addrlen: *mut crate::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 crate::sockaddr, namelen: crate::socklen_t) -> c_int; + + // socket.h + pub fn getpeername( + s: c_int, + name: *mut crate::sockaddr, + namelen: *mut crate::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 crate::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 crate::sockaddr, + pFromLen: *mut crate::socklen_t, + ) -> ssize_t; + + pub fn recvmsg(socket: c_int, mp: *mut crate::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 crate::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; + + // unistd.h + pub fn setpgid(pid: pid_t, pgid: pid_t) -> pid_t; + + // wait.h + pub fn waitpid(pid: pid_t, status: *mut c_int, options: 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 crate::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; + + // unistd.h + pub fn fdatasync(fd: c_int) -> c_int; + + // dirent.h + pub fn closedir(ptr: *mut crate::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: crate::pid_t, param: *const crate::sched_param) -> c_int; + + //sched.h + pub fn sched_getparam(pid: crate::pid_t, param: *mut crate::sched_param) -> c_int; + + //sched.h + pub fn sched_setscheduler( + pid: crate::pid_t, + policy: c_int, + param: *const crate::sched_param, + ) -> c_int; + + //sched.h + pub fn sched_getscheduler(pid: crate::pid_t) -> c_int; + + //sched.h + pub fn sched_rr_get_interval(pid: crate::pid_t, tp: *mut crate::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: crate::gid_t) -> c_int; + + // unistd.h + pub fn getgid() -> crate::gid_t; + + // unistd.h + pub fn setuid(uid: crate::uid_t) -> c_int; + + // unistd.h + pub fn getuid() -> crate::uid_t; + + // signal.h + pub fn sigemptyset(__set: *mut sigset_t) -> 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; + + // 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: crate::sigval) -> c_int; + + // signal.h for user + pub fn _sigqueue( + rtpId: crate::RTP_ID, + signo: c_int, + pValue: *const crate::sigval, + sigCode: c_int, + ) -> c_int; + + // signal.h + pub fn taskKill(taskId: crate::TASK_ID, signo: c_int) -> c_int; + + // signal.h + pub fn raise(__signo: c_int) -> c_int; + + // taskLibCommon.h + pub fn taskIdSelf() -> crate::TASK_ID; + pub fn taskDelay(ticks: crate::_Vx_ticks_t) -> c_int; + + // taskLib.h + pub fn taskNameSet(task_id: crate::TASK_ID, task_name: *mut c_char) -> c_int; + pub fn taskNameGet(task_id: crate::TASK_ID, buf_name: *mut c_char, bufsize: size_t) -> c_int; + + // rtpLibCommon.h + pub fn rtpInfoGet(rtpId: crate::RTP_ID, rtpStruct: *mut crate::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 crate::iovec, iovcnt: c_int) -> ssize_t; + pub fn readv(fd: c_int, iov: *const crate::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, ...) -> crate::mqd_t; + pub fn mq_close(mqd: crate::mqd_t) -> c_int; + pub fn mq_unlink(name: *const c_char) -> c_int; + pub fn mq_receive( + mqd: crate::mqd_t, + msg_ptr: *mut c_char, + msg_len: size_t, + msg_prio: *mut c_uint, + ) -> ssize_t; + pub fn mq_timedreceive( + mqd: crate::mqd_t, + msg_ptr: *mut c_char, + msg_len: size_t, + msg_prio: *mut c_uint, + abs_timeout: *const crate::timespec, + ) -> ssize_t; + pub fn mq_send( + mqd: crate::mqd_t, + msg_ptr: *const c_char, + msg_len: size_t, + msg_prio: c_uint, + ) -> c_int; + pub fn mq_timedsend( + mqd: crate::mqd_t, + msg_ptr: *const c_char, + msg_len: size_t, + msg_prio: c_uint, + abs_timeout: *const crate::timespec, + ) -> c_int; + pub fn mq_getattr(mqd: crate::mqd_t, attr: *mut crate::mq_attr) -> c_int; + pub fn mq_setattr( + mqd: crate::mqd_t, + newattr: *const crate::mq_attr, + oldattr: *mut crate::mq_attr, + ) -> c_int; + + // vxCpuLib.h + pub fn vxCpuEnabledGet() -> crate::cpuset_t; // Get set of running CPU's in the system + pub fn vxCpuConfiguredGet() -> crate::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 safe fn WIFEXITED(status: c_int) -> bool { + (status & 0xFF00) == 0 + } + pub const safe fn WIFSIGNALED(status: c_int) -> bool { + (status & 0xFF00) != 0 + } + pub const safe fn WIFSTOPPED(status: c_int) -> bool { + (status & 0xFF0000) != 0 + } + pub const safe fn WEXITSTATUS(status: c_int) -> c_int { + status & 0xFF + } + pub const safe fn WIFCONTINUED(status: c_int) -> c_int { + (status >> 24) & 0xFF + } + pub const safe fn WTERMSIG(status: c_int) -> c_int { + (status >> 8) & 0xFF + } + pub const safe fn WSTOPSIG(status: c_int) -> c_int { + (status >> 16) & 0xFF + } +} + +pub unsafe 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::() != 0) { + return crate::EINVAL; + } + + unsafe { + // posix_memalign should not set errno + let e = crate::errnoGet(); + + let temp = memalign(align, size); + crate::errnoSet(e as c_int); + + if temp.is_null() { + crate::ENOMEM + } else { + *memptr = temp; + 0 + } + } +} + +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..376783c --- /dev/null +++ b/vendor/libc/src/vxworks/powerpc.rs @@ -0,0 +1 @@ +pub type wchar_t = u32; diff --git a/vendor/libc/src/vxworks/powerpc64.rs b/vendor/libc/src/vxworks/powerpc64.rs new file mode 100644 index 0000000..376783c --- /dev/null +++ b/vendor/libc/src/vxworks/powerpc64.rs @@ -0,0 +1 @@ +pub type wchar_t = u32; diff --git a/vendor/libc/src/vxworks/riscv32.rs b/vendor/libc/src/vxworks/riscv32.rs new file mode 100644 index 0000000..f562626 --- /dev/null +++ b/vendor/libc/src/vxworks/riscv32.rs @@ -0,0 +1 @@ +pub type wchar_t = i32; diff --git a/vendor/libc/src/vxworks/riscv64.rs b/vendor/libc/src/vxworks/riscv64.rs new file mode 100644 index 0000000..f562626 --- /dev/null +++ b/vendor/libc/src/vxworks/riscv64.rs @@ -0,0 +1 @@ +pub type wchar_t = i32; diff --git a/vendor/libc/src/vxworks/x86.rs b/vendor/libc/src/vxworks/x86.rs new file mode 100644 index 0000000..f562626 --- /dev/null +++ b/vendor/libc/src/vxworks/x86.rs @@ -0,0 +1 @@ +pub type wchar_t = i32; diff --git a/vendor/libc/src/vxworks/x86_64.rs b/vendor/libc/src/vxworks/x86_64.rs new file mode 100644 index 0000000..f562626 --- /dev/null +++ b/vendor/libc/src/vxworks/x86_64.rs @@ -0,0 +1 @@ +pub type wchar_t = i32; diff --git a/vendor/libc/src/wasi/mod.rs b/vendor/libc/src/wasi/mod.rs new file mode 100644 index 0000000..9bce096 --- /dev/null +++ b/vendor/libc/src/wasi/mod.rs @@ -0,0 +1,1098 @@ +//! [wasi-libc](https://github.com/WebAssembly/wasi-libc) definitions. +//! +//! `wasi-libc` project provides multiple libraries including emulated features, but we list only +//! basic features with `libc.a` here. + +use core::iter::Iterator; + +use crate::prelude::*; + +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 = c_longlong; +pub type pid_t = i32; +pub type clock_t = c_longlong; +pub type time_t = c_longlong; +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; +pub type locale_t = *mut __locale_struct; +pub type pthread_t = *mut c_void; +pub type pthread_once_t = c_int; +pub type pthread_key_t = c_uint; +pub type pthread_spinlock_t = c_int; + +s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4], + } +} + +extern_ty! { + pub type FILE; + pub type DIR; + pub type __locale_struct; +} + +// Deprecated impls: see #5296 +unsafe impl Send for DIR {} +unsafe impl Sync for DIR {} + +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, + } + + #[derive(Default)] + pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: suseconds_t, + } + + #[derive(Default)] + 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: Padding, + 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: Padding<[c_longlong; 3]>, + } + + pub struct fd_set { + __nfds: usize, + __fds: [c_int; FD_SETSIZE as usize], + } + + pub struct pthread_attr_t { + size: [c_long; 9], + } + + pub struct pthread_mutexattr_t { + __attr: c_uint, + } + + pub struct pthread_condattr_t { + __attr: c_uint, + } + + pub struct pthread_barrierattr_t { + __attr: c_uint, + } + + pub struct pthread_rwlockattr_t { + __attr: [c_uint; 2], + } + + pub struct pthread_cond_t { + size: [*mut c_void; 12], + } + + pub struct pthread_mutex_t { + size: [*mut c_void; 6], + } + + pub struct pthread_rwlock_t { + size: [*mut c_void; 8], + } + + pub struct pthread_barrier_t { + size: [*mut c_void; 5], + } +} + +// 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)] +#[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 = u32_cast_long(0xfffffffe); +pub const UTIME_NOW: c_long = u32_cast_long(0xffffffff); +pub const S_IFIFO: mode_t = 0o1_0000; +pub const S_IFCHR: mode_t = 0o2_0000; +pub const S_IFBLK: mode_t = 0o6_0000; +pub const S_IFDIR: mode_t = 0o4_0000; +pub const S_IFREG: mode_t = 0o10_0000; +pub const S_IFLNK: mode_t = 0o12_0000; +pub const S_IFSOCK: mode_t = 0o14_0000; +pub const S_IFMT: mode_t = 0o17_0000; +pub const S_IRWXO: mode_t = 0o0007; +pub const S_IXOTH: mode_t = 0o0001; +pub const S_IWOTH: mode_t = 0o0002; +pub const S_IROTH: mode_t = 0o0004; +pub const S_IRWXG: mode_t = 0o0070; +pub const S_IXGRP: mode_t = 0o0010; +pub const S_IWGRP: mode_t = 0o0020; +pub const S_IRGRP: mode_t = 0o0040; +pub const S_IRWXU: mode_t = 0o0700; +pub const S_IXUSR: mode_t = 0o0100; +pub const S_IWUSR: mode_t = 0o0200; +pub const S_IRUSR: mode_t = 0o0400; +pub const S_ISVTX: mode_t = 0o1000; +pub const S_ISGID: mode_t = 0o2000; +pub const S_ISUID: mode_t = 0o4000; +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_FIFO: u8 = 6; +pub const DT_LNK: u8 = 7; +pub const DT_SOCK: u8 = 20; +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_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 _SC_MINSIGSTKSZ: c_int = 249; +pub const _SC_SIGSTKSZ: c_int = 250; + +// FIXME(msrv): `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(core::ptr::addr_of!(_CLOCK_MONOTONIC)) }; +#[allow(unused_unsafe)] +pub static CLOCK_REALTIME: clockid_t = unsafe { clockid_t(core::ptr::addr_of!(_CLOCK_REALTIME)) }; + +pub const ABDAY_1: crate::nl_item = 0x20000; +pub const ABDAY_2: crate::nl_item = 0x20001; +pub const ABDAY_3: crate::nl_item = 0x20002; +pub const ABDAY_4: crate::nl_item = 0x20003; +pub const ABDAY_5: crate::nl_item = 0x20004; +pub const ABDAY_6: crate::nl_item = 0x20005; +pub const ABDAY_7: crate::nl_item = 0x20006; + +pub const DAY_1: crate::nl_item = 0x20007; +pub const DAY_2: crate::nl_item = 0x20008; +pub const DAY_3: crate::nl_item = 0x20009; +pub const DAY_4: crate::nl_item = 0x2000A; +pub const DAY_5: crate::nl_item = 0x2000B; +pub const DAY_6: crate::nl_item = 0x2000C; +pub const DAY_7: crate::nl_item = 0x2000D; + +pub const ABMON_1: crate::nl_item = 0x2000E; +pub const ABMON_2: crate::nl_item = 0x2000F; +pub const ABMON_3: crate::nl_item = 0x20010; +pub const ABMON_4: crate::nl_item = 0x20011; +pub const ABMON_5: crate::nl_item = 0x20012; +pub const ABMON_6: crate::nl_item = 0x20013; +pub const ABMON_7: crate::nl_item = 0x20014; +pub const ABMON_8: crate::nl_item = 0x20015; +pub const ABMON_9: crate::nl_item = 0x20016; +pub const ABMON_10: crate::nl_item = 0x20017; +pub const ABMON_11: crate::nl_item = 0x20018; +pub const ABMON_12: crate::nl_item = 0x20019; + +pub const MON_1: crate::nl_item = 0x2001A; +pub const MON_2: crate::nl_item = 0x2001B; +pub const MON_3: crate::nl_item = 0x2001C; +pub const MON_4: crate::nl_item = 0x2001D; +pub const MON_5: crate::nl_item = 0x2001E; +pub const MON_6: crate::nl_item = 0x2001F; +pub const MON_7: crate::nl_item = 0x20020; +pub const MON_8: crate::nl_item = 0x20021; +pub const MON_9: crate::nl_item = 0x20022; +pub const MON_10: crate::nl_item = 0x20023; +pub const MON_11: crate::nl_item = 0x20024; +pub const MON_12: crate::nl_item = 0x20025; + +pub const AM_STR: crate::nl_item = 0x20026; +pub const PM_STR: crate::nl_item = 0x20027; + +pub const D_T_FMT: crate::nl_item = 0x20028; +pub const D_FMT: crate::nl_item = 0x20029; +pub const T_FMT: crate::nl_item = 0x2002A; +pub const T_FMT_AMPM: crate::nl_item = 0x2002B; + +pub const ERA: crate::nl_item = 0x2002C; +pub const ERA_D_FMT: crate::nl_item = 0x2002E; +pub const ALT_DIGITS: crate::nl_item = 0x2002F; +pub const ERA_D_T_FMT: crate::nl_item = 0x20030; +pub const ERA_T_FMT: crate::nl_item = 0x20031; + +pub const CODESET: crate::nl_item = 14; +pub const CRNCYSTR: crate::nl_item = 0x4000F; +pub const RADIXCHAR: crate::nl_item = 0x10000; +pub const THOUSEP: crate::nl_item = 0x10001; +pub const YESEXPR: crate::nl_item = 0x50000; +pub const NOEXPR: crate::nl_item = 0x50001; +pub const YESSTR: crate::nl_item = 0x50002; +pub const NOSTR: crate::nl_item = 0x50003; + +pub const PTHREAD_STACK_MIN: usize = 2048; +pub const TIMER_ABSTIME: c_int = 1; + +f! { + pub unsafe 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 unsafe 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 unsafe 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_REALTIME: 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 crate::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 crate::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 crate::FILE; + pub fn fileno(stream: *mut crate::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 crate::DIR; + pub fn fdopendir(fd: c_int) -> *mut crate::DIR; + pub fn readdir(dirp: *mut crate::DIR) -> *mut crate::dirent; + pub fn closedir(dirp: *mut crate::DIR) -> c_int; + pub fn rewinddir(dirp: *mut crate::DIR); + pub fn dirfd(dirp: *mut crate::DIR) -> c_int; + pub fn seekdir(dirp: *mut crate::DIR, loc: c_long); + pub fn telldir(dirp: *mut crate::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 crate::timeval, tz: *mut c_void) -> c_int; + pub fn times(buf: *mut crate::tms) -> crate::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 crate::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 crate::FILE, offset: off_t, whence: c_int) -> c_int; + pub fn ftello(stream: *mut crate::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 crate::iovec, iovcnt: c_int) -> ssize_t; + pub fn readv(fd: c_int, iov: *const crate::iovec, iovcnt: c_int) -> ssize_t; + pub fn pwritev(fd: c_int, iov: *const crate::iovec, iovcnt: c_int, offset: off_t) -> ssize_t; + pub fn preadv(fd: c_int, iov: *const crate::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 crate::timespec) -> c_int; + pub fn utimensat( + dirfd: c_int, + path: *const c_char, + times: *const crate::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: crate::locale_t) -> crate::locale_t; + pub fn freelocale(loc: crate::locale_t); + pub fn newlocale(mask: c_int, locale: *const c_char, base: crate::locale_t) -> crate::locale_t; + pub fn uselocale(loc: crate::locale_t) -> crate::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: crate::nl_item) -> *mut c_char; + pub fn nl_langinfo_l(item: crate::nl_item, loc: crate::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; + + #[cfg(target_env = "p1")] + 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 crate::timespec, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_nocwd_opendirat(dirfd: c_int, path: *const c_char) -> *mut crate::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 crate::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; + + 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 realpath(pathname: *const c_char, resolved: *mut c_char) -> *mut c_char; + + pub fn pthread_self() -> pthread_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_equal(t1: pthread_t, t2: pthread_t) -> c_int; + pub fn pthread_join(native: pthread_t, value: *mut *mut c_void) -> c_int; + 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 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; +} + +cfg_if! { + if #[cfg(not(target_env = "p1"))] { + 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..7332a77 --- /dev/null +++ b/vendor/libc/src/wasi/p2.rs @@ -0,0 +1,188 @@ +use crate::prelude::*; + +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 struct linger { + pub l_onoff: c_int, + pub l_linger: c_int, + } +} + +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_TYPE: c_int = 3; +pub const SO_ERROR: c_int = 4; +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_LINGER: c_int = 13; +pub const SO_ACCEPTCONN: c_int = 30; +pub const SO_PROTOCOL: c_int = 38; +pub const SO_DOMAIN: c_int = 39; +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 SOCK_NONBLOCK: c_int = 0x00004000; + +pub const SOL_SOCKET: c_int = 0x7fffffff; + +pub const AF_UNSPEC: c_int = 0; +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_UDP: c_int = 17; +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_UNICAST_HOPS: c_int = 16; +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 TCP_KEEPIDLE: c_int = 4; +pub const TCP_KEEPINTVL: c_int = 5; +pub const TCP_KEEPCNT: c_int = 6; + +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 accept4( + socket: c_int, + addr: *mut sockaddr, + addrlen: *mut socklen_t, + flags: c_int, + ) -> 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/mod.rs b/vendor/libc/src/windows/gnu/mod.rs new file mode 100644 index 0000000..6dfa852 --- /dev/null +++ b/vendor/libc/src/windows/gnu/mod.rs @@ -0,0 +1,35 @@ +use crate::prelude::*; + +// The below configuration for machines with 32-bit word size aligns with the +// declaration in the `mingw-w64` headers. +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + s_no_extra_traits! { + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4], + } + } + } else if #[cfg(target_pointer_width = "32")] { + s_no_extra_traits! { + #[repr(align(8))] + pub struct max_align_t { + priv_: [i64; 3], + } + } + } +} + +// 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 crate::wchar_t, c: crate::wchar_t, n: size_t) -> *mut crate::wchar_t; +} diff --git a/vendor/libc/src/windows/mod.rs b/vendor/libc/src/windows/mod.rs new file mode 100644 index 0000000..67e8df3 --- /dev/null +++ b/vendor/libc/src/windows/mod.rs @@ -0,0 +1,643 @@ +//! Windows CRT definitions + +use crate::prelude::*; + +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 wchar_t = u16; + +pub type clock_t = i32; + +pub type errno_t = c_int; + +cfg_if! { + // FIXME(1.0): Windows GNU has 64-bit `time_t` by default. In x86 this is + // wrongly bound. + if #[cfg(all( + target_arch = "x86", + target_env = "gnu", + not(gnu_time_bits64) + ))] { + 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; + +extern_ty! { + pub type timezone; +} + +pub type time64_t = i64; + +pub type SOCKET = crate::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, + } + + #[derive(Default)] + pub struct timeval { + pub tv_sec: c_long, + pub tv_usec: c_long, + } + + #[derive(Default)] + 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 = 0o2_0000; +pub const S_IFDIR: c_int = 0o4_0000; +pub const S_IFREG: c_int = 0o10_0000; +pub const S_IFMT: c_int = 0o17_0000; +pub const S_IEXEC: c_int = 0o0100; +pub const S_IWRITE: c_int = 0o0200; +pub const S_IREAD: c_int = 0o0400; + +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: crate::sighandler_t = 0; +pub const SIG_IGN: crate::sighandler_t = 1; +pub const SIG_GET: crate::sighandler_t = 2; +pub const SIG_SGE: crate::sighandler_t = 3; +pub const SIG_ACK: crate::sighandler_t = 4; + +pub const L_tmpnam: c_uint = 260; +pub const TMP_MAX: c_uint = 0x7fff_ffff; + +// DIFF(main): removed in 458c58f409 +// FIXME(msrv): done by `std` starting in 1.79.0 +// 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" {} + +extern_ty! { + pub type FILE; + pub type fpos_t; // FIXME(windows): fill this out with a struct +} + +// 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; + pub fn snprintf( + buffer: *mut c_char, + count: size_t, + format: *const c_char, + ... + ) -> c_int; + pub fn sprintf(buffer: *mut c_char, format: *const c_char, ...) -> c_int; + + pub fn scanf(format: *const c_char, ...) -> c_int; + pub fn sscanf(buffer: *const c_char, format: *const c_char, ...) -> c_int; + pub fn fscanf(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 qsort( + base: *mut c_void, + num: size_t, + size: size_t, + compar: Option c_int>, + ); + pub fn qsort_s( + base: *mut c_void, + num: size_t, + size: size_t, + compar: Option c_int>, + arg: *mut c_void, + ); + 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 wcsnlen(str: *const wchar_t, numberOfElements: size_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; + + // By default, the following link to 64-bit variants where the expected + // `time_t` is also 64-bits. + // + // Under Windows x86 with GNU, `time_t` is still 32-bit wide on stable, so + // these routines have to link with their 32-bit variants. + cfg_if! { + if #[cfg(all( + target_arch = "x86", + target_env = "gnu", + not(gnu_time_bits64), + ))] { + #[link_name = "_ctime32"] + pub fn ctime(sourceTime: *const time_t) -> *mut c_char; + #[link_name = "_difftime32"] + pub fn difftime(timeEnd: time_t, timeStart: time_t) -> c_double; + #[link_name = "_gmtime32_s"] + pub fn gmtime_s(destTime: *mut tm, srcTime: *const time_t) -> c_int; + #[link_name = "_localtime32_s"] + pub fn localtime_s(tmDest: *mut tm, sourceTime: *const time_t) -> crate::errno_t; + #[link_name = "_time32"] + pub fn time(destTime: *mut time_t) -> time_t; + } else { + pub fn ctime(sourceTime: *const time_t) -> *mut c_char; + pub fn difftime(timeEnd: time_t, timeStart: time_t) -> c_double; + #[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) -> crate::errno_t; + #[link_name = "_time64"] + pub fn time(destTime: *mut time_t) -> time_t; + } + } + + pub fn clock() -> clock_t; + #[link_name = "_get_daylight"] + pub fn get_daylight(hours: *mut c_int) -> errno_t; + #[link_name = "_get_dstbias"] + pub fn get_dstbias(seconds: *mut c_long) -> errno_t; + #[link_name = "_get_timezone"] + pub fn get_timezone(seconds: *mut c_long) -> errno_t; + #[link_name = "_get_tzname"] + pub fn get_tzname( + p_return_value: *mut size_t, + time_zone_name: *mut c_char, + size_in_bytes: size_t, + index: c_int, + ) -> errno_t; + #[link_name = "_tzset"] + pub fn tzset(); + #[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 crate::FILE; + #[link_name = "_pclose"] + pub fn pclose(stream: *mut crate::FILE) -> c_int; + #[link_name = "_fdopen"] + pub fn fdopen(fd: c_int, mode: *const c_char) -> *mut crate::FILE; + #[link_name = "_fileno"] + pub fn fileno(stream: *mut crate::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"] + // DIFF(main): changed to `intptr_t` in e77f551de9 + 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 = "_aligned_realloc"] + pub fn aligned_realloc(memblock: *mut c_void, size: size_t, alignment: size_t) -> *mut c_void; + #[link_name = "_putenv"] + pub fn putenv(envstring: *const c_char) -> c_int; + #[link_name = "_wputenv"] + pub fn wputenv(envstring: *const crate::wchar_t) -> c_int; + #[link_name = "_putenv_s"] + pub fn putenv_s(envstring: *const c_char, value_string: *const c_char) -> crate::errno_t; + #[link_name = "_wputenv_s"] + pub fn wputenv_s( + envstring: *const crate::wchar_t, + value_string: *const crate::wchar_t, + ) -> crate::errno_t; +} + +extern "system" { + pub fn listen(s: SOCKET, backlog: c_int) -> c_int; + pub fn accept(s: SOCKET, addr: *mut crate::sockaddr, addrlen: *mut c_int) -> SOCKET; + pub fn bind(s: SOCKET, name: *const crate::sockaddr, namelen: c_int) -> c_int; + pub fn connect(s: SOCKET, name: *const crate::sockaddr, namelen: c_int) -> c_int; + pub fn getpeername(s: SOCKET, name: *mut crate::sockaddr, nameln: *mut c_int) -> c_int; + pub fn getsockname(s: SOCKET, name: *mut crate::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 crate::sockaddr, + fromlen: *mut c_int, + ) -> c_int; + pub fn sendto( + s: SOCKET, + buf: *const c_char, + len: c_int, + flags: c_int, + to: *const crate::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(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..967df8c --- /dev/null +++ b/vendor/libc/src/windows/msvc/mod.rs @@ -0,0 +1,14 @@ +use crate::prelude::*; + +// 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..2415fd4 --- /dev/null +++ b/vendor/libc/src/xous.rs @@ -0,0 +1,18 @@ +//! Xous C type definitions + +use crate::prelude::*; + +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 wchar_t = u32; + +pub const INT_MIN: c_int = -2147483648; +pub const INT_MAX: c_int = 2147483647; diff --git a/vendor/libc/tests/const_fn.rs b/vendor/libc/tests/const_fn.rs new file mode 100644 index 0000000..d9b41b8 --- /dev/null +++ b/vendor/libc/tests/const_fn.rs @@ -0,0 +1,3 @@ +#[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/limbo_graph/.cargo-checksum.json b/vendor/limbo_graph/.cargo-checksum.json new file mode 100644 index 0000000..a223b17 --- /dev/null +++ b/vendor/limbo_graph/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"67662fc16023bcfb40700b3110af13988115301630e4740bd75e04f32eb8a5b8","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"a9a6d9e60c9c070f260cd41fcfe3c33a7641f98168c6e6489bd1f4f429adca5c","src/error.rs":"6e71305a1d18d3fd264409f565122c73f821351c03f9689280721153d13a4a7c","src/lib.rs":"ba0f1b0002739821c64c1d42d065c0eb69debb768b0e24ab5ab38ff69c271578","src/node.rs":"3e7363b059774c16204ad13752c07afc323019d7f9543da0dd9c4a5fcc64c66e"},"package":null} \ No newline at end of file diff --git a/vendor/limbo_graph/Cargo.toml b/vendor/limbo_graph/Cargo.toml new file mode 100644 index 0000000..c7e02e8 --- /dev/null +++ b/vendor/limbo_graph/Cargo.toml @@ -0,0 +1,28 @@ +# 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" +name = "limbo_graph" +version = "0.1.0" +build = false +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = "README.md" + +[lib] +name = "limbo_graph" +path = "src/lib.rs" + +[dependencies] diff --git a/vendor/limbo_graph/LICENSE b/vendor/limbo_graph/LICENSE new file mode 100644 index 0000000..14e2f77 --- /dev/null +++ b/vendor/limbo_graph/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/vendor/limbo_graph/README.md b/vendor/limbo_graph/README.md new file mode 100644 index 0000000..08c307b --- /dev/null +++ b/vendor/limbo_graph/README.md @@ -0,0 +1,3 @@ +# limbo_graph + +An implementation of a directed graph in Rust. diff --git a/vendor/limbo_graph/src/error.rs b/vendor/limbo_graph/src/error.rs new file mode 100644 index 0000000..6906965 --- /dev/null +++ b/vendor/limbo_graph/src/error.rs @@ -0,0 +1,36 @@ +// +// Copyright 2023 James Pace +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +// +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. +// +use alloc::string::{String, ToString}; + +#[derive(Debug, Clone)] +pub enum Error { + Msg(String), +} + +impl Error { + pub fn from_msg(msg: &str) -> Self { + Error::Msg(msg.to_string()) + } +} + +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + match self { + Error::Msg(msg) => { + write!(f, "Error manipulating graph: {}", msg) + } + } + } +} + +impl core::error::Error for Error {} + +pub type Result = core::result::Result; diff --git a/vendor/limbo_graph/src/lib.rs b/vendor/limbo_graph/src/lib.rs new file mode 100644 index 0000000..f73d28a --- /dev/null +++ b/vendor/limbo_graph/src/lib.rs @@ -0,0 +1,226 @@ +// +// Copyright 2023 James Pace +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +// +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. +// +#![no_std] +extern crate alloc; +mod error; +mod node; + +use alloc::collections::vec_deque::VecDeque; +use alloc::vec; +use alloc::vec::Vec; +pub use error::*; +pub use node::*; + +/// A generic graph type holding values connected to other values. +/// Values can be added to the graph, but not removed. +#[derive(Clone)] +pub struct Graph { + nodes: Vec>, +} + +impl Graph { + /// Make a new graph with a root node with value `root`. + pub fn new(root: NodeValueT) -> Self { + // Make root node from its value. + let root_node = Node::new(root, None); + // Make graph with root_node as the one value in the vec. + Graph { + nodes: vec![root_node], + } + } + + /// Add a child wth value `val` to the parent with Key `parent`. + /// If the parent key is not in the graph, returns an error. + /// Returns a result with the key of the new node or an error. + pub fn add(&mut self, val: NodeValueT, parent: Key) -> Result { + // Make sure parent is valid. + if parent >= self.nodes.len() { + return Err(Error::from_msg("Parent node not in graph.")); + } + // Add new node to graph, get it's key. + let new_node = Node::new(val, Some(parent)); + self.nodes.push(new_node.clone()); + let new_node_key = self.nodes.len() - 1; + // Add it's key to parent's children. + self.nodes[parent].add_child(new_node_key); + Ok(new_node_key) + } + + /// Replace the value of `key` with value `value`. + /// `key` must already exist in the graph, and no connections will be modified. + pub fn replace_value_of(&mut self, key: &Key, value: NodeValueT) -> Result<()> { + if let Some(node) = self.nodes.get_mut(*key) { + node.set_value(value); + return Ok(()); + } + Err(Error::from_msg("Can't set value of invalid key.")) + } + + /// Get the value of key `key` if the key is valid. + pub fn value_of(&self, key: &Key) -> Result { + if key >= &self.nodes.len() { + return Err(Error::from_msg("Can't get value of invalid key.")); + } + Ok(self.nodes[*key].value()) + } + + /// Get the children (as a list of keys) of key `key` if the key is valid. + pub fn children_of(&self, key: &Key) -> Result> { + if key >= &self.nodes.len() { + return Err(Error::from_msg("Can't get children of invalid key.")); + } + Ok(self.nodes[*key].children()) + } + + /// Get the parent of key `key` if the key is valid. + /// Will return None if the node at `key` as no parent (i.e. is the root node). + pub fn parent_of(&self, key: &Key) -> Result> { + if key >= &self.nodes.len() { + return Err(Error::from_msg("Can't get parent of invalid key.")); + } + Ok(self.nodes[*key].parent()) + } + + /// Get the key for the root of the graph. + pub fn root_key(&self) -> Key { + // This is always 0. + 0 + } + + /// Find all nodes that are leaf nodes. + /// A leaf node is one that doesn't have any children. + pub fn find_leaf_keys(&self) -> Result> { + let mut leaf_keys = Vec::::new(); + + for key in 0..self.nodes.len() { + let children_of_node = self.children_of(&key)?; + if children_of_node.len() == 0 { + leaf_keys.push(key); + } + } + + Ok(leaf_keys) + } + + /// Return all keys ordered like you were doing + /// a depth first search. + pub fn get_keys_by_depth(&self) -> Result> { + let mut visited_keys = Vec::::new(); + let mut stack = Vec::::new(); + + stack.push(self.root_key()); + + while stack.len() > 0 { + let next_key = stack.pop().unwrap(); + if !visited_keys.contains(&next_key) { + visited_keys.push(next_key); + let children_of_next_key = self.children_of(&next_key)?; + stack.extend(children_of_next_key); + } + } + + Ok(visited_keys) + } + + /// Given a key, return the vec of keys connecting that key to the root. + /// Order is root->key inclusive. + pub fn backtrack_from_key(&self, key: &Key) -> Result> { + let mut curr_key = key.clone(); + let mut deque = VecDeque::::new(); + deque.push_front(curr_key.clone()); + + while curr_key != self.root_key() { + let new_parent = self.parent_of(&curr_key)?.unwrap(); + deque.push_front(new_parent.clone()); + curr_key = new_parent; + } + + Ok(Vec::from(deque)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use core::cmp::PartialEq; + + #[derive(Debug, Clone, PartialEq)] + struct NodeType { + pub x: f64, + } + impl NodeValue for NodeType {} + impl NodeType { + fn new(val: f64) -> Self { + NodeType { x: val } + } + } + + #[test] + fn node_manipulation() { + let mut node = Node::new(NodeType::new(1.0), None); + assert!(node.parent().is_none()); + assert!(node.value() == NodeType::new(1.0)); + let child_key: Key = 1; + node.add_child(child_key.clone()); + assert!(node.children().len() == 1); + assert!(node.children()[0] == child_key); + } + + #[test] + fn graph_manipulation() { + let root_val = NodeType::new(1.0); + let mut graph = Graph::new(root_val); + + let second_val = NodeType::new(2.0); + let second_add_res = graph.add(second_val, 0); + assert!(second_add_res.is_ok()); + assert!(second_add_res.unwrap() == 1); + + assert!(graph.value_of(&1).unwrap() == NodeType::new(2.0)); + assert!(graph.parent_of(&1).unwrap() == Some(0)); + assert!(graph.children_of(&1).unwrap().len() == 0); + } + + #[test] + fn graph_search() { + // Build the graph. + let root_val = NodeType::new(1.0); + let mut graph = Graph::new(root_val); + + let second_val = NodeType::new(2.0); + let second_add_res = graph.add(second_val, 0); + assert!(second_add_res.is_ok()); + + let third_val = NodeType::new(3.0); + let third_add_res = graph.add(third_val, 0); + assert!(third_add_res.is_ok()); + + let fourth_val = NodeType::new(4.0); + let fourth_add_res = graph.add(fourth_val, 1); + assert!(fourth_add_res.is_ok()); + + let fifth_val = NodeType::new(5.0); + let fifth_add_res = graph.add(fifth_val, 2); + assert!(fifth_add_res.is_ok()); + + // Do the testing. + let leaf_keys = graph.find_leaf_keys().unwrap(); + assert!(leaf_keys.len() == 2); + + let keys_by_depth = graph.get_keys_by_depth().unwrap(); + let expected_keys_by_depth = vec![0, 2, 4, 1, 3]; + assert!(keys_by_depth == expected_keys_by_depth); + + let backtracked_keys = graph.backtrack_from_key(&4).unwrap(); + let expected_backtracked_keys = vec![0, 2, 4]; + assert!(backtracked_keys == expected_backtracked_keys); + } +} diff --git a/vendor/limbo_graph/src/node.rs b/vendor/limbo_graph/src/node.rs new file mode 100644 index 0000000..73f23a0 --- /dev/null +++ b/vendor/limbo_graph/src/node.rs @@ -0,0 +1,53 @@ +// +// Copyright 2023 James Pace +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +// +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. +// +use alloc::vec; +use alloc::vec::Vec; + +pub type Key = usize; + +pub trait NodeValue: Clone {} + +#[derive(Debug, Clone)] +pub struct Node { + value: NodeValueT, + children: Vec, + parent: Option, +} + +impl Node { + pub fn new(value: NodeValueT, parent: Option) -> Self { + Node { + value: value, + children: vec![], + parent: parent, + } + } + + pub fn add_child(&mut self, child_key: Key) { + self.children.push(child_key); + } + + pub fn children(&self) -> Vec { + self.children.clone() + } + + pub fn parent(&self) -> Option { + self.parent.clone() + } + + pub fn value(&self) -> NodeValueT { + self.value.clone() + } + + pub fn set_value(&mut self, value: NodeValueT) { + self.value = value; + } +} diff --git a/vendor/memchr/.cargo-checksum.json b/vendor/memchr/.cargo-checksum.json new file mode 100644 index 0000000..2c5ead3 --- /dev/null +++ b/vendor/memchr/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo_vcs_info.json":"739b57f156ae78ce5ad0f2bc44ff727f1a9d48e743bc266e8e3ab8c35baa5ecb",".ignore":"ae8b19032d4fc418b99ccae9e7cc3996b1386665d0bd5edc5634a158e7d2f6a2",".vim/coc-settings.json":"cdc5e2b88bddbdbd1b85f21389c4d882720e4c4488ad566c43fccd9124f2e3bf","AI_POLICY.md":"eb058d5b8387f03159cf6ef868100459d7e01f49499733028fcc916bc97c1cc4","CONTRIBUTING.md":"f5b2b4a9a3dbcd9a6f2654eb97dd7135e6af3717b9a3f037a9cbf714e387af76","COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.lock":"54b66d3eabcf4993f06c5b556ab1df0082dd14985529e301124590280dbe0554","Cargo.toml":"a14f68b8fa55f15fd03b15dced37bcf66a0a628f568eedc82817cdb7f9281951","Cargo.toml.orig":"2d004168044e88b00f971e65d7e6c988a555aa00d7ef4d0ceb5b5a9c228fb0c9","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":"32d3e4cd0dd9b6c8382e5308cbd896d20242c90b12862c44a5de6a8b4d6126df","src/arch/all/memchr.rs":"b0b1214aa573ed5d02ae62a77c42c773065566b50274d4096e37817d65ab1594","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":"06038cce1cbead7b088e541ba41bcc1c095c34bde483b7df6ad9f77a49c1063c","src/arch/all/shiftor.rs":"0d79117f52a1e4795843603a3bb0b45397df4ad5e4184bbc923658dab9dc3b5f","src/arch/all/twoway.rs":"0b27eb1cd7402c1375a50466f8f66a68cb2806c3f69a647340b2759793eed4f8","src/arch/generic/memchr.rs":"ee2a77afcbf506655e352eb3cd42451a70cc2c39e3da487b2985638bc09ced3e","src/arch/generic/mod.rs":"1dd75f61e0ea2563b8205a08aaa7b55500130aa331d18b9e9f995724b66c7a39","src/arch/generic/packedpair.rs":"892d6ee28f0f5007c973d11d697e43e6f6888341b15ea95ce4571e9584069dc5","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":"4cf0611c926c3016d1b640880ef14e5654a8d1c1b480fe9a5965956be7eeeeef","src/arch/x86_64/mod.rs":"61b2aa876942fd3e78714c2ae21e356c8634545c06995020f443fa50218df027","src/arch/x86_64/sse2/memchr.rs":"0de0444e26d885eaf866220578752aac871e03bebee7b4f5de7fe8a35f5fa97f","src/arch/x86_64/sse2/mod.rs":"38b70ae52a64ec974dbb91d04d6ca8013d9e06d1fe4af852206bbc2faf1c59aa","src/arch/x86_64/sse2/packedpair.rs":"ad893c5ab9525966693e742673fb666f54ff9102949fc91c5e61642c8ad2f110","src/cow.rs":"2b053e393d3841f780425b3b0da5bec4f187603fa7c271b045ecb7d885b23395","src/ext.rs":"210f89d1e32211bc64414cbd56e97b4f56ce8a8832d321d77a9fe519634e27ea","src/lib.rs":"614f778a41e88a29ea0ceb8e92c839dbb6b5a61c967f8bfd962975e18f932c71","src/macros.rs":"3e4b39252bfa471fad384160a43f113ebfec7bec46a85d16f006622881dd2081","src/memchr.rs":"6ae779ec5d00f443075316e0105edf30b489a38e2e96325bec14ccecd014145b","src/memmem/mod.rs":"d869159f0d0c1915d7acc42a6a4aa3c97c049ddc043e6566afeb78ad290995d1","src/memmem/searcher.rs":"84f6a23bef907696cb672e6898c15fb87008058abc100dde58519d8ec5ebca5d","src/tests/memchr/mod.rs":"269f8e4b4f7f5ea458f27a3c174eb1020ffb2484eeba9464170beb51747df69b","src/tests/memchr/naive.rs":"6a0bee033e5edfb5b1d5769a5fa1c78388f7e9ff7bb91cb67f0ad029289e00e7","src/tests/memchr/prop.rs":"1854eea2338c405fe4635aac430f51e10d2069cd37a7489ddaff47da95f8720b","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":"9b104d0bda9b8e18b10c41633513637af84346282bf113f3be3813725605fe31"},"package":"cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"} \ No newline at end of file diff --git a/vendor/memchr/.cargo_vcs_info.json b/vendor/memchr/.cargo_vcs_info.json new file mode 100644 index 0000000..eeb3b56 --- /dev/null +++ b/vendor/memchr/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "5fdb40c054e1fff359a2f7bdf7f87a13b34b465d" + }, + "path_in_vcs": "" +} \ No newline at end of file diff --git a/vendor/memchr/.ignore b/vendor/memchr/.ignore new file mode 100644 index 0000000..47ec474 --- /dev/null +++ b/vendor/memchr/.ignore @@ -0,0 +1 @@ +!.github diff --git a/vendor/memchr/.vim/coc-settings.json b/vendor/memchr/.vim/coc-settings.json new file mode 100644 index 0000000..38f35ce --- /dev/null +++ b/vendor/memchr/.vim/coc-settings.json @@ -0,0 +1,16 @@ +{ + "rust-analyzer.cargo.allFeatures": false, + "rust-analyzer.linkedProjects": [ + "benchmarks/engines/libc/Cargo.toml", + "benchmarks/engines/rust-bytecount/Cargo.toml", + "benchmarks/engines/rust-jetscii/Cargo.toml", + "benchmarks/engines/rust-memchr/Cargo.toml", + "benchmarks/engines/rust-memchrold/Cargo.toml", + "benchmarks/engines/rust-sliceslice/Cargo.toml", + "benchmarks/engines/rust-std/Cargo.toml", + "benchmarks/engines/stringzilla/Cargo.toml", + "benchmarks/shared/Cargo.toml", + "fuzz/Cargo.toml", + "Cargo.toml" + ] +} diff --git a/vendor/memchr/AI_POLICY.md b/vendor/memchr/AI_POLICY.md new file mode 100644 index 0000000..e0ddbaa --- /dev/null +++ b/vendor/memchr/AI_POLICY.md @@ -0,0 +1,38 @@ +# AI Policy + +Using AI (i.e., LLMs) as tools for coding is welcome. A high bar is held for +all contributions to this project. Moreover, the project maintainers remain +responsible for any code that is published as part of a release. Contributors +are expected to be responsible for any code they publish. + +**AI should not be used to generate comments when communicating with +maintainers**. Comments are expected to be written by humans. Comments that are +believed to be written by AI may be hidden without notice. + +If you are opening an issue, you should be able to describe the problem in your +own words. + +If you are opening a pull request, you are expected to be able to explain the +proposed changes in your own words. This includes the pull request body and +responses to questions. **Do not copy responses from the AI when replying to +questions from maintainers.** + +This project requires a human in the loop who understands the work produced +by AI. **Autonomous agents are not allowed to be used for contributing to our +projects**. Pull requests that appear in violation of this will be closed, +perhaps without notice. + +If you wish to include context from an interaction with AI in your comments, it +must be in a quote block (e.g., using `>`) and disclosed as such. It must be +accompanied by human commentary explaining the relevance and implications of +the context. Do not share long snippets. + +AI is useful when communicating as a non-native English speaker. If you are +using AI to edit your comments for this purpose, please take the time to ensure +it reflects your own voice and ideas. If using AI for translation, we recommend +writing in your native language and including the AI translation in a quote +block. + +This policy was adapted from [uv's AI policy]. + +[uv's AI policy]: https://github.com/astral-sh/.github/blob/c5187e200db51bfe11d56e13053d29bd3793fdd8/AI_POLICY.md diff --git a/vendor/memchr/CONTRIBUTING.md b/vendor/memchr/CONTRIBUTING.md new file mode 100644 index 0000000..86cb4d0 --- /dev/null +++ b/vendor/memchr/CONTRIBUTING.md @@ -0,0 +1,8 @@ +# Contributing + +## Use of AI + +All use of AI in contributions must follow the +[AI Policy](https://github.com/BurntSushi/jiff/blob/master/AI_POLICY.md). + +Contributions not following the AI Policy will be closed. 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.lock b/vendor/memchr/Cargo.lock new file mode 100644 index 0000000..ecdaf9b --- /dev/null +++ b/vendor/memchr/Cargo.lock @@ -0,0 +1,80 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.176" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "memchr" +version = "2.8.3" +dependencies = [ + "log", + "quickcheck", + "rustc-std-workspace-core", +] + +[[package]] +name = "quickcheck" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" +dependencies = [ + "rand", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rustc-std-workspace-core" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9c45b374136f52f2d6311062c7146bff20fec063c3f5d46a410bd937746955" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" diff --git a/vendor/memchr/Cargo.toml b/vendor/memchr/Cargo.toml new file mode 100644 index 0000000..a03a2ad --- /dev/null +++ b/vendor/memchr/Cargo.toml @@ -0,0 +1,89 @@ +# 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.8.3" +authors = [ + "Andrew Gallant ", + "bluss", +] +build = false +exclude = [ + "/.github", + "/benchmarks", + "/fuzz", + "/scripts", + "/tmp", +] +autolib = false +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"] + +[features] +alloc = [] +default = ["std"] +libc = [] +logging = ["dep:log"] +rustc-dep-of-std = ["core"] +std = ["alloc"] +use_std = ["std"] + +[lib] +name = "memchr" +path = "src/lib.rs" +bench = false + +[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 + +[profile.bench] +debug = 2 + +[profile.release] +debug = 2 + +[profile.test] +opt-level = 3 +debug = 2 diff --git a/vendor/memchr/Cargo.toml.orig b/vendor/memchr/Cargo.toml.orig new file mode 100644 index 0000000..5459969 --- /dev/null +++ b/vendor/memchr/Cargo.toml.orig @@ -0,0 +1,78 @@ +[package] +name = "memchr" +version = "2.8.3" #:version +authors = ["Andrew Gallant ", "bluss"] +description = """ +Provides extremely fast (uses SIMD on x86_64, aarch64 and wasm32) routines for +1, 2 or 3 byte search and single substring search. +""" +documentation = "https://docs.rs/memchr/" +homepage = "https://github.com/BurntSushi/memchr" +repository = "https://github.com/BurntSushi/memchr" +readme = "README.md" +keywords = ["memchr", "memmem", "substring", "find", "search"] +license = "Unlicense OR MIT" +exclude = ["/.github", "/benchmarks", "/fuzz", "/scripts", "/tmp"] +edition = "2021" +rust-version = "1.61" + +[lib] +name = "memchr" +bench = false + +[features] +default = ["std"] + +# The 'std' feature permits the memchr crate to use the standard library. This +# permits this crate to use runtime CPU feature detection to automatically +# accelerate searching via vector instructions. Without the standard library, +# this automatic detection is not possible. +std = ["alloc"] + +# The 'alloc' feature enables some APIs that require allocation, such as +# 'Finder::into_owned'. Note that this feature does not enable runtime CPU +# feature detection. That still requires 'std'. +alloc = [] + +# When enabled (it's disabled by default), the `log` crate will be used to +# emit a spattering of log messages. For the most part, the log messages are +# meant to indicate what strategies are being employed. For example, whether +# a vector or a scalar algorithm is used for substring search. This can be +# useful when debugging performance problems. +# +# This is disabled by default. +logging = ["dep:log"] + +# The 'use_std' feature is DEPRECATED. It will be removed in memchr 3. Until +# then, it is alias for the 'std' feature. +use_std = ["std"] + +# The 'libc' feature has been DEPRECATED and no longer has any effect. +libc = [] + +# Internal feature, only used when building as part of libstd, not part of the +# stable interface of this crate. +rustc-dep-of-std = ['core'] + +[dependencies] +# Only used when the `logging` feature is enabled (disabled by default). +log = { version = "0.4.20", optional = true } +# Internal feature, only used when building as part of libstd, not part of the +# stable interface of this crate. +core = { version = '1.0.0', optional = true, package = 'rustc-std-workspace-core' } + +[dev-dependencies] +quickcheck = { version = "1.0.3", default-features = false } + +[profile.release] +debug = true + +[profile.bench] +debug = true + +[profile.test] +opt-level = 3 +debug = true + +[package.metadata.docs.rs] +rustdoc-args = ["--generate-link-to-definition"] 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..5cc2a02 --- /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 NEON 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..7f327f8 --- /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, than 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 + // 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 + // 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..ce14795 --- /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.first() { + 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..d166c8c --- /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.first() { + 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.first() { + 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..d5501d4 --- /dev/null +++ b/vendor/memchr/src/arch/generic/memchr.rs @@ -0,0 +1,1220 @@ +/*! +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 pseudo 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)?; + let idx = found.distance(start); + // Required by safety invariant required for find_raw + // this lets the compiler know the returned index is in bounds for the slice + if idx >= haystack.len() { + core::hint::unreachable_unchecked(); + } + Some(idx) +} + +/// 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..45d088c --- /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.distance(cur) < needle.len() { + 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..e12d0d3 --- /dev/null +++ b/vendor/memchr/src/arch/x86_64/memchr.rs @@ -0,0 +1,339 @@ +/*! +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 ensure 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) unsafe 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) unsafe 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) unsafe 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) unsafe 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) unsafe 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) unsafe 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) unsafe 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..79572b8 --- /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, than 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..75329c2 --- /dev/null +++ b/vendor/memchr/src/arch/x86_64/sse2/packedpair.rs @@ -0,0 +1,253 @@ +/*! +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() + } + + // A demonstration of UB (caught under Miri) through some of memchr's + // lower level but public APIs. + // + // See: https://github.com/BurntSushi/memchr/issues/225 + #[test] + fn regression_undefined_behavior() { + let construct_needle: &[u8] = b"ab"; // length 2 → pair indices 0,1 + let pair = Pair::new(construct_needle).unwrap(); + let Some(finder) = Finder::with_pair(construct_needle, pair) else { + return; + }; + let mhl = finder.min_haystack_len(); // 17 + let mut haystack = alloc::vec![b'.'; mhl + 5]; + haystack[0] = b'a'; + // force entry into find_in_chunk inner branch + haystack[1] = b'b'; + // 122 > haystack.len()=22 + let long_needle = alloc::vec![b'X'; haystack.len() + 100]; + let _ = finder.find(&haystack, &long_needle); + } +} diff --git a/vendor/memchr/src/cow.rs b/vendor/memchr/src/cow.rs new file mode 100644 index 0000000..5306f97 --- /dev/null +++ b/vendor/memchr/src/cow.rs @@ -0,0 +1,109 @@ +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)] + pub(crate) 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..ab19a9d --- /dev/null +++ b/vendor/memchr/src/memmem/mod.rs @@ -0,0 +1,767 @@ +/*! +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 = self.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 } + } + + /// 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 } + } + + /// 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 an owned forward finder using the given needle from the current + /// settings. + #[cfg(feature = "alloc")] + pub fn build_forward_owned>>( + &self, + needle: B, + ) -> Finder<'static> { + self.build_forward_with_ranker_owned(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 an owned 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. + #[cfg(feature = "alloc")] + pub fn build_forward_with_ranker_owned< + R: HeuristicFrequencyRank, + B: Into>, + >( + &self, + ranker: R, + needle: B, + ) -> Finder<'static> { + let needle = needle.into(); + let searcher = Searcher::new(self.prefilter, ranker, &needle); + Finder { needle: CowBytes::new_owned(needle), searcher } + } + + /// 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), + } + } + + /// Build an owned reverse finder using the given needle from the current + /// settings. + #[cfg(feature = "alloc")] + pub fn build_reverse_owned>>( + &self, + needle: B, + ) -> FinderRev<'static> { + let needle = needle.into(); + let searcher = SearcherRev::new(&needle); + FinderRev { needle: CowBytes::new_owned(needle), searcher } + } + + /// 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..73ece73 --- /dev/null +++ b/vendor/memchr/src/memmem/searcher.rs @@ -0,0 +1,1028 @@ +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)?; + 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..949ef1f --- /dev/null +++ b/vendor/memchr/src/tests/memchr/prop.rs @@ -0,0 +1,323 @@ +/// Defines a host of quickcheck tests for the given memchr searcher. +#[cfg(miri)] +#[macro_export] +macro_rules! define_memchr_quickcheck { + ($($tt:tt)*) => {}; +} + +/// Defines a host of quickcheck tests for the given memchr searcher. +#[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..a243273 --- /dev/null +++ b/vendor/memchr/src/vector.rs @@ -0,0 +1,514 @@ +/// 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 and define 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)] + #[cfg(target_endian = "little")] + 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)] + #[cfg(target_endian = "big")] + unsafe fn movemask(self) -> NeonMoveMask { + // Swap the endianness of each 16-bit input. + let asu16s = vreinterpretq_u16_u8(vrev16q_u8(self)); + let mask = vshrn_n_u16(asu16s, 4); + let asu64 = vreinterpret_u64_u8(mask); + // Use `swap_bytes` to swap the endianness of the 64-bit output. + let scalar64 = vget_lane_u64(asu64, 0).swap_bytes(); + 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 + /// adjacent 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. + /// + /// The mask is always already in host-endianness, so this is a no-op. + #[inline(always)] + fn get_for_offset(self) -> u64 { + 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..7639992 --- /dev/null +++ b/vendor/once_cell/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo_vcs_info.json":"abe28464063d16bc9b0ebaad2b1682fc1a8052b0968bb4277f6b265844822c67",".github/workflows/ci.yaml":"b1c9b12babf51fcaa7de2adc737c91e882da240cf847becf380141cec320cf2d","CHANGELOG.md":"c104a8ec44b9087539185006e8187a8412883b902318e0a0a807a23ac756a070","Cargo.lock":"25438daaf9e812ea9c506823a9030c708b38e0a664039c91f4d16b05d0444dd4","Cargo.toml":"87e5b7ee438abdef12e46386e86370f54ad70cabdcf949556b9ef012a9da9587","Cargo.toml.orig":"cce5bf836e33ad0e9adfb6e900d432371af2ca3861da45b719a0fce716ea810f","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":"9337fcbbfb80606de9f785f5e0f2d5ba513d7fd13918f90504bb24189831f877","src/imp_std.rs":"1c130f83be5c1360dfd379911f97797c1e4c730b845f465c8c2630467ca317d2","src/lib.rs":"9868277311543bf4a22463d41948af6e810feb40fdd7844d47893eeab1780215","src/race.rs":"4751464e8ccedb102097962a68d736de6f9434f78aa7761a1a03efd4a360c6c3","tests/it/main.rs":"e6e9987e053af84b9d76052602995b1e777efb5bc06cd5f49009e6f03b18626c","tests/it/race.rs":"5e299887123a852cb33692e27d88d59d2a007252675b60722d5e3ce5ca93dc19","tests/it/race_once_box.rs":"0cb5b3852f92002445ccc481de11642b22b9137f3a09db566cb484ab8eb32325","tests/it/sync_lazy.rs":"a36c5d66340b3d6d20aad331a499858a2125dfdfd624c5bf3b4b06a0b157c75c","tests/it/sync_once_cell.rs":"e6e539ce06966f656b24cc692603cf39241690fa58339d2775ecccda274b3769","tests/it/unsync_lazy.rs":"51a1ffd411770d1e32399ec23feb5f61be362bbed34e100eb7509f8496224e1a","tests/it/unsync_once_cell.rs":"82b72936d7bd4090db25cfc543c01ef3206d6917ac56f09d17d4110a65deb30a"},"package":"9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"} \ No newline at end of file diff --git a/vendor/once_cell/.cargo_vcs_info.json b/vendor/once_cell/.cargo_vcs_info.json new file mode 100644 index 0000000..2a60bf8 --- /dev/null +++ b/vendor/once_cell/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "80fe900b21f6d76c1a2ed74d3343e8a3a88c46d0" + }, + "path_in_vcs": "" +} \ No newline at end of file diff --git a/vendor/once_cell/.github/workflows/ci.yaml b/vendor/once_cell/.github/workflows/ci.yaml new file mode 100644 index 0000000..6a998a8 --- /dev/null +++ b/vendor/once_cell/.github/workflows/ci.yaml @@ -0,0 +1,28 @@ +name: CI +on: + pull_request: + push: + branches: ["master", "staging", "trying"] + +env: + CARGO_INCREMENTAL: 0 + CARGO_NET_RETRY: 10 + CI: 1 + RUST_BACKTRACE: short + RUSTFLAGS: -D warnings + RUSTUP_MAX_RETRIES: 10 + +jobs: + test: + name: Rust + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # fetch tags for publish + - uses: Swatinem/rust-cache@359a70e43a0bb8a13953b04a90f76428b4959bb6 + - run: cargo run -p xtask -- ci + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} + MIRIFLAGS: -Zmiri-strict-provenance diff --git a/vendor/once_cell/CHANGELOG.md b/vendor/once_cell/CHANGELOG.md new file mode 100644 index 0000000..ac9797a --- /dev/null +++ b/vendor/once_cell/CHANGELOG.md @@ -0,0 +1,263 @@ +# Changelog + +## 1.21.4 + +- Fix unsoundness in `OnceCell::wait` under `--features=parking_lot`, [#295](https://github.com/matklad/once_cell/pull/295). + + If thread A calls `wait`, while thread B calls `get_or_try_init(f)`, and, furthermore, `f` panics, + the `wait` incorrectly returns and thread A observes uninitialized memory. + + Kudos to [@meng-xu-cs](https://github.com/meng-xu-cs) for a nice find! + +## 1.21.3 + +- Outline more initialization in `race`: [#284](https://github.com/matklad/once_cell/pull/284), + [#285](https://github.com/matklad/once_cell/pull/285). + +## 1.21.2 +- Relax success ordering from AcqRel to Release in `race`: [#278](https://github.com/matklad/once_cell/pull/278). + +## 1.21.1 +- Reduce MSRV to 1.65: [#277](https://github.com/matklad/once_cell/pull/277). + +## 1.21.0 + +- Outline initialization in `race`: [#273](https://github.com/matklad/once_cell/pull/273). +- Add `OnceNonZereUsize::get_unchecked`: [#274](https://github.com/matklad/once_cell/pull/274). +- Add `OnceBox::clone` and `OnceBox::with_value`: [#275](https://github.com/matklad/once_cell/pull/275). +- Increase MSRV to 1.70 + +## 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.lock b/vendor/once_cell/Cargo.lock new file mode 100644 index 0000000..5c074d8 --- /dev/null +++ b/vendor/once_cell/Cargo.lock @@ -0,0 +1,179 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "critical-section" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f64009896348fc5af4222e9cf7d7d82a95a256c634ebcf61c53e4ea461422242" + +[[package]] +name = "libc" +version = "0.2.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "once_cell" +version = "1.21.4" +dependencies = [ + "critical-section", + "parking_lot_core", + "portable-atomic", + "regex", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + +[[package]] +name = "redox_syscall" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/vendor/once_cell/Cargo.toml b/vendor/once_cell/Cargo.toml new file mode 100644 index 0000000..cbc2491 --- /dev/null +++ b/vendor/once_cell/Cargo.toml @@ -0,0 +1,119 @@ +# 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.65" +name = "once_cell" +version = "1.21.4" +authors = ["Aleksey Kladov "] +build = false +exclude = [ + "*.png", + "*.svg", + "/Cargo.lock.msrv", + "rustfmt.toml", +] +autolib = false +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"] + +[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 = [] + +[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" diff --git a/vendor/once_cell/Cargo.toml.orig b/vendor/once_cell/Cargo.toml.orig new file mode 100644 index 0000000..69fffdd --- /dev/null +++ b/vendor/once_cell/Cargo.toml.orig @@ -0,0 +1,92 @@ +[package] +name = "once_cell" +version = "1.21.4" +authors = ["Aleksey Kladov "] +license = "MIT OR Apache-2.0" +edition = "2021" +rust-version = "1.65" + +description = "Single assignment cells and lazy values." +readme = "README.md" +documentation = "https://docs.rs/once_cell" + +repository = "https://github.com/matklad/once_cell" +keywords = ["lazy", "static"] +categories = ["rust-patterns", "memory-management"] + +exclude = ["*.png", "*.svg", "/Cargo.lock.msrv", "rustfmt.toml"] + +[workspace] +members = ["xtask"] + +[dependencies] +parking_lot_core = { version = "0.9.10", optional = true, default-features = false } +portable-atomic = { version = "1.8", optional = true, default-features = false } +critical-section = { version = "1.1.3", optional = true } + +[dev-dependencies] +regex = "1.10.6" +critical-section = { version = "1.1.3", features = ["std"] } + +[features] +default = ["std"] + +# Enables `once_cell::sync` module. +std = ["alloc"] + +# Enables `once_cell::race::OnceBox` type. +alloc = ["race"] + +# Enables `once_cell::race` module. +race = [] + +# Uses parking_lot to implement once_cell::sync::OnceCell. +# This makes no speed difference, but makes each OnceCell +# up to 16 bytes smaller, depending on the size of the T. +parking_lot = ["dep:parking_lot_core"] + +# Uses `portable-atomic` to implement `race` module. in +# `#![no_std]` mode. Please read `portable-atomic` docs carefully +# before enabling this feature. +portable-atomic = ["dep:portable-atomic"] + +# Uses `critical-section` to implement `sync` module. in +# `#![no_std]` mode. Please read `critical-section` docs carefully +# before enabling this feature. +# `portable-atomic` feature is enabled for backwards compatibility. +critical-section = ["dep:critical-section", "portable-atomic"] + +# Enables semver-exempt APIs of this crate. +# At the moment, this feature is unused. +unstable = [] + +# Only for backwards compatibility. +atomic-polyfill = ["critical-section"] + +[[example]] +name = "bench" +required-features = ["std"] + +[[example]] +name = "bench_acquire" +required-features = ["std"] + +[[example]] +name = "lazy_static" +required-features = ["std"] + +[[example]] +name = "reentrant_init_deadlocks" +required-features = ["std"] + +[[example]] +name = "regex" +required-features = ["std"] + +[[example]] +name = "test_synchronization" +required-features = ["std"] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--generate-link-to-definition"] 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..93bfced --- /dev/null +++ b/vendor/once_cell/src/imp_pl.rs @@ -0,0 +1,176 @@ +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 { + while self.state.load(Ordering::Acquire) != COMPLETE { + 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..0ccab15 --- /dev/null +++ b/vendor/once_cell/src/lib.rs @@ -0,0 +1,1422 @@ +//! # 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 +//! # #[cfg(any(feature = "std", feature = "critical-section"))] { +//! 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 +//! # #[cfg(any(feature = "std", feature = "critical-section"))] { +//! 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 +//! # #[cfg(any(feature = "std", feature = "critical-section"))] { +//! 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: +//! +//! ``` +//! # #[cfg(any(feature = "std", feature = "critical-section"))] { +//! 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: +//! +//! +//! ``` +//! # #[cfg(any(feature = "std", feature = "critical-section"))] { +//! 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::sync::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..852a804 --- /dev/null +++ b/vendor/once_cell/src/race.rs @@ -0,0 +1,498 @@ +//! 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`. + +// The "atomic orderings" section of the documentation above promises +// "happens-before" semantics. This drives the choice of orderings in the uses +// of `compare_exchange` below. On success, the value was zero/null, so there +// was nothing to acquire (there is never any `Ordering::Release` store of 0). +// On failure, the value was nonzero, so it was initialized previously (perhaps +// on another thread) using `Ordering::Release`, so we must use +// `Ordering::Acquire` to ensure that store "happens-before" this load. + +#[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() -> Self { + Self { inner: AtomicUsize::new(0) } + } + + /// Gets the underlying value. + #[inline] + pub fn get(&self) -> Option { + let val = self.inner.load(Ordering::Acquire); + NonZeroUsize::new(val) + } + + /// 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 unsafe fn get_unchecked(&self) -> NonZeroUsize { + #[inline(always)] + fn as_const_ptr(r: &AtomicUsize) -> *const usize { + use core::mem::align_of; + + let p: *const AtomicUsize = r; + // SAFETY: "This type has the same size and bit validity as + // the underlying integer type, usize. However, the alignment of + // this type is always equal to its size, even on targets where + // usize has a lesser alignment." + const _ALIGNMENT_COMPATIBLE: () = + assert!(align_of::() % align_of::() == 0); + p.cast::() + } + + // TODO(MSRV-1.70): Use `AtomicUsize::as_ptr().cast_const()` + // See https://github.com/rust-lang/rust/issues/138246. + let p = as_const_ptr(&self.inner); + + // SAFETY: The caller is responsible for ensuring that the value + // was initialized and that the contents have been acquired by + // this thread. Assuming that, we can assume there will be no + // conflicting writes to the value since the value will never + // change once initialized. This relies on the statement in + // https://doc.rust-lang.org/1.83.0/core/sync/atomic/ that "(A + // `compare_exchange` or `compare_exchange_weak` that does not + // succeed is not considered a write." + let val = unsafe { p.read() }; + + // SAFETY: The caller is responsible for ensuring the value is + // initialized and thus not zero. + unsafe { NonZeroUsize::new_unchecked(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<(), ()> { + match self.compare_exchange(value) { + 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, + { + match self.get() { + Some(it) => Ok(it), + None => self.init(f), + } + } + + #[cold] + #[inline(never)] + fn init(&self, f: impl FnOnce() -> Result) -> Result { + let nz = f()?; + let mut val = nz.get(); + if let Err(old) = self.compare_exchange(nz) { + val = old; + } + Ok(unsafe { NonZeroUsize::new_unchecked(val) }) + } + + #[inline(always)] + fn compare_exchange(&self, val: NonZeroUsize) -> Result { + self.inner.compare_exchange(0, val.get(), Ordering::Release, Ordering::Acquire) + } +} + +/// 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() -> Self { + Self { inner: OnceNonZeroUsize::new() } + } + + /// Gets the underlying value. + #[inline] + pub fn get(&self) -> Option { + self.inner.get().map(Self::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(Self::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, + { + Self::from_usize(self.inner.get_or_init(|| Self::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(Self::to_usize)).map(Self::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() -> Self { + Self { 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<(), ()> { + match self.compare_exchange(value) { + 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>, + { + match self.get() { + Some(val) => Ok(val), + None => self.init(f), + } + } + + #[cold] + #[inline(never)] + fn init(&self, f: impl FnOnce() -> Result<&'a T, E>) -> Result<&'a T, E> { + let mut value: &'a T = f()?; + if let Err(old) = self.compare_exchange(value) { + value = unsafe { &*old }; + } + Ok(value) + } + + #[inline(always)] + fn compare_exchange(&self, value: &'a T) -> Result<(), *const T> { + self.inner + .compare_exchange( + ptr::null_mut(), + <*const T>::cast_mut(value), + Ordering::Release, + Ordering::Acquire, + ) + .map(|_: *mut T| ()) + .map_err(<*mut T>::cast_const) + } + + /// ```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() -> Self { + Self { inner: AtomicPtr::new(ptr::null_mut()), ghost: PhantomData } + } + + /// Creates a new cell with the given value. + pub fn with_value(value: Box) -> Self { + Self { inner: AtomicPtr::new(Box::into_raw(value)), 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::Release, + 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>, + { + match self.get() { + Some(val) => Ok(val), + None => self.init(f) + } + } + + #[cold] + #[inline(never)] + fn init(&self, f: impl FnOnce() -> Result, E>) -> Result<&T, E> { + let val = f()?; + let mut ptr = Box::into_raw(val); + let exchange = self.inner.compare_exchange( + ptr::null_mut(), + ptr, + Ordering::Release, + Ordering::Acquire, + ); + if let Err(old) = exchange { + drop(unsafe { Box::from_raw(ptr) }); + ptr = old; + } + Ok(unsafe { &*ptr }) + } + } + + unsafe impl Sync for OnceBox {} + + impl Clone for OnceBox { + fn clone(&self) -> Self { + match self.get() { + Some(value) => OnceBox::with_value(Box::new(value.clone())), + None => OnceBox::new(), + } + } + } + + /// ```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..8716f70 --- /dev/null +++ b/vendor/once_cell/tests/it/race.rs @@ -0,0 +1,191 @@ +#[cfg(feature = "std")] +use std::sync::Barrier; +use std::{ + num::NonZeroUsize, + sync::atomic::{AtomicUsize, Ordering::SeqCst}, + thread::scope, +}; + +use once_cell::race::{OnceBool, OnceNonZeroUsize, OnceRef}; + +#[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)); +} + +#[test] +fn once_bool_get_or_try_init() { + let cell = OnceBool::new(); + + let result1: Result = cell.get_or_try_init(|| Ok(true)); + let result2: Result = cell.get_or_try_init(|| Ok(false)); + assert_eq!(result1, Ok(true)); + assert_eq!(result2, Ok(true)); + + let cell = OnceBool::new(); + + let result3: Result = cell.get_or_try_init(|| Err(())); + assert_eq!(result3, Err(())); +} + +#[test] +fn once_ref_smoke_test() { + let cnt: AtomicUsize = AtomicUsize::new(0); + let cell: OnceRef<'_, &str> = OnceRef::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_ref_set() { + let cell: OnceRef<'_, &str> = OnceRef::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")); +} + +#[test] +fn get_unchecked() { + let cell = OnceNonZeroUsize::new(); + cell.set(NonZeroUsize::new(92).unwrap()).unwrap(); + let value = unsafe { cell.get_unchecked() }; + assert_eq!(value, NonZeroUsize::new(92).unwrap()); +} 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..e9ff2c1 --- /dev/null +++ b/vendor/once_cell/tests/it/race_once_box.rs @@ -0,0 +1,162 @@ +#[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()); +} + +#[test] +fn onece_box_with_value() { + let cell = OnceBox::with_value(Box::new(92)); + assert_eq!(cell.get(), Some(&92)); +} + +#[test] +fn onece_box_clone() { + let cell1 = OnceBox::new(); + let cell2 = cell1.clone(); + cell1.set(Box::new(92)).unwrap(); + let cell3 = cell1.clone(); + assert_eq!(cell1.get(), Some(&92)); + assert_eq!(cell2.get(), None); + assert_eq!(cell3.get(), Some(&92)); +} 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..18382d8 --- /dev/null +++ b/vendor/once_cell/tests/it/sync_once_cell.rs @@ -0,0 +1,328 @@ +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 wait_panic() { + let cell: OnceCell = OnceCell::new(); + scope(|s| { + let h1 = s.spawn(|| { + cell.get_or_try_init(|| -> Result { panic!() }).unwrap(); + }); + let h2 = s.spawn(|| { + assert!(h1.join().is_err()); + cell.get_or_try_init(|| -> Result { Ok("hello".to_string()) }).unwrap(); + }); + + let greeting = cell.wait(); + assert_eq!(greeting, "hello"); + assert!(h2.join().is_ok()); + }); +} + +#[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/portable-atomic/.cargo-checksum.json b/vendor/portable-atomic/.cargo-checksum.json new file mode 100644 index 0000000..3f6d993 --- /dev/null +++ b/vendor/portable-atomic/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo_vcs_info.json":"3704de1736ccc44c6ef99d7563fa51cfafa77d135a2bdeff864fcfe0f3087ed0","CHANGELOG.md":"71861d11d0f90b2e2ec64986d4f99aa813b84b34f955a4a5d34f51dd3c378204","Cargo.lock":"a7572366edd2c39d5ee4b8440fa76c56060ddae97b7bbfff83aa803a06f3c4b8","Cargo.toml":"30e602bcf54f19dbdcf52315a262c88e8efbd12455ee4d4fe63f2880e4ac10e1","Cargo.toml.orig":"4fd62c038201d9efe897d2320af051c38e69cbb3cca9d77c589568e60cd83365","LICENSE-APACHE":"0d542e0c8804e39aa7f37eb00da5a762149dc682d7829451287e11b938e94594","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"a66e02c23633b74d19013225a52fe26742b59b9575a5cb0451f53e8e7468b622","build.rs":"9d0b1e071715580497aadb918d4b3b124ee366ba66f15ac05a3d8045f0bc2cf0","portable-atomic-util/README.md":"6a69c6fa501d2470e8b038160736c08897cdbbddd4318361c7a29cd20cf86261","src/cfgs.rs":"7a438600e742bca248c16c980c20c2b65be01bb786e6cde738cbd94f612344e0","src/gen/build.rs":"4ad2fa43f8f725631e9754338f39b80f64a2e61facdb3bd735efc215b95a6597","src/gen/utils.rs":"c44ee71296aaa90c8104339e470688f631a2380d7f10349c7766205c415050aa","src/imp/arm_linux.rs":"6f5ba9542ec89340444094ee4c96503dec7476c38d308abd1b09168785d672c5","src/imp/atomic128/README.md":"240d085f57eff9e5c92cb87498e0d1bb260a4f0fe41cd64eb86cb96e1d686c96","src/imp/atomic128/aarch64.rs":"8fe3bebbf1a7991b35e6ffeb796ff872bc15edcdbbdcf7a5835cb2b1ce149542","src/imp/atomic128/intrinsics.rs":"882b817a77ba6b90ad96585bdd5545c8526a9590473a93ca8dda96d91d1fcbcb","src/imp/atomic128/macros.rs":"31f63dd5f6523fdc80d752afdd7b13e90394e7210b8f14bfa38a4feab0822cd5","src/imp/atomic128/mod.rs":"4d12d39ed3c0e5ab46724ac9536598ccc0028147d258b739ed27212c4e4d5e7e","src/imp/atomic128/powerpc64.rs":"f1831b186b89049aba31be4c4cd37b5572554f2655944d5cfc04ab5654691715","src/imp/atomic128/riscv64.rs":"115c4d8bc0fed79973bc12462f506121c7e612f3cf14cc627a0d024c3a131387","src/imp/atomic128/s390x.rs":"b657e6f3e48d12b79dfaf7dec5268d2558967c14288e097bb37e40d49b9b6eba","src/imp/atomic128/x86_64.rs":"19c67a75d8ee1392aae67f49b88a3b69e78acce5004280c7a7be33051774c8ed","src/imp/atomic64/README.md":"56ef5c1f1750515a6a8a94b9347fd42faa889cddf5a9f77cd7d650008a4a8b7c","src/imp/atomic64/arm_linux.rs":"e4857c2c7240b73a3e3c9bb092b1251d9b71a44617cc43345ffd14bf11ee5f65","src/imp/atomic64/macros.rs":"5b6f0bfe40064885926cfd57a336f15da92f6964864c50d339d1bb9903802a9d","src/imp/atomic64/mod.rs":"2977468d184134a068179eb8361d73500865b8d1476b87590099d6b503db30e5","src/imp/atomic64/riscv32.rs":"c8e00a15c0524fc94b0df7946fcd84b6779eb01bfe48f06bf6f4f84039c00337","src/imp/avr.rs":"085cdcc03d7ffb85c491f3939e0bcc3ae1e78738acadf09472f547a0b9d7c8fc","src/imp/core_atomic.rs":"0ce4a6ca4fb50fd8e3c6fb2adf96535ab9b8593b951d25f16b5762ddf867b7bd","src/imp/detect/README.md":"24db78df52c56bb4bebc699ad0ce21272b214d9caed7c70fd92702f2331d6837","src/imp/detect/aarch64_aa64reg.rs":"77d6b3a2fafbdeb881c671379d0be0a330b46d78c8252d074c97ed44b1138123","src/imp/detect/aarch64_apple.rs":"149a79530b9bdb11b1521918a4d61ece2be2cb99ab4c86cb6765c3acde1c727a","src/imp/detect/aarch64_fuchsia.rs":"edb86bdc2630329b96396d3da23d3ee2ca55d3d45737df2de76ac2bfbce4964f","src/imp/detect/aarch64_illumos.rs":"50b95302831a5fe2837fc13b882d6d4e92f79e05b004c4c6cd2a6402d86eefc3","src/imp/detect/aarch64_windows.rs":"2cfc29df37c09aa8685b47e4973ab11fdb18f66ca9bbc2346e2713ef6898e1e1","src/imp/detect/auxv.rs":"4897e7d126b69bc7d8121bdc7516aca794c361ed767d6031e61b1e4456f9cae6","src/imp/detect/common.rs":"735925ba2717d649f49a7550d78fd523b002fb8c030cb7d52e542d982ada43a9","src/imp/detect/powerpc64_aix.rs":"b635538662e9add807cebd26c5742eae6dd764e11fd2c30fc6661baa03b69d01","src/imp/detect/riscv_linux.rs":"9e8b214013992dcf7ff5e0beb9228db4f2125aa134afdc573781788349f3a159","src/imp/detect/x86_64.rs":"8b315b61a409d3350b19c02e98a741f4c1c1e3861e6792594137267f4595eeb1","src/imp/fallback/mod.rs":"970934078d4cf02e424f2bc80ad7724e188bc8fe4c883898311ef32b4601d826","src/imp/fallback/outline_atomics.rs":"041d872affc4ad0b6b452f695a1373a1f76fe75d1b2377c24c3c0d199d89e383","src/imp/fallback/seq_lock.rs":"f099568551ecd866b8deff71655421f7eff21d045af598debe44d7a355c7bb39","src/imp/fallback/seq_lock_common.rs":"2c519835f7a9b20b64b9cc3428dcf9ed18ad7e56fd73791404d4f7f87975dd3e","src/imp/fallback/seq_lock_wide.rs":"b2870e179e7d903327ef4ca52e13471e771622ebefd8b06940a5584d8e83416c","src/imp/fallback/utils.rs":"4b04423031fa66eaf7619e4ddbb30689eb834f74e9dd876b8f4d163cf9c75f73","src/imp/float/aarch64.rs":"b3d69ef526252b8ee99662f2059898cfa6cb99e1c969828225a2be99de2d45df","src/imp/float/int.rs":"8801b336650a039bc6e056857c0f65c2f148a0774c83baa9bd9bf415618107e5","src/imp/float/mod.rs":"2c722182baee05df65f9f6e2b4de5d5474a3b2bf0c24803a65a771de78b76f95","src/imp/interrupt/README.md":"1f4ed0b78b42832800bc8e4db98576f17ef51e8e84b07375fa3e076addbf83e0","src/imp/interrupt/armv4t.rs":"6fb9e7d01f7fb483bc6bec07916fdcba8563b605b53bd87c5310662da04e55a4","src/imp/interrupt/armv6m.rs":"364a38f18ffb2b3cd836700dff6a390d9542f0f2a3eda07bc63bc8868dafaad1","src/imp/interrupt/avr.rs":"252569da4b194f91d7f52c6480a869e26679dc74c30a3a8fcd6568a39b90440d","src/imp/interrupt/mod.rs":"256ed2675f921dc2c2fb0ea06b610990e391ec2714dc460383e21d688a0f751f","src/imp/interrupt/msp430.rs":"a7131a478fca956de4ca569f340641da2eb6a5cbd86a05a854f1231dd24e62d1","src/imp/interrupt/riscv.rs":"32a0291b174310385f850c19283d583852b128cb9c037633c8a5e872245842bc","src/imp/interrupt/xtensa.rs":"7c877f42c237d7ff6564776ee9c4afa5b8143d4fb6b39b4ac869e5e357189b4f","src/imp/mod.rs":"d9505be50a63ea4b00590a3637266ccb88dc85078572aa8fd8bf4236bb9ae18c","src/imp/msp430.rs":"16635485eeca1c1c4b866253eefc1f39fa6121c84c16ec389b904c03fa9cdb55","src/imp/riscv.rs":"72c05a835e13b007ff587ec2fd35f619c32b74f18f0aa544fc304456ad5d255a","src/imp/x86.rs":"4c11976fccadc618d68d6aba4caf744d2859f60f63c6fb08f626f2a2561e6b52","src/lib.rs":"8fac4257f626a2669a44dd74a966677b368647fd883e32d8db79c57a06af6895","src/rustdoc.css":"fb503ec0cf2eb0dacbbdbea63ffb66d538637ddb0a6617cad69906bf58831d7f","src/tests/helper.rs":"dc3d529032bd0a0ec4c9f25246504758042531109b3fd1a65a6be5bc1c4b7265","src/tests/mod.rs":"74aff58531edbba0c833d6a3ec7a45b987896945074763ab3a88f6d99feff05e","src/utils.rs":"9211b8295c0ec7dc02592731264a0d5516622541126ddd768006d79ef6749dfe","tests/.gitignore":"3c761e8831e160876acdfee9a0f48bc27270d671f58130bc67445897e9e7de81","version.rs":"25c4e742d5a9e49ee16793b607157e181fd79eeafcbcbf0aa389f31b8d5514d1"},"package":"05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85"} \ No newline at end of file diff --git a/vendor/portable-atomic/.cargo_vcs_info.json b/vendor/portable-atomic/.cargo_vcs_info.json new file mode 100644 index 0000000..570438e --- /dev/null +++ b/vendor/portable-atomic/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "e4595528211f1d53b7f4d93e528ef84b491fc871" + }, + "path_in_vcs": "" +} \ No newline at end of file diff --git a/vendor/portable-atomic/CHANGELOG.md b/vendor/portable-atomic/CHANGELOG.md new file mode 100644 index 0000000..6ab1e8b --- /dev/null +++ b/vendor/portable-atomic/CHANGELOG.md @@ -0,0 +1,683 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +This project adheres to [Semantic Versioning](https://semver.org). + +Releases may yanked if there is a security bug, a soundness bug, or a regression. + + + +## [Unreleased] + +## [1.15.0] - 2026-08-09 + +- Work around [`core::sync::atomic` bug](https://github.com/rust-lang/compiler-builtins/pull/1234) which may cause data races with non-relaxed load/CAS on pre-v6 ARM Linux/Android due to missing memory barrier. ([#112](https://github.com/taiki-e/portable-atomic/pull/112)) + +- Make {8,16,32}-bit non-relaxed load compatible with read-only memory on pre-v6 ARM Linux/Android. Previously only relaxed load was compatible with read-only memory. ([#112](https://github.com/taiki-e/portable-atomic/pull/112)) + +- Make `from_ptr` `const fn` on Rust 1.58+. Previously it was `const fn` only on Rust 1.83+. ([c09d0e6](https://github.com/taiki-e/portable-atomic/commit/c09d0e624f1416a01bbb11bba22c148b42dcb081)) + +- Optimize non-relaxed load/store on pre-v6 ARM Linux/Android. ([#112](https://github.com/taiki-e/portable-atomic/pull/112)) + +- Optimize fence on pre-v6 ARM Linux/Android. ([#112](https://github.com/taiki-e/portable-atomic/pull/112)) + +- Optimize 128-bit CAS/swap/min/max on s390x. This also includes removing the code complexity that caused the bug fixed in 1.14.0. ([33cd7e5](https://github.com/taiki-e/portable-atomic/commit/33cd7e55acfe1438c853b20b09ec786613228122), [6c8f764](https://github.com/taiki-e/portable-atomic/commit/6c8f764bee3c3ca570552e49a8117402b0186ead)) + +- Documentation improvements. + +## [1.14.0] - 2026-07-17 + +- Guarantee that `is_lock_free` to always return the same result. ([e74f384](https://github.com/taiki-e/portable-atomic/commit/e74f384efab9eae540087a20ed140dddc0d06ce7)) + +- Fix bug in 128-bit `fetch_{min,max}` on pre-z196 s390x. ([a6c6c4b](https://github.com/taiki-e/portable-atomic/commit/a6c6c4bdb7c1b4f9d406ebbdcc54805e5e7eec10)) + +- Fix bug in atomic float `fetch_{add,sub,max,min}` on AArch64 when FEAT_LSFE is enabled. (There are currently no known CPUs that support FEAT_LSFE.) ([b105f9bc](https://github.com/taiki-e/portable-atomic/commit/b105f9bc612e07c6f6a07291fa2be8cba38fa5df)) + +- Fix panic in build script when custom target with non-standard name on non-nightly rustc. ([02ca737](https://github.com/taiki-e/portable-atomic/commit/02ca7371eecd005fa1b170c12f8a0bad5e77a7fb)) + +- Improve robustness of interrupt disable/restore on RISC-V and Xtensa. ([88cb3d5](https://github.com/taiki-e/portable-atomic/commit/88cb3d50c66569dab95cc93250bd1e4202508a65)) + +- Optimize SeqCst fence on x86. ([9127b31](https://github.com/taiki-e/portable-atomic/commit/9127b31caae0545424254b5ba6dcf5c91b7d59e6)) + +- Optimize 128-bit CAS when FEAT_LSE is not enabled. ([671b9a89](https://github.com/taiki-e/portable-atomic/commit/671b9a89d1e324547a3f29ae09a5a306b3b54a3b)) + +- Optimize SeqCst atomics on AArch64 Windows MSVC. ([671b9a89](https://github.com/taiki-e/portable-atomic/commit/671b9a89d1e324547a3f29ae09a5a306b3b54a3b)) + +- Optimize 8-bit fetch_and/fetch_or/fetch_xor/fetch_not on AVR when RMW instructions available. ([6f2f11f2](https://github.com/taiki-e/portable-atomic/commit/6f2f11f243673380e8732c5c5c1e18e6a5b553ff)) + +- Optimize 128-bit RMW on s390x. ([b8c502a9](https://github.com/taiki-e/portable-atomic/commit/b8c502a9238e9aed4e169f909b3d25c797f76cc4)) + +- Optimize run-time CPU feature detection. ([cae7032](https://github.com/taiki-e/portable-atomic/commit/cae703222aca87d2a014372a02afb14c0b80ed32)) + +- Enable run-time detection by default on AArch64 Apple targets. ([6c92015](https://github.com/taiki-e/portable-atomic/commit/6c920155e7645b859e6f667963c90f775e561213)) + +- Enable run-time detection by default on AArch64 illumos. ([59e3636b](https://github.com/taiki-e/portable-atomic/commit/59e3636bbe5515121c137d3b939e2cd39b50f1a4)) + +- aarch64: Support run-time detection of FEAT_LSE2 on Windows. ([16bc44f0](https://github.com/taiki-e/portable-atomic/commit/16bc44f07b0709828a9d2f100dccde7db5477794)) + +- Make `portable_atomic_no_outline_atomics` cfg no-op instead of compile error on unsupported architectures. ([6b8e3eb](https://github.com/taiki-e/portable-atomic/commit/6b8e3eb3b92bd64a0a6516bf4f72feb467ccbb3d)) + +- Improve compile-time detection of AVR target features. ([2b5a9a4f](https://github.com/taiki-e/portable-atomic/commit/2b5a9a4f6df1736f536aecade53181ca24446846)) + +- Documentation improvements. + +## [1.13.1] - 2026-01-31 + +- Update to stabilized [PowerPC64](https://github.com/rust-lang/rust/pull/147996) inline assembly. ([92b02f8a](https://github.com/taiki-e/portable-atomic/commit/92b02f8a279327a1780cbe127d9effb2baae9b2f)) + +- Work around [rustc_codegen_gcc bugs on x86_64](https://github.com/rust-lang/rustc_codegen_gcc/issues/821#issuecomment-3793567607). ([ae4c501](https://github.com/taiki-e/portable-atomic/commit/ae4c501aec84a3537fe35ec57ceae94b3a05ade0)) + +- Optimize x86_64 128-bit atomics. ([a9d61eb](https://github.com/taiki-e/portable-atomic/commit/a9d61ebf8d7f466286a71a17f7d9063fcf07fce0), [90a17ca4](https://github.com/taiki-e/portable-atomic/commit/90a17ca40a8ff433d767c3b56264fb02ccdd71e1)) + +- Improve compile-time detection of RISC-V target features. ([535fced](https://github.com/taiki-e/portable-atomic/commit/535fced071ed095ee4d35b440ba55a0e2f533d80)) + +- Enable [release immutability](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/immutable-releases). + +## [1.13.0] - 2025-12-27 + +- Add `unsafe-assume-privileged` feature / `portable_atomic_unsafe_assume_privileged` cfg for safer lock-based fallback on multi-core privileged environments. ([b084ee1](https://github.com/taiki-e/portable-atomic/commit/b084ee1b6cba3e9d7158a6c9e5450e1fc8bbde36)) + +- Support `unsafe-assume-single-core`/`unsafe-assume-privileged` on all 32-bit Arm targets. Previously it was only M-profile and pre-v6 targets. ([7e07f5e](https://github.com/taiki-e/portable-atomic/commit/7e07f5e2bc8ad74287830522c02f960a8c8da59e)) + +- Make `AtomicPtr::fetch_*` strict-provenance compatible on all environments. Previously it was only strict-provenance compatible on `cfg(miri)` and otherwise permissive-provenance compatible. ([4306943](https://github.com/taiki-e/portable-atomic/commit/4306943fb09af3a4f763f1f8ff257fe752c7b7e3)) + +- Ensure sequential consistency in lock-based fallback when SeqCst is used. ([7e80742](https://github.com/taiki-e/portable-atomic/commit/7e80742eeed9fc4d1aa15455b862d70194f6f1bf)) + +- Support compile-time detection for x86_64 VMOVDQA. ([f7bb1aa](https://github.com/taiki-e/portable-atomic/commit/f7bb1aa246df0e13fa02fb707f8462d8dfe6b7e9)) + +- Improve compile-time detection of s390x miscellaneous-extensions-3. ([11045fe](https://github.com/taiki-e/portable-atomic/commit/11045fe513689a842e393324c05f2c5f169b59d4)) + +- Optimize AVR 8-bit swap when RMW instructions available. ([8cedb34](https://github.com/taiki-e/portable-atomic/commit/8cedb34a0b9f2ca1680d893a58020ba1e5d0a87b)) + +- Optimize interrupt restore on RISC-V. ([9b97a2a](https://github.com/taiki-e/portable-atomic/commit/9b97a2a18142c9a8d21f03de7fff30caea89d51e)) + +## [1.12.0] - 2025-12-19 + +- Fix build error on no-std pre-v6 Arm targets due to the [recent upstream change](https://github.com/rust-lang/rust/pull/149241). ([83f6f3e](https://github.com/taiki-e/portable-atomic/commit/83f6f3e4957833af6dd1bae054da1e8d51501a76)) + +- Support `unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg for targets with CAS. ([38e9572](https://github.com/taiki-e/portable-atomic/commit/38e95722dde98e7a9b59d2acbff968450a0b09ea)) + +- Improve compile-time detection of s390x target feature. ([5ae0ef5](https://github.com/taiki-e/portable-atomic/commit/5ae0ef5ed7f9a0c9efe9e628ba2fbc5876487219)) + +- Documentation improvements. ([c84f720](https://github.com/taiki-e/portable-atomic/commit/c84f7203ae6e39a5c9966748123b95b90e8a127a)) + +## [1.11.1] - 2025-06-06 + +- Fix build error when building aarch64/arm64ec/powerpc64/s390x targets for Miri or ThreadSanitizer since nightly-2025-05-31. + +- aarch64: Optimize atomic floats when FEAT_LSFE is enabled. ([#201](https://github.com/taiki-e/portable-atomic/pull/201)) + +- Improve compile-time detection of RISC-V Zacas extension. ([b7634e2](https://github.com/taiki-e/portable-atomic/commit/b7634e2cd808ea118266d12f99fd8877a92e3d31)) + +- Improve run-time detection on linux-musl. ([7fdad7f](https://github.com/taiki-e/portable-atomic/commit/7fdad7f7dd32e32ece7bd0eaf565db657b3406bb)) + +- Optimize interrupt restore on thumbv6m. ([dd2004a](https://github.com/taiki-e/portable-atomic/commit/dd2004aaa14d034b0db652eb9939b780d0d8221f)) + +## [1.11.0] - 2025-02-24 + +- Work around [nightly-2025-02-24 rustc regression causing "cannot use value of type `*mut T` for inline assembly" error](https://github.com/rust-lang/rust/issues/137512) on RISC-V without A extension, MSP430, and pre-v6 no-std Arm targets. ([eeb0235](https://github.com/taiki-e/portable-atomic/commit/eeb0235b9fda4c28a56ee5a9ffe0d7fb884a50ab)) + +- Support `AtomicF16` and `AtomicF128` for [unstable `f16` and `f128`](https://github.com/rust-lang/rust/issues/116909) under unstable cfgs. ([#200](https://github.com/taiki-e/portable-atomic/pull/200)) + +- RISC-V Zacas extension support is no longer experimental. ([#206](https://github.com/taiki-e/portable-atomic/pull/206)) + +- Improve support of run-time detection and outline-atomics: + - riscv: Enable run-time detection of Zacas extension by default on Linux/Android. ([#207](https://github.com/taiki-e/portable-atomic/pull/207)) + - aarch64: Support run-time detection of FEAT_LRCPC3/FEAT_LSE128 on FreeBSD. ([6a5075d](https://github.com/taiki-e/portable-atomic/commit/6a5075d43543875cf38d6114f2951047e2e64f1a)) + - powerpc64: Support run-time detection of quadword-atomics on AIX (currently disabled by default because detection support for AIX is experimental). ([#102](https://github.com/taiki-e/portable-atomic/pull/102)) + +## [1.10.0] - 2024-11-23 + +- Update to stabilized [s390x](https://github.com/rust-lang/rust/pull/131258) and [Arm64EC](https://github.com/rust-lang/rust/pull/131781) inline assembly. ([97645c1](https://github.com/taiki-e/portable-atomic/commit/97645c1b2b938249f16eacb0fe696d4c7bb96754), [e1d1a97](https://github.com/taiki-e/portable-atomic/commit/e1d1a97cd1ab4bd04b45962c44ca1e9f0f9e1456)) + +- Make `get_mut` `const fn` on Rust 1.83+. ([0dea68c](https://github.com/taiki-e/portable-atomic/commit/0dea68c26e2bba3a83a849e2f137a2da445fc014)) + +- Make `from_ptr` `const fn` on Rust 1.83+. (align to the [std atomic change in Rust 1.84](https://github.com/rust-lang/rust/pull/131717)) ([50532d8](https://github.com/taiki-e/portable-atomic/commit/50532d8ce92408976307431a2f1a94000c630b23)) + +- Various optimizations: + - RISC-V without A-extension: Optimize 16-bit fetch_not when Zabha enabled. ([a487a09](https://github.com/taiki-e/portable-atomic/commit/a487a094ab99fdf8ef3413b943c9c154a352d8c4)) + - s390x: Optimize 128-bit CAS/RMW. ([fba028d](https://github.com/taiki-e/portable-atomic/commit/fba028d7618e47b3de5b352c1789ea52f45298b4), [33ab2c1](https://github.com/taiki-e/portable-atomic/commit/33ab2c19719b29c0a30df8d011d0cd4003495dc8)) + - PowerPC64: Optimize 128-bit Acquire/AcqRel/SeqCst CAS/RMW and 128-bit CAS with Relaxed failure ordering. ([33ab2c1](https://github.com/taiki-e/portable-atomic/commit/33ab2c19719b29c0a30df8d011d0cd4003495dc8)) + - AVR: Optimize 8-bit load/store. ([33ab2c1](https://github.com/taiki-e/portable-atomic/commit/33ab2c19719b29c0a30df8d011d0cd4003495dc8)) + +- Improve support of run-time detection and outline-atomics: + - Enable run-time detection by default on powerpc64 and aarch64 linux-uclibc. ([#193](https://github.com/taiki-e/portable-atomic/pull/193)) + - Improve run-time detection of powerpc64 quadword-atomics. ([1e3bfda](https://github.com/taiki-e/portable-atomic/commit/1e3bfda29bf6eb06a359f24554f19fc080ae57eb)) + - Improve run-time detection of Zhaoxin CPU. ([f283d2a](https://github.com/taiki-e/portable-atomic/commit/f283d2a1deb94e84676a2c1ee678439f507482db)) + +- Support RISC-V Zacas extension on pre-1.82 rustc. ([#194](https://github.com/taiki-e/portable-atomic/pull/194)) + +- Improve compile-time detection of RISC-V Zaamo/Zabha extensions. ([673137a](https://github.com/taiki-e/portable-atomic/commit/673137afb87b731ed19a1b0717059468712fad1d)) + +- Respect [`RUSTC_BOOTSTRAP=-1` recently added in nightly](https://github.com/rust-lang/rust/pull/132993) in rustc version detection. ([5b2847a](https://github.com/taiki-e/portable-atomic/commit/5b2847a8b99aa2a57a6c80f5a47327b2764f08cc)) + +## [1.9.0] - 2024-09-28 + +- RISC-V without A-extension: Support RMW when Zaamo extension enabled (even when `unsafe-assume-single-core` disabled). ([#185](https://github.com/taiki-e/portable-atomic/pull/185), [9983a8b](https://github.com/taiki-e/portable-atomic/commit/9983a8b9ad66efe4303b95678014369a56839aef)) + See "operations don't require disabling interrupts" list in [`interrupt` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/interrupt/README.md) for the operations provided. + +- Support run-time detection of RISC-V Zacas extension (currently disabled by default). ([#183](https://github.com/taiki-e/portable-atomic/pull/183)) + +- Support 128-bit atomics on Arm64EC (currently nightly-only) ([#184](https://github.com/taiki-e/portable-atomic/pull/184)) + +- Improve compile-time detection of powerpc64 quadword-atomics. ([3eb8507](https://github.com/taiki-e/portable-atomic/commit/3eb8507f91c1ab382d9f455b2311a8664a4c33ff)) + +## [1.8.0] - 2024-09-20 + +- Improve diagnostics when method that requires CAS is unavailable. ([#181](https://github.com/taiki-e/portable-atomic/pull/181)) + + Before: + + ```text + error[E0599]: no method named `compare_exchange` found for struct `portable_atomic::AtomicUsize` in the current scope + --> src/race.rs:60:24 + | + 60 | self.inner.compare_exchange(0, value.get(), Ordering::AcqRel, Ordering::Acquire); + | ^^^^^^^^^^^^^^^^ method not found in `AtomicUsize` + ``` + + After: + + ```text + error[E0277]: `compare_exchange` requires atomic CAS but not available on this target by default + --> src/race.rs:60:24 + | + 60 | self.inner.compare_exchange(0, value.get(), Ordering::AcqRel, Ordering::Acquire); + | ^^^^^^^^^^^^^^^^ this associated function is not available on this target by default + | + = help: the trait `HasCompareExchange` is not implemented for `&portable_atomic::AtomicUsize` + = note: consider enabling one of the `unsafe-assume-single-core` or `critical-section` Cargo features + = note: see for more. + ``` + +- Improve compile error messages for some other cases ([19716ac](https://github.com/taiki-e/portable-atomic/commit/19716ac1d3b6082a8cb838af532ccab871041249), [61dcaaa](https://github.com/taiki-e/portable-atomic/commit/61dcaaa320cb347ab799c6c4f4480600692de2ad)) + +- Various improvements to RISC-V. + - riscv64: Support 128-bit atomics when Zacas extension enabled. ([173](https://github.com/taiki-e/portable-atomic/pull/173)) This is currently marked as experimental because LLVM marking the corresponding target feature as experimental. + - riscv32: Support 64-bit atomics when Zacas extension enabled. ([173](https://github.com/taiki-e/portable-atomic/pull/173)) This is currently marked as experimental because LLVM marking the corresponding target feature as experimental. + - Improvements for RISC-V without A-extension: + - Support zaamo target feature. When building for single-core RISC-V without A-extension, this is equivalent to force-amo feature ([8abba4b](https://github.com/taiki-e/portable-atomic/commit/8abba4b0ea920d23799c2d7b6985617e6392d176)) + - Support zabha target feature. ([694364a](https://github.com/taiki-e/portable-atomic/commit/694364a179441f723e429516132436c46f5857b4)) + - Strengthen SeqCst store to improve compatibility with code that uses atomic instruction mapping that differs from LLVM and GCC. ([5b10b15](https://github.com/taiki-e/portable-atomic/commit/5b10b1516e056b16b851e498a271f751152feed9)) + +- Improve support of run-time detection and outline-atomics: + - aarch64: Support run-time detection of FEAT_LRCPC3/FEAT_LSE128 for load/store. ([#174](https://github.com/taiki-e/portable-atomic/pull/174)) + - aarch64: Support run-time detection of FEAT_LSE2 on OpenBSD. ([4f8c735](https://github.com/taiki-e/portable-atomic/commit/4f8c7350fd80d005233d85191707e4329a5ef484)) + - aarch64: Support run-time detection of FEAT_LSE/FEAT_LSE2 on illumos (currently disabled by default because illumos AArch64 port is experimental). ([#175](https://github.com/taiki-e/portable-atomic/pull/175)) + - powerpc64: Support run-time detection on OpenBSD 7.6+ (currently disabled by default for compatibility with old versions). ([09a967b](https://github.com/taiki-e/portable-atomic/commit/09a967b59c217dc9ebb4d78ec114758ef9941fc8)) + +- Support AArch64 FEAT_LRCPC3/FEAT_LSE128 with pre-16 LLVM. ([#178](https://github.com/taiki-e/portable-atomic/pull/178)) + +- Improve compile-time detection of AArch64 FEAT_LSE2/FEAT_LRCPC3/FEAT_LSE128. ([10d47de](https://github.com/taiki-e/portable-atomic/commit/10d47def74b9c13fd864436d6118e902f118c028)) + +- Relax minimal version of `serde` (supported via optional feature) to 1.0.60. + +## [1.7.0] - 2024-07-19 + +- Support run-time detection for cmpxchg16b on x86_64 on pre-1.69 rustc. ([#154](https://github.com/taiki-e/portable-atomic/pull/154)) + +- Make `into_inner` `const fn` on Rust 1.56+. (align to the [std atomic change in Rust 1.79](https://github.com/rust-lang/rust/pull/123522)) ([dee1f89](https://github.com/taiki-e/portable-atomic/commit/dee1f89739594271e4f5b5d3f122d2762fcbbd7d)) + +- Work around [rustc_codegen_gcc bug on x86_64](https://github.com/rust-lang/rustc_codegen_gcc/issues/485). ([d938f77](https://github.com/taiki-e/portable-atomic/commit/d938f77f3f2f353cbfb525ac23e63e880cd583df)) + +- Optimize x86_64 atomics. + - Optimize 128-bit load/store on Zhaoxin CPU with AVX. ([86cee8f](https://github.com/taiki-e/portable-atomic/commit/86cee8fccf7deedb5b8cbcb3868ec2e43aca575f)) + - Optimize 128-bit SeqCst store on Intel/AMD/Zhaoxin CPU with AVX. ([#156](https://github.com/taiki-e/portable-atomic/pull/156), [0483042](https://github.com/taiki-e/portable-atomic/commit/0483042671fad4ccd0bdb691424a967fc2a5cb8e)) + - Remove needless test in CAS. ([573e025](https://github.com/taiki-e/portable-atomic/commit/573e02586f933a257c8e7383dcf64408b4708b85)) + +- Make rustc version detection robust for custom toolchains. ([f8ea85e](https://github.com/taiki-e/portable-atomic/commit/f8ea85e1aa46fa00bc865633fb40b05f8a0c823b)) + +- Respect `RUSTC_WRAPPER` in rustc version detection. + +- Our build script is now less likely to be [re-run unnecessarily](https://github.com/taiki-e/portable-atomic/issues/151) in versions where the cargo bug fix is available (cargo 1.79+). ([52c277b](https://github.com/taiki-e/portable-atomic/commit/52c277bc9a9a8031175aaed54987260da1750af4)) + +## [1.6.0] - 2023-12-06 + +- Add `cfg_{has,no}_atomic_{8,16,32,64,128,ptr}` macros to enable code when the corresponding atomic implementation is available/unavailable. + +- Add `cfg_{has,no}_atomic_cas` macros to enable code when atomic CAS/RMW implementation is available/unavailable. + +- Improve support for RISC-V targets without atomic CAS. + +## [1.5.1] - 2023-10-29 + +- Fix bug in `i{8,16}` `fetch_{or,xor}` on RISC-V without A-extension where `unsafe-assume-single-core` and `force-amo` are enabled. + +- Optimize `swap` for targets that do not have native atomic CAS instructions. + +## [1.5.0] - 2023-10-23 + +**Note:** This release has been yanked due to a bug fixed in 1.5.1. + +- Add `from_ptr`. + +- Add `force-amo` feature (`portable_atomic_force_amo` cfg) for single-core RISC-V without A-extension. ([#124](https://github.com/taiki-e/portable-atomic/pull/124)) + +- Support run-time detection on AArch64 on pre-1.61 rustc. ([#98](https://github.com/taiki-e/portable-atomic/pull/98)) + + This also solves [a compatibility issue with rustc_codegen_cranelift](https://github.com/rust-lang/rustc_codegen_cranelift/issues/1400). + +- Support run-time detection of FEAT_LSE2. ([#126](https://github.com/taiki-e/portable-atomic/pull/126)) + +- Support run-time detection of FEAT_LSE on AArch64 NetBSD. ([#66](https://github.com/taiki-e/portable-atomic/pull/66)) + +- Acknowledge ESP-IDF targets' 64-bit atomics are not lock-free. See [#122](https://github.com/taiki-e/portable-atomic/issues/122) for more. + +- Optimize 128-bit weak CAS on powerpc64. + +- Optimize interrupt disable on no-std pre-v6 Arm where `unsafe-assume-single-core` and `disable-fiq` are enabled. ([771c45d](https://github.com/taiki-e/portable-atomic/commit/771c45da2d2afc4f83df033dd4bdf3f976d14a74)) + +- Improve detection of Apple hardware. ([5c3a43b](https://github.com/taiki-e/portable-atomic/commit/5c3a43b53f1c4188f9dd597599633bc1a315bf44)) + +- Improve compatibility with the future version of Miri. + +## [1.4.3] - 2023-08-25 + +- Optimize AArch64 128-bit atomic store/swap/fetch_and/fetch_or when the `lse128` target feature is enabled at compile-time. ([#68](https://github.com/taiki-e/portable-atomic/pull/68)) + +- Optimize AArch64 128-bit atomic load/store when the `rcpc3` target feature is enabled at compile-time. ([#68](https://github.com/taiki-e/portable-atomic/pull/68)) + +- Optimize inline assemblies on Arm, AArch64, and MSP430. + +## [1.4.2] - 2023-07-27 + +- Optimize `AtomicBool` on RISC-V/LoongArch64. This is the same as [rust-lang/rust#114034](https://github.com/rust-lang/rust/pull/114034), but is available for all rustc versions. + +## [1.4.1] - 2023-07-15 + +- Improve compatibility with the future version of Miri. + +## [1.4.0] - 2023-07-11 + +- Allow using embedded-related cfgs as Cargo features. ([#94](https://github.com/taiki-e/portable-atomic/pull/94), thanks @Dirbaio) + + Originally, we were providing these as cfgs instead of features, but based on a strong request from the embedded ecosystem, we have agreed to provide them as features as well. See [#94](https://github.com/taiki-e/portable-atomic/pull/94) for more. + + cfgs are kept and can be used as aliases for features. + +- Acknowledge all x86_64 Apple targets support 128-bit atomics. + + Our code already recognizes this via `cfg(target_feature)`, so this only affects docs and users using pre-1.69 stable rustc. + + See also [rust-lang/rust#112150](https://github.com/rust-lang/rust/pull/112150). + +- Optimize 128-bit atomics on AArch64/s390x. + +## [1.3.3] - 2023-05-31 + +- Fix build error on AArch64 ILP32 ABI targets (tier 3). + +- Optimize 128-bit atomics on s390x. + +## [1.3.2] - 2023-05-09 + +- Fix bug in powerpc64/s390x 128-bit atomic RMWs on old nightly. + +- Optimize 128-bit atomics on powerpc64/s390x. + +## [1.3.1] - 2023-05-07 + +- Documentation improvements. + +## [1.3.0] - 2023-05-06 + +- Add `require-cas` feature. ([#100](https://github.com/taiki-e/portable-atomic/pull/100)) + + If your crate supports no-std environment and requires atomic CAS, enabling this feature will allow the `portable-atomic` to display helpful error messages to users on targets requiring additional action on the user side to provide atomic CAS. + + ```toml + [dependencies] + portable-atomic = { version = "1.3", default-features = false, features = ["require-cas"] } + ``` + + See [#100](https://github.com/taiki-e/portable-atomic/pull/100) for more. + +- Support `portable_atomic_unsafe_assume_single_core` cfg on Xtensa targets without atomic CAS. ([#86](https://github.com/taiki-e/portable-atomic/pull/86)) + +- Fix bug in AArch64 128-bit SeqCst load when FEAT_LSE2 is enabled at compile-time. This is [the same bug that was fixed in the recently released GCC 13.1](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108891). LLVM also has the same bug, which had not yet been fixed when the patch was created; I will open a bug report if necessary after looking into the situation in LLVM. ([a29154b](https://github.com/taiki-e/portable-atomic/commit/a29154b21da270e90cb86f6865b591ab36eade7d)) + +- Fix compile error on `bpf{eb,el}-unknown-none` (tier 3) and `mipsel-sony-psx` (tier 3) when `critical-section` feature is disabled. + +- Various optimizations + - Optimize x86_64 128-bit outline-atomics. This improves performance by up to 15% in concurrent RMW/store for cases where the `cmpxchg16b` target feature is not available at compile-time. ([40c4cd4](https://github.com/taiki-e/portable-atomic/commit/40c4cd4f682f1cb153f18d4d6a88795bafaf5667)) + - Optimize x86_64 128-bit load that uses cmpxchg16b. ([40c4cd4](https://github.com/taiki-e/portable-atomic/commit/40c4cd4f682f1cb153f18d4d6a88795bafaf5667)) + - Optimize AArch64 128-bit load that uses FEAT_LSE. ([40c4cd4](https://github.com/taiki-e/portable-atomic/commit/40c4cd4f682f1cb153f18d4d6a88795bafaf5667)) + - Optimize pre-Armv6 Linux/Android 64-bit atomics. ([efacc89](https://github.com/taiki-e/portable-atomic/commit/efacc89c210d7a34ef5e879821112189da5d1901)) + - Support outline-atomics for powerpc64 128-bit atomics. This is currently disabled by default, and can be enabled by `--cfg portable_atomic_outline_atomics`. ([#90](https://github.com/taiki-e/portable-atomic/pull/90)) + - Optimize AArch64 outline-atomics on linux-musl. On linux-musl, outline-atomics is enabled by default only when dynamic linking is enabled. When static linking is enabled, this can be enabled by `--cfg portable_atomic_outline_atomics`. See the [`atomic128` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/atomic128/README.md#run-time-feature-detection) for more. ([8418235](https://github.com/taiki-e/portable-atomic/commit/84182354e4a149074e28bda4683d538e5fb617ce), [31d0862](https://github.com/taiki-e/portable-atomic/commit/31d08623d4e21af207ff2343f5553b9b5a030452)) + +## [1.2.0] - 2023-03-25 + +- Make 64-bit atomics lock-free on Arm Linux/Android targets that do not have 64-bit atomics (e.g., armv5te-unknown-linux-gnueabi, arm-linux-androideabi, etc.) when the kernel version is 3.1 or later. ([#82](https://github.com/taiki-e/portable-atomic/pull/82)) + +- Fix AArch64 128-bit atomics performance regression on Apple hardware. ([#89](https://github.com/taiki-e/portable-atomic/pull/89)) + +- Optimize 128-bit atomics on AArch64, x86_64, powerpc64, and s390x. + +## [1.1.0] - 2023-03-24 + +- Add `Atomic{I,U}*::bit_{set,clear,toggle}` and `AtomicPtr::bit_{set,clear,toggle}`. ([#72](https://github.com/taiki-e/portable-atomic/pull/72)) + + They correspond to x86's `lock bt{s,r,c}`, and the implementation calls them on x86/x86_64. + +- Add `AtomicU*::{fetch_neg,neg}` methods. Previously it was only available on `AtomicI*` and `AtomicF*`. + +- Add `as_ptr` method to all atomic types. ([#79](https://github.com/taiki-e/portable-atomic/pull/79)) + +- Make `AtomicF{32,64}::as_bits` `const fn` on Rust 1.58+. ([#79](https://github.com/taiki-e/portable-atomic/pull/79)) + +- Relax ordering in `Serialize` impl to reflect the [upstream change](https://github.com/serde-rs/serde/pull/2263). + +- Optimize x86_64 outline-atomics for 128-bit atomics. + - Support outline-atomics for cmpxchg16b on Rust 1.69+ (i.e., on Rust 1.69+, x86_64 128-bit atomics is lock-free on all Intel chips and almost all AMD chips, even if cmpxchg16b is not available at compile-time.). Previously it was only nightly. ([#80](https://github.com/taiki-e/portable-atomic/pull/80)) + - portable-atomic no longer enables outline-atomics on target where run-time CPU feature detection is not available. ([#80](https://github.com/taiki-e/portable-atomic/pull/80)) + +- Optimize AArch64 outline-atomics for 128-bit atomics. + - Support more targets and improve performance. ([#63](https://github.com/taiki-e/portable-atomic/pull/63), [#64](https://github.com/taiki-e/portable-atomic/pull/64), [#67](https://github.com/taiki-e/portable-atomic/pull/67), [#69](https://github.com/taiki-e/portable-atomic/pull/69), [#75](https://github.com/taiki-e/portable-atomic/pull/75), [#76](https://github.com/taiki-e/portable-atomic/pull/76), [#77](https://github.com/taiki-e/portable-atomic/pull/77)) + See the [`atomic128` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/atomic128/README.md#run-time-feature-detection) for a list of platforms that support outline-atomics. + Most of these improvements have already been [submitted and accepted in rust-lang/stdarch](https://github.com/rust-lang/stdarch/pulls?q=is%3Apr+author%3Ataiki-e+std_detect) and will soon be available in `std::arch::is_aarch64_feature_detected`. + - portable-atomic no longer enables outline-atomics on target where run-time CPU feature detection is not available. + +- Performance improvements. ([#70](https://github.com/taiki-e/portable-atomic/pull/70), [#81](https://github.com/taiki-e/portable-atomic/pull/81), [6c189ae](https://github.com/taiki-e/portable-atomic/commit/6c189ae1792ce0c08b4f56b6e6c256c223475ce2), [13c92b0](https://github.com/taiki-e/portable-atomic/commit/13c92b015a8e8646a4b885229157547354d03b9e), etc.) + +- Improve support for old nightly. ([#73](https://github.com/taiki-e/portable-atomic/pull/73), [872feb9](https://github.com/taiki-e/portable-atomic/commit/872feb9d7f3a4ca7cf9b63935265d46498fcae99)) + +- Documentation improvements. + +## [1.0.1] - 2023-01-21 + +- Optimize `Atomic{I,U}*::{fetch_not,not}` methods. ([#62](https://github.com/taiki-e/portable-atomic/pull/62)) + +## [1.0.0] - 2023-01-15 + +- Add `critical-section` feature to use [critical-section](https://github.com/rust-embedded/critical-section) on targets where atomic CAS is not natively available. ([#51](https://github.com/taiki-e/portable-atomic/pull/51), thanks @Dirbaio) + + This is useful to get atomic CAS when `--cfg portable_atomic_unsafe_assume_single_core` can't be used, such as multi-core targets, unprivileged code running under some RTOS, or environments where disabling interrupts needs extra care due to e.g. real-time requirements. + + See [documentation](https://github.com/taiki-e/portable-atomic#optional-features-critical-section) for more. + +- Remove `outline-atomics` feature. This was no-op since 0.3.19. + +- Documentation improvements. + +## [0.3.20] - 2023-05-07 + +The latest version of portable-atomic is 1.x. This release makes portable-atomic 0.3 is built on top of portable-atomic 1.x to make bug fixes and improvements such as [support for new targets](https://github.com/taiki-e/portable-atomic/pull/86) in 1.x available to the ecosystem that depends on older portable-atomic. portable-atomic 0.3 is still maintained passively, but upgrading to portable-atomic 1.x is recommended. (There are no breaking changes from 0.3, except that a deprecated no-op `outline-atomics` Cargo feature has been removed.) ([#99](https://github.com/taiki-e/portable-atomic/pull/99)) + +## [0.3.19] - 2022-12-25 + +- Add `AtomicI*::{fetch_neg,neg}` and `AtomicF*::fetch_neg` methods. ([#54](https://github.com/taiki-e/portable-atomic/pull/54)) + + `AtomicI*::neg` are equivalent to the corresponding `fetch_*` methods, but do not return the previous value. They are intended for optimization on platforms that have atomic instructions for the corresponding operation, such as x86's `lock neg`. + + Currently, optimizations by these methods (`neg`) are only guaranteed for x86/x86_64. + +- Add `Atomic{I,U}*::{fetch_not,not}` methods. ([#54](https://github.com/taiki-e/portable-atomic/pull/54)) + + `Atomic{I,U}*::not` are equivalent to the corresponding `fetch_*` methods, but do not return the previous value. They are intended for optimization on platforms that have atomic instructions for the corresponding operation, such as x86's `lock not`, MSP430's `inv`. + + Currently, optimizations by these methods (`not`) are only guaranteed for x86/x86_64 and MSP430. + + (Note: `AtomicBool` already has `fetch_not` and `not` methods.) + +- Enable outline-atomics for 128-bit atomics by default. ([#57](https://github.com/taiki-e/portable-atomic/pull/57)) See [#57](https://github.com/taiki-e/portable-atomic/pull/57) for more. + +- Improve support for old nightly compilers. + +## [0.3.18] - 2022-12-15 + +- Fix build error when not using `portable_atomic_unsafe_assume_single_core` cfg on AVR and MSP430 custom targets. ([#50](https://github.com/taiki-e/portable-atomic/pull/50)) + + Since 0.3.11, atomic CAS was supported without the cfg on AVR and MSP430 builtin targets, but that change was not applied to custom targets. + +## [0.3.17] - 2022-12-14 + +- Optimize x86_64 128-bit atomic load/store on AMD CPU with AVX. ([#49](https://github.com/taiki-e/portable-atomic/pull/49)) + +- Improve support for custom targets on old rustc. + +## [0.3.16] - 2022-12-09 + +- Add `Atomic{I,U}*::{add,sub,and,or,xor}` and `AtomicBool::{and,or,xor}` methods. ([#47](https://github.com/taiki-e/portable-atomic/pull/47)) + + They are equivalent to the corresponding `fetch_*` methods, but do not return the previous value. They are intended for optimization on platforms that implement atomics using inline assembly, such as the MSP430. + + Currently, optimizations by these methods (`add`,`sub`,`and`,`or`,`xor`) are only guaranteed for MSP430; on x86/x86_64, LLVM can optimize in most cases, so cases, where this would improve things, should be rare. + +- Various improvements to `portable_atomic_unsafe_assume_single_core` cfg. ([#44](https://github.com/taiki-e/portable-atomic/pull/44), [#40](https://github.com/taiki-e/portable-atomic/pull/40)) + + - Support disabling FIQs on pre-v6 Arm under `portable_atomic_disable_fiq` cfg. + - Support RISC-V supervisor mode under `portable_atomic_s_mode` cfg. + - Optimize interrupt restore on AVR and MSP430. ([#40](https://github.com/taiki-e/portable-atomic/pull/40)) + - Documentation improvements. + + See [#44](https://github.com/taiki-e/portable-atomic/pull/44) for more. + +## [0.3.15] - 2022-09-09 + +- Implement workaround for std cpuid bug due to LLVM bug ([rust-lang/rust#101346](https://github.com/rust-lang/rust/issues/101346), [llvm/llvm-project#57550](https://github.com/llvm/llvm-project/issues/57550)). + + - Our use case is likely not affected, but we implement this just in case. + - We've confirmed that the uses of inline assembly in this crate are not affected by this LLVM bug. + +## [0.3.14] - 2022-09-04 + +- Optimize atomic load/store on no-std pre-v6 Arm when `portable_atomic_unsafe_assume_single_core` cfg is used. ([#36](https://github.com/taiki-e/portable-atomic/pull/36)) + +- Support pre-power8 powerpc64le. powerpc64le's default cpu version is power8, but you can technically compile it for the old cpu using the unsafe `-C target-cpu` rustc flag. + +## [0.3.13] - 2022-08-15 + +- Use track_caller when debug assertions are enabled on Rust 1.46+. + +- Make powerpc64 128-bit atomics compatible with Miri and ThreadSanitizer on LLVM 15+. + +- Document that 128-bit atomics are compatible with Miri and ThreadSanitizer on recent nightly. + +## [0.3.12] - 2022-08-13 + +- Support atomic CAS on no-std pre-v6 Arm targets (e.g., thumbv4t-none-eabi) under unsafe cfg `portable_atomic_unsafe_assume_single_core`. ([#28](https://github.com/taiki-e/portable-atomic/pull/28)) + +## [0.3.11] - 2022-08-12 + +- Always provide atomic CAS for MSP430 and AVR. ([#31](https://github.com/taiki-e/portable-atomic/pull/31)) + + This previously required unsafe cfg `portable_atomic_unsafe_assume_single_core`, but since all MSP430 and AVR are single-core, we can safely provide atomic CAS based on disabling interrupts. + +- Support `fence` and `compiler_fence` on MSP430. (On MSP430, the standard library's fences are currently unavailable due to LLVM errors.) + +- Update safety requirements for unsafe cfg `portable_atomic_unsafe_assume_single_core` to mention use of privileged instructions to disable interrupts. + +- Atomic operations based on disabling interrupts on single-core systems are now considered lock-free. + + The previous behavior was inconsistent because we consider the pre-v6 Arm Linux's atomic operations provided in a similar way by the Linux kernel to be lock-free. + +- Respect `-Z allow-features`. + +## [0.3.10] - 2022-08-03 + +- Optimize AArch64 128-bit atomic load when the `lse` target feature is enabled at compile-time. ([#20](https://github.com/taiki-e/portable-atomic/pull/20)) + +## [0.3.9] - 2022-08-03 + +- Fix build error on old Miri. + +- Documentation improvements. + +## [0.3.8] - 2022-08-02 + +- Make AArch64 and s390x 128-bit atomics compatible with Miri and ThreadSanitizer. + +## [0.3.7] - 2022-07-31 + +- Provide stable equivalent of [`#![feature(strict_provenance_atomic_ptr)]`](https://github.com/rust-lang/rust/issues/99108). ([#23](https://github.com/taiki-e/portable-atomic/pull/23)) + + - `AtomicPtr::fetch_ptr_{add,sub}` + - `AtomicPtr::fetch_byte_{add,sub}` + - `AtomicPtr::fetch_{or,and,xor}` + + These APIs are compatible with strict-provenance on `cfg(miri)`. Otherwise, they are compatible with permissive-provenance. + Once `#![feature(strict_provenance_atomic_ptr)]` is stabilized, these APIs will be strict-provenance compatible in all cases from the version in which it is stabilized. + +- Provide stable equivalent of [`#![feature(atomic_bool_fetch_not)]`](https://github.com/rust-lang/rust/issues/98485). ([#24](https://github.com/taiki-e/portable-atomic/pull/24)) + + - `AtomicBool::fetch_not` + +- Optimize x86_64 128-bit RMWs. ([#22](https://github.com/taiki-e/portable-atomic/pull/22)) + +- Optimize x86_64 outline-atomics. + +- Optimize inline assemblies on Arm and AArch64. + +- Revert [thumbv6m atomic load/store changes made in 0.3.5](https://github.com/taiki-e/portable-atomic/pull/18). This is because [rust-lang/rust#99595](https://github.com/rust-lang/rust/pull/99595) has been reverted, so this is no longer needed. + +## [0.3.6] - 2022-07-26 + +- Fix build failure due to the existence of the `specs` directory. + +- Documentation improvements. + +- Optimize inline assemblies on x86_64, RISC-V, and MSP430. + +## [0.3.5] - 2022-07-23 + +**Note:** This release has been yanked due to a bug fixed in 0.3.6. + +- Provide thumbv6m atomic load/store which is planned to be removed from the standard library in [rust-lang/rust#99595](https://github.com/rust-lang/rust/pull/99595). ([#18](https://github.com/taiki-e/portable-atomic/pull/18)) + +- Optimize inline assemblies on AArch64, RISC-V, and powerpc64. + +## [0.3.4] - 2022-06-25 + +- Optimize x86_64 128-bit atomic store. + +## [0.3.3] - 2022-06-24 + +- Allow CAS failure ordering stronger than success ordering. ([#17](https://github.com/taiki-e/portable-atomic/pull/17)) + +## [0.3.2] - 2022-06-19 + +- Optimize x86_64 128-bit atomic load/store on Intel CPU with AVX. ([#16](https://github.com/taiki-e/portable-atomic/pull/16)) + +- Support native 128-bit atomic operations for powerpc64 (le or pwr8+, currently nightly-only). + +- Fix behavior differences between stable and nightly. ([#15](https://github.com/taiki-e/portable-atomic/pull/15)) + +## [0.3.1] - 2022-06-16 + +- Optimize AArch64 128-bit atomic load/store when the `lse2` target feature is enabled at compile-time. ([#11](https://github.com/taiki-e/portable-atomic/pull/11)) + +- Relax ordering in `Debug` impl to reflect std changes. ([#12](https://github.com/taiki-e/portable-atomic/pull/12)) + +## [0.3.0] - 2022-03-25 + +- Support native 128-bit atomic operations for s390x (currently nightly-only). + +- Add `AtomicF{32,64}::fetch_abs`. + +- Add `#[must_use]` to constructors. + +- Use 128-bit atomic operation mappings same as LLVM on AArch64. + +- Remove `parking_lot` optional feature to allow the use of this crate within global allocators. + +## [0.2.1] - 2022-03-17 + +- Implement AArch64 outline-atomics. + +## [0.2.0] - 2022-03-10 + +- Remove `i128` feature. `Atomic{I,U}128` are now always enabled. + +- Add `outline-atomics` feature. Currently, this is the same as the 0.1's `i128-dynamic`, except that `fallback` feature is not implicitly enabled. + +- Remove `i128-dynamic` feature in favor of `outline-atomics` feature. + +- Add `AtomicF{32,64}::as_bits`. + +## [0.1.4] - 2022-03-02 + +- Support native 128-bit atomic operations for AArch64 at Rust 1.59+. This was previously supported only on nightly. ([#6](https://github.com/taiki-e/portable-atomic/pull/6)) + +## [0.1.3] - 2022-02-28 + +- Fix inline assembly for RISC-V without A-extension. + +## [0.1.2] - 2022-02-26 + +**Note:** This release has been yanked due to a bug fixed in 0.1.3. + +- Add `parking_lot` feature to use parking_lot in global locks of fallback implementation. + +- Fix bug in cmpxchg16b support. ([#5](https://github.com/taiki-e/portable-atomic/pull/5)) + +## [0.1.1] - 2022-02-25 + +**Note:** This release has been yanked due to a bug fixed in 0.1.3. + +- Fix doc cfg on `Atomic{I,U}128`. + +## [0.1.0] - 2022-02-24 + +**Note:** This release has been yanked due to a bug fixed in 0.1.3. + +Initial release + +[Unreleased]: https://github.com/taiki-e/portable-atomic/compare/v1.15.0...HEAD +[1.15.0]: https://github.com/taiki-e/portable-atomic/compare/v1.14.0...v1.15.0 +[1.14.0]: https://github.com/taiki-e/portable-atomic/compare/v1.13.1...v1.14.0 +[1.13.1]: https://github.com/taiki-e/portable-atomic/compare/v1.13.0...v1.13.1 +[1.13.0]: https://github.com/taiki-e/portable-atomic/compare/v1.12.0...v1.13.0 +[1.12.0]: https://github.com/taiki-e/portable-atomic/compare/v1.11.1...v1.12.0 +[1.11.1]: https://github.com/taiki-e/portable-atomic/compare/v1.11.0...v1.11.1 +[1.11.0]: https://github.com/taiki-e/portable-atomic/compare/v1.10.0...v1.11.0 +[1.10.0]: https://github.com/taiki-e/portable-atomic/compare/v1.9.0...v1.10.0 +[1.9.0]: https://github.com/taiki-e/portable-atomic/compare/v1.8.0...v1.9.0 +[1.8.0]: https://github.com/taiki-e/portable-atomic/compare/v1.7.0...v1.8.0 +[1.7.0]: https://github.com/taiki-e/portable-atomic/compare/v1.6.0...v1.7.0 +[1.6.0]: https://github.com/taiki-e/portable-atomic/compare/v1.5.1...v1.6.0 +[1.5.1]: https://github.com/taiki-e/portable-atomic/compare/v1.5.0...v1.5.1 +[1.5.0]: https://github.com/taiki-e/portable-atomic/compare/v1.4.3...v1.5.0 +[1.4.3]: https://github.com/taiki-e/portable-atomic/compare/v1.4.2...v1.4.3 +[1.4.2]: https://github.com/taiki-e/portable-atomic/compare/v1.4.1...v1.4.2 +[1.4.1]: https://github.com/taiki-e/portable-atomic/compare/v1.4.0...v1.4.1 +[1.4.0]: https://github.com/taiki-e/portable-atomic/compare/v1.3.3...v1.4.0 +[1.3.3]: https://github.com/taiki-e/portable-atomic/compare/v1.3.2...v1.3.3 +[1.3.2]: https://github.com/taiki-e/portable-atomic/compare/v1.3.1...v1.3.2 +[1.3.1]: https://github.com/taiki-e/portable-atomic/compare/v1.3.0...v1.3.1 +[1.3.0]: https://github.com/taiki-e/portable-atomic/compare/v1.2.0...v1.3.0 +[1.2.0]: https://github.com/taiki-e/portable-atomic/compare/v1.1.0...v1.2.0 +[1.1.0]: https://github.com/taiki-e/portable-atomic/compare/v1.0.1...v1.1.0 +[1.0.1]: https://github.com/taiki-e/portable-atomic/compare/v1.0.0...v1.0.1 +[1.0.0]: https://github.com/taiki-e/portable-atomic/compare/v0.3.19...v1.0.0 +[0.3.20]: https://github.com/taiki-e/portable-atomic/compare/v0.3.19...v0.3.20 +[0.3.19]: https://github.com/taiki-e/portable-atomic/compare/v0.3.18...v0.3.19 +[0.3.18]: https://github.com/taiki-e/portable-atomic/compare/v0.3.17...v0.3.18 +[0.3.17]: https://github.com/taiki-e/portable-atomic/compare/v0.3.16...v0.3.17 +[0.3.16]: https://github.com/taiki-e/portable-atomic/compare/v0.3.15...v0.3.16 +[0.3.15]: https://github.com/taiki-e/portable-atomic/compare/v0.3.14...v0.3.15 +[0.3.14]: https://github.com/taiki-e/portable-atomic/compare/v0.3.13...v0.3.14 +[0.3.13]: https://github.com/taiki-e/portable-atomic/compare/v0.3.12...v0.3.13 +[0.3.12]: https://github.com/taiki-e/portable-atomic/compare/v0.3.11...v0.3.12 +[0.3.11]: https://github.com/taiki-e/portable-atomic/compare/v0.3.10...v0.3.11 +[0.3.10]: https://github.com/taiki-e/portable-atomic/compare/v0.3.9...v0.3.10 +[0.3.9]: https://github.com/taiki-e/portable-atomic/compare/v0.3.8...v0.3.9 +[0.3.8]: https://github.com/taiki-e/portable-atomic/compare/v0.3.7...v0.3.8 +[0.3.7]: https://github.com/taiki-e/portable-atomic/compare/v0.3.6...v0.3.7 +[0.3.6]: https://github.com/taiki-e/portable-atomic/compare/v0.3.5...v0.3.6 +[0.3.5]: https://github.com/taiki-e/portable-atomic/compare/v0.3.4...v0.3.5 +[0.3.4]: https://github.com/taiki-e/portable-atomic/compare/v0.3.3...v0.3.4 +[0.3.3]: https://github.com/taiki-e/portable-atomic/compare/v0.3.2...v0.3.3 +[0.3.2]: https://github.com/taiki-e/portable-atomic/compare/v0.3.1...v0.3.2 +[0.3.1]: https://github.com/taiki-e/portable-atomic/compare/v0.3.0...v0.3.1 +[0.3.0]: https://github.com/taiki-e/portable-atomic/compare/v0.2.1...v0.3.0 +[0.2.1]: https://github.com/taiki-e/portable-atomic/compare/v0.2.0...v0.2.1 +[0.2.0]: https://github.com/taiki-e/portable-atomic/compare/v0.1.4...v0.2.0 +[0.1.4]: https://github.com/taiki-e/portable-atomic/compare/v0.1.3...v0.1.4 +[0.1.3]: https://github.com/taiki-e/portable-atomic/compare/v0.1.2...v0.1.3 +[0.1.2]: https://github.com/taiki-e/portable-atomic/compare/v0.1.1...v0.1.2 +[0.1.1]: https://github.com/taiki-e/portable-atomic/compare/v0.1.0...v0.1.1 +[0.1.0]: https://github.com/taiki-e/portable-atomic/releases/tag/v0.1.0 diff --git a/vendor/portable-atomic/Cargo.lock b/vendor/portable-atomic/Cargo.lock new file mode 100644 index 0000000..88cb40d --- /dev/null +++ b/vendor/portable-atomic/Cargo.lock @@ -0,0 +1,203 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "build-context" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "crossbeam-utils" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.163 (registry+https://github.com/rust-lang/crates.io-index)", + "r-efi 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.163" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "portable-atomic" +version = "1.15.0" +dependencies = [ + "build-context 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "critical-section 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)", + "fastrand 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.163 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", + "quickcheck 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustversion 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.229 (registry+https://github.com/rust-lang/crates.io-index)", + "sptr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "windows-sys 0.61.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-ident 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quickcheck" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.107 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde_core 1.0.229 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde_derive 1.0.229 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.107 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.107 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-ident 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "windows-link 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum build-context 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ebb068a5ba5b65a7cdba869497ca2a352e88e6093c4909ddf4d12d9d3151ee9c" +"checksum cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +"checksum critical-section 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" +"checksum crossbeam-utils 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)" = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" +"checksum fastrand 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" +"checksum getrandom 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +"checksum libc 0.2.163 (registry+https://github.com/rust-lang/crates.io-index)" = "1fdaeca4cf44ed4ac623e86ef41f056e848dbeab7ec043ecb7326ba300b36fd0" +"checksum paste 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +"checksum proc-macro2 1.0.107 (registry+https://github.com/rust-lang/crates.io-index)" = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +"checksum quickcheck 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95c589f335db0f6aaa168a7cd27b1fc6920f5e1470c804f814d9cd6e62a0f70b" +"checksum quote 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +"checksum r-efi 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +"checksum rand 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" +"checksum rand_core 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" +"checksum rustversion 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" +"checksum serde 1.0.229 (registry+https://github.com/rust-lang/crates.io-index)" = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +"checksum serde_core 1.0.229 (registry+https://github.com/rust-lang/crates.io-index)" = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +"checksum serde_derive 1.0.229 (registry+https://github.com/rust-lang/crates.io-index)" = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +"checksum sptr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" +"checksum static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +"checksum syn 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +"checksum unicode-ident 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +"checksum windows-link 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +"checksum windows-sys 0.61.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" diff --git a/vendor/portable-atomic/Cargo.toml b/vendor/portable-atomic/Cargo.toml new file mode 100644 index 0000000..106bf29 --- /dev/null +++ b/vendor/portable-atomic/Cargo.toml @@ -0,0 +1,266 @@ +# 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.34" +name = "portable-atomic" +version = "1.15.0" +build = "build.rs" +exclude = [ + "/.*", + "/tools", + "/target-specs", + "/DEVELOPMENT.md", +] +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = """ +Portable atomic types including support for 128-bit atomics, atomic float, etc. +""" +readme = "README.md" +keywords = ["atomic"] +categories = [ + "concurrency", + "embedded", + "hardware-support", + "no-std", + "no-std::no-alloc", +] +license = "Apache-2.0 OR MIT" +repository = "https://github.com/taiki-e/portable-atomic" + +[package.metadata.docs.rs] +features = [ + "float", + "std", + "serde", + "critical-section", +] +rustdoc-args = [ + "--extend-css", + "src/rustdoc.css", + "--cfg", + "portable_atomic_unstable_f16", + "--cfg", + "portable_atomic_unstable_f128", +] +targets = ["x86_64-unknown-linux-gnu"] + +[package.metadata.cargo_check_external_types] +allowed_external_types = ["serde_core::*"] + +[features] +default = ["fallback"] +disable-fiq = [] +fallback = [] +float = [] +force-amo = [] +require-cas = [] +s-mode = [] +std = [] +unsafe-assume-privileged = [] +unsafe-assume-single-core = [] + +[lib] +name = "portable_atomic" +path = "src/lib.rs" +doc-scrape-examples = false + +[dependencies.critical-section] +version = "1" +optional = true + +[dependencies.serde] +version = "1.0.60" +optional = true +default-features = false + +[dev-dependencies.build-context] +version = "0.1" + +[dev-dependencies.crossbeam-utils] +version = "0.8" + +[dev-dependencies.fastrand] +version = "2" + +[dev-dependencies.paste] +version = "1" + +[dev-dependencies.quickcheck] +version = "1" +default-features = false + +[dev-dependencies.rustversion] +version = "1" + +[dev-dependencies.sptr] +version = "0.3" + +[dev-dependencies.static_assertions] +version = "1" + +[target."cfg(unix)".dev-dependencies.libc] +version = "=0.2.163" + +[target."cfg(windows)".dev-dependencies.windows-sys] +version = "0.61" +features = [ + "Win32_Foundation", + "Win32_System_Threading", +] + +[lints.clippy] +all = "warn" +as_ptr_cast_mut = "warn" +as_underscore = "warn" +default_union_representation = "warn" +inline_asm_x86_att_syntax = "warn" +pedantic = "warn" +trailing_empty_array = "warn" +transmute_undefined_repr = "warn" +undocumented_unsafe_blocks = "warn" +unused_trait_names = "warn" + +[lints.clippy.assert_is_empty] +level = "allow" +priority = 1 + +[lints.clippy.bool_assert_comparison] +level = "allow" +priority = 1 + +[lints.clippy.borrow_as_ptr] +level = "allow" +priority = 1 + +[lints.clippy.cast_lossless] +level = "allow" +priority = 1 + +[lints.clippy.collapsible_match] +level = "allow" +priority = 1 + +[lints.clippy.declare_interior_mutable_const] +level = "allow" +priority = 1 + +[lints.clippy.doc_markdown] +level = "allow" +priority = 1 + +[lints.clippy.float_cmp] +level = "allow" +priority = 1 + +[lints.clippy.incompatible_msrv] +level = "allow" +priority = 1 + +[lints.clippy.manual_assert] +level = "allow" +priority = 1 + +[lints.clippy.manual_range_contains] +level = "allow" +priority = 1 + +[lints.clippy.missing_errors_doc] +level = "allow" +priority = 1 + +[lints.clippy.module_name_repetitions] +level = "allow" +priority = 1 + +[lints.clippy.naive_bytecount] +level = "allow" +priority = 1 + +[lints.clippy.nonminimal_bool] +level = "allow" +priority = 1 + +[lints.clippy.range_plus_one] +level = "allow" +priority = 1 + +[lints.clippy.similar_names] +level = "allow" +priority = 1 + +[lints.clippy.single_match] +level = "allow" +priority = 1 + +[lints.clippy.single_match_else] +level = "allow" +priority = 1 + +[lints.clippy.struct_excessive_bools] +level = "allow" +priority = 1 + +[lints.clippy.struct_field_names] +level = "allow" +priority = 1 + +[lints.clippy.too_many_arguments] +level = "allow" +priority = 1 + +[lints.clippy.too_many_lines] +level = "allow" +priority = 1 + +[lints.clippy.type_complexity] +level = "allow" +priority = 1 + +[lints.rust] +deprecated_safe = "warn" +improper_ctypes = "warn" +improper_ctypes_definitions = "warn" +non_ascii_idents = "warn" +rust_2018_idioms = "warn" +single_use_lifetimes = "warn" +unnameable_types = "warn" +unreachable_pub = "warn" + +[lints.rust.unexpected_cfgs] +level = "warn" +priority = 0 +check-cfg = [ + 'cfg(target_arch,values("xtensa"))', + 'cfg(target_arch,values("amdgpu"))', + 'cfg(target_arch,values("loongarch32"))', + 'cfg(target_os,values("trusty"))', + 'cfg(target_os,values("psx"))', + 'cfg(target_os,values("zos"))', + 'cfg(target_env,values("psx"))', + 'cfg(target_feature,values("lse2","lse128","rcpc3"))', + 'cfg(target_feature,values("quadword-atomics"))', + 'cfg(target_feature,values("zaamo","zabha"))', + 'cfg(target_feature,values("zacas"))', + 'cfg(target_feature,values("ztso"))', + 'cfg(target_feature,values("miscellaneous-extensions-3"))', + 'cfg(target_pointer_width,values("128"))', + "cfg(portable_atomic_no_outline_atomics,portable_atomic_outline_atomics,portable_atomic_unstable_f16,portable_atomic_unstable_f128)", + "cfg(portable_atomic_test_detect_false,portable_atomic_test_no_std_static_assert_ffi,qemu,valgrind,valgrind_cross)", +] + +[profile.release] +debug = 2 diff --git a/vendor/portable-atomic/Cargo.toml.orig b/vendor/portable-atomic/Cargo.toml.orig new file mode 100644 index 0000000..33dab6d --- /dev/null +++ b/vendor/portable-atomic/Cargo.toml.orig @@ -0,0 +1,160 @@ +[package] +name = "portable-atomic" +version = "1.15.0" #publish:version +edition = "2018" +# NB: Sync with rust-version field in other Cargo.toml files and msrv badge in README.md +rust-version = "1.34" # For Atomic{I,U}{8,16,32,64} +license = "Apache-2.0 OR MIT" +repository = "https://github.com/taiki-e/portable-atomic" +keywords = ["atomic"] +categories = ["concurrency", "embedded", "hardware-support", "no-std", "no-std::no-alloc"] +exclude = ["/.*", "/tools", "/target-specs", "/DEVELOPMENT.md"] +description = """ +Portable atomic types including support for 128-bit atomics, atomic float, etc. +""" + +[package.metadata.docs.rs] +# NB: sync with: +# - env.TEST_FEATURES in .github/workflows/ci.yml. +# - test_features list in tools/build.sh and tools/test.sh. +features = ["float", "std", "serde", "critical-section"] +rustdoc-args = ["--extend-css", "src/rustdoc.css", "--cfg", "portable_atomic_unstable_f16", "--cfg", "portable_atomic_unstable_f128"] +targets = ["x86_64-unknown-linux-gnu"] + +[package.metadata.cargo_check_external_types] +# The following are external types that are allowed to be exposed in our public API. +allowed_external_types = [ + "serde_core::*", +] + +[lib] +doc-scrape-examples = false + +# Please read the documentation before using optional features: +# https://github.com/taiki-e/portable-atomic#optional-features +[features] +default = ["fallback"] +fallback = [] +float = [] +std = [] +require-cas = [] +unsafe-assume-single-core = [] +unsafe-assume-privileged = [] +s-mode = [] +force-amo = [] +disable-fiq = [] + +# Note: serde and critical-section are public dependencies. +[dependencies] +# Please read the documentation before using optional features: +# https://github.com/taiki-e/portable-atomic#optional-features +serde = { version = "1.0.60", optional = true, default-features = false } +critical-section = { version = "1", optional = true } + +# [target.'cfg(portable_atomic_test_no_std_static_assert_ffi)'.dependencies] #build:static_assert_ffi +# test-helper = { features = ["sys"], git = "https://github.com/taiki-e/test-helper.git", rev = "24b3ad70c19ea8de9cd4c87f2e549b930f1e3305" } #build:static_assert_ffi +# [target.'cfg(all(portable_atomic_test_no_std_static_assert_ffi, target_os = "aix"))'.dependencies] #build:static_assert_ffi +# libc = "=0.2.163" #build:static_assert_ffi + +[dev-dependencies] +build-context = "0.1" +crossbeam-utils = "0.8" +fastrand = "2" +paste = "1" +quickcheck = { version = "1", default-features = false, git = "https://github.com/taiki-e/quickcheck.git", rev = "83b1d5955557fc9dacc52d4a78098d8e6d7eda3b" } # https://github.com/BurntSushi/quickcheck/pull/304 + https://github.com/BurntSushi/quickcheck/pull/282 + https://github.com/BurntSushi/quickcheck/pull/296 + f16/f128 support + lower MSRV +rustversion = "1" +serde_test = { git = "https://github.com/taiki-e/serde_test.git", rev = "df513c55a97f0a72fa67bad5396ed09123e5676c" } # support {i,u}128 +sptr = "0.3" +static_assertions = "1" +test-helper = { features = ["sys", "critical-section-std", "valgrind"], git = "https://github.com/taiki-e/test-helper.git", rev = "24b3ad70c19ea8de9cd4c87f2e549b930f1e3305" } + +[target.'cfg(unix)'.dev-dependencies] +libc = "=0.2.163" # newer libc requires Rust 1.63 + +[target.'cfg(windows)'.dev-dependencies] +windows-sys = { version = "0.61", features = [ + "Win32_Foundation", + "Win32_System_Threading", # IsProcessorFeaturePresent +] } + +[lints] +workspace = true + +[workspace] +members = [ + "bench", + "tests/api-test", +] + +# This table is shared by projects under github.com/taiki-e. +# Expect for unexpected_cfgs.check-cfg, it is not intended for manual editing. +[workspace.lints.rust] +deprecated_safe = "warn" +improper_ctypes = "warn" +improper_ctypes_definitions = "warn" +non_ascii_idents = "warn" +rust_2018_idioms = "warn" +single_use_lifetimes = "warn" +unexpected_cfgs = { level = "warn", check-cfg = [ + 'cfg(target_arch,values("xtensa"))', # 1.81+ https://github.com/rust-lang/rust/pull/125141 + 'cfg(target_arch,values("amdgpu"))', # 1.86+ https://github.com/rust-lang/rust/pull/134740 + 'cfg(target_arch,values("loongarch32"))', # 1.89+ https://github.com/rust-lang/rust/pull/142053 + 'cfg(target_os,values("trusty"))', # 1.82+ https://github.com/rust-lang/rust/pull/129490 + 'cfg(target_os,values("psx"))', # 1.84+ https://github.com/rust-lang/rust/pull/131168 + 'cfg(target_os,values("zos"))', # https://github.com/rust-lang/compiler-team/issues/992 + 'cfg(target_env,values("psx"))', # pre-1.84 https://github.com/rust-lang/rust/pull/131168 + 'cfg(target_feature,values("lse2","lse128","rcpc3"))', # 1.82+ https://github.com/rust-lang/rust/pull/128192 + 'cfg(target_feature,values("quadword-atomics"))', # 1.83+ https://github.com/rust-lang/rust/pull/130873 + 'cfg(target_feature,values("zaamo","zabha"))', # 1.83+ https://github.com/rust-lang/rust/pull/130877 + 'cfg(target_feature,values("zacas"))', # 1.87+ https://github.com/rust-lang/rust/pull/137417 + 'cfg(target_feature,values("ztso"))', # 1.88+ https://github.com/rust-lang/rust/pull/139440 + 'cfg(target_feature,values("miscellaneous-extensions-3"))', # 1.89+ https://github.com/rust-lang/rust/pull/141250 + 'cfg(target_pointer_width,values("128"))', + # Known custom cfgs, excluding those that may be set by build script. + # Public APIs, considered unstable unless documented as stable in readme. + 'cfg(portable_atomic_no_outline_atomics,portable_atomic_outline_atomics,portable_atomic_unstable_f16,portable_atomic_unstable_f128)', + # Not public API. + 'cfg(portable_atomic_test_detect_false,portable_atomic_test_no_std_static_assert_ffi,qemu,valgrind,valgrind_cross)', +] } +unnameable_types = "warn" +unreachable_pub = "warn" +# unsafe_op_in_unsafe_fn = "warn" # Set at crate-level instead since https://github.com/rust-lang/rust/pull/100081 merged in Rust 1.65 is not available on MSRV +[workspace.lints.clippy] +all = "warn" # Downgrade deny-by-default lints +pedantic = "warn" +as_ptr_cast_mut = "warn" +as_underscore = "warn" +default_union_representation = "warn" +inline_asm_x86_att_syntax = "warn" +trailing_empty_array = "warn" +transmute_undefined_repr = "warn" +undocumented_unsafe_blocks = "warn" +unused_trait_names = "warn" +# Suppress buggy or noisy clippy lints +assert_is_empty = { level = "allow", priority = 1 } # completely useless in assert_ne case +bool_assert_comparison = { level = "allow", priority = 1 } +borrow_as_ptr = { level = "allow", priority = 1 } # https://github.com/rust-lang/rust-clippy/issues/8286 +cast_lossless = { level = "allow", priority = 1 } # suggested code has poor codegen with -C opt-level=0 https://godbolt.org/z/GzTxzbd9q +collapsible_match = { level = "allow", priority = 1 } +declare_interior_mutable_const = { level = "allow", priority = 1 } # https://github.com/rust-lang/rust-clippy/issues/7665 +doc_markdown = { level = "allow", priority = 1 } +float_cmp = { level = "allow", priority = 1 } # https://github.com/rust-lang/rust-clippy/issues/7725 +incompatible_msrv = { level = "allow", priority = 1 } # buggy: doesn't consider cfg, https://github.com/rust-lang/rust-clippy/issues/12280, https://github.com/rust-lang/rust-clippy/issues/12257#issuecomment-2093667187 +manual_assert = { level = "allow", priority = 1 } +manual_range_contains = { level = "allow", priority = 1 } # https://github.com/rust-lang/rust-clippy/issues/6455#issuecomment-1225966395 +missing_errors_doc = { level = "allow", priority = 1 } +module_name_repetitions = { level = "allow", priority = 1 } # buggy: https://github.com/rust-lang/rust-clippy/issues?q=is%3Aissue+is%3Aopen+module_name_repetitions +naive_bytecount = { level = "allow", priority = 1 } +nonminimal_bool = { level = "allow", priority = 1 } # buggy: https://github.com/rust-lang/rust-clippy/issues?q=is%3Aissue+is%3Aopen+nonminimal_bool +range_plus_one = { level = "allow", priority = 1 } # buggy: https://github.com/rust-lang/rust-clippy/issues?q=is%3Aissue+is%3Aopen+range_plus_one +similar_names = { level = "allow", priority = 1 } +single_match = { level = "allow", priority = 1 } +single_match_else = { level = "allow", priority = 1 } +struct_excessive_bools = { level = "allow", priority = 1 } +struct_field_names = { level = "allow", priority = 1 } +too_many_arguments = { level = "allow", priority = 1 } +too_many_lines = { level = "allow", priority = 1 } +type_complexity = { level = "allow", priority = 1 } + +[profile.release] +debug = true diff --git a/vendor/portable-atomic/LICENSE-APACHE b/vendor/portable-atomic/LICENSE-APACHE new file mode 100644 index 0000000..f433b1a --- /dev/null +++ b/vendor/portable-atomic/LICENSE-APACHE @@ -0,0 +1,177 @@ + + 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/portable-atomic/LICENSE-MIT b/vendor/portable-atomic/LICENSE-MIT new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/vendor/portable-atomic/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/portable-atomic/README.md b/vendor/portable-atomic/README.md new file mode 100644 index 0000000..18e127c --- /dev/null +++ b/vendor/portable-atomic/README.md @@ -0,0 +1,250 @@ +# portable-atomic + +[![crates.io](https://img.shields.io/crates/v/portable-atomic?style=flat-square&logo=rust)](https://crates.io/crates/portable-atomic) +[![docs.rs](https://img.shields.io/badge/docs.rs-portable--atomic-blue?style=flat-square&logo=docs.rs)](https://docs.rs/portable-atomic) +[![license](https://img.shields.io/badge/license-Apache--2.0_OR_MIT-blue?style=flat-square)](#license) +[![msrv](https://img.shields.io/badge/msrv-1.34-blue?style=flat-square&logo=rust)](https://www.rust-lang.org) +[![github actions](https://img.shields.io/github/actions/workflow/status/taiki-e/portable-atomic/ci.yml?branch=main&style=flat-square&logo=github)](https://github.com/taiki-e/portable-atomic/actions) + + + +Portable atomic types including support for 128-bit atomics, atomic float, etc. + +- Provide all atomic integer types (`Atomic{I,U}{8,16,32,64}`) for all targets that can use atomic CAS. (i.e., all targets that can use `std`, and most no-std targets) +- Provide `AtomicI128` and `AtomicU128`. +- Provide `AtomicF32` and `AtomicF64`. ([optional, requires the `float` feature](#optional-features-float)) +- Provide `AtomicF16` and `AtomicF128` for [unstable `f16` and `f128`](https://github.com/rust-lang/rust/issues/116909). ([optional, requires the `float` feature and unstable cfgs](#optional-features-float)) +- Provide atomic load/store for targets where atomic is not available at all in the standard library. (RISC-V without A-extension, MSP430, AVR) +- Provide atomic CAS for targets where atomic CAS is not available in the standard library. (thumbv6m, pre-v6 Arm, RISC-V without A-extension, MSP430, AVR, Xtensa, etc.) (always enabled for MSP430 and AVR, [optional](#optional-features-critical-section) otherwise) +- Make features that require newer compilers, such as [`fetch_{max,min}`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.fetch_max), [`fetch_update`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.fetch_update), [`as_ptr`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.as_ptr), [`from_ptr`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.from_ptr), [`AtomicBool::fetch_not`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicBool.html#method.fetch_not), [`AtomicPtr::fetch_*`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicPtr.html#method.fetch_and), and [stronger CAS failure ordering](https://github.com/rust-lang/rust/pull/98383) available on Rust 1.34+. +- Provide workaround for bugs in the standard library's atomic-related APIs, such as [rust-lang/compiler-builtins#1234], [rust-lang/rust#100650], `fence`/`compiler_fence` on MSP430 that cause LLVM error, etc. + + + +portable-atomic version of `std::sync::Arc` and `std::task::Wake` is provided by the [portable-atomic-util] crate. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +portable-atomic = "1" +``` + +The default features are mainly for users who use atomics larger than the pointer width. +If you don't need them, disabling the default features may reduce code size and compile time slightly. + +```toml +[dependencies] +portable-atomic = { version = "1", default-features = false } +``` + +If your crate supports no-std environment and requires atomic CAS, enabling the `require-cas` feature will allow the portable-atomic to display a [helpful error message](https://github.com/taiki-e/portable-atomic/pull/100) to users on targets requiring additional action on the user side to provide atomic CAS. + +```toml +[dependencies] +portable-atomic = { version = "1.3", default-features = false, features = ["require-cas"] } +``` + +(Since 1.8, portable-atomic can display a [helpful error message](https://github.com/taiki-e/portable-atomic/pull/181) even without the `require-cas` feature when the rustc version is 1.78+. However, the `require-cas` feature also allows rejecting builds at an earlier stage, we recommend enabling it unless enabling it causes [problems](https://github.com/matklad/once_cell/pull/267).) + +## 128-bit atomics support + +Native 128-bit atomic operations are available on x86_64 (Rust 1.59+), AArch64 (Rust 1.59+), riscv64 (Rust 1.59+), Arm64EC (Rust 1.84+), s390x (Rust 1.84+), and powerpc64 (Rust 1.95+), otherwise the fallback implementation is used. + +On x86_64, even if `cmpxchg16b` is not available at compile-time (Note: `cmpxchg16b` target feature is enabled by default only on Apple, Windows (except Windows 7), and Fuchsia targets), run-time detection checks whether `cmpxchg16b` is available. If `cmpxchg16b` is not available at either compile-time or run-time detection, the fallback implementation is used. See also [`portable_atomic_no_outline_atomics`](#optional-cfg-no-outline-atomics) cfg. + +They are usually implemented using inline assembly, and when using Miri or ThreadSanitizer that do not support inline assembly, core intrinsics are used instead of inline assembly if possible. + +See the [`atomic128` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/atomic128/README.md) for details. + +## Optional features/cfgs + +portable-atomic provides features and cfgs to allow enabling specific APIs and customizing its behavior. + +Some options have both a feature and a cfg. When both exist, it indicates that the feature does not follow Cargo's recommendation that [features should be additive](https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-unification). Therefore, the maintainer's recommendation is to use cfg instead of feature. However, in the embedded ecosystem, it is very common to use features in such places, so these options provide both so you can choose based on your preference. + +
+How to enable cfg (click to show) + +One of the ways to enable cfg is to set [rustflags in the cargo config](https://doc.rust-lang.org/cargo/reference/config.html#targettriplerustflags): + +```toml +# .cargo/config.toml +[target.] +rustflags = ["--cfg", "portable_atomic_unsafe_assume_single_core"] +``` + +Or set environment variable: + +```sh +RUSTFLAGS="--cfg portable_atomic_unsafe_assume_single_core" cargo ... +``` + +
+ +- **`fallback` feature** *(enabled by default)*
+ Enable fallback implementations. + + This enables atomic types with larger than the width supported by atomic instructions available on the current target. If the current target [supports 128-bit atomics](#128-bit-atomics-support), this is no-op. + + This uses fallback implementation that using global locks by default. The following features/cfgs change this behavior: + - [`unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg](#optional-features-unsafe-assume-single-core): Use fallback implementations that disabling interrupts instead of using global locks. + - If your target is single-core and calling interrupt disable instructions is safe, this is a safer and more efficient option. + - [`unsafe-assume-privileged` feature / `portable_atomic_unsafe_assume_privileged` cfg](#optional-features-unsafe-assume-privileged): Use fallback implementations that using global locks with disabling interrupts. + - If your target is multi-core and calling interrupt disable instructions is safe, this is a safer option. + +- **`float` feature**
+ Provide `AtomicF{32,64}`. + + If you want atomic types for unstable float types ([`f16` and `f128`](https://github.com/rust-lang/rust/issues/116909)), enable unstable cfg (`portable_atomic_unstable_f16` cfg for `AtomicF16`, `portable_atomic_unstable_f128` cfg for `AtomicF128`, [there is no possibility that both feature and cfg will be provided for unstable options.](https://github.com/taiki-e/portable-atomic/pull/200#issuecomment-2682252991)). + +> [!NOTE] +> - Atomic float's `fetch_{add,sub,min,max}` are usually implemented using CAS loops, which can be slower than equivalent operations of atomic integers. As an exception, AArch64 with FEAT_LSFE and GPU targets have atomic float instructions and we use them on AArch64 when `lsfe` target feature is available at compile-time. We [plan to use atomic float instructions for GPU targets as well in the future.](https://github.com/taiki-e/portable-atomic/issues/34) +> - Unstable cfgs are outside of the normal semver guarantees and minor or patch versions of portable-atomic may make breaking changes to them at any time. + +- **`std` feature**
+ Use `std`. + +- **`require-cas` feature**
+ Emit compile error if atomic CAS is not available. See [Usage](#usage) section for usage of this feature. + +- **`serde` feature**
+ Implement `serde::{Serialize,Deserialize}` for atomic types. + + Note: + - The MSRV when this feature is enabled depends on the MSRV of [serde]. + +- **`critical-section` feature**
+ Use [critical-section] to provide atomic CAS for targets where atomic CAS is not available in the standard library. + + `critical-section` support is useful to get atomic CAS when the [`unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)](#optional-features-unsafe-assume-single-core) can't be used, + such as multi-core targets, unprivileged code running under some RTOS, or environments where disabling interrupts + needs extra care due to e.g. real-time requirements. + +> [!NOTE] +> - When enabling this feature, you should provide a suitable critical section implementation for the current target, see the [critical-section] documentation for details on how to do so. +> - With this feature, critical sections are taken for all atomic operations, while with `unsafe-assume-single-core` feature [some operations](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/interrupt/README.md#no-disable-interrupts) don't require disabling interrupts. Therefore, for better performance, if all the `critical-section` implementation for your target does is disable interrupts, prefer using `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg) instead. +> - It is usually **discouraged** to always enable this feature in libraries that depend on `portable-atomic`. +> +> Enabling this feature will prevent the end user from having the chance to take advantage of other (potentially) efficient implementations (implementations provided by `unsafe-assume-single-core` feature mentioned above, implementation proposed in [#60], etc.). Also, targets that are currently unsupported may be supported in the future. +> +> The recommended approach for libraries is to leave it up to the end user whether or not to enable this feature. (However, it may make sense to enable this feature by default for libraries specific to a platform where other implementations are known not to work.) +> +> See also [this comment](https://github.com/matklad/once_cell/issues/264#issuecomment-2352654806). +> +> As an example, the end-user's `Cargo.toml` that uses a crate that provides a critical-section implementation and a crate that depends on portable-atomic as an option would be expected to look like this: +> +> ```toml +> [dependencies] +> portable-atomic = { version = "1", default-features = false, features = ["critical-section"] } +> crate-provides-critical-section-impl = "..." +> crate-uses-portable-atomic-as-feature = { version = "...", features = ["portable-atomic"] } +> ``` +> +> - Enabling both this feature and `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg) will result in a compile error. +> - Enabling both this feature and `unsafe-assume-privileged` feature (or `portable_atomic_unsafe_assume_privileged` cfg) will result in a compile error. +> - The MSRV when this feature is enabled depends on the MSRV of [critical-section]. + +- **`unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg**
+ Assume that the target is single-core and privileged instructions required to disable interrupts are available. + + - When this feature/cfg is enabled, this crate provides atomic CAS for targets where atomic CAS is not available in the standard library by disabling interrupts. + - When both this feature/cfg and enabled-by-default `fallback` feature is enabled, this crate provides atomic types with larger than the width supported by native instructions by disabling interrupts. + +> [!WARNING] +> This feature/cfg is `unsafe`, and note the following safety requirements: +> - Enabling this feature/cfg for multi-core systems is always **unsound**. +> +> - This uses privileged instructions to disable interrupts, so it usually doesn't work on unprivileged mode. +> +> Enabling this feature/cfg in an environment where privileged instructions are not available, or if the instructions used are not sufficient to disable interrupts in the system, it is also usually considered **unsound**, although the details are system-dependent. +> +> The following are known cases: +> - On Arm (except for M-Profile architectures), this disables only IRQs by default. For many systems (e.g., GBA) this is enough. If the system need to disable both IRQs and FIQs, you need to enable the `disable-fiq` feature (or `portable_atomic_disable_fiq` cfg) together. +> - On RISC-V, this generates code for machine-mode (M-mode) by default. If you enable the `s-mode` feature (or `portable_atomic_s_mode` cfg) together, this generates code for supervisor-mode (S-mode). In particular, `qemu-system-riscv*` uses [OpenSBI](https://github.com/riscv-software-src/opensbi) as the default firmware. + +Consider using the [`unsafe-assume-privileged` feature (or `portable_atomic_unsafe_assume_privileged` cfg)](#optional-features-unsafe-assume-privileged) for multi-core systems with atomic CAS. + +Consider using the [`critical-section` feature](#optional-features-critical-section) for systems that cannot use this feature/cfg. + +See also the [`interrupt` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/interrupt/README.md). + +> [!NOTE] +> - It is **very strongly discouraged** to enable this feature/cfg in libraries that depend on `portable-atomic`. +> +> The recommended approach for libraries is to leave it up to the end user whether or not to enable this feature/cfg. (However, it may make sense to enable this feature/cfg by default for libraries specific to a platform where it is guaranteed to always be sound, for example in a hardware abstraction layer targeting a single-core chip.) +> - Enabling this feature/cfg for unsupported architectures will result in a compile error. +> - Arm, RISC-V, and Xtensa are currently supported. (Since all MSP430 and AVR are single-core, we always provide atomic CAS for them without this feature/cfg.) +> - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target is not supported yet. +> - Enabling this feature/cfg for targets where privileged instructions are obviously unavailable (e.g., Linux) will result in a compile error. +> - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target supports privileged instructions but the build rejected. +> - Enabling both this feature/cfg and `critical-section` feature will result in a compile error. +> - When both this feature/cfg and `unsafe-assume-privileged` feature (or `portable_atomic_unsafe_assume_privileged` cfg) are enabled, this feature/cfg is preferred. + +- **`unsafe-assume-privileged` feature / `portable_atomic_unsafe_assume_privileged` cfg**
+ Similar to `unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg, but only assumes about availability of privileged instructions required to disable interrupts. + + - When both this feature/cfg and enabled-by-default `fallback` feature is enabled, this crate provides atomic types with larger than the width supported by native instructions by using global locks with disabling interrupts. + +> [!WARNING] +> This feature/cfg is `unsafe`, and except for being sound in multi-core systems, this has the same safety requirements as [`unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg](#optional-features-unsafe-assume-single-core). + +> [!NOTE] +> - It is **very strongly discouraged** to enable this feature/cfg in libraries that depend on `portable-atomic`. +> +> The recommended approach for libraries is to leave it up to the end user whether or not to enable this feature/cfg. (However, it may make sense to enable this feature/cfg by default for libraries specific to a platform where it is guaranteed to always be sound, for example in a hardware abstraction layer.) +> - Enabling this feature/cfg for unsupported targets will result in a compile error. +> - This requires atomic CAS (`cfg(target_has_atomic = "ptr")` or `cfg_no_atomic_cas!`). +> - Arm, RISC-V, and Xtensa are currently supported. +> - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target is not supported yet. +> - Enabling this feature/cfg for targets where privileged instructions are obviously unavailable (e.g., Linux) will result in a compile error. +> - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target supports privileged instructions but the build rejected. +> - Enabling both this feature/cfg and `critical-section` feature will result in a compile error. +> - When both this feature/cfg and `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg) are enabled, `unsafe-assume-single-core` is preferred. + +- **`portable_atomic_no_outline_atomics` cfg**
+ Disable dynamic dispatching by run-time CPU feature detection. + + Dynamic dispatching by run-time CPU feature detection allows maintaining support for older CPUs while using features that are not supported on older CPUs, such as CMPXCHG16B (x86_64) and FEAT_LSE/FEAT_LSE2 (AArch64). + + See also the [`atomic128` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/atomic128/README.md). + +> [!NOTE] +> - If the required target features are enabled at compile-time, dynamic dispatching is automatically disabled and the atomic operations are inlined. +> - This is compatible with no-std (as with all features except `std`). +> - On some targets, run-time detection is disabled by default mainly for compatibility with incomplete build environments or support for it is experimental, and can be enabled by `portable_atomic_outline_atomics` cfg. (When both cfg are enabled, `*_no_*` cfg is preferred.) +> - Some AArch64 targets enable LLVM's `outline-atomics` target feature by default, so if you set this cfg, you may want to disable that as well. (However, portable-atomic's outline-atomics does not depend on the compiler-rt symbols, so even if you need to disable LLVM's outline-atomics, you may not need to disable portable-atomic's outline-atomics.) +> - Dynamic detection is currently only supported in x86_64, AArch64, Arm, RISC-V, Arm64EC, and powerpc64. Enabling this cfg for unsupported architectures will be ignored. + +## Related Projects + +- [portable-atomic-util]: Synchronization primitives built with portable-atomic. This provides portable-atomic version of `std::sync::Arc` and `std::task::Wake`. +- [atomic-maybe-uninit]: Atomic operations on potentially uninitialized integers. +- [atomic-memcpy]: Byte-wise atomic memcpy. +- [asmtest]: A library for tracking generated assemblies. + +[#60]: https://github.com/taiki-e/portable-atomic/issues/60 +[asmtest]: https://github.com/taiki-e/asmtest +[atomic-maybe-uninit]: https://github.com/taiki-e/atomic-maybe-uninit +[atomic-memcpy]: https://github.com/taiki-e/atomic-memcpy +[critical-section]: https://github.com/rust-embedded/critical-section +[portable-atomic-util]: https://github.com/taiki-e/portable-atomic-util +[rust-lang/compiler-builtins#1234]: https://github.com/rust-lang/compiler-builtins/pull/1234 +[rust-lang/rust#100650]: https://github.com/rust-lang/rust/issues/100650 +[serde]: https://github.com/serde-rs/serde + + + +## License + +Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or +[MIT license](LICENSE-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/portable-atomic/build.rs b/vendor/portable-atomic/build.rs new file mode 100644 index 0000000..a87ced3 --- /dev/null +++ b/vendor/portable-atomic/build.rs @@ -0,0 +1,629 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +// The rustc-cfg emitted by the build script are *not* public API. + +#![allow(clippy::match_same_arms)] // https://github.com/rust-lang/rust-clippy/issues/12044 + +#[path = "src/gen/build.rs"] +mod generated; +#[path = "version.rs"] +mod version; + +use std::{env, str}; + +use self::version::{Version, rustc_version}; + +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-changed=src/gen/build.rs"); + println!("cargo:rerun-if-changed=version.rs"); + + #[cfg(feature = "unsafe-assume-single-core")] + println!("cargo:rustc-cfg=portable_atomic_unsafe_assume_single_core"); + #[cfg(feature = "unsafe-assume-privileged")] + println!("cargo:rustc-cfg=portable_atomic_unsafe_assume_privileged"); + #[cfg(feature = "s-mode")] + println!("cargo:rustc-cfg=portable_atomic_s_mode"); + #[cfg(feature = "force-amo")] + println!("cargo:rustc-cfg=portable_atomic_force_amo"); + #[cfg(feature = "disable-fiq")] + println!("cargo:rustc-cfg=portable_atomic_disable_fiq"); + + let target = &*env::var("TARGET").expect("TARGET not set"); + let target_arch = &*env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH not set"); + let target_os = &*env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS not set"); + + let version = match rustc_version() { + Some(version) => version, + None => { + if env::var_os("PORTABLE_ATOMIC_DENY_WARNINGS").is_some() { + panic!("unable to determine rustc version") + } + println!( + "cargo:warning={}: unable to determine rustc version; assuming latest stable rustc (1.{})", + env!("CARGO_PKG_NAME"), + Version::LATEST.minor + ); + Version::LATEST + } + }; + + if version.minor >= 80 { + println!( + r#"cargo:rustc-check-cfg=cfg(target_feature,values("lsfe","fast-serialization","load-store-on-cond","distinct-ops","rmw"))"# + ); + + // Custom cfgs set by build script. Not public API. + // grep -F 'cargo:rustc-cfg=' build.rs | grep -Ev '^ *//' | sed -E 's/^.*cargo:rustc-cfg=//; s/(=\\)?".*$//' | LC_ALL=C sort -u | tr '\n' ',' | sed -E 's/,$/\n/' + println!( + "cargo:rustc-check-cfg=cfg(portable_atomic_atomic_intrinsics,portable_atomic_disable_fiq,portable_atomic_force_amo,portable_atomic_ll_sc_rmw,portable_atomic_no_asm,portable_atomic_no_asm_maybe_uninit,portable_atomic_no_asm_syscall,portable_atomic_no_atomic_64,portable_atomic_no_atomic_cas,portable_atomic_no_atomic_load_store,portable_atomic_no_atomic_min_max,portable_atomic_no_cfg_target_has_atomic,portable_atomic_no_cmpxchg16b_intrinsic,portable_atomic_no_cmpxchg16b_target_feature,portable_atomic_no_const_mut_refs,portable_atomic_no_const_raw_ptr_deref,portable_atomic_no_const_transmute,portable_atomic_no_core_unwind_safe,portable_atomic_no_diagnostic_namespace,portable_atomic_no_strict_provenance,portable_atomic_no_strict_provenance_atomic_ptr,portable_atomic_no_stronger_failure_ordering,portable_atomic_no_track_caller,portable_atomic_no_unsafe_op_in_unsafe_fn,portable_atomic_pre_llvm_16,portable_atomic_pre_llvm_18,portable_atomic_pre_llvm_20,portable_atomic_s_mode,portable_atomic_sanitize_thread,portable_atomic_target_feature,portable_atomic_unsafe_assume_privileged,portable_atomic_unsafe_assume_single_core,portable_atomic_unstable_asm,portable_atomic_unstable_asm_experimental_arch,portable_atomic_unstable_cfg_target_has_atomic,portable_atomic_unstable_isa_attribute)" + ); + // TODO: handle multi-line target_feature_fallback + // grep -F 'target_feature_fallback("' build.rs | grep -Ev '^ *//' | sed -E 's/^.*target_feature_fallback\(//; s/",.*$/"/' | LC_ALL=C sort -u | tr '\n' ',' | sed -E 's/,$/\n/' + println!( + r#"cargo:rustc-check-cfg=cfg(portable_atomic_target_feature,values("cmpxchg16b","distinct-ops","fast-serialization","load-store-on-cond","lse","lse128","lse2","lsfe","mclass","miscellaneous-extensions-3","quadword-atomics","rcpc3","rmw","v6","v7","zaamo","zabha","zacas"))"# + ); + } + + // https://github.com/rust-lang/rust/pull/123745 (includes https://github.com/rust-lang/cargo/pull/13560) merged in Rust 1.79 (nightly-2024-04-11). + if !version.probe(79, 2024, 4, 10) { + // HACK: If --target is specified, rustflags is not applied to the build + // script itself, so the build script will not be recompiled when rustflags + // is changed. That in itself is not a problem, but the old Cargo does + // not rerun the build script as well, which can be problematic. + // https://github.com/rust-lang/cargo/issues/13003 + // This problem has been fixed in 1.79 so only older versions need a workaround. + println!("cargo:rerun-if-env-changed=CARGO_ENCODED_RUSTFLAGS"); + println!("cargo:rerun-if-env-changed=RUSTFLAGS"); + println!("cargo:rerun-if-env-changed=CARGO_BUILD_RUSTFLAGS"); + let mut target_upper = target.replace(|c: char| c == '-' || c == '.', "_"); + target_upper.make_ascii_uppercase(); + println!("cargo:rerun-if-env-changed=CARGO_TARGET_{}_RUSTFLAGS", target_upper); + } + + // Note that cfgs are `no_`*, not `has_*`. This allows treating as the latest + // stable rustc is used when the build script doesn't run. This is useful + // for non-cargo build systems that don't run the build script. + + // atomic_min_max stabilized in Rust 1.45 (nightly-2020-05-30): https://github.com/rust-lang/rust/pull/72324 + if !version.probe(45, 2020, 5, 29) { + println!("cargo:rustc-cfg=portable_atomic_no_atomic_min_max"); + } + // track_caller stabilized in Rust 1.46 (nightly-2020-07-02): https://github.com/rust-lang/rust/pull/72445 + if !version.probe(46, 2020, 7, 1) { + println!("cargo:rustc-cfg=portable_atomic_no_track_caller"); + } + // unsafe_op_in_unsafe_fn stabilized in Rust 1.52 (nightly-2021-03-11): https://github.com/rust-lang/rust/pull/79208 + if !version.probe(52, 2021, 3, 10) { + println!("cargo:rustc-cfg=portable_atomic_no_unsafe_op_in_unsafe_fn"); + } + // const_transmute stabilized in Rust 1.56 (nightly-2021-07-29): https://github.com/rust-lang/rust/pull/85769 + if !version.probe(56, 2021, 7, 28) { + println!("cargo:rustc-cfg=portable_atomic_no_const_transmute"); + } + // https://github.com/rust-lang/rust/pull/84662 merged in Rust 1.56 (nightly-2021-08-02). + if !version.probe(56, 2021, 8, 1) { + println!("cargo:rustc-cfg=portable_atomic_no_core_unwind_safe"); + } + // const_raw_ptr_deref stabilized in Rust 1.58 (nightly-2021-11-15): https://github.com/rust-lang/rust/pull/89551 + if !version.probe(58, 2021, 11, 14) { + println!("cargo:rustc-cfg=portable_atomic_no_const_raw_ptr_deref"); + } + // https://github.com/rust-lang/rust/pull/98383 merged in Rust 1.64 (nightly-2022-07-19). + if !version.probe(64, 2022, 7, 18) { + println!("cargo:rustc-cfg=portable_atomic_no_stronger_failure_ordering"); + } + // https://github.com/rust-lang/rust/pull/114790 merged in nightly-2023-08-24 + if !version.probe(74, 2023, 8, 23) { + println!("cargo:rustc-cfg=portable_atomic_no_asm_maybe_uninit"); + } + // #[diagnostic] stabilized in Rust 1.78 (nightly-2024-03-09): https://github.com/rust-lang/rust/pull/119888 + if !version.probe(78, 2024, 3, 8) { + println!("cargo:rustc-cfg=portable_atomic_no_diagnostic_namespace"); + } + // const_mut_refs/const_refs_to_cell stabilized in Rust 1.83 (nightly-2024-09-16): https://github.com/rust-lang/rust/pull/129195 + if !version.probe(83, 2024, 9, 15) { + println!("cargo:rustc-cfg=portable_atomic_no_const_mut_refs"); + } + // strict_provenance/exposed_provenance APIs stabilized in Rust 1.84 (nightly-2024-10-22): https://github.com/rust-lang/rust/pull/130350 + if !version.probe(84, 2024, 10, 21) { + println!("cargo:rustc-cfg=portable_atomic_no_strict_provenance"); + } + // strict_provenance_atomic_ptr stabilized in Rust 1.91 (nightly-2024-10-22): https://github.com/rust-lang/rust/pull/145467 + if !version.probe(91, 2025, 8, 30) { + println!("cargo:rustc-cfg=portable_atomic_no_strict_provenance_atomic_ptr"); + } + + // For Miri and ThreadSanitizer. (aarch64, arm64ec, s390x, powerpc64) + // https://github.com/rust-lang/rust/pull/97423 merged in Rust 1.64 (nightly-2022-06-30). + // https://github.com/rust-lang/rust/pull/141507 merged in Rust 1.89 (nightly-2025-05-31). + if version.nightly + && version.probe(64, 2022, 6, 29) + && !version.probe(89, 2025, 5, 30) + && (target_arch != "powerpc64" || version.llvm >= 15) + { + println!("cargo:rustc-cfg=portable_atomic_atomic_intrinsics"); + } + + // asm! on AArch64, Arm, RISC-V, x86, and x86_64 stabilized in Rust 1.59 (nightly-2021-12-16): https://github.com/rust-lang/rust/pull/91728 + let no_asm = !version.probe(59, 2021, 12, 15); + if no_asm { + if version.nightly + && version.probe(46, 2020, 6, 20) + && ((target_arch != "x86" && target_arch != "x86_64") || version.llvm >= 10) + && is_allowed_feature("asm") + { + // This feature was added in Rust 1.45 (nightly-2020-05-20), but + // concat! in asm! requires Rust 1.46 (nightly-2020-06-21). + // x86 intel syntax requires LLVM 10 (since Rust 1.53, the minimum + // external LLVM version is 10+: https://github.com/rust-lang/rust/pull/83387). + // The part of this feature we use has not been changed since nightly-2020-06-21 + // until it was stabilized, so it can safely be enabled in nightly for that period. + println!("cargo:rustc-cfg=portable_atomic_unstable_asm"); + if (target_arch == "riscv32" || target_arch == "riscv64") + && !version.probe(56, 2021, 8, 15) + { + // Clobbering vector status needed for asm syscall require Rust 1.56 (nightly-2021-08-16): https://github.com/rust-lang/rust/pull/87581 + println!("cargo:rustc-cfg=portable_atomic_no_asm_syscall"); + } + } + println!("cargo:rustc-cfg=portable_atomic_no_asm"); + } else { + match target_arch { + "arm64ec" | "s390x" => { + // asm! on Arm64EC and s390x stabilized in Rust 1.84 (nightly-2024-11-11): https://github.com/rust-lang/rust/pull/131781, https://github.com/rust-lang/rust/pull/131258 + if !version.probe(84, 2024, 11, 10) { + if version.nightly + && (target_arch != "s390x" || version.probe(71, 2023, 5, 8)) + && is_allowed_feature("asm_experimental_arch") + { + // https://github.com/rust-lang/rust/pull/111331 merged in Rust 1.71 (nightly-2023-05-09). + // The part of this feature we use has not been changed since nightly-2023-05-09 + // until it was stabilized, so it can safely be enabled in nightly for that period. + println!("cargo:rustc-cfg=portable_atomic_unstable_asm_experimental_arch"); + } else { + println!("cargo:rustc-cfg=portable_atomic_no_asm"); + } + } + } + "powerpc64" => { + // asm! on PowerPC stabilized in Rust 1.95 (nightly-2026-01-28): https://github.com/rust-lang/rust/pull/147996 + if !version.probe(95, 2026, 1, 27) { + if version.nightly + && version.probe(60, 2022, 2, 12) + && is_allowed_feature("asm_experimental_arch") + { + // https://github.com/rust-lang/rust/pull/93868 merged in Rust 1.60 (nightly-2022-02-13). + // The part of this feature we use has not been changed since nightly-2022-02-13 + // until it was stabilized, so it can safely be enabled in nightly for that period. + println!("cargo:rustc-cfg=portable_atomic_unstable_asm_experimental_arch"); + } else { + println!("cargo:rustc-cfg=portable_atomic_no_asm"); + } + if !version.probe(92, 2025, 9, 22) + || env::var("CARGO_CFG_TARGET_ABI") + .unwrap_or_default() + .split(',') + .any(|abi| abi == "spu") + { + // Clobbering ctr register needed for asm syscall require Rust 1.92 (nightly-2025-09-23): https://github.com/rust-lang/rust/pull/146831 + // Cell/B.E. Linux's SPU syscalls support a subset of powerpc64 syscalls with the exact semantics: https://github.com/torvalds/linux/blob/v7.1/arch/powerpc/platforms/cell/spu_callbacks.c#L17 + // but have a different syscall sequence: https://github.com/mirror/newlib-cygwin/blob/newlib-4.4.0/libgloss/spu/linux_syscalls.c#L37 + // This is currently used only for testing. + println!("cargo:rustc-cfg=portable_atomic_no_asm_syscall"); + } + } + } + _ => {} + } + } + + // feature(cfg_target_has_atomic) stabilized in Rust 1.60 (nightly-2022-02-11): https://github.com/rust-lang/rust/pull/93824 + if !version.probe(60, 2022, 2, 10) { + if version.nightly + && version.probe(40, 2019, 10, 13) + && is_allowed_feature("cfg_target_has_atomic") + { + // The part of this feature we use has not been changed since nightly-2019-10-14 + // until it was stabilized, so it can safely be enabled in nightly for that period. + println!("cargo:rustc-cfg=portable_atomic_unstable_cfg_target_has_atomic"); + } else { + println!("cargo:rustc-cfg=portable_atomic_no_cfg_target_has_atomic"); + let target = &*convert_custom_linux_target(target); + if generated::NO_ATOMIC_CAS.contains(&target) { + println!("cargo:rustc-cfg=portable_atomic_no_atomic_cas"); + } + if generated::NO_ATOMIC_64.contains(&target) { + println!("cargo:rustc-cfg=portable_atomic_no_atomic_64"); + } else { + // Otherwise, assuming `"max-atomic-width" == 64` or `"max-atomic-width" == 128`. + } + } + } + // We don't need to use convert_custom_linux_target here because all linux targets have atomics. + if generated::NO_ATOMIC.contains(&target) { + println!("cargo:rustc-cfg=portable_atomic_no_atomic_load_store"); + } + + if version.llvm < 20 { + println!("cargo:rustc-cfg=portable_atomic_pre_llvm_20"); + if version.llvm < 18 { + println!("cargo:rustc-cfg=portable_atomic_pre_llvm_18"); + if version.llvm < 16 { + println!("cargo:rustc-cfg=portable_atomic_pre_llvm_16"); + } + } + } + + if version.nightly { + // `cfg(sanitize = "..")` is not stabilized. + let sanitize = env::var("CARGO_CFG_SANITIZE").unwrap_or_default(); + if sanitize.contains("thread") { + // Most kinds of sanitizers are not compatible with asm + // (https://github.com/google/sanitizers/issues/192), + // but it seems that ThreadSanitizer is the only one that can cause + // false positives in our code. + println!("cargo:rustc-cfg=portable_atomic_sanitize_thread"); + } + } + + match target_arch { + "x86_64" => { + // cmpxchg16b_target_feature stabilized in Rust 1.69 (nightly-2023-03-01): https://github.com/rust-lang/rust/pull/106774 + if !version.probe(69, 2023, 2, 28) { + println!("cargo:rustc-cfg=portable_atomic_no_cmpxchg16b_target_feature"); + } + // For Miri and ThreadSanitizer. + // https://github.com/rust-lang/rust/pull/109359 (includes https://github.com/rust-lang/stdarch/pull/1358) merged in Rust 1.70 (nightly-2023-03-24). + if version.nightly && !version.probe(70, 2023, 3, 23) { + println!("cargo:rustc-cfg=portable_atomic_no_cmpxchg16b_intrinsic"); + } + + // cmpxchg16b_target_feature stabilized in Rust 1.69. + if needs_target_feature_fallback(&version, Some(69)) { + // x86_64 Apple targets always support CMPXCHG16B: + // https://github.com/rust-lang/rust/blob/1.68.0/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs#L8 + // https://github.com/rust-lang/rust/blob/1.68.0/compiler/rustc_target/src/spec/apple_base.rs#L69-L70 + // (Windows (except Windows 7, since Rust 1.78) and Fuchsia (since Rust 1.87) targets + // also enable CMPXCHG16B, but this branch is only used on pre-1.69 that + // cmpxchg16b_target_feature is unstable.) + // Script to get builtin targets that support CMPXCHG16B by default: + // $ (for target in $(rustc -Z unstable-options --print all-target-specs-json | jq -r '. | to_entries[] | if .value.arch == "x86_64" then .key else empty end'); do rustc --print cfg --target "${target}" | grep -Fq '"cmpxchg16b"' && printf '%s\n' "${target}"; done) + let is_apple = env::var("CARGO_CFG_TARGET_VENDOR").unwrap_or_default() == "apple"; + let cmpxchg16b = is_apple; + // LLVM recognizes this also as cx16 target feature: https://godbolt.org/z/KM3jz616j + // However, it is unlikely that rustc will support that name, so we ignore it. + target_feature_fallback("cmpxchg16b", cmpxchg16b); + } + } + "aarch64" | "arm64ec" => { + // target_feature "lse2"/"lse128"/"rcpc3" is unstable and available on rustc side since nightly-2024-08-30: https://github.com/rust-lang/rust/pull/128192 + if !version.probe(82, 2024, 8, 29) || needs_target_feature_fallback(&version, None) { + // FEAT_LSE2 doesn't imply FEAT_LSE. FEAT_LSE128 implies FEAT_LSE but not FEAT_LSE2. + // AArch64 macOS always supports FEAT_LSE and FEAT_LSE2 because M1 is Armv8.4 with all features of Armv8.5 except FEAT_BTI: + // https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/AArch64/AArch64Processors.td#L1558 + // https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/AArch64/AArch64Processors.td#L1180 + // Script to get builtin targets that support FEAT_LSE/FEAT_LSE2 by default: + // $ (for target in $(rustc -Z unstable-options --print all-target-specs-json | jq -r '. | to_entries[] | if .value.arch == "aarch64" or .value.arch == "arm64ec" then .key else empty end'); do rustc --print cfg --target "${target}" | grep -Fq '"lse"' && printf '%s\n' "${target}"; done) + // $ (for target in $(rustc -Z unstable-options --print all-target-specs-json | jq -r '. | to_entries[] | if .value.arch == "aarch64" or .value.arch == "arm64ec" then .key else empty end'); do rustc --print cfg --target "${target}" | grep -Fq '"lse2"' && printf '%s\n' "${target}"; done) + let is_macos = target_os == "macos"; + let mut lse = is_macos; + target_feature_fallback("lse2", is_macos); + lse |= target_feature_fallback("lse128", false); + target_feature_fallback("rcpc3", false); + // aarch64_target_feature stabilized in Rust 1.61. + if needs_target_feature_fallback(&version, Some(61)) { + target_feature_fallback("lse", lse); + } + } + // As of Rust 1.85, target_feature "lsfe" is not available on rustc side: + // https://github.com/rust-lang/rust/blob/1.85.0/compiler/rustc_target/src/target_features.rs + target_feature_fallback("lsfe", false); + + // As of Apple M1/M1 Pro, on Apple hardware, CAS-loop-based RMW is much slower than + // LL/SC-loop-based RMW: https://github.com/taiki-e/portable-atomic/pull/89 + let is_apple = env::var("CARGO_CFG_TARGET_VENDOR").unwrap_or_default() == "apple"; + if is_apple || target_cpu().map_or(false, |cpu| cpu.starts_with("apple-")) { + println!("cargo:rustc-cfg=portable_atomic_ll_sc_rmw"); + } + } + "arm" => { + // For non-Linux/Android pre-v6 Arm (tier 3) with unsafe_assume_single_core enabled. + // feature(isa_attribute) stabilized in Rust 1.67 (nightly-2022-11-06): https://github.com/rust-lang/rust/pull/102458 + if version.nightly && !version.probe(67, 2022, 11, 5) { + println!("cargo:rustc-cfg=portable_atomic_unstable_isa_attribute"); + } + + if needs_target_feature_fallback(&version, None) { + // #[cfg(target_feature = "v7")] and others don't work on stable. + // armv7-unknown-linux-gnueabihf + // ^^ + let mut mclass = false; + let mut v6 = false; + let mut v7 = false; + if let Some(mut subarch) = + strip_prefix(target, "arm").or_else(|| strip_prefix(target, "thumb")) + { + subarch = strip_prefix(subarch, "eb").unwrap_or(subarch); // ignore endianness + subarch = subarch.split('-').next().unwrap(); // ignore vender/os/env + let mut i = subarch.splitn(2, '.'); + subarch = i.next().unwrap(); + let suffix = i.next().unwrap_or_default(); // .base/.main suffix + let mut known = true; + // See https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/build.rs for details + match subarch { + "v7" | "v7a" | "v7neon" | "v7s" | "v7k" | "v8" | "v8a" | "v9" | "v9a" => {} // aclass + "v7r" | "v8r" | "v9r" => {} // rclass + "v6m" | "v7em" | "v7m" | "v8m" => mclass = true, + // arm-linux-androideabi is v5te + // https://github.com/rust-lang/rust/blob/1.84.0/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs#L18 + _ if target == "arm-linux-androideabi" => subarch = "v5te", + // armeb-unknown-linux-gnueabi is v8 & aclass + // https://github.com/rust-lang/rust/blob/1.84.0/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs#L18 + _ if target == "armeb-unknown-linux-gnueabi" => subarch = "v8", + // Legacy Arm architectures (pre-v7 except v6m) don't have *class target feature. + "" => subarch = "v6", + "v4t" | "v5te" | "v6" | "v6k" => {} + _ => { + known = false; + if env::var_os("PORTABLE_ATOMIC_DENY_WARNINGS").is_some() { + panic!("unrecognized Arm subarch: {}", target) + } + println!( + "cargo:warning={}: unrecognized Arm subarch: {}", + env!("CARGO_PKG_NAME"), + target + ); + } + } + v6 = known && subarch.starts_with("v6"); + v7 = known && subarch.starts_with("v7"); + if known && (subarch.starts_with("v8") || subarch.starts_with("v9")) { + // Armv8-M is not considered as v8 by LLVM. + // https://github.com/rust-lang/stdarch/blob/a0c30f3e3c75adcd6ee7efc94014ebcead61c507/crates/core_arch/src/arm_shared/mod.rs + if mclass { + // Armv8-M Mainline is a superset of Armv7-M. + // Armv8-M Baseline is a superset of Armv6-M. + // That said, LLVM handles thumbv8m.main without v8m like v6m, not v7m: https://godbolt.org/z/Ph96v9zae + // TODO: Armv9-M has not yet been released, + // so it is not clear how it will be handled here. + v6 = true; + v7 = suffix == "main"; + } else { + v7 = true; + } + } + } + v6 |= target_feature_fallback("v7", v7); + target_feature_fallback("v6", v6); + target_feature_fallback("mclass", mclass); + } + } + "riscv32" | "riscv64" => { + // zabha and zacas imply zaamo in GCC, LLVM 20+, and Rust, but do not in LLVM 19. + // However, enabling them without zaamo or a is not allowed in LLVM 19, so we can assume + // zaamo is available when zabha is enabled). + // https://github.com/llvm/llvm-project/commit/956361ca080a689a96b6552d28681aaf0ad2f494 + // https://github.com/gcc-mirror/gcc/commit/7b2b2e3d660edc8ef3a8cfbdfc2b0fd499459601 + // https://github.com/gcc-mirror/gcc/commit/11c2453a16b725b7fb67778e1ab4636a51a1217d + // https://github.com/rust-lang/rust/pull/130877 + let mut zaamo = false; + // target_feature "zacas" is available as unstable on rustc side + // since nightly-2025-02-26 (https://github.com/rust-lang/rust/pull/137417), + // and stabilized in Rust 1.94 (https://github.com/rust-lang/rust/pull/145948). + if !version.probe(87, 2025, 2, 25) || needs_target_feature_fallback(&version, Some(94)) + { + // amocas.{w,d,q} (and amocas.{b,h} if zabha is also available) + // available as experimental since LLVM 17 https://github.com/llvm/llvm-project/commit/29f630a1ddcbb03caa31b5002f0cbc105ff3a869 + // available non-experimental since LLVM 20 https://github.com/llvm/llvm-project/commit/614aeda93b2225c6eb42b00ba189ba7ca2585c60 + zaamo |= target_feature_fallback("zacas", false); + } + // target_feature "zaamo"/"zabha" is available as unstable on rustc side + // since nightly-2024-10-02 (https://github.com/rust-lang/rust/pull/130877), + // and stabilized in Rust 1.94 (https://github.com/rust-lang/rust/pull/145948). + if !version.probe(83, 2024, 10, 1) || needs_target_feature_fallback(&version, Some(94)) + { + if version.llvm >= 19 { + // amo*.{b,h} + // available since LLVM 19 https://github.com/llvm/llvm-project/commit/89f87c387627150d342722b79c78cea2311cddf7 / https://github.com/llvm/llvm-project/commit/6b7444964a8d028989beee554a1f5c61d16a1cac + zaamo |= target_feature_fallback("zabha", false); + } + // amo*.{w,d} + target_feature_fallback("zaamo", zaamo); + } + } + "powerpc64" => { + // target_feature "quadword-atomics" is unstable and available on rustc side since nightly-2024-09-28: https://github.com/rust-lang/rust/pull/130873 + if !version.probe(83, 2024, 9, 27) || needs_target_feature_fallback(&version, None) { + let mut pwr8_features = false; + if let Some(cpu) = target_cpu() { + if let Some(mut cpu_version) = strip_prefix(&cpu, "pwr") { + cpu_version = strip_suffix(cpu_version, "x").unwrap_or(cpu_version); // for pwr5x and pwr6x + if let Ok(cpu_version) = cpu_version.parse::() { + pwr8_features = cpu_version >= 8; + } + } else { + // https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/PowerPC/PPC.td#L789 + // https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/PowerPC/PPC.td#L557 + // On the minimum external LLVM version of the oldest rustc version which we can use asm_experimental_arch + // on this target (see CI config for more), "future" is based on pwr10 features. + // https://github.com/llvm/llvm-project/blob/llvmorg-12.0.0/llvm/lib/Target/PowerPC/PPC.td#L370 + pwr8_features = cpu == "future" || cpu == "ppc64le"; + } + } else { + // powerpc64le is pwr8 by default https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/PowerPC/PPC.td#L789 + // See also https://github.com/rust-lang/rust/issues/59932 + pwr8_features = env::var("CARGO_CFG_TARGET_ENDIAN") + .expect("CARGO_CFG_TARGET_ENDIAN not set") + == "little"; + } + // power8 features: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/PowerPC/PPC.td#L484 + // lqarx and stqcx. + target_feature_fallback("quadword-atomics", pwr8_features); + } + } + "s390x" => { + let mut arch9_features = false; // z196+ + let mut arch13_features = false; // z15+ + if let Some(cpu) = target_cpu() { + // LLVM and GCC recognize the same names: + // https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/SystemZ/SystemZProcessors.td + // https://github.com/gcc-mirror/gcc/blob/releases/gcc-15.2.0/gcc/config/s390/s390.opt#L58-L128 + if let Some(arch_version) = strip_prefix(&cpu, "arch") { + if let Ok(arch_version) = arch_version.parse::() { + arch9_features = arch_version >= 9; + arch13_features = arch_version >= 13; + } + } else { + match &*cpu { + "z196" | "zEC12" | "z13" | "z14" => arch9_features = true, + "z15" | "z16" | "z17" => { + arch9_features = true; + arch13_features = true; + } + _ => {} + } + } + } + // target_feature "miscellaneous-extensions-3" is available as unstable on rustc side + // since nightly-2025-06-05 (https://github.com/rust-lang/rust/pull/141250), + // and stabilized in Rust 1.93 (https://github.com/rust-lang/rust/pull/145656). + if !version.probe(89, 2025, 6, 4) || needs_target_feature_fallback(&version, Some(93)) { + // arch13 features: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/SystemZ/SystemZFeatures.td#L303 + // nand (nnr{,g}k), select (sel{,g}r), etc. + target_feature_fallback("miscellaneous-extensions-3", arch13_features); + } + // As of Rust 1.84, target_feature "fast-serialization"/"load-store-on-cond"/"distinct-ops"/"miscellaneous-extensions-3" is not available on rustc side: + // https://github.com/rust-lang/rust/blob/1.84.0/compiler/rustc_target/src/target_features.rs#L547 + // arch9 features: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/SystemZ/SystemZFeatures.td#L103 + // bcr 14,0 + target_feature_fallback("fast-serialization", arch9_features); + // {l,st}oc{,g}{,r} + target_feature_fallback("load-store-on-cond", arch9_features); + // {al,sl,n,o,x}{,g}rk + target_feature_fallback("distinct-ops", arch9_features); + } + "avr" => { + // target_feature "rmw" is unstable and available on rustc side since nightly-2026-02-08: https://github.com/rust-lang/rust/pull/146900 + if !version.probe(95, 2026, 2, 7) || needs_target_feature_fallback(&version, None) { + // https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/AVR/AVRDevices.td + let mut xmegau = false; // FamilyXMEGAU + if let Some(cpu) = target_cpu() { + match &*cpu { + "atxmega16a4u" | "atxmega16c4" | "atxmega32a4u" | "atxmega32c3" + | "atxmega32c4" | "atxmega32e5" | "atxmega16e5" | "atxmega8e5" + | "atxmega64a3u" | "atxmega64a4u" | "atxmega64b1" | "atxmega64b3" + | "atxmega64c3" | "atxmega64a1u" | "atxmega128a3u" | "atxmega128b1" + | "atxmega128b3" | "atxmega128c3" | "atxmega192a3u" | "atxmega192c3" + | "atxmega256a3u" | "atxmega256a3bu" | "atxmega256c3" | "atxmega384c3" + | "atxmega128a1u" | "atxmega128a4u" => xmegau = true, + _ => {} + } + } + target_feature_fallback("rmw", xmegau); + } + } + _ => {} + } +} + +// HACK: Currently, it seems that the only way to handle unstable target +// features on the stable is to parse the `-C target-feature` in RUSTFLAGS. +// +// - #[cfg(target_feature = "unstable_target_feature")] doesn't work on stable. +// - CARGO_CFG_TARGET_FEATURE excludes unstable target features on stable. +// +// As mentioned in the [RFC2045], unstable target features are also passed to LLVM +// (e.g., https://godbolt.org/z/4rr7rMcfG), so this hack works properly on stable. +// +// [RFC2045]: https://rust-lang.github.io/rfcs/2045-target-feature.html#backend-compilation-options +fn needs_target_feature_fallback(version: &Version, stable: Option) -> bool { + match stable { + // In these cases, cfg(target_feature = "...") would work, so skip emitting our own fallback target_feature cfg. + _ if version.nightly => false, + Some(stabilized) if version.minor >= stabilized => false, + _ => true, + } +} +fn target_feature_fallback(name: &str, mut has_target_feature: bool) -> bool { + if let Some(rustflags) = env::var_os("CARGO_ENCODED_RUSTFLAGS") { + for mut flag in rustflags.to_string_lossy().split('\x1f') { + flag = strip_prefix(flag, "-C").unwrap_or(flag); + if let Some(flag) = strip_prefix(flag, "target-feature=") { + for s in flag.split(',') { + // TODO: Handles cases where a specific target feature + // implicitly enables another target feature. + match (s.as_bytes().first(), s.as_bytes().get(1..)) { + (Some(b'+'), Some(f)) if f == name.as_bytes() => has_target_feature = true, + (Some(b'-'), Some(f)) if f == name.as_bytes() => has_target_feature = false, + _ => {} + } + } + } + } + } + if has_target_feature { + println!("cargo:rustc-cfg=portable_atomic_target_feature=\"{}\"", name); + } + has_target_feature +} + +fn target_cpu() -> Option { + let rustflags = env::var_os("CARGO_ENCODED_RUSTFLAGS")?; + let rustflags = rustflags.to_string_lossy(); + let mut cpu = None; + for mut flag in rustflags.split('\x1f') { + flag = strip_prefix(flag, "-C").unwrap_or(flag); + if let Some(flag) = strip_prefix(flag, "target-cpu=") { + cpu = Some(flag); + } + } + cpu.map(str::to_owned) +} + +fn is_allowed_feature(name: &str) -> bool { + // https://github.com/dtolnay/thiserror/pull/248 + if env::var_os("RUSTC_STAGE").is_some() { + return false; + } + + // allowed by default + let mut allowed = true; + if let Some(rustflags) = env::var_os("CARGO_ENCODED_RUSTFLAGS") { + for mut flag in rustflags.to_string_lossy().split('\x1f') { + flag = strip_prefix(flag, "-Z").unwrap_or(flag); + if let Some(flag) = strip_prefix(flag, "allow-features=") { + // If it is specified multiple times, the last value will be preferred. + allowed = flag.split(',').any(|allowed| allowed == name); + } + } + } + allowed +} + +// Adapted from https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/build-common.rs. +// +// The target triplets have the form of 'arch-vendor-system'. +// +// When building for Linux (e.g. the 'system' part is +// 'linux-something'), replace the vendor with 'unknown' +// so that mapping to rust standard targets happens correctly. +fn convert_custom_linux_target(target: &str) -> String { + let mut parts: Vec<&str> = target.split('-').collect(); + let system = parts.get(2); + if system == Some(&"linux") { + parts[1] = "unknown"; + } + parts.join("-") +} + +// str::strip_prefix requires Rust 1.45 +#[must_use] +fn strip_prefix<'a>(s: &'a str, pat: &str) -> Option<&'a str> { + if s.starts_with(pat) { Some(&s[pat.len()..]) } else { None } +} +// str::strip_suffix requires Rust 1.45 +#[must_use] +fn strip_suffix<'a>(s: &'a str, pat: &str) -> Option<&'a str> { + if s.ends_with(pat) { Some(&s[..s.len() - pat.len()]) } else { None } +} diff --git a/vendor/portable-atomic/portable-atomic-util/README.md b/vendor/portable-atomic/portable-atomic-util/README.md new file mode 100644 index 0000000..c541a4d --- /dev/null +++ b/vendor/portable-atomic/portable-atomic-util/README.md @@ -0,0 +1,3 @@ +# portable-atomic-util + +portable-atomic-util crate has been moved to [its own repository](https://github.com/taiki-e/portable-atomic-util). diff --git a/vendor/portable-atomic/src/cfgs.rs b/vendor/portable-atomic/src/cfgs.rs new file mode 100644 index 0000000..a3116d3 --- /dev/null +++ b/vendor/portable-atomic/src/cfgs.rs @@ -0,0 +1,631 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +#![allow(missing_docs)] + +#[cfg(not(all( + portable_atomic_no_atomic_load_store, + not(any( + target_arch = "avr", + target_arch = "msp430", + target_arch = "riscv32", + target_arch = "riscv64", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + )), +)))] +#[macro_use] +mod atomic_8_16_macros { + #[macro_export] + macro_rules! cfg_has_atomic_8 { + ($($tt:tt)*) => { + $($tt)* + }; + } + #[macro_export] + macro_rules! cfg_no_atomic_8 { + ($($tt:tt)*) => {}; + } + #[macro_export] + macro_rules! cfg_has_atomic_16 { + ($($tt:tt)*) => { + $($tt)* + }; + } + #[macro_export] + macro_rules! cfg_no_atomic_16 { + ($($tt:tt)*) => {}; + } +} +#[cfg(all( + portable_atomic_no_atomic_load_store, + not(any( + target_arch = "avr", + target_arch = "msp430", + target_arch = "riscv32", + target_arch = "riscv64", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + )), +))] +#[macro_use] +mod atomic_8_16_macros { + #[macro_export] + macro_rules! cfg_has_atomic_8 { + ($($tt:tt)*) => {}; + } + #[macro_export] + macro_rules! cfg_no_atomic_8 { + ($($tt:tt)*) => { + $($tt)* + }; + } + #[macro_export] + macro_rules! cfg_has_atomic_16 { + ($($tt:tt)*) => {}; + } + #[macro_export] + macro_rules! cfg_no_atomic_16 { + ($($tt:tt)*) => { + $($tt)* + }; + } +} + +#[cfg(all( + any(not(target_pointer_width = "16"), feature = "fallback"), + not(all( + portable_atomic_no_atomic_load_store, + not(any( + target_arch = "avr", + target_arch = "msp430", + target_arch = "riscv32", + target_arch = "riscv64", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + )), + )), +))] +#[macro_use] +mod atomic_32_macros { + #[macro_export] + macro_rules! cfg_has_atomic_32 { + ($($tt:tt)*) => { + $($tt)* + }; + } + #[macro_export] + macro_rules! cfg_no_atomic_32 { + ($($tt:tt)*) => {}; + } +} +#[cfg(not(all( + any(not(target_pointer_width = "16"), feature = "fallback"), + not(all( + portable_atomic_no_atomic_load_store, + not(any( + target_arch = "avr", + target_arch = "msp430", + target_arch = "riscv32", + target_arch = "riscv64", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + )), + )), +)))] +#[macro_use] +mod atomic_32_macros { + #[macro_export] + macro_rules! cfg_has_atomic_32 { + ($($tt:tt)*) => {}; + } + #[macro_export] + macro_rules! cfg_no_atomic_32 { + ($($tt:tt)*) => { + $($tt)* + }; + } +} + +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any( + all( + feature = "fallback", + any( + not(portable_atomic_no_atomic_cas), + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ), + ), + not(portable_atomic_no_atomic_64), + not(any(target_pointer_width = "16", target_pointer_width = "32")), + all( + target_arch = "riscv32", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_feature = "zacas", portable_atomic_target_feature = "zacas"), + ), + )) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any( + all( + feature = "fallback", + any( + target_has_atomic = "ptr", + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ), + ), + target_has_atomic = "64", + not(any(target_pointer_width = "16", target_pointer_width = "32")), + all( + target_arch = "riscv32", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_feature = "zacas", portable_atomic_target_feature = "zacas"), + ), + )) +)] +#[macro_use] +mod atomic_64_macros { + #[macro_export] + macro_rules! cfg_has_atomic_64 { + ($($tt:tt)*) => { + $($tt)* + }; + } + #[macro_export] + macro_rules! cfg_no_atomic_64 { + ($($tt:tt)*) => {}; + } +} +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(not(any( + all( + feature = "fallback", + any( + not(portable_atomic_no_atomic_cas), + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ), + ), + not(portable_atomic_no_atomic_64), + not(any(target_pointer_width = "16", target_pointer_width = "32")), + all( + target_arch = "riscv32", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_feature = "zacas", portable_atomic_target_feature = "zacas"), + ), + ))) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(not(any( + all( + feature = "fallback", + any( + target_has_atomic = "ptr", + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ), + ), + target_has_atomic = "64", + not(any(target_pointer_width = "16", target_pointer_width = "32")), + all( + target_arch = "riscv32", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_feature = "zacas", portable_atomic_target_feature = "zacas"), + ), + ))) +)] +#[macro_use] +mod atomic_64_macros { + #[macro_export] + macro_rules! cfg_has_atomic_64 { + ($($tt:tt)*) => {}; + } + #[macro_export] + macro_rules! cfg_no_atomic_64 { + ($($tt:tt)*) => { + $($tt)* + }; + } +} + +#[cfg_attr( + not(feature = "fallback"), + cfg(any( + all( + target_arch = "aarch64", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + ), + all( + target_arch = "arm64ec", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + ), + all( + target_arch = "x86_64", + not(all( + any(miri, portable_atomic_sanitize_thread), + portable_atomic_no_cmpxchg16b_intrinsic, + )), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + ), + all( + target_arch = "riscv64", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_feature = "zacas", portable_atomic_target_feature = "zacas"), + ), + all( + target_arch = "powerpc64", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + ), + ), + all( + target_arch = "s390x", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + ), + )) +)] +#[cfg_attr( + all(feature = "fallback", portable_atomic_no_cfg_target_has_atomic), + cfg(any( + not(portable_atomic_no_atomic_cas), + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + )) +)] +#[cfg_attr( + all(feature = "fallback", not(portable_atomic_no_cfg_target_has_atomic)), + cfg(any( + target_has_atomic = "ptr", + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + )) +)] +#[macro_use] +mod atomic_128_macros { + #[macro_export] + macro_rules! cfg_has_atomic_128 { + ($($tt:tt)*) => { + $($tt)* + }; + } + #[macro_export] + macro_rules! cfg_no_atomic_128 { + ($($tt:tt)*) => {}; + } +} +#[cfg_attr( + not(feature = "fallback"), + cfg(not(any( + all( + target_arch = "aarch64", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + ), + all( + target_arch = "arm64ec", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + ), + all( + target_arch = "x86_64", + not(all( + any(miri, portable_atomic_sanitize_thread), + portable_atomic_no_cmpxchg16b_intrinsic, + )), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + ), + all( + target_arch = "riscv64", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_feature = "zacas", portable_atomic_target_feature = "zacas"), + ), + all( + target_arch = "powerpc64", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + ), + ), + all( + target_arch = "s390x", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + ), + ))) +)] +#[cfg_attr( + all(feature = "fallback", portable_atomic_no_cfg_target_has_atomic), + cfg(not(any( + not(portable_atomic_no_atomic_cas), + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ))) +)] +#[cfg_attr( + all(feature = "fallback", not(portable_atomic_no_cfg_target_has_atomic)), + cfg(not(any( + target_has_atomic = "ptr", + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ))) +)] +#[macro_use] +mod atomic_128_macros { + #[macro_export] + macro_rules! cfg_has_atomic_128 { + ($($tt:tt)*) => {}; + } + #[macro_export] + macro_rules! cfg_no_atomic_128 { + ($($tt:tt)*) => { + $($tt)* + }; + } +} + +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any( + not(portable_atomic_no_atomic_cas), + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + )) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any( + target_has_atomic = "ptr", + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + )) +)] +#[macro_use] +mod atomic_cas_macros { + #[macro_export] + macro_rules! cfg_has_atomic_cas { + ($($tt:tt)*) => { + $($tt)* + }; + } + #[macro_export] + macro_rules! cfg_no_atomic_cas { + ($($tt:tt)*) => {}; + } + // private + macro_rules! cfg_has_atomic_cas_or_amo32 { + ($($tt:tt)*) => { + $($tt)* + }; + } + macro_rules! cfg_has_atomic_cas_or_amo8 { + ($($tt:tt)*) => { + $($tt)* + }; + } +} +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(not(any( + not(portable_atomic_no_atomic_cas), + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ))) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(not(any( + target_has_atomic = "ptr", + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ))) +)] +#[macro_use] +mod atomic_cas_macros { + #[macro_export] + macro_rules! cfg_has_atomic_cas { + ($($tt:tt)*) => {}; + } + #[macro_export] + macro_rules! cfg_no_atomic_cas { + ($($tt:tt)*) => { + $($tt)* + }; + } + // private + #[cfg_attr( + any(target_arch = "riscv32", target_arch = "riscv64"), + cfg(not(any(target_feature = "zaamo", portable_atomic_target_feature = "zaamo"))) + )] + macro_rules! cfg_has_atomic_cas_or_amo32 { + ($($tt:tt)*) => {}; + } + #[cfg_attr( + any(target_arch = "riscv32", target_arch = "riscv64"), + cfg(not(any(target_feature = "zaamo", portable_atomic_target_feature = "zaamo"))) + )] + macro_rules! cfg_no_atomic_cas_or_amo32 { + ($($tt:tt)*) => { + $($tt)* + }; + } + #[cfg(all( + any(target_arch = "riscv32", target_arch = "riscv64"), + any(target_feature = "zaamo", portable_atomic_target_feature = "zaamo"), + ))] + macro_rules! cfg_has_atomic_cas_or_amo32 { + ($($tt:tt)*) => { + $($tt)* + }; + } + #[cfg(all( + any(target_arch = "riscv32", target_arch = "riscv64"), + any(target_feature = "zaamo", portable_atomic_target_feature = "zaamo"), + ))] + macro_rules! cfg_no_atomic_cas_or_amo32 { + ($($tt:tt)*) => {}; + } + #[cfg_attr( + any(target_arch = "riscv32", target_arch = "riscv64"), + cfg(not(any(target_feature = "zabha", portable_atomic_target_feature = "zabha"))) + )] + #[allow(unused_macros)] + macro_rules! cfg_has_atomic_cas_or_amo8 { + ($($tt:tt)*) => {}; + } + #[cfg_attr( + any(target_arch = "riscv32", target_arch = "riscv64"), + cfg(not(any(target_feature = "zabha", portable_atomic_target_feature = "zabha"))) + )] + #[cfg_attr(target_arch = "bpf", allow(unused_macros))] + macro_rules! cfg_no_atomic_cas_or_amo8 { + ($($tt:tt)*) => { + $($tt)* + }; + } + #[cfg(all( + any(target_arch = "riscv32", target_arch = "riscv64"), + any(target_feature = "zabha", portable_atomic_target_feature = "zabha"), + ))] + macro_rules! cfg_has_atomic_cas_or_amo8 { + ($($tt:tt)*) => { + $($tt)* + }; + } + #[cfg(all( + any(target_arch = "riscv32", target_arch = "riscv64"), + any(target_feature = "zabha", portable_atomic_target_feature = "zabha"), + ))] + macro_rules! cfg_no_atomic_cas_or_amo8 { + ($($tt:tt)*) => {}; + } +} + +macro_rules! cfg_core_atomic { + ($($tt:tt)*) => { + #[cfg(not(any( + target_arch = "avr", + target_arch = "msp430", + all( + portable_atomic_no_atomic_load_store, + not(all(target_arch = "bpf", not(feature = "critical-section"))), + ), + )))] + #[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(not(all( + any( + target_arch = "riscv32", + target_arch = "riscv64", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ), + portable_atomic_no_atomic_cas, + ))) + )] + #[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(not(all( + any( + target_arch = "riscv32", + target_arch = "riscv64", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ), + not(target_has_atomic = "ptr"), + ))) + )] + items!($($tt)*); + }; +} + +// Check that all cfg_ macros work. +mod check { + crate::cfg_has_atomic_8! { type _Atomic8 = (); } + crate::cfg_no_atomic_8! { type _Atomic8 = (); } + crate::cfg_has_atomic_16! { type _Atomic16 = (); } + crate::cfg_no_atomic_16! { type _Atomic16 = (); } + crate::cfg_has_atomic_32! { type _Atomic32 = (); } + crate::cfg_no_atomic_32! { type _Atomic32 = (); } + crate::cfg_has_atomic_64! { type _Atomic64 = (); } + crate::cfg_no_atomic_64! { type _Atomic64 = (); } + crate::cfg_has_atomic_128! { type _Atomic128 = (); } + crate::cfg_no_atomic_128! { type _Atomic128 = (); } + crate::cfg_has_atomic_ptr! { type _AtomicPtr = (); } + crate::cfg_no_atomic_ptr! { type _AtomicPtr = (); } + crate::cfg_has_atomic_cas! { type __AtomicPtr = (); } + crate::cfg_no_atomic_cas! { type __AtomicPtr = (); } + #[allow(unused_imports)] + use self::{ + __AtomicPtr as _, _Atomic8 as _, _Atomic16 as _, _Atomic32 as _, _Atomic64 as _, + _Atomic128 as _, _AtomicPtr as _, + }; +} diff --git a/vendor/portable-atomic/src/gen/build.rs b/vendor/portable-atomic/src/gen/build.rs new file mode 100644 index 0000000..39c4032 --- /dev/null +++ b/vendor/portable-atomic/src/gen/build.rs @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// This file is @generated by target_spec.sh. +// It is not intended for manual editing. + +// Note: This is the list as of nightly-2022-02-10. We don't refer to this in +// nightly-2022-02-11+ because feature(cfg_target_has_atomic) stabilized. +#[rustfmt::skip] +pub(crate) static NO_ATOMIC_CAS: &[&str] = &[ + "avr-unknown-gnu-atmega328", + "bpfeb-unknown-none", + "bpfel-unknown-none", + "msp430-none-elf", + "riscv32i-unknown-none-elf", + "riscv32imc-unknown-none-elf", + "thumbv4t-none-eabi", + "thumbv6m-none-eabi", +]; + +// Note: This is the list as of nightly-2022-02-10. We don't refer to this in +// nightly-2022-02-11+ because feature(cfg_target_has_atomic) stabilized. +#[rustfmt::skip] +pub(crate) static NO_ATOMIC_64: &[&str] = &[ + "arm-linux-androideabi", + "armebv7r-none-eabi", + "armebv7r-none-eabihf", + "armv4t-unknown-linux-gnueabi", + "armv5te-unknown-linux-gnueabi", + "armv5te-unknown-linux-musleabi", + "armv5te-unknown-linux-uclibceabi", + "armv6k-nintendo-3ds", + "armv7r-none-eabi", + "armv7r-none-eabihf", + "avr-unknown-gnu-atmega328", + "hexagon-unknown-linux-musl", + "m68k-unknown-linux-gnu", + "mips-unknown-linux-gnu", + "mips-unknown-linux-musl", + "mips-unknown-linux-uclibc", + "mipsel-sony-psp", + "mipsel-unknown-linux-gnu", + "mipsel-unknown-linux-musl", + "mipsel-unknown-linux-uclibc", + "mipsel-unknown-none", + "mipsisa32r6-unknown-linux-gnu", + "mipsisa32r6el-unknown-linux-gnu", + "msp430-none-elf", + "powerpc-unknown-freebsd", + "powerpc-unknown-linux-gnu", + "powerpc-unknown-linux-gnuspe", + "powerpc-unknown-linux-musl", + "powerpc-unknown-netbsd", + "powerpc-unknown-openbsd", + "powerpc-wrs-vxworks", + "powerpc-wrs-vxworks-spe", + "riscv32gc-unknown-linux-gnu", + "riscv32gc-unknown-linux-musl", + "riscv32i-unknown-none-elf", + "riscv32imac-unknown-none-elf", + "riscv32imc-esp-espidf", + "riscv32imc-unknown-none-elf", + "thumbv4t-none-eabi", + "thumbv6m-none-eabi", + "thumbv7em-none-eabi", + "thumbv7em-none-eabihf", + "thumbv7m-none-eabi", + "thumbv8m.base-none-eabi", + "thumbv8m.main-none-eabi", + "thumbv8m.main-none-eabihf", +]; + +#[rustfmt::skip] +pub(crate) static NO_ATOMIC: &[&str] = &[ + "armv4t-none-eabi", + "armv5te-none-eabi", + "bpfeb-unknown-none", + "bpfel-unknown-none", + "mipsel-sony-psx", + "thumbv4t-none-eabi", + "thumbv5te-none-eabi", +]; diff --git a/vendor/portable-atomic/src/gen/utils.rs b/vendor/portable-atomic/src/gen/utils.rs new file mode 100644 index 0000000..7c8a88e --- /dev/null +++ b/vendor/portable-atomic/src/gen/utils.rs @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// This file is @generated by target_spec.sh. +// It is not intended for manual editing. + +#![allow(dead_code, unused_macros)] + +// On AArch64, the base register of memory-related instructions must be 64-bit. +// Passing a 32-bit value to `in(reg)` on AArch64 results in the upper bits +// having an undefined value, but to work correctly with ILP32 ABI, the upper +// bits must be zero, which is handled here by casting to u64. Another way to +// handle this is to pass it as a pointer and clear the upper bits inside asm, +// but it is easier to overlook than cast, which can catch overlooks by +// asm_sub_register lint. +// See also https://github.com/ARM-software/abi-aa/blob/2025Q4/aapcs64/aapcs64.rst#pointers +// +// Except for x86_64, which can use 32-bit registers in the destination operand +// (on x86_64, we use the ptr_modifier macro to handle this), we need to do the +// same for ILP32 ABI on other 64-bit architectures. (At least, as far as I can +// see from the assembly generated by LLVM, this is also required for MIPS64 N32 +// ABI. I don't know about other similar ABIs, but in any case, this should be +// a safe default for such ABIs). +// +// Known architectures that have such ABI are x86_64 (X32), AArch64 (ILP32), +// mips64/mips64r6 (N32), riscv64 (RV64ILP32*), PowerPC64 (Lv2). (As of +// 2026-03-22, only the former two are supported by rustc.) However, we list +// all known 64-bit architectures because similar ABIs may exist or future added +// for other architectures. +#[cfg(all( + target_pointer_width = "32", + any( + target_arch = "aarch64", + target_arch = "amdgpu", + target_arch = "arm64ec", + target_arch = "bpf", + target_arch = "loongarch64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "nvptx64", + target_arch = "powerpc64", + target_arch = "riscv64", + target_arch = "s390x", + target_arch = "sparc64", + target_arch = "wasm64", + target_arch = "x86_64", + ), +))] +#[macro_use] +mod imp { + #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] + macro_rules! ptr_reg { + ($ptr:ident) => {{ + let _: *const _ = $ptr; // ensure $ptr is a pointer (*mut _ or *const _) + #[cfg(not(portable_atomic_no_asm_maybe_uninit))] + #[allow(clippy::ptr_as_ptr)] + { + // If we cast to u64 here, the provenance will be lost, + // so we convert to MaybeUninit via zero extend helper. + crate::utils::zero_extend64_ptr($ptr as *mut ()) + } + #[cfg(portable_atomic_no_asm_maybe_uninit)] + { + // Use cast on old rustc because it does not support MaybeUninit + // registers. This is still permissive-provenance compatible and + // is sound. + $ptr as u64 + } + }}; + } + pub(crate) type RegISize = i64; + pub(crate) type RegSize = u64; +} +#[cfg(not(all( + target_pointer_width = "32", + any( + target_arch = "aarch64", + target_arch = "amdgpu", + target_arch = "arm64ec", + target_arch = "bpf", + target_arch = "loongarch64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "nvptx64", + target_arch = "powerpc64", + target_arch = "riscv64", + target_arch = "s390x", + target_arch = "sparc64", + target_arch = "wasm64", + target_arch = "x86_64", + ), +)))] +#[macro_use] +mod imp { + #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] + macro_rules! ptr_reg { + ($ptr:ident) => {{ + let _: *const _ = $ptr; // ensure $ptr is a pointer (*mut _ or *const _) + $ptr // cast is unnecessary here. + }}; + } + pub(crate) type RegISize = isize; + pub(crate) type RegSize = usize; +} +pub(crate) use self::imp::{RegISize, RegSize}; + +// Some 64-bit architectures have ABI with 32-bit pointer width (e.g., x86_64 X32 ABI, +// AArch64 ILP32 ABI, MIPS64 N32 ABI). On those targets, AtomicU64 is available +// and fast, so use it to implement normal sequence lock. +// +// See ptr_reg macro for the reason why all known 64-bit architectures are listed. +// +// Note: These macros are cfg_*!({ }), not cfg_*! { }. +// An extra brace is used in input to make contents rustfmt-able. +#[cfg(any( + not(any(target_pointer_width = "16", target_pointer_width = "32")), // i.e., 64-bit or greater + target_arch = "aarch64", + target_arch = "amdgpu", + target_arch = "arm64ec", + target_arch = "bpf", + target_arch = "loongarch64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "nvptx64", + target_arch = "powerpc64", + target_arch = "riscv64", + target_arch = "s390x", + target_arch = "sparc64", + target_arch = "wasm64", + target_arch = "x86_64", +))] +#[macro_use] +mod fast_atomic_64_macros { + macro_rules! cfg_has_fast_atomic_64 { + ({$($tt:tt)*}) => { + $($tt)* + }; + } + macro_rules! cfg_no_fast_atomic_64 { + ({$($tt:tt)*}) => {}; + } +} +#[cfg(not(any( + not(any(target_pointer_width = "16", target_pointer_width = "32")), // i.e., 64-bit or greater + target_arch = "aarch64", + target_arch = "amdgpu", + target_arch = "arm64ec", + target_arch = "bpf", + target_arch = "loongarch64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "nvptx64", + target_arch = "powerpc64", + target_arch = "riscv64", + target_arch = "s390x", + target_arch = "sparc64", + target_arch = "wasm64", + target_arch = "x86_64", +)))] +#[macro_use] +mod fast_atomic_64_macros { + macro_rules! cfg_has_fast_atomic_64 { + ({$($tt:tt)*}) => {}; + } + macro_rules! cfg_no_fast_atomic_64 { + ({$($tt:tt)*}) => { + $($tt)* + }; + } +} diff --git a/vendor/portable-atomic/src/imp/arm_linux.rs b/vendor/portable-atomic/src/imp/arm_linux.rs new file mode 100644 index 0000000..6d67c74 --- /dev/null +++ b/vendor/portable-atomic/src/imp/arm_linux.rs @@ -0,0 +1,257 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Atomic operations implementation on pre-v6 ARM Linux/Android. + +This module optimizes cases where LLVM code generation is not optimal, +and provides workaround for core::sync::atomic bug (https://github.com/rust-lang/compiler-builtins/pull/1234). + +See "Atomic operation overview by architecture" in atomic-maybe-uninit for a more comprehensive and +detailed description of the atomic and synchronize instructions in this architecture: +https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#arm + +Refs: +- https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/arm/kernel_user_helpers.rst +- https://github.com/rust-lang/compiler-builtins/blob/compiler_builtins-v0.1.124/src/arm_linux.rs +- https://github.com/taiki-e/atomic-maybe-uninit + +Note: __kuser_memory_barrier is always SeqCst. +https://github.com/taiki-e/atomic-maybe-uninit/blob/v0.3.21/src/arch/arm.rs#L215 + +Note: On Miri and ThreadSanitizer which do not go through compiler-builtins, we don't use +this module and use normal core::sync::atomic instead. +*/ + +use core::{mem, sync::atomic::Ordering}; + +// https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/arm/kernel_user_helpers.rst +// __kuser_helper_version >= 3 (kernel version 2.6.15+) +const KUSER_MEMORY_BARRIER: usize = 0xFFFF0FA0; +#[inline] +fn __kuser_memory_barrier() { + // SAFETY: kernel docs specify a known address with the given signature. + // core assumes __kuser_helper_version >= 3. + unsafe { + let f: extern "C" fn() = + mem::transmute(crate::utils::ptr::with_exposed_provenance::<()>(KUSER_MEMORY_BARRIER)); + f(); + } +} + +/// An atomic fence. +/// +/// # Panics +/// +/// Panics if `order` is [`Relaxed`](Ordering::Relaxed). +#[cfg_attr(doc, allow(dead_code))] +#[inline] +#[cfg_attr(any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), track_caller)] +pub fn fence(order: Ordering) { + // Call __kuser_memory_barrier without going through __sync_synchronize. + match order { + Ordering::Relaxed => panic!("there is no such thing as a relaxed fence"), + _ => __kuser_memory_barrier(), + } +} + +cfg_core_atomic!({ + use super::core_atomic::{ + AtomicI8, AtomicI16, AtomicI32, AtomicIsize, AtomicPtr, AtomicU8, AtomicU16, AtomicU32, + AtomicUsize, + }; + macro_rules! atomic { + ($([$($generics:tt)*])? $atomic_type:ident, $value_type:ty) => { + impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? { + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn load(&self, order: Ordering) -> $value_type { + crate::utils::assert_load_ordering(order); + match order { + Ordering::Relaxed => self.inner.load(Ordering::Relaxed), + // Acquire and SeqCst loads are equivalent. + // This matches with LLVM, but GCC emits `dmb; ldr*; dmb` for SeqCst load. + Ordering::Acquire | Ordering::SeqCst => { + let out = self.inner.load(Ordering::Relaxed); + __kuser_memory_barrier(); + out + } + _ => unreachable!(), + } + } + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn store(&self, val: $value_type, order: Ordering) { + crate::utils::assert_store_ordering(order); + match order { + Ordering::Relaxed => self.inner.store(val, Ordering::Relaxed), + Ordering::Release => { + __kuser_memory_barrier(); + self.inner.store(val, Ordering::Relaxed); + } + Ordering::SeqCst => { + __kuser_memory_barrier(); + self.inner.store(val, Ordering::Relaxed); + __kuser_memory_barrier(); + } + _ => unreachable!(), + } + } + } + #[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(not(portable_atomic_no_atomic_cas)) + )] + #[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(target_has_atomic = "ptr") + )] + impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? { + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn compare_exchange( + &self, + current: $value_type, + new: $value_type, + success: Ordering, + failure: Ordering, + ) -> Result<$value_type, $value_type> { + crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check) + #[cfg(portable_atomic_no_stronger_failure_ordering)] + let success = crate::utils::upgrade_success_ordering(success, failure); + let res = self.inner.compare_exchange(current, new, success, failure); + if failure != Ordering::Relaxed && res.is_err() { + __kuser_memory_barrier(); + } + res + } + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn compare_exchange_weak( + &self, + current: $value_type, + new: $value_type, + success: Ordering, + failure: Ordering, + ) -> Result<$value_type, $value_type> { + crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check) + #[cfg(portable_atomic_no_stronger_failure_ordering)] + let success = crate::utils::upgrade_success_ordering(success, failure); + let res = self.inner.compare_exchange_weak(current, new, success, failure); + if failure != Ordering::Relaxed && res.is_err() { + __kuser_memory_barrier(); + } + res + } + } + }; + } + + atomic!(AtomicI8, i8); + atomic!(AtomicU8, u8); + atomic!(AtomicI16, i16); + atomic!(AtomicU16, u16); + atomic!(AtomicI32, i32); + atomic!(AtomicU32, u32); + atomic!(AtomicIsize, isize); + atomic!(AtomicUsize, usize); + atomic!([T] AtomicPtr, *mut T); +}); + +#[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(not(portable_atomic_no_atomic_64)))] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any( + target_has_atomic = "64", + not(any(target_pointer_width = "16", target_pointer_width = "32")), + )) +)] +items!({ + // This is not normally reached on this platform. + // It is only reached if something strange occurs, such as using target-feature=-v6 on armv6 target. + // Since 64-bit atomic operations differ from 32-bit or smaller ones on Arm, similar optimizations + // or workarounds are useless here, so do the same as atomic_int! macro in core_atomic.rs. + // NB: Sync with atomic_int! macro in core_atomic.rs + use super::core_atomic::{AtomicI64, AtomicU64}; + macro_rules! atomic_int { + ($atomic_type:ident, $int_type:ident) => { + impl $atomic_type { + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn load(&self, order: Ordering) -> $int_type { + crate::utils::assert_load_ordering(order); // for track_caller (compiler can omit double check) + self.inner.load(order) + } + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn store(&self, val: $int_type, order: Ordering) { + crate::utils::assert_store_ordering(order); // for track_caller (compiler can omit double check) + self.inner.store(val, order); + } + } + #[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(not(portable_atomic_no_atomic_cas)) + )] + #[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(target_has_atomic = "ptr") + )] + impl $atomic_type { + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn compare_exchange( + &self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering, + ) -> Result<$int_type, $int_type> { + crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check) + #[cfg(portable_atomic_no_stronger_failure_ordering)] + let success = crate::utils::upgrade_success_ordering(success, failure); + self.inner.compare_exchange(current, new, success, failure) + } + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn compare_exchange_weak( + &self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering, + ) -> Result<$int_type, $int_type> { + crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check) + #[cfg(portable_atomic_no_stronger_failure_ordering)] + let success = crate::utils::upgrade_success_ordering(success, failure); + self.inner.compare_exchange_weak(current, new, success, failure) + } + } + }; + } + atomic_int!(AtomicI64, i64); + atomic_int!(AtomicU64, u64); +}); diff --git a/vendor/portable-atomic/src/imp/atomic128/README.md b/vendor/portable-atomic/src/imp/atomic128/README.md new file mode 100644 index 0000000..a785d15 --- /dev/null +++ b/vendor/portable-atomic/src/imp/atomic128/README.md @@ -0,0 +1,39 @@ +# 128-bit atomic implementations on 64-bit architectures + +(See the [`atomic64` module](../atomic64) for 64-bit atomic implementations on 32-bit architectures.) + +## 128-bit atomic instructions + +Here is the table of targets that support 128-bit atomics and the instructions used: + +| target_arch | load | store | CAS | RMW | note | +| ----------- | ---- | ----- | --- | --- | ---- | +| x86_64 | cmpxchg16b or vmovdqa | cmpxchg16b or vmovdqa | cmpxchg16b | cmpxchg16b | Requires `cmpxchg16b` target feature (enabled by default on Apple, Windows (except Windows 7, since Rust 1.78), and Fuchsia (since Rust 1.87) targets). vmovdqa requires `avx` target feature.
Both compile-time and run-time detection are supported.
Requires Rust 1.59+ | +| aarch64/arm64ec | ldxp/stxp or casp or ldp/ldiapp | ldxp/stxp or casp or stp/stilp/swpp | ldxp/stxp or casp | ldxp/stxp or casp/swpp/ldclrp/ldsetp | casp requires `lse` target feature, ldp/stp requires `lse2` target feature, ldiapp/stilp requires `lse2` and `rcpc3` target features, swpp/ldclrp/ldsetp requires `lse128` target feature.
Both compile-time and run-time detection are supported.
Requires Rust 1.59+ (aarch64) / 1.84+ (arm64ec) | +| riscv64 | amocas.q | amocas.q | amocas.q | amocas.q | Requires `zacas` target feature. Both compile-time and run-time detection are supported.
Requires Rust 1.59+ | +| powerpc64 | lq | stq | lqarx/stqcx. | lqarx/stqcx. | Requires `quadword-atomics` target feature (enabled by default on powerpc64le). Both compile-time and run-time detection are supported.
Requires Rust 1.95+ | +| s390x | lpq | stpq | cdsg | cdsg | Requires Rust 1.84+ | +| loongarch64 | sc.q | sc.q | sc.q | sc.q | Unimplemented. Requires `scq` target feature. | +| mips64r6 | lldp | lldp/scdp | lldp/scdp | lldp/scdp | Unimplemented (unsupported in LLVM). Requires Release 6 Paired LL/SC family of instructions | +| nvptx64 | ld.b128 | st.b128 | atom.cas.b128 | atom.exch.b128/atom.cas.b128 | Unimplemented. Requires `ptx83` and `sm_90`. | + +On compiler versions or platforms where these are not supported, the fallback implementation is used. + +See [aarch64.rs](aarch64.rs) module-level comments for more details on the instructions used on AArch64. + +## Comparison with core::intrinsics::atomic_\* (core::sync::atomic::Atomic{I,U}128) + +This directory has target-specific implementations with inline assembly ([x86_64.rs](x86_64.rs), [aarch64.rs](aarch64.rs), [riscv64.rs](riscv64.rs), [powerpc64.rs](powerpc64.rs), [s390x.rs](s390x.rs)) and an implementation without inline assembly ([intrinsics.rs](intrinsics.rs)). The latter currently always needs nightly compilers and is only used for Miri and ThreadSanitizer, which do not support inline assembly. + +Implementations with inline assembly generate assemblies almost equivalent to the `core::intrinsics::atomic_*` (used in `core::sync::atomic::Atomic{I,U}128`) for many operations, but some operations may or may not generate more efficient code. For example: + +- On x86_64 and AArch64, implementation with inline assembly contains additional optimizations (e.g., [#16](https://github.com/taiki-e/portable-atomic/pull/16), [#126](https://github.com/taiki-e/portable-atomic/pull/126)) and is much faster for some operations. +- On AArch64, implementation with inline assembly supports outline-atomics on more operating systems, and may be faster in environments where outline-atomics can improve performance. +- On powerpc64, LLVM does not support generating some 128-bit atomic operations (see [intrinsics.rs](intrinsics.rs) module-level comments), and we use CAS loop to implement them, so implementation with inline assembly may be faster for those operations. +- In implementations without inline assembly, the compiler may reuse condition flags that have changed as a result of the operation, or use immediate values instead of registers, depending on the situation. + +As 128-bit atomics-related APIs stabilize in the standard library, implementations with inline assembly are planned to be updated to get the benefits of both. + +## Run-time CPU feature detection + +See the [`detect` module's readme](../detect/README.md) for run-time CPU feature detection. diff --git a/vendor/portable-atomic/src/imp/atomic128/aarch64.rs b/vendor/portable-atomic/src/imp/atomic128/aarch64.rs new file mode 100644 index 0000000..65af504 --- /dev/null +++ b/vendor/portable-atomic/src/imp/atomic128/aarch64.rs @@ -0,0 +1,2239 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +128-bit atomic implementation on AArch64. + +This architecture provides the following 128-bit atomic instructions: + +- LDXP/STXP: LL/SC (Armv8.0 baseline) +- CASP: CAS (added as Armv8.1 FEAT_LSE (optional from Armv8.0, mandatory from Armv8.1)) +- LDP/STP: load/store (if Armv8.4 FEAT_LSE2 (optional from Armv8.2, mandatory from Armv8.4) is available) +- LDIAPP/STILP: acquire-load/release-store (added as Armv8.9 FEAT_LRCPC3 (optional from Armv8.2) (if FEAT_LSE2 is also available)) +- LDCLRP/LDSETP/SWPP: fetch-and-{clear,or},swap (added as Armv9.4 FEAT_LSE128 (optional from Armv9.3)) + +See "Atomic operation overview by architecture" in atomic-maybe-uninit for a more comprehensive and +detailed description of the atomic and synchronize instructions in this architecture: +https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#aarch64 + +This module supports all of these instructions and attempts to select the best +one based on compile-time and run-time information about available CPU features +and platforms. For example: + +- If outline-atomics is not enabled and FEAT_LSE is not available at + compile-time, we use LDXP/STXP loop. +- If outline-atomics is enabled and FEAT_LSE is not available at + compile-time, we use CASP for CAS if FEAT_LSE is available + at run-time, otherwise, use LDXP/STXP loop. +- If FEAT_LSE is available at compile-time, we use CASP for load/store/CAS/RMW. + However, when portable_atomic_ll_sc_rmw cfg is set, use LDXP/STXP loop instead of CASP + loop for RMW (by default, it is set on Apple hardware where CASP is slow; + see build script for details). +- If outline-atomics is enabled and FEAT_LSE2 is not available at compile-time, + we use LDP/STP (and also LDIAPP/STILP/SWPP if FEAT_LRCPC3/FEAT_LSE128 is + available) for load/store if FEAT_LSE2 is available at run-time, otherwise, + use LDXP/STXP or CASP depending on whether FEAT_LSE is available. +- If FEAT_LSE2 is available at compile-time, we use LDP/STP for load/store. +- If FEAT_LSE128 is available at compile-time, we use LDCLRP/LDSETP/SWPP for fetch_and/fetch_or/swap/{release,seqcst}-store. +- If FEAT_LSE2 and FEAT_LRCPC3 are available at compile-time, we use LDIAPP/STILP for acquire-load/release-store. + +See each "Instruction selection flow for ..." comment in this file for the exact +instruction selection per operation. + +Note: FEAT_LSE2 doesn't imply FEAT_LSE. FEAT_LSE128 implies FEAT_LSE but not FEAT_LSE2. + +Note that we do not separate LL and SC into separate functions, but handle +them within a single asm block. This is because it is theoretically possible +for the compiler to insert operations that might clear the reservation between +LL and SC. Considering the type of operations we are providing and the fact +that [progress64](https://github.com/ARM-software/progress64) uses such code, +this is probably not a problem for AArch64, but it seems that AArch64 doesn't +guarantee it and hexagon is the only architecture with hardware guarantees +that such code works. See also: + +- https://yarchive.net/comp/linux/cmpxchg_ll_sc_portability.html +- https://lists.llvm.org/pipermail/llvm-dev/2016-May/099490.html +- https://lists.llvm.org/pipermail/llvm-dev/2018-June/123993.html + +Also, even when using a CAS loop to implement atomic RMW, include the loop itself +in the asm block because it is more efficient for some codegen backends. +https://github.com/rust-lang/compiler-builtins/issues/339#issuecomment-1191260474 + +Note: On Miri and ThreadSanitizer which do not support inline assembly, we don't use +this module and use intrinsics.rs instead. + +Refs: +- Arm A-profile A64 Instruction Set Architecture + https://developer.arm.com/documentation/ddi0602/2025-06 +- C/C++ Atomics Application Binary Interface Standard for the Arm® 64-bit Architecture + https://github.com/ARM-software/abi-aa/blob/2025Q4/atomicsabi64/atomicsabi64.rst +- Arm Compiler armasm User Guide + https://developer.arm.com/documentation/dui0801/latest +- Arm Architecture Reference Manual for A-profile architecture + https://developer.arm.com/documentation/ddi0487/latest (PDF) +- Arm Architecture Reference Manual Supplement - Armv8, for Armv8-R AArch64 architecture profile + https://developer.arm.com/documentation/ddi0600/latest (PDF) +- atomic-maybe-uninit https://github.com/taiki-e/atomic-maybe-uninit + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +include!("macros.rs"); + +// On musl with static linking, it seems that getauxval is not always available. +// See detect/auxv.rs for more. +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(any( + test, + not(all( + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + any(target_feature = "lse2", portable_atomic_target_feature = "lse2"), + )), +))] +#[cfg(any( + all( + target_os = "linux", + any( + target_env = "gnu", + all(target_env = "musl", any(not(target_feature = "crt-static"), feature = "std")), + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + portable_atomic_outline_atomics, + ), + ), + target_os = "android", + target_os = "freebsd", +))] +#[path = "../detect/auxv.rs"] +mod detect; +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(any( + test, + not(all( + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + any(target_feature = "lse2", portable_atomic_target_feature = "lse2"), + )), +))] +#[cfg(any(target_os = "netbsd", target_os = "openbsd"))] +#[path = "../detect/aarch64_aa64reg.rs"] +mod detect; +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(any( + test, + not(all( + any(target_feature = "lse2", portable_atomic_target_feature = "lse2"), + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + )), +))] +#[cfg(target_os = "illumos")] +#[path = "../detect/aarch64_illumos.rs"] +mod detect; +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(any(test, not(any(target_feature = "lse", portable_atomic_target_feature = "lse"))))] +#[cfg(target_os = "fuchsia")] +#[path = "../detect/aarch64_fuchsia.rs"] +mod detect; +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(any( + test, + not(all( + any(target_feature = "lse2", portable_atomic_target_feature = "lse2"), + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + )), +))] +#[cfg(target_vendor = "apple")] +#[path = "../detect/aarch64_apple.rs"] +mod detect; +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(any( + test, + not(all( + any(target_feature = "lse2", portable_atomic_target_feature = "lse2"), + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + )), +))] +#[cfg(windows)] +#[path = "../detect/aarch64_windows.rs"] +mod detect; + +#[cfg(test)] // test-only (we use auxv.rs instead) +#[cfg(not(valgrind))] +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(any(target_os = "linux", target_os = "android", target_os = "freebsd"))] +#[path = "../detect/aarch64_aa64reg.rs"] +mod test_detect_aa64reg; +#[cfg(test)] // test-only (we use aarch64_aa64reg.rs instead) +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(target_os = "openbsd")] +#[path = "../detect/auxv.rs"] +mod test_detect_auxv; + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; +use core::sync::atomic::Ordering; + +#[cfg(portable_atomic_no_strict_provenance)] +use crate::utils::ptr::PtrExt as _; +use crate::utils::{Pair, U128}; + +#[cfg(any( + target_feature = "lse", + portable_atomic_target_feature = "lse", + not(portable_atomic_no_outline_atomics), +))] +#[rustfmt::skip] +macro_rules! debug_assert_lse { + () => { + #[cfg(all( + not(portable_atomic_no_outline_atomics), + any( + all( + target_os = "linux", + any( + target_env = "gnu", + all( + target_env = "musl", + any(not(target_feature = "crt-static"), feature = "std"), + ), + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + portable_atomic_outline_atomics, + ), + ), + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + target_os = "fuchsia", + target_vendor = "apple", + windows, + ), + ))] + #[cfg(not(any(target_feature = "lse", portable_atomic_target_feature = "lse")))] + { + debug_assert!(detect::detect().lse()); + } + }; +} +#[cfg(any( + target_feature = "lse2", + portable_atomic_target_feature = "lse2", + not(portable_atomic_no_outline_atomics), +))] +#[rustfmt::skip] +macro_rules! debug_assert_lse2 { + () => { + #[cfg(all( + not(portable_atomic_no_outline_atomics), + any( + all( + target_os = "linux", + any( + target_env = "gnu", + all( + target_env = "musl", + any(not(target_feature = "crt-static"), feature = "std"), + ), + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + portable_atomic_outline_atomics, + ), + ), + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + // These don't support detection of FEAT_LSE2. + // target_os = "fuchsia", + target_vendor = "apple", + windows, + ), + ))] + #[cfg(not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")))] + { + debug_assert!(detect::detect().lse2()); + } + }; +} +#[cfg(any( + target_feature = "lse128", + portable_atomic_target_feature = "lse128", + all( + not(portable_atomic_no_outline_atomics), + not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")), + ), +))] +#[rustfmt::skip] +macro_rules! debug_assert_lse128 { + () => { + #[cfg(all( + not(portable_atomic_no_outline_atomics), + any( + all( + target_os = "linux", + any( + target_env = "gnu", + all( + target_env = "musl", + any(not(target_feature = "crt-static"), feature = "std"), + ), + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + portable_atomic_outline_atomics, + ), + ), + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + // These don't support detection of FEAT_LSE128. + // target_os = "fuchsia", + target_vendor = "apple", + windows, + ), + ))] + #[cfg(not(any(target_feature = "lse128", portable_atomic_target_feature = "lse128")))] + { + debug_assert!(detect::detect().lse128()); + } + }; +} +#[cfg(any( + target_feature = "rcpc3", + portable_atomic_target_feature = "rcpc3", + all( + not(portable_atomic_no_outline_atomics), + not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")), + ), +))] +#[rustfmt::skip] +macro_rules! debug_assert_rcpc3 { + () => { + #[cfg(all( + not(portable_atomic_no_outline_atomics), + any( + all( + target_os = "linux", + any( + target_env = "gnu", + all( + target_env = "musl", + any(not(target_feature = "crt-static"), feature = "std"), + ), + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + portable_atomic_outline_atomics, + ), + ), + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + // These don't support detection of FEAT_LRCPC3. + // target_os = "fuchsia", + target_vendor = "apple", + windows, + ), + ))] + #[cfg(not(any(target_feature = "rcpc3", portable_atomic_target_feature = "rcpc3")))] + { + debug_assert!(detect::detect().rcpc3()); + } + }; +} + +// Refs: https://developer.arm.com/documentation/100067/0611/armclang-Integrated-Assembler/AArch32-Target-selection-directives +// +// This is similar to #[target_feature(enable = "lse")], except that there are +// no compiler guarantees regarding (un)inlining, and the scope is within an asm +// block rather than a function. We use this directive because #[target_feature(enable = "lse")] +// is unstable on pre-1.61 rustc and incompatible with rustc_codegen_cranelift: +// https://github.com/rust-lang/rustc_codegen_cranelift/issues/1400#issuecomment-1774599775 +// +// The .arch_extension directive in asm! is effective until the end of the assembly block and +// is not propagated to subsequent code, so the end_lse macro is unneeded. +// https://godbolt.org/z/o6EPndP94 +// https://github.com/torvalds/linux/commit/e0d5896bd356cd577f9710a02d7a474cdf58426b +// https://github.com/torvalds/linux/commit/dd1f6308b28edf0452dd5dc7877992903ec61e69 +// (It seems GCC effectively ignores this directive and always allow FEAT_LSE instructions: https://godbolt.org/z/W9W6rensG) +// Note that the .arch_extension directive in global_asm!/naked_asm! which are +// not used in this crate has different behavior: https://github.com/rust-lang/rust/pull/137720#discussion_r1973608259 +// Note that this directive currently cannot be used correctly with global_asm!/naked_asm! +// due to LLVM bug: https://github.com/rust-lang/rust/pull/137720#discussion_r2014505753 +// +// The .arch directive has a similar effect, but we don't use it due to the following issue: +// https://github.com/torvalds/linux/commit/dd1f6308b28edf0452dd5dc7877992903ec61e69 +// +// Note: If FEAT_LSE is not available at compile-time, we must guarantee that +// the function that uses it is not inlined into a function where it is not +// clear whether FEAT_LSE is available. Otherwise, (even if we checked whether +// FEAT_LSE is available at run-time) optimizations that reorder its +// instructions across the if condition might introduce undefined behavior. +// (see also https://rust-lang.github.io/rfcs/2045-target-feature.html#safely-inlining-target_feature-functions-on-more-contexts) +// However, our code uses the ifunc helper macro that works with function pointers, +// so we don't have to worry about this unless calling without helper macro. +#[cfg(any( + target_feature = "lse", + portable_atomic_target_feature = "lse", + not(portable_atomic_no_outline_atomics), +))] +macro_rules! start_lse { + () => { + ".arch_extension lse" + }; +} +#[cfg(not(portable_atomic_pre_llvm_16))] +#[cfg(any( + target_feature = "lse128", + portable_atomic_target_feature = "lse128", + all( + not(portable_atomic_no_outline_atomics), + not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")), + ), +))] +macro_rules! start_lse128 { + () => { + ".arch_extension lse128" + }; +} +#[cfg(not(portable_atomic_pre_llvm_16))] +#[cfg(any( + target_feature = "rcpc3", + portable_atomic_target_feature = "rcpc3", + all( + not(portable_atomic_no_outline_atomics), + not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")), + ), +))] +macro_rules! start_rcpc3 { + () => { + ".arch_extension rcpc3" + }; +} + +#[cfg(target_endian = "little")] +macro_rules! select_le_or_be { + ($le:expr, $be:expr) => { + $le + }; +} +#[cfg(target_endian = "big")] +macro_rules! select_le_or_be { + ($le:expr, $be:expr) => { + $be + }; +} + +macro_rules! atomic_rmw { + ($op:ident, $order:ident) => { + atomic_rmw!($op, $order, write = $order) + }; + ($op:ident, $order:ident, write = $write:ident) => { + match $order { + Ordering::Relaxed => $op!("", "", ""), + Ordering::Acquire => $op!("a", "", ""), + Ordering::Release => $op!("", "l", ""), + Ordering::AcqRel => $op!("a", "l", ""), + // In MSVC environments, SeqCst stores/writes by non-LSE* instructions needs fences after writes. + // https://reviews.llvm.org/D141748 + // https://github.com/llvm/llvm-project/commit/1ea201d73be2fdf03347e9c6be09ebed5f8e0e00 + #[cfg(target_env = "msvc")] + Ordering::SeqCst if $write == Ordering::SeqCst => $op!("a", "l", "dmb ish"), + // AcqRel and SeqCst RMWs are equivalent in non-MSVC environments. + Ordering::SeqCst => $op!("a", "l", ""), + _ => unreachable!(), + } + }; +} +#[cfg(portable_atomic_pre_llvm_16)] +#[cfg(any( + target_feature = "lse128", + portable_atomic_target_feature = "lse128", + all( + not(portable_atomic_no_outline_atomics), + not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")), + ), +))] +macro_rules! atomic_rmw_inst { + ($op:ident, $order:ident) => { + atomic_rmw_inst!($op, $order, write = $order) + }; + ($op:ident, $order:ident, write = $write:ident) => { + match $order { + Ordering::Relaxed => $op!("2", ""), // "" + Ordering::Acquire => $op!("a", ""), // "a" + Ordering::Release => $op!("6", ""), // "l" + Ordering::AcqRel => $op!("e", ""), // "al" + // In MSVC environments, SeqCst stores/writes by non-LSE* instructions needs fences after writes. + // https://reviews.llvm.org/D141748 + // https://github.com/llvm/llvm-project/commit/1ea201d73be2fdf03347e9c6be09ebed5f8e0e00 + #[cfg(target_env = "msvc")] + Ordering::SeqCst if $write == Ordering::SeqCst => $op!("e", "dmb ish"), + // AcqRel and SeqCst RMWs are equivalent in non-MSVC environments. + Ordering::SeqCst => $op!("e", ""), + _ => unreachable!(), + } + }; +} + +// ----------------------------------------------------------------------------- +// load + +/* + +Instruction selection flow for load: +- if compile_time(FEAT_LSE2) => ldp: + - if compile_time(FEAT_LRCPC3) && order != relaxed => ldiapp + - else => ldp +- if platform_supports_detection_of(FEAT_LSE2): + - if detect(FEAT_LSE2) && detect(FEAT_LRCPC3) && order != relaxed => lse2_rcpc3 (ldiapp) + - if detect(FEAT_LSE2) => lse2 (ldp) +- else => no_lse2: + - if compile_time(FEAT_LSE) => casp + - else => ldxp_stxp + +Note: +- If FEAT_LSE2 is available at compile-time, we don't do run-time detection of + FEAT_LRCPC3 at this time, since FEAT_LRCPC3 is not yet available for most CPUs. + (macOS that doesn't have any FEAT_LRCPC3-enabled CPUs as of M4 is only a platform + that currently enables FEAT_LSE2 at compile-time by default.) +- If FEAT_LSE2 is not available at compile-time, we want to do run-time detection + of FEAT_LSE2, so we do run-time detection of FEAT_LRCPC3 at the same time. +- We don't do run-time detection of FEAT_LSE for load at this time, but since + load by CAS is wait-free, it would probably make sense to do run-time detection. (TODO) + +*/ + +cfg_sel!({ + // if compile_time(FEAT_LSE2) => ldp: + // cfg guarantee that the CPU supports FEAT_LSE2. + #[cfg(any(target_feature = "lse2", portable_atomic_target_feature = "lse2"))] + { + use self::_atomic_load_ldp as atomic_load; + } + // if platform_supports_detection_of(FEAT_LSE2): + #[cfg(all( + not(portable_atomic_no_outline_atomics), + any( + all( + target_os = "linux", + any( + target_env = "gnu", + all( + target_env = "musl", + any(not(target_feature = "crt-static"), feature = "std"), + ), + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + portable_atomic_outline_atomics, + ), + ), + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + // These don't support detection of FEAT_LSE2. + // target_os = "fuchsia", + target_vendor = "apple", + windows, + ), + ))] + { + #[inline] + unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 { + fn_alias! { + // inline(never) is just a hint and also not strictly necessary + // because we use ifunc helper macro, but used for clarity. + #[inline(never)] + unsafe fn(src: *mut u128) -> u128; + atomic_load_lse2_relaxed = _atomic_load_ldp(Ordering::Relaxed); + atomic_load_lse2_acquire = _atomic_load_ldp(Ordering::Acquire); + atomic_load_lse2_seqcst = _atomic_load_ldp(Ordering::SeqCst); + atomic_load_lse2_rcpc3_acquire = _atomic_load_ldiapp(Ordering::Acquire); + atomic_load_lse2_rcpc3_seqcst = _atomic_load_ldiapp(Ordering::SeqCst); + } + fn_alias! { + unsafe fn(src: *mut u128) -> u128; + atomic_load_no_lse2_relaxed = atomic_load_no_lse2(Ordering::Relaxed); + atomic_load_no_lse2_acquire = atomic_load_no_lse2(Ordering::Acquire); + atomic_load_no_lse2_seqcst = atomic_load_no_lse2(Ordering::SeqCst); + } + // SAFETY: the caller must uphold the safety contract. + // and we've checked if FEAT_LSE2/FEAT_LRCPC3 is available. + unsafe { + match order { + Ordering::Relaxed => { + ifunc!(unsafe fn(src: *mut u128) -> u128 { + let cpuinfo = detect::detect(); + if cpuinfo.lse2() { + // if detect(FEAT_LSE2) => lse2 (ldp) + atomic_load_lse2_relaxed + } else { + // else => no_lse2: + atomic_load_no_lse2_relaxed + } + }) + } + Ordering::Acquire => { + ifunc!(unsafe fn(src: *mut u128) -> u128 { + let cpuinfo = detect::detect(); + if cpuinfo.lse2() { + if cpuinfo.rcpc3() { + // if detect(FEAT_LSE2) && detect(FEAT_LRCPC3) && order != relaxed => lse2_rcpc3 (ldiapp) + atomic_load_lse2_rcpc3_acquire + } else { + // if detect(FEAT_LSE2) => lse2 (ldp) + atomic_load_lse2_acquire + } + } else { + // else => no_lse2: + atomic_load_no_lse2_acquire + } + }) + } + Ordering::SeqCst => { + ifunc!(unsafe fn(src: *mut u128) -> u128 { + let cpuinfo = detect::detect(); + if cpuinfo.lse2() { + if cpuinfo.rcpc3() { + // if detect(FEAT_LSE2) && detect(FEAT_LRCPC3) && order != relaxed => lse2_rcpc3 (ldiapp) + atomic_load_lse2_rcpc3_seqcst + } else { + // if detect(FEAT_LSE2) => lse2 (ldp) + atomic_load_lse2_seqcst + } + } else { + // else => no_lse2: + atomic_load_no_lse2_seqcst + } + }) + } + _ => unreachable!(), + } + } + } + } + // else => no_lse2: + #[cfg(else)] + { + use self::atomic_load_no_lse2 as atomic_load; + } +}); +#[cfg(not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")))] +cfg_sel!({ + // if compile_time(FEAT_LSE) => casp + // cfg guarantee that the CPU supports FEAT_LSE. + #[cfg(any(target_feature = "lse", portable_atomic_target_feature = "lse"))] + { + use self::_atomic_load_casp as atomic_load_no_lse2; + } + // else => ldxp_stxp + #[cfg(else)] + { + use self::_atomic_load_ldxp_stxp as atomic_load_no_lse2; + } +}); +// If CPU supports FEAT_LSE2, LDP/LDIAPP is single-copy atomic reads, +// otherwise it is two single-copy atomic reads. +// Refs: B2.2.1 of the Arm Architecture Reference Manual Armv8, for Armv8-A architecture profile +#[cfg(any( + target_feature = "lse2", + portable_atomic_target_feature = "lse2", + not(portable_atomic_no_outline_atomics), +))] +#[inline] +unsafe fn _atomic_load_ldp(src: *mut u128, order: Ordering) -> u128 { + debug_assert!(src.addr() % 16 == 0); + debug_assert_lse2!(); + + // SAFETY: the caller must guarantee that `dst` is valid for reads, + // 16-byte aligned, that there are no concurrent non-atomic operations. + // + // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/LDP--Load-pair-of-registers- + unsafe { + let (out_lo, out_hi); + macro_rules! atomic_load_relaxed { + ($acquire:tt) => {{ + asm!( + "ldp {out_lo}, {out_hi}, [{src}]", // atomic { out_lo:out_hi = *src } + $acquire, // fence + src = in(reg) ptr_reg!(src), + out_hi = lateout(reg) out_hi, + out_lo = lateout(reg) out_lo, + options(nostack, preserves_flags), + ); + U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole + }}; + } + match order { + // if compile_time(FEAT_LRCPC3) && order != relaxed => ldiapp + // SAFETY: cfg guarantee that the CPU supports FEAT_LRCPC3. + #[cfg(any(target_feature = "rcpc3", portable_atomic_target_feature = "rcpc3"))] + Ordering::Acquire | Ordering::SeqCst => _atomic_load_ldiapp(src, order), + + // else => ldp + Ordering::Relaxed => atomic_load_relaxed!(""), + #[cfg(not(any(target_feature = "rcpc3", portable_atomic_target_feature = "rcpc3")))] + Ordering::Acquire => atomic_load_relaxed!("dmb ishld"), + #[cfg(not(any(target_feature = "rcpc3", portable_atomic_target_feature = "rcpc3")))] + Ordering::SeqCst => { + asm!( + // ldar (or dmb ishld) is required to prevent reordering with preceding stlxp. + // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108891 for details. + "ldar {tmp}, [{src}]", // atomic { tmp = *src } + "ldp {out_lo}, {out_hi}, [{src}]", // atomic { out_lo:out_hi = *src } + "dmb ishld", // fence + src = in(reg) ptr_reg!(src), + out_hi = lateout(reg) out_hi, + out_lo = lateout(reg) out_lo, + tmp = out(reg) _, + options(nostack, preserves_flags), + ); + U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole + } + _ => unreachable!(), + } + } +} +#[cfg(any( + target_feature = "lse2", + portable_atomic_target_feature = "lse2", + not(portable_atomic_no_outline_atomics), +))] +#[cfg(any( + target_feature = "rcpc3", + portable_atomic_target_feature = "rcpc3", + all( + not(portable_atomic_no_outline_atomics), + not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")), + ), +))] +#[inline] +unsafe fn _atomic_load_ldiapp(src: *mut u128, order: Ordering) -> u128 { + debug_assert!(src.addr() % 16 == 0); + debug_assert_lse2!(); + debug_assert_rcpc3!(); + + // SAFETY: the caller must guarantee that `dst` is valid for reads, + // 16-byte aligned, that there are no concurrent non-atomic operations. + // + // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/LDIAPP--Load-Acquire-RCpc-ordered-pair-of-registers- + unsafe { + let (out_lo, out_hi); + match order { + Ordering::Acquire => { + #[cfg(not(portable_atomic_pre_llvm_16))] + asm!( + start_rcpc3!(), + "ldiapp {out_lo}, {out_hi}, [{src}]", // atomic { out_lo:out_hi = *src } + src = in(reg) ptr_reg!(src), + out_hi = lateout(reg) out_hi, + out_lo = lateout(reg) out_lo, + options(nostack, preserves_flags), + ); + // LLVM supports FEAT_LRCPC3 instructions on LLVM 16+, so use .inst directive on old LLVM. + // https://github.com/llvm/llvm-project/commit/a6aaa969f7caec58a994142f8d855861cf3a1463 + #[cfg(portable_atomic_pre_llvm_16)] + asm!( + // ldiapp x0, x1, [x0] // atomic { out_lo:out_hi = *src } + ".inst 0xd9411800", + in("x0") ptr_reg!(src), + lateout("x1") out_hi, + lateout("x0") out_lo, + options(nostack, preserves_flags), + ); + } + Ordering::SeqCst => { + #[cfg(not(portable_atomic_pre_llvm_16))] + asm!( + start_rcpc3!(), + // ldar (or dmb ishld) is required to prevent reordering with preceding stlxp. + // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108891 for details. + "ldar {tmp}, [{src}]", // atomic { tmp = *src } + "ldiapp {out_lo}, {out_hi}, [{src}]", // atomic { out_lo:out_hi = *src } + src = in(reg) ptr_reg!(src), + out_hi = lateout(reg) out_hi, + out_lo = lateout(reg) out_lo, + tmp = out(reg) _, + options(nostack, preserves_flags), + ); + // LLVM supports FEAT_LRCPC3 instructions on LLVM 16+, so use .inst directive on old LLVM. + // https://github.com/llvm/llvm-project/commit/a6aaa969f7caec58a994142f8d855861cf3a1463 + #[cfg(portable_atomic_pre_llvm_16)] + asm!( + // ldar (or dmb ishld) is required to prevent reordering with preceding stlxp. + // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108891 for details. + "ldar {tmp}, [x0]", // atomic { out_lo:out_hi = *src } + // ldiapp x0, x1, [x0] // atomic { tmp = *src } + ".inst 0xd9411800", + tmp = out(reg) _, + in("x0") ptr_reg!(src), + lateout("x1") out_hi, + lateout("x0") out_lo, + options(nostack, preserves_flags), + ); + } + _ => unreachable!(), + } + U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole + } +} +// Do not use _atomic_compare_exchange_casp because it needs extra MOV to implement load. +#[cfg(any(test, not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2"))))] +#[cfg(any(target_feature = "lse", portable_atomic_target_feature = "lse"))] +#[inline] +unsafe fn _atomic_load_casp(src: *mut u128, order: Ordering) -> u128 { + debug_assert!(src.addr() % 16 == 0); + debug_assert_lse!(); + + // SAFETY: the caller must uphold the safety contract. + // cfg guarantee that the CPU supports FEAT_LSE. + unsafe { + let (out_lo, out_hi); + macro_rules! atomic_load { + ($acquire:tt, $release:tt) => { + asm!( + start_lse!(), + concat!("casp", $acquire, $release, " x2, x3, x2, x3, [{src}]"), // atomic { if *src == x2:x3 { *dst = x2:x3 } else { x2:x3 = *dst } } + src = in(reg) ptr_reg!(src), + // must be allocated to even/odd register pair + inout("x2") 0_u64 => out_lo, + inout("x3") 0_u64 => out_hi, + options(nostack, preserves_flags), + ) + }; + } + match order { + Ordering::Relaxed => atomic_load!("", ""), + Ordering::Acquire => atomic_load!("a", ""), + // TODO: in atomicsabi64, seqcst load is the same as acquire load + Ordering::SeqCst => atomic_load!("a", "l"), + _ => unreachable!(), + } + U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole + } +} +#[cfg(any( + test, + all( + not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")), + not(any(target_feature = "lse", portable_atomic_target_feature = "lse")), + ), +))] +#[inline] +unsafe fn _atomic_load_ldxp_stxp(src: *mut u128, order: Ordering) -> u128 { + debug_assert!(src.addr() % 16 == 0); + + // SAFETY: the caller must uphold the safety contract. + unsafe { + let (mut out_lo, mut out_hi); + macro_rules! atomic_load { + ($acquire:tt, $release:tt) => { + asm!( + "2:", // 'retry: + concat!("ld", $acquire, "xp {out_lo}, {out_hi}, [{src}]"), // atomic { out_lo:out_hi = *src; EXCLUSIVE = src } + // write back to ensure atomicity + concat!("st", $release, "xp {r:w}, {out_lo}, {out_hi}, [{src}]"), // atomic { if EXCLUSIVE == src { *src = out_lo:out_hi; r = 0 } else { r = 1 }; EXCLUSIVE = None } + "cbnz {r:w}, 2b", // if r != 0 { jump 'retry } + src = in(reg) ptr_reg!(src), + out_lo = out(reg) out_lo, + out_hi = out(reg) out_hi, + r = out(reg) _, + options(nostack, preserves_flags), + ) + }; + } + match order { + Ordering::Relaxed => atomic_load!("", ""), + Ordering::Acquire => atomic_load!("a", ""), + // TODO: in atomicsabi64, seqcst load is the same as acquire load + Ordering::SeqCst => atomic_load!("a", "l"), + _ => unreachable!(), + } + U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole + } +} + +// ----------------------------------------------------------------------------- +// store + +/* + +Instruction selection flow for store: +- if compile_time(FEAT_LSE2) => stp: + - if compile_time(FEAT_LSE128) && order == seqcst => swpp + - if compile_time(FEAT_LRCPC3) && order != relaxed => stilp + - if compile_time(FEAT_LSE128) && order != relaxed => swpp + - else => stp +- if platform_supports_detection_of(FEAT_LSE2): + - if detect(FEAT_LSE2) && detect(FEAT_LSE128) && order == seqcst => lse128 (swpp) + - if detect(FEAT_LSE2) && detect(FEAT_LRCPC3) && order != relaxed => lse2_rcpc3 (stilp) + - if detect(FEAT_LSE2) && detect(FEAT_LSE128) && order != relaxed => lse128 (swpp) + - if detect(FEAT_LSE2) => lse2 (stp) +- else => no_lse2: + - if compile_time(FEAT_LSE) && not(ll_sc_rmw) => casp + - else => ldxp_stxp + +Note: +- If FEAT_LSE2 is available at compile-time, we don't do run-time detection of + FEAT_LRCPC3/FEAT_LSE128 at this time, since FEAT_LRCPC3/FEAT_LSE128 is not yet available for most CPUs. + (macOS that doesn't have any FEAT_LRCPC3/FEAT_LSE128-enabled CPUs as of M4 is only a platform + that currently enables FEAT_LSE2 at compile-time by default.) +- If FEAT_LSE2 is not available at compile-time, we want to do run-time detection + of FEAT_LSE2, so we do run-time detection of FEAT_LRCPC3/FEAT_LSE128 at the same time. +- We don't do run-time detection of FEAT_LSE for store at this time. + +*/ + +cfg_sel!({ + // if compile_time(FEAT_LSE2) => stp: + // cfg guarantee that the CPU supports FEAT_LSE2. + #[cfg(any(target_feature = "lse2", portable_atomic_target_feature = "lse2"))] + { + use self::_atomic_store_stp as atomic_store; + } + // if platform_supports_detection_of(FEAT_LSE2): + #[cfg(all( + not(portable_atomic_no_outline_atomics), + any( + all( + target_os = "linux", + any( + target_env = "gnu", + all( + target_env = "musl", + any(not(target_feature = "crt-static"), feature = "std"), + ), + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + portable_atomic_outline_atomics, + ), + ), + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + // These don't support detection of FEAT_LSE2. + // target_os = "fuchsia", + target_vendor = "apple", + windows, + ), + ))] + { + #[inline] + unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) { + #[cfg(any( + target_feature = "lse128", + portable_atomic_target_feature = "lse128", + all( + not(portable_atomic_no_outline_atomics), + not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")), + ), + ))] + #[inline] + unsafe fn _atomic_store_swpp(dst: *mut u128, val: u128, order: Ordering) { + // SAFETY: the caller must uphold the safety contract. + unsafe { + _atomic_swap_swpp(dst, val, order); + } + } + fn_alias! { + // inline(never) is just a hint and also not strictly necessary + // because we use ifunc helper macro, but used for clarity. + #[inline(never)] + unsafe fn(dst: *mut u128, val: u128); + atomic_store_lse2_relaxed = _atomic_store_stp(Ordering::Relaxed); + atomic_store_lse2_release = _atomic_store_stp(Ordering::Release); + atomic_store_lse2_seqcst = _atomic_store_stp(Ordering::SeqCst); + atomic_store_lse2_rcpc3_release = _atomic_store_stilp(Ordering::Release); + atomic_store_lse2_rcpc3_seqcst = _atomic_store_stilp(Ordering::SeqCst); + atomic_store_lse128_release = _atomic_store_swpp(Ordering::Release); + atomic_store_lse128_seqcst = _atomic_store_swpp(Ordering::SeqCst); + } + fn_alias! { + unsafe fn(dst: *mut u128, val: u128); + atomic_store_no_lse2_relaxed = atomic_store_no_lse2(Ordering::Relaxed); + atomic_store_no_lse2_release = atomic_store_no_lse2(Ordering::Release); + atomic_store_no_lse2_seqcst = atomic_store_no_lse2(Ordering::SeqCst); + } + // SAFETY: the caller must uphold the safety contract. + // and we've checked if FEAT_LSE2/FEAT_LRCPC3/FEAT_LSE128 is available. + unsafe { + match order { + Ordering::Relaxed => { + ifunc!(unsafe fn(dst: *mut u128, val: u128) { + let cpuinfo = detect::detect(); + if cpuinfo.lse2() { + // if detect(FEAT_LSE2) => lse2 (stp) + atomic_store_lse2_relaxed + } else { + // else => no_lse2: + atomic_store_no_lse2_relaxed + } + }); + } + Ordering::Release => { + ifunc!(unsafe fn(dst: *mut u128, val: u128) { + let cpuinfo = detect::detect(); + if cpuinfo.lse2() { + if cpuinfo.rcpc3() { + // if detect(FEAT_LSE2) && detect(FEAT_LRCPC3) && order != relaxed => lse2_rcpc3 (stilp) + atomic_store_lse2_rcpc3_release + } else if cpuinfo.lse128() { + // if detect(FEAT_LSE2) && detect(FEAT_LSE128) && order != relaxed => lse128 (swpp) + atomic_store_lse128_release + } else { + // if detect(FEAT_LSE2) => lse2 (stp) + atomic_store_lse2_release + } + } else { + // else => no_lse2: + atomic_store_no_lse2_release + } + }); + } + Ordering::SeqCst => { + ifunc!(unsafe fn(dst: *mut u128, val: u128) { + let cpuinfo = detect::detect(); + if cpuinfo.lse2() { + if cpuinfo.lse128() { + // if detect(FEAT_LSE2) && detect(FEAT_LSE128) && order == seqcst => lse128 (swpp) + atomic_store_lse128_seqcst + } else if cpuinfo.rcpc3() { + // if detect(FEAT_LSE2) && detect(FEAT_LRCPC3) && order != relaxed => lse2_rcpc3 (stilp) + atomic_store_lse2_rcpc3_seqcst + } else { + // if detect(FEAT_LSE2) => lse2 (stp) + atomic_store_lse2_seqcst + } + } else { + // else => no_lse2: + atomic_store_no_lse2_seqcst + } + }); + } + _ => unreachable!(), + } + } + } + } + // else => no_lse2: + #[cfg(else)] + { + use self::atomic_store_no_lse2 as atomic_store; + } +}); +#[cfg(not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")))] +cfg_sel!({ + // if compile_time(FEAT_LSE) && not(ll_sc_rmw) => casp + // If FEAT_LSE is available at compile-time and portable_atomic_ll_sc_rmw cfg is not set, + // we use CAS-based atomic RMW. + #[cfg(all( + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + not(portable_atomic_ll_sc_rmw), + ))] + { + #[inline] + unsafe fn atomic_store_no_lse2(dst: *mut u128, val: u128, order: Ordering) { + // SAFETY: the caller must uphold the safety contract. + // cfg guarantee that the CPU supports FEAT_LSE. + unsafe { + _atomic_swap_casp(dst, val, order); + } + } + } + // else => ldxp_stxp + #[cfg(else)] + { + use self::_atomic_store_ldxp_stxp as atomic_store_no_lse2; + } +}); +// If CPU supports FEAT_LSE2, STP/STILP is single-copy atomic writes, +// otherwise it is two single-copy atomic writes. +// Refs: B2.2.1 of the Arm Architecture Reference Manual Armv8, for Armv8-A architecture profile +#[cfg(any( + target_feature = "lse2", + portable_atomic_target_feature = "lse2", + not(portable_atomic_no_outline_atomics), +))] +#[inline] +unsafe fn _atomic_store_stp(dst: *mut u128, val: u128, order: Ordering) { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_lse2!(); + + // SAFETY: the caller must guarantee that `dst` is valid for writes, + // 16-byte aligned, that there are no concurrent non-atomic operations. + // + // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/STP--Store-pair-of-registers- + unsafe { + macro_rules! atomic_store { + ($acquire:tt, $release:tt) => {{ + let val = U128 { whole: val }; + asm!( + $release, // fence + "stp {val_lo}, {val_hi}, [{dst}]", // atomic { *dst = val_lo:val_hi } + $acquire, // fence + dst = in(reg) ptr_reg!(dst), + val_lo = in(reg) val.pair.lo, + val_hi = in(reg) val.pair.hi, + options(nostack, preserves_flags), + ); + }}; + } + match order { + // if compile_time(FEAT_LSE128) && order == seqcst => swpp + // Prefer swpp if stp requires fences. https://reviews.llvm.org/D143506 + // SAFETY: cfg guarantee that the CPU supports FEAT_LSE128. + #[cfg(any(target_feature = "lse128", portable_atomic_target_feature = "lse128"))] + Ordering::SeqCst => { + _atomic_swap_swpp(dst, val, order); + } + + // if compile_time(FEAT_LRCPC3) && order != relaxed => stilp + // SAFETY: cfg guarantee that the CPU supports FEAT_LRCPC3. + #[cfg(any(target_feature = "rcpc3", portable_atomic_target_feature = "rcpc3"))] + Ordering::Release => _atomic_store_stilp(dst, val, order), + #[cfg(any(target_feature = "rcpc3", portable_atomic_target_feature = "rcpc3"))] + #[cfg(not(any(target_feature = "lse128", portable_atomic_target_feature = "lse128")))] + Ordering::SeqCst => _atomic_store_stilp(dst, val, order), + + // if compile_time(FEAT_LSE128) && order != relaxed => swpp + // Prefer swpp if stp requires fences. https://reviews.llvm.org/D143506 + // SAFETY: cfg guarantee that the CPU supports FEAT_LSE128. + #[cfg(not(any(target_feature = "rcpc3", portable_atomic_target_feature = "rcpc3")))] + #[cfg(any(target_feature = "lse128", portable_atomic_target_feature = "lse128"))] + Ordering::Release => { + _atomic_swap_swpp(dst, val, order); + } + + // else => stp + Ordering::Relaxed => atomic_store!("", ""), + #[cfg(not(any(target_feature = "rcpc3", portable_atomic_target_feature = "rcpc3")))] + #[cfg(not(any(target_feature = "lse128", portable_atomic_target_feature = "lse128")))] + Ordering::Release => atomic_store!("", "dmb ish"), + #[cfg(not(any(target_feature = "rcpc3", portable_atomic_target_feature = "rcpc3")))] + #[cfg(not(any(target_feature = "lse128", portable_atomic_target_feature = "lse128")))] + Ordering::SeqCst => atomic_store!("dmb ish", "dmb ish"), + _ => unreachable!(), + } + } +} +#[cfg(any( + target_feature = "lse2", + portable_atomic_target_feature = "lse2", + not(portable_atomic_no_outline_atomics), +))] +#[cfg(any( + target_feature = "rcpc3", + portable_atomic_target_feature = "rcpc3", + all( + not(portable_atomic_no_outline_atomics), + not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")), + ), +))] +#[inline] +unsafe fn _atomic_store_stilp(dst: *mut u128, val: u128, order: Ordering) { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_lse2!(); + debug_assert_rcpc3!(); + + // SAFETY: the caller must guarantee that `dst` is valid for writes, + // 16-byte aligned, that there are no concurrent non-atomic operations. + // + // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/STILP--Store-release-ordered-pair-of-registers- + unsafe { + macro_rules! atomic_store { + ($acquire:tt) => {{ + let val = U128 { whole: val }; + #[cfg(not(portable_atomic_pre_llvm_16))] + asm!( + start_rcpc3!(), + "stilp {val_lo}, {val_hi}, [{dst}]", // atomic { *dst = val_lo:val_hi } + $acquire, // fence + dst = in(reg) ptr_reg!(dst), + val_lo = in(reg) val.pair.lo, + val_hi = in(reg) val.pair.hi, + options(nostack, preserves_flags), + ); + // LLVM supports FEAT_LRCPC3 instructions on LLVM 16+, so use .inst directive on old LLVM. + // https://github.com/llvm/llvm-project/commit/a6aaa969f7caec58a994142f8d855861cf3a1463 + #[cfg(portable_atomic_pre_llvm_16)] + asm!( + // stilp x2, x3, [x0] // atomic { *dst = x2:x3 } + ".inst 0xd9031802", + $acquire, // fence + in("x0") ptr_reg!(dst), + in("x2") val.pair.lo, + in("x3") val.pair.hi, + options(nostack, preserves_flags), + ); + }}; + } + match order { + Ordering::Release => atomic_store!(""), + // TODO: in atomicsabi64, seqcst store is the same as release store + // LLVM uses store-release (dmb ish; stp); dmb ish, GCC (libatomic) and Atomics ABI Standard + // uses store-release (stilp) without fence for SeqCst store + // (https://github.com/gcc-mirror/gcc/commit/7107574958e2bed11d916a1480ef1319f15e5ffe). + // Considering https://reviews.llvm.org/D141748, LLVM's lowering seems + // to be the safer option here (I'm not convinced that the libatomic's implementation is wrong). + Ordering::SeqCst => atomic_store!("dmb ish"), + _ => unreachable!(), + } + } +} +// Do not use _atomic_swap_ldxp_stxp because it needs extra registers to implement store. +#[cfg(any( + test, + not(all( + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + not(portable_atomic_ll_sc_rmw), + )) +))] +#[inline] +unsafe fn _atomic_store_ldxp_stxp(dst: *mut u128, val: u128, order: Ordering) { + debug_assert!(dst.addr() % 16 == 0); + + // SAFETY: the caller must uphold the safety contract. + unsafe { + let val = U128 { whole: val }; + macro_rules! store { + ($acquire:tt, $release:tt, $msvc_fence:tt) => { + asm!( + "2:", // 'retry: + concat!("ld", $acquire, "xp xzr, {tmp}, [{dst}]"), // atomic { xzr:tmp = *dst; EXCLUSIVE = dst } + concat!("st", $release, "xp {tmp:w}, {val_lo}, {val_hi}, [{dst}]"), // atomic { if EXCLUSIVE == dst { *dst = val_lo:val_hi; tmp = 0 } else { tmp = 1 }; EXCLUSIVE = None } + "cbnz {tmp:w}, 2b", // if tmp != 0 { jump 'retry } + $msvc_fence, // fence + dst = in(reg) ptr_reg!(dst), + val_lo = in(reg) val.pair.lo, + val_hi = in(reg) val.pair.hi, + tmp = out(reg) _, + options(nostack, preserves_flags), + ) + }; + } + atomic_rmw!(store, order); + } +} + +// ----------------------------------------------------------------------------- +// compare_exchange + +/* + +Instruction selection flow for compare_exchange: +- if compile_time(FEAT_LSE) => casp +- if platform_supports_detection_of(FEAT_LSE): + - if detect(FEAT_LSE) => casp +- else => ldxp_stxp + +*/ + +#[inline] +unsafe fn atomic_compare_exchange( + dst: *mut u128, + old: u128, + new: u128, + success: Ordering, + failure: Ordering, +) -> Result { + // if compile_time(FEAT_LSE) => casp + #[cfg(any(target_feature = "lse", portable_atomic_target_feature = "lse"))] + // SAFETY: the caller must uphold the safety contract. + // cfg guarantee that the CPU supports FEAT_LSE. + let prev = unsafe { _atomic_compare_exchange_casp(dst, old, new, success, failure) }; + // if platform_supports_detection_of(FEAT_LSE): + #[cfg(all( + not(portable_atomic_no_outline_atomics), + any( + all( + target_os = "linux", + any( + target_env = "gnu", + all( + target_env = "musl", + any(not(target_feature = "crt-static"), feature = "std"), + ), + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + portable_atomic_outline_atomics, + ), + ), + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + target_os = "fuchsia", + target_vendor = "apple", + windows, + ), + ))] + #[cfg(not(any(target_feature = "lse", portable_atomic_target_feature = "lse")))] + let prev = { + fn_alias! { + // inline(never) is just a hint and also not strictly necessary + // because we use ifunc helper macro, but used for clarity. + #[inline(never)] + unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128; + atomic_compare_exchange_casp_relaxed + = _atomic_compare_exchange_casp(Ordering::Relaxed, Ordering::Relaxed); + atomic_compare_exchange_casp_acquire + = _atomic_compare_exchange_casp(Ordering::Acquire, Ordering::Acquire); + atomic_compare_exchange_casp_release + = _atomic_compare_exchange_casp(Ordering::Release, Ordering::Relaxed); + atomic_compare_exchange_casp_acqrel + = _atomic_compare_exchange_casp(Ordering::AcqRel, Ordering::Acquire); + } + fn_alias! { + unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128; + atomic_compare_exchange_ldxp_stxp_relaxed + = _atomic_compare_exchange_ldxp_stxp(Ordering::Relaxed, Ordering::Relaxed); + atomic_compare_exchange_ldxp_stxp_acquire + = _atomic_compare_exchange_ldxp_stxp(Ordering::Acquire, Ordering::Acquire); + atomic_compare_exchange_ldxp_stxp_release + = _atomic_compare_exchange_ldxp_stxp(Ordering::Release, Ordering::Relaxed); + atomic_compare_exchange_ldxp_stxp_acqrel + = _atomic_compare_exchange_ldxp_stxp(Ordering::AcqRel, Ordering::Acquire); + // AcqRel and SeqCst RMWs are equivalent in non-MSVC environments. + #[cfg(target_env = "msvc")] + atomic_compare_exchange_ldxp_stxp_seqcst + = _atomic_compare_exchange_ldxp_stxp(Ordering::SeqCst, Ordering::SeqCst); + } + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned, that there are no concurrent non-atomic operations, + // and we've checked if FEAT_LSE is available. + unsafe { + let success = crate::utils::upgrade_success_ordering(success, failure); + match success { + Ordering::Relaxed => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128 { + if detect::detect().lse() { + // if detect(FEAT_LSE) => casp + atomic_compare_exchange_casp_relaxed + } else { + // else => ldxp_stxp + atomic_compare_exchange_ldxp_stxp_relaxed + } + }) + } + Ordering::Acquire => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128 { + if detect::detect().lse() { + // if detect(FEAT_LSE) => casp + atomic_compare_exchange_casp_acquire + } else { + // else => ldxp_stxp + atomic_compare_exchange_ldxp_stxp_acquire + } + }) + } + Ordering::Release => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128 { + if detect::detect().lse() { + // if detect(FEAT_LSE) => casp + atomic_compare_exchange_casp_release + } else { + // else => ldxp_stxp + atomic_compare_exchange_ldxp_stxp_release + } + }) + } + // AcqRel and SeqCst RMWs are equivalent in both implementations in non-MSVC environments + // or LSE* instructions is used. + #[cfg(not(target_env = "msvc"))] + Ordering::AcqRel | Ordering::SeqCst => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128 { + if detect::detect().lse() { + // if detect(FEAT_LSE) => casp + atomic_compare_exchange_casp_acqrel + } else { + // else => ldxp_stxp + atomic_compare_exchange_ldxp_stxp_acqrel + } + }) + } + #[cfg(target_env = "msvc")] + Ordering::AcqRel => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128 { + if detect::detect().lse() { + // if detect(FEAT_LSE) => casp + atomic_compare_exchange_casp_acqrel + } else { + // else => ldxp_stxp + atomic_compare_exchange_ldxp_stxp_acqrel + } + }) + } + #[cfg(target_env = "msvc")] + Ordering::SeqCst => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128 { + if detect::detect().lse() { + // if detect(FEAT_LSE) => casp + atomic_compare_exchange_casp_acqrel + } else { + // else => ldxp_stxp + atomic_compare_exchange_ldxp_stxp_seqcst + } + }) + } + _ => unreachable!(), + } + } + }; + // else => ldxp_stxp + #[cfg(not(all( + not(portable_atomic_no_outline_atomics), + any( + all( + target_os = "linux", + any( + target_env = "gnu", + all( + target_env = "musl", + any(not(target_feature = "crt-static"), feature = "std"), + ), + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + portable_atomic_outline_atomics, + ), + ), + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + target_os = "fuchsia", + target_vendor = "apple", + windows, + ), + )))] + #[cfg(not(any(target_feature = "lse", portable_atomic_target_feature = "lse")))] + // SAFETY: the caller must uphold the safety contract. + let prev = unsafe { _atomic_compare_exchange_ldxp_stxp(dst, old, new, success, failure) }; + if prev == old { Ok(prev) } else { Err(prev) } +} +#[cfg(any( + target_feature = "lse", + portable_atomic_target_feature = "lse", + not(portable_atomic_no_outline_atomics), +))] +#[inline] +unsafe fn _atomic_compare_exchange_casp( + dst: *mut u128, + old: u128, + new: u128, + success: Ordering, + failure: Ordering, +) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_lse!(); + let order = crate::utils::upgrade_success_ordering(success, failure); + + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned, that there are no concurrent non-atomic operations, + // and the CPU supports FEAT_LSE. + // + // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/CASP--CASPA--CASPAL--CASPL--Compare-and-swap-pair-of-words-or-doublewords-in-memory- + unsafe { + let old = U128 { whole: old }; + let new = U128 { whole: new }; + let (prev_lo, prev_hi); + macro_rules! cmpxchg { + ($acquire:tt, $release:tt, $_msvc_fence:tt) => { + asm!( + start_lse!(), + concat!("casp", $acquire, $release, " x6, x7, x4, x5, [{dst}]"), // atomic { if *dst == x6:x7 { *dst = x4:x5 } else { x6:x7 = *dst } } + dst = in(reg) ptr_reg!(dst), + // must be allocated to even/odd register pair + inout("x6") old.pair.lo => prev_lo, + inout("x7") old.pair.hi => prev_hi, + // must be allocated to even/odd register pair + in("x4") new.pair.lo, + in("x5") new.pair.hi, + options(nostack, preserves_flags), + ) + }; + } + atomic_rmw!(cmpxchg, order, write = success); + U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole + } +} +#[cfg(any(test, not(any(target_feature = "lse", portable_atomic_target_feature = "lse"))))] +#[inline] +unsafe fn _atomic_compare_exchange_ldxp_stxp( + dst: *mut u128, + old: u128, + new: u128, + success: Ordering, + failure: Ordering, +) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + let order = crate::utils::upgrade_success_ordering(success, failure); + + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned, and that there are no concurrent non-atomic operations. + // + // Refs: + // - LDXP: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/LDXP--Load-exclusive-pair-of-registers- + // - LDAXP: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/LDAXP--Load-acquire-exclusive-pair-of-registers- + // - STXP: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/STXP--Store-exclusive-pair-of-registers- + // - STLXP: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/STLXP--Store-release-exclusive-pair-of-registers- + // + // Note: Load-Exclusive pair (by itself) does not guarantee atomicity; to complete an atomic + // operation (even load/store), a corresponding Store-Exclusive pair must succeed. + // See Arm Architecture Reference Manual for A-profile architecture + // Section B2.2.1 "Requirements for single-copy atomicity", and + // Section B2.9 "Synchronization and semaphores" for more. + unsafe { + let old = U128 { whole: old }; + let new = U128 { whole: new }; + let (mut prev_lo, mut prev_hi); + macro_rules! cmpxchg { + ($acquire:tt, $release:tt, $msvc_fence:tt) => { + asm!( + "2:", // 'retry: + concat!("ld", $acquire, "xp {prev_lo}, {prev_hi}, [{dst}]"), // atomic { prev_lo:prev_hi = *dst; EXCLUSIVE = dst } + "cmp {prev_lo}, {old_lo}", // if prev_lo == old_lo { Z = 1 } else { Z = 0 } + "ccmp {prev_hi}, {old_hi}, #0, eq", // if Z == 1 { if prev_hi == old_hi { Z = 1 } else { Z = 0 } } else { Z = 0 } + // write back to ensure atomicity + "csel {tmp_lo}, {new_lo}, {prev_lo}, eq", // if Z == 1 { tmp_lo = new_lo } else { tmp_lo = prev_lo } + "csel {tmp_hi}, {new_hi}, {prev_hi}, eq", // if Z == 1 { tmp_hi = new_hi } else { tmp_hi = prev_hi } + concat!("st", $release, "xp {r:w}, {tmp_lo}, {tmp_hi}, [{dst}]"), // atomic { if EXCLUSIVE == dst { *dst = tmp_lo:tmp_hi; r = 0 } else { r = 1 }; EXCLUSIVE = None } + "cbnz {r:w}, 2b", // if r != 0 { jump 'retry } + $msvc_fence, // fence + dst = in(reg) ptr_reg!(dst), + old_lo = in(reg) old.pair.lo, + old_hi = in(reg) old.pair.hi, + new_lo = in(reg) new.pair.lo, + new_hi = in(reg) new.pair.hi, + prev_lo = out(reg) prev_lo, + prev_hi = out(reg) prev_hi, + r = out(reg) _, + tmp_lo = out(reg) _, + tmp_hi = out(reg) _, + // Do not use `preserves_flags` because CMP and CCMP modify the condition flags. + options(nostack), + ) + }; + } + atomic_rmw!(cmpxchg, order, write = success); + U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole + } +} + +// casp is always strong, and ldxp requires a corresponding (succeed) stxp for +// its atomicity (see code comment in _atomic_compare_exchange_ldxp_stxp). +// (i.e., AArch64 doesn't have 128-bit weak CAS) +use self::atomic_compare_exchange as atomic_compare_exchange_weak; + +// ----------------------------------------------------------------------------- +// RMW + +/* + +Instruction selection flow for swap/fetch_and/fetch_or: +- if compile_time(FEAT_LSE128) => swpp/ldclrp/ldsetp +- if compile_time(FEAT_LSE) && not(ll_sc_rmw) => casp +- else => ldxp_stxp + +Instruction selection flow for other RMWs: +- if compile_time(FEAT_LSE) && not(ll_sc_rmw) => casp +- else => ldxp_stxp + +Note: +- We don't do run-time detection of FEAT_LSE128 at this time, because + FEAT_LSE128 is not yet available for most CPUs, but since + swpp/ldclrp/ldsetp is wait-free, it would make sense to do run-time + detection in the future. (TODO) +- We don't do run-time detection of FEAT_LSE for store at this time. + +*/ + +cfg_sel!({ + #[cfg(any(target_feature = "lse128", portable_atomic_target_feature = "lse128"))] + { + use self::_atomic_swap_swpp as atomic_swap; + } + #[cfg(all( + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + not(portable_atomic_ll_sc_rmw), + ))] + { + use self::_atomic_swap_casp as atomic_swap; + } + #[cfg(else)] + { + use self::_atomic_swap_ldxp_stxp as atomic_swap; + } +}); +#[cfg(any( + target_feature = "lse128", + portable_atomic_target_feature = "lse128", + all( + not(portable_atomic_no_outline_atomics), + not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")), + ), +))] +#[inline] +unsafe fn _atomic_swap_swpp(dst: *mut u128, val: u128, order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_lse128!(); + + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned, that there are no concurrent non-atomic operations, + // and the CPU supports FEAT_LSE128. + // + // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/SWPP--SWPPA--SWPPAL--SWPPL--Swap-quadword-in-memory- + unsafe { + let val = U128 { whole: val }; + let (prev_lo, prev_hi); + #[cfg(not(portable_atomic_pre_llvm_16))] + macro_rules! swap { + ($acquire:tt, $release:tt, $_msvc_fence:tt) => { + asm!( + start_lse128!(), + concat!("swpp", $acquire, $release, " {val_lo}, {val_hi}, [{dst}]"), // atomic { _x = *dst; *dst = val_lo:val_hi; val_lo:val_hi = _x } + dst = in(reg) ptr_reg!(dst), + val_lo = inout(reg) val.pair.lo => prev_lo, + val_hi = inout(reg) val.pair.hi => prev_hi, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(not(portable_atomic_pre_llvm_16))] + atomic_rmw!(swap, order); + // LLVM supports FEAT_LSE128 instructions on LLVM 16+, so use .inst directive on old LLVM. + // https://github.com/llvm/llvm-project/commit/7fea6f2e0e606e5339c3359568f680eaf64aa306 + #[cfg(portable_atomic_pre_llvm_16)] + macro_rules! swap { + ($order:tt, $_msvc_fence:tt) => { + asm!( + // swpp{,a,l,al} x2, x1, [x0] // atomic { _x = *x0; *x0 = x2:x1; x2:x1 = _x } + concat!(".inst 0x19", $order, "18002"), + in("x0") ptr_reg!(dst), + inout("x2") val.pair.lo => prev_lo, + inout("x1") val.pair.hi => prev_hi, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(portable_atomic_pre_llvm_16)] + atomic_rmw_inst!(swap, order); + U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole + } +} +// Do not use atomic_rmw_cas_3 because it needs extra MOV to implement swap. +#[cfg(any(test, not(portable_atomic_ll_sc_rmw)))] +#[cfg(any(target_feature = "lse", portable_atomic_target_feature = "lse"))] +#[inline] +unsafe fn _atomic_swap_casp(dst: *mut u128, val: u128, order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_lse!(); + + // SAFETY: the caller must uphold the safety contract. + // cfg guarantee that the CPU supports FEAT_LSE. + unsafe { + let val = U128 { whole: val }; + let (mut prev_lo, mut prev_hi); + macro_rules! swap { + ($acquire:tt, $release:tt, $_msvc_fence:tt) => { + asm!( + start_lse!(), + // If FEAT_LSE2 is not supported, this works like byte-wise atomic. + // This is not single-copy atomic reads, but this is ok because subsequent + // CAS will check for consistency. + "ldp x4, x5, [{dst}]", // atomic { x4:x5 = *dst } + "2:", // 'retry: + // casp writes the current value to the first register pair, + // so copy the `out`'s value for later comparison. + "mov {tmp_lo}, x4", // tmp_lo = x4 + "mov {tmp_hi}, x5", // tmp_hi = x5 + concat!("casp", $acquire, $release, " x4, x5, x2, x3, [{dst}]"), // atomic { if *dst == x4:x5 { *dst = x2:x3 } else { x4:x5 = *dst } } + "cmp {tmp_hi}, x5", // if tmp_hi == x5 { Z = 1 } else { Z = 0 } + "ccmp {tmp_lo}, x4, #0, eq", // if Z == 1 { if tmp_lo == x4 { Z = 1 } else { Z = 0 } } else { Z = 0 } + "b.ne 2b", // if Z == 0 { jump 'retry } + dst = in(reg) ptr_reg!(dst), + tmp_lo = out(reg) _, + tmp_hi = out(reg) _, + // must be allocated to even/odd register pair + out("x4") prev_lo, + out("x5") prev_hi, + // must be allocated to even/odd register pair + in("x2") val.pair.lo, + in("x3") val.pair.hi, + // Do not use `preserves_flags` because CMP and CCMP modify the condition flags. + options(nostack), + ) + }; + } + atomic_rmw!(swap, order); + U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole + } +} +// Do not use atomic_rmw_ll_sc_3 because it needs extra MOV to implement swap. +#[cfg(any( + test, + not(all( + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + not(portable_atomic_ll_sc_rmw), + )) +))] +#[inline] +unsafe fn _atomic_swap_ldxp_stxp(dst: *mut u128, val: u128, order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + + // SAFETY: the caller must uphold the safety contract. + unsafe { + let val = U128 { whole: val }; + let (mut prev_lo, mut prev_hi); + macro_rules! swap { + ($acquire:tt, $release:tt, $msvc_fence:tt) => { + asm!( + "2:", // 'retry: + concat!("ld", $acquire, "xp {prev_lo}, {prev_hi}, [{dst}]"), // atomic { prev_lo:prev_hi = *dst; EXCLUSIVE = dst } + concat!("st", $release, "xp {r:w}, {val_lo}, {val_hi}, [{dst}]"), // atomic { if EXCLUSIVE == dst { *dst = val_lo:val_hi; r = 0 } else { r = 1 }; EXCLUSIVE = None } + "cbnz {r:w}, 2b", // if r != 0 { jump 'retry } + $msvc_fence, // fence + dst = in(reg) ptr_reg!(dst), + val_lo = in(reg) val.pair.lo, + val_hi = in(reg) val.pair.hi, + prev_lo = out(reg) prev_lo, + prev_hi = out(reg) prev_hi, + r = out(reg) _, + options(nostack, preserves_flags), + ) + }; + } + atomic_rmw!(swap, order); + U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole + } +} + +/// Atomic RMW by LL/SC loop (3 arguments) +/// `unsafe fn(dst: *mut u128, val: u128, order: Ordering) -> u128;` +/// +/// `$op` can use the following registers: +/// - val_lo/val_hi pair: val argument (read-only for `$op`) +/// - prev_lo/prev_hi pair: previous value loaded by ll (read-only for `$op`) +/// - new_lo/new_hi pair: new value that will be stored by sc +macro_rules! atomic_rmw_ll_sc_3 { + ($name:ident as $reexport_name:ident $(($preserves_flags:tt))?, $($op:tt)*) => { + // If FEAT_LSE is available at compile-time and portable_atomic_ll_sc_rmw cfg is not set, + // we use CAS-based atomic RMW generated by atomic_rmw_cas_3! macro instead. + #[cfg(not(all( + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + not(portable_atomic_ll_sc_rmw), + )))] + use self::$name as $reexport_name; + #[cfg(any( + test, + not(all( + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + not(portable_atomic_ll_sc_rmw), + )) + ))] + #[inline] + unsafe fn $name(dst: *mut u128, val: u128, order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + // SAFETY: the caller must uphold the safety contract. + unsafe { + let val = U128 { whole: val }; + let (mut prev_lo, mut prev_hi); + macro_rules! op { + ($acquire:tt, $release:tt, $msvc_fence:tt) => { + asm!( + "2:", // 'retry: + concat!("ld", $acquire, "xp {prev_lo}, {prev_hi}, [{dst}]"), // atomic { prev_lo:prev_hi = *dst; EXCLUSIVE = dst } + $($op)* + concat!("st", $release, "xp {r:w}, {new_lo}, {new_hi}, [{dst}]"), // atomic { if EXCLUSIVE == dst { *dst = new_lo:new_hi; r = 0 } else { r = 1 }; EXCLUSIVE = None } + "cbnz {r:w}, 2b", // if r != 0 { jump 'retry } + $msvc_fence, // fence + dst = in(reg) ptr_reg!(dst), + val_lo = in(reg) val.pair.lo, + val_hi = in(reg) val.pair.hi, + prev_lo = out(reg) prev_lo, + prev_hi = out(reg) prev_hi, + new_lo = out(reg) _, + new_hi = out(reg) _, + r = out(reg) _, + options(nostack $(, $preserves_flags)?), + ) + }; + } + atomic_rmw!(op, order); + U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole + } + } + }; +} +/// Atomic RMW by CAS loop (3 arguments) +/// `unsafe fn(dst: *mut u128, val: u128, order: Ordering) -> u128;` +/// +/// `$op` can use the following registers: +/// - val_lo/val_hi pair: val argument (read-only for `$op`) +/// - x6/x7 pair: previous value loaded (read-only for `$op`) +/// - x4/x5 pair: new value that will be stored +macro_rules! atomic_rmw_cas_3 { + ($name:ident as $reexport_name:ident, $($op:tt)*) => { + // If FEAT_LSE is not available at compile-time or portable_atomic_ll_sc_rmw cfg is set, + // we use LL/SC-based atomic RMW generated by atomic_rmw_ll_sc_3! macro instead. + #[cfg(all( + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + not(portable_atomic_ll_sc_rmw), + ))] + use self::$name as $reexport_name; + #[cfg(any(test, not(portable_atomic_ll_sc_rmw)))] + #[cfg(any(target_feature = "lse", portable_atomic_target_feature = "lse"))] + #[inline] + unsafe fn $name(dst: *mut u128, val: u128, order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_lse!(); + // SAFETY: the caller must uphold the safety contract. + // cfg guarantee that the CPU supports FEAT_LSE. + unsafe { + let val = U128 { whole: val }; + let (mut prev_lo, mut prev_hi); + macro_rules! op { + ($acquire:tt, $release:tt, $_msvc_fence:tt) => { + asm!( + start_lse!(), + // If FEAT_LSE2 is not supported, this works like byte-wise atomic. + // This is not single-copy atomic reads, but this is ok because subsequent + // CAS will check for consistency. + "ldp x6, x7, [{dst}]", // atomic { x6:x7 = *dst } + "2:", // 'retry: + // casp writes the current value to the first register pair, + // so copy the `out`'s value for later comparison. + "mov {tmp_lo}, x6", // tmp_lo = x6 + "mov {tmp_hi}, x7", // tmp_hi = x7 + $($op)* + concat!("casp", $acquire, $release, " x6, x7, x4, x5, [{dst}]"), // atomic { if *dst == x6:x7 { *dst = x4:x5 } else { x6:x7 = *dst } } + "cmp {tmp_hi}, x7", // if tmp_hi == x7 { Z = 1 } else { Z = 0 } + "ccmp {tmp_lo}, x6, #0, eq", // if Z == 1 { if tmp_lo == x6 { Z = 1 } else { Z = 0 } } else { Z = 0 } + "b.ne 2b", // if Z == 0 { jump 'retry } + dst = in(reg) ptr_reg!(dst), + val_lo = in(reg) val.pair.lo, + val_hi = in(reg) val.pair.hi, + tmp_lo = out(reg) _, + tmp_hi = out(reg) _, + // must be allocated to even/odd register pair + out("x6") prev_lo, + out("x7") prev_hi, + // must be allocated to even/odd register pair + out("x4") _, + out("x5") _, + // Do not use `preserves_flags` because CMP and CCMP modify the condition flags. + options(nostack), + ) + }; + } + atomic_rmw!(op, order); + U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole + } + } + }; +} + +/// Atomic RMW by LL/SC loop (2 arguments) +/// `unsafe fn(dst: *mut u128, order: Ordering) -> u128;` +/// +/// `$op` can use the following registers: +/// - prev_lo/prev_hi pair: previous value loaded by ll (read-only for `$op`) +/// - new_lo/new_hi pair: new value that will be stored by sc +macro_rules! atomic_rmw_ll_sc_2 { + ($name:ident as $reexport_name:ident $(($preserves_flags:tt))?, $($op:tt)*) => { + // If FEAT_LSE is available at compile-time and portable_atomic_ll_sc_rmw cfg is not set, + // we use CAS-based atomic RMW generated by atomic_rmw_cas_2! macro instead. + #[cfg(not(all( + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + not(portable_atomic_ll_sc_rmw), + )))] + use self::$name as $reexport_name; + #[cfg(any( + test, + not(all( + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + not(portable_atomic_ll_sc_rmw), + )) + ))] + #[inline] + unsafe fn $name(dst: *mut u128, order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + // SAFETY: the caller must uphold the safety contract. + unsafe { + let (mut prev_lo, mut prev_hi); + macro_rules! op { + ($acquire:tt, $release:tt, $msvc_fence:tt) => { + asm!( + "2:", // 'retry: + concat!("ld", $acquire, "xp {prev_lo}, {prev_hi}, [{dst}]"), // atomic { prev_lo:prev_hi = *dst; EXCLUSIVE = dst } + $($op)* + concat!("st", $release, "xp {r:w}, {new_lo}, {new_hi}, [{dst}]"), // atomic { if EXCLUSIVE == dst { *dst = new_lo:new_hi; r = 0 } else { r = 1 }; EXCLUSIVE = None } + "cbnz {r:w}, 2b", // if r != 0 { jump 'retry } + $msvc_fence, // fence + dst = in(reg) ptr_reg!(dst), + prev_lo = out(reg) prev_lo, + prev_hi = out(reg) prev_hi, + new_lo = out(reg) _, + new_hi = out(reg) _, + r = out(reg) _, + options(nostack $(, $preserves_flags)?), + ) + }; + } + atomic_rmw!(op, order); + U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole + } + } + }; +} +/// Atomic RMW by CAS loop (2 arguments) +/// `unsafe fn(dst: *mut u128, order: Ordering) -> u128;` +/// +/// `$op` can use the following registers: +/// - x6/x7 pair: previous value loaded (read-only for `$op`) +/// - x4/x5 pair: new value that will be stored +macro_rules! atomic_rmw_cas_2 { + ($name:ident as $reexport_name:ident, $($op:tt)*) => { + // If FEAT_LSE is not available at compile-time or portable_atomic_ll_sc_rmw cfg is set, + // we use LL/SC-based atomic RMW generated by atomic_rmw_ll_sc_3! macro instead. + #[cfg(all( + any(target_feature = "lse", portable_atomic_target_feature = "lse"), + not(portable_atomic_ll_sc_rmw), + ))] + use self::$name as $reexport_name; + #[cfg(any(test, not(portable_atomic_ll_sc_rmw)))] + #[cfg(any(target_feature = "lse", portable_atomic_target_feature = "lse"))] + #[inline] + unsafe fn $name(dst: *mut u128, order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_lse!(); + // SAFETY: the caller must uphold the safety contract. + // cfg guarantee that the CPU supports FEAT_LSE. + unsafe { + let (mut prev_lo, mut prev_hi); + macro_rules! op { + ($acquire:tt, $release:tt, $_msvc_fence:tt) => { + asm!( + start_lse!(), + // If FEAT_LSE2 is not supported, this works like byte-wise atomic. + // This is not single-copy atomic reads, but this is ok because subsequent + // CAS will check for consistency. + "ldp x6, x7, [{dst}]", // atomic { x6:x7 = *dst } + "2:", // 'retry: + // casp writes the current value to the first register pair, + // so copy the `out`'s value for later comparison. + "mov {tmp_lo}, x6", // tmp_lo = x6 + "mov {tmp_hi}, x7", // tmp_hi = x7 + $($op)* + concat!("casp", $acquire, $release, " x6, x7, x4, x5, [{dst}]"), // atomic { if *dst == x6:x7 { *dst = x4:x5 } else { x6:x7 = *dst } } + "cmp {tmp_hi}, x7", // if tmp_hi == x7 { Z = 1 } else { Z = 0 } + "ccmp {tmp_lo}, x6, #0, eq", // if Z == 1 { if tmp_lo == x6 { Z = 1 } else { Z = 0 } } else { Z = 0 } + "b.ne 2b", // if Z == 0 { jump 'retry } + dst = in(reg) ptr_reg!(dst), + tmp_lo = out(reg) _, + tmp_hi = out(reg) _, + // must be allocated to even/odd register pair + out("x6") prev_lo, + out("x7") prev_hi, + // must be allocated to even/odd register pair + out("x4") _, + out("x5") _, + // Do not use `preserves_flags` because CMP and CCMP modify the condition flags. + options(nostack), + ) + }; + } + atomic_rmw!(op, order); + U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole + } + } + }; +} + +// Do not use `preserves_flags` because ADDS modifies the condition flags. +atomic_rmw_ll_sc_3! { + _atomic_add_ldxp_stxp as atomic_add, + select_le_or_be!("adds {new_lo}, {prev_lo}, {val_lo}", "adds {new_hi}, {prev_hi}, {val_hi}"), // if endian == little { new_lo = prev_lo + val_lo } else { new_hi = prev_hi + val_hi }; C = carry + select_le_or_be!("adc {new_hi}, {prev_hi}, {val_hi}", "adc {new_lo}, {prev_lo}, {val_lo}"), // if endian == little { new_hi = prev_hi + val_hi + C } else { new_lo = prev_lo + val_lo + C } +} +atomic_rmw_cas_3! { + _atomic_add_casp as atomic_add, + select_le_or_be!("adds x4, x6, {val_lo}", "adds x5, x7, {val_hi}"), // if endian == little { x4 = x6 + val_lo } else { x5 = x7 + val_hi }; C = carry + select_le_or_be!("adc x5, x7, {val_hi}", "adc x4, x6, {val_lo}"), // if endian == little { x5 = x7 + val_hi + C } else { x4 = x6 + val_lo + C } +} + +// Do not use `preserves_flags` because SUBS modifies the condition flags. +atomic_rmw_ll_sc_3! { + _atomic_sub_ldxp_stxp as atomic_sub, + select_le_or_be!("subs {new_lo}, {prev_lo}, {val_lo}", "subs {new_hi}, {prev_hi}, {val_hi}"), // if endian == little { new_lo = prev_lo - val_lo } else { new_hi = prev_hi - val_hi }; C = !borrow + select_le_or_be!("sbc {new_hi}, {prev_hi}, {val_hi}", "sbc {new_lo}, {prev_lo}, {val_lo}"), // if endian == little { new_hi = prev_hi - val_hi - !C } else { new_lo = prev_lo - val_lo - !C } +} +atomic_rmw_cas_3! { + _atomic_sub_casp as atomic_sub, + select_le_or_be!("subs x4, x6, {val_lo}", "subs x5, x7, {val_hi}"), // if endian == little { x4 = x6 - val_lo } else { x5 = x7 - val_hi }; C = !borrow + select_le_or_be!("sbc x5, x7, {val_hi}", "sbc x4, x6, {val_lo}"), // if endian == little { x5 = x7 - val_hi - !C } else { x4 = x6 - val_lo - !C } +} + +#[cfg(not(any(target_feature = "lse128", portable_atomic_target_feature = "lse128")))] +atomic_rmw_ll_sc_3! { + _atomic_and_ldxp_stxp as atomic_and (preserves_flags), + "and {new_lo}, {prev_lo}, {val_lo}", // new_lo = prev_lo & val_lo + "and {new_hi}, {prev_hi}, {val_hi}", // new_hi = prev_hi & val_hi +} +#[cfg(not(any(target_feature = "lse128", portable_atomic_target_feature = "lse128")))] +atomic_rmw_cas_3! { + _atomic_and_casp as atomic_and, + "and x4, x6, {val_lo}", // x4 = x6 & val_lo + "and x5, x7, {val_hi}", // x5 = x7 & val_hi +} +#[cfg(any(target_feature = "lse128", portable_atomic_target_feature = "lse128"))] +#[inline] +unsafe fn atomic_and(dst: *mut u128, val: u128, order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned, that there are no concurrent non-atomic operations, + // and the CPU supports FEAT_LSE128. + // + // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/LDCLRP--LDCLRPA--LDCLRPAL--LDCLRPL--Atomic-bit-clear-on-quadword-in-memory- + unsafe { + let val = U128 { whole: !val }; + let (prev_lo, prev_hi); + #[cfg(not(portable_atomic_pre_llvm_16))] + macro_rules! clear { + ($acquire:tt, $release:tt, $_msvc_fence:tt) => { + asm!( + start_lse128!(), + concat!("ldclrp", $acquire, $release, " {val_lo}, {val_hi}, [{dst}]"), // atomic { _x = *dst; *dst = _x & !val; val = _x } + dst = in(reg) ptr_reg!(dst), + val_lo = inout(reg) val.pair.lo => prev_lo, + val_hi = inout(reg) val.pair.hi => prev_hi, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(not(portable_atomic_pre_llvm_16))] + atomic_rmw!(clear, order); + // LLVM supports FEAT_LSE128 instructions on LLVM 16+, so use .inst directive on old LLVM. + // https://github.com/llvm/llvm-project/commit/7fea6f2e0e606e5339c3359568f680eaf64aa306 + #[cfg(portable_atomic_pre_llvm_16)] + macro_rules! clear { + ($order:tt, $_msvc_fence:tt) => { + asm!( + // ldclrp{,a,l,al} x8, x1, [x0] // atomic { _x = *x0; *x0 = _x & !x8:x1; x8:x1 = _x } + concat!(".inst 0x19", $order, "11008"), + in("x0") ptr_reg!(dst), + inout("x8") val.pair.lo => prev_lo, + inout("x1") val.pair.hi => prev_hi, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(portable_atomic_pre_llvm_16)] + atomic_rmw_inst!(clear, order); + U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole + } +} + +atomic_rmw_ll_sc_3! { + _atomic_nand_ldxp_stxp as atomic_nand (preserves_flags), + "and {new_lo}, {prev_lo}, {val_lo}", // new_lo = prev_lo & val_lo + "and {new_hi}, {prev_hi}, {val_hi}", // new_hi = prev_hi & val_hi + "mvn {new_lo}, {new_lo}", // new_lo = !new_lo + "mvn {new_hi}, {new_hi}", // new_hi = !new_hi +} +atomic_rmw_cas_3! { + _atomic_nand_casp as atomic_nand, + "and x4, x6, {val_lo}", // x4 = x6 & val_lo + "and x5, x7, {val_hi}", // x5 = x7 & val_hi + "mvn x4, x4", // x4 = !x4 + "mvn x5, x5", // x5 = !x5 +} + +#[cfg(not(any(target_feature = "lse128", portable_atomic_target_feature = "lse128")))] +atomic_rmw_ll_sc_3! { + _atomic_or_ldxp_stxp as atomic_or (preserves_flags), + "orr {new_lo}, {prev_lo}, {val_lo}", // new_lo = prev_lo | val_lo + "orr {new_hi}, {prev_hi}, {val_hi}", // new_hi = prev_hi | val_hi +} +#[cfg(not(any(target_feature = "lse128", portable_atomic_target_feature = "lse128")))] +atomic_rmw_cas_3! { + _atomic_or_casp as atomic_or, + "orr x4, x6, {val_lo}", // x4 = x6 | val_lo + "orr x5, x7, {val_hi}", // x5 = x7 | val_hi +} +#[cfg(any(target_feature = "lse128", portable_atomic_target_feature = "lse128"))] +#[inline] +unsafe fn atomic_or(dst: *mut u128, val: u128, order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned, that there are no concurrent non-atomic operations, + // and the CPU supports FEAT_LSE128. + // + // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/LDSETP--LDSETPA--LDSETPAL--LDSETPL--Atomic-bit-set-on-quadword-in-memory- + unsafe { + let val = U128 { whole: val }; + let (prev_lo, prev_hi); + #[cfg(not(portable_atomic_pre_llvm_16))] + macro_rules! or { + ($acquire:tt, $release:tt, $_msvc_fence:tt) => { + asm!( + start_lse128!(), + concat!("ldsetp", $acquire, $release, " {val_lo}, {val_hi}, [{dst}]"), // atomic { _x = *dst; *dst = _x | val; val = _x } + dst = in(reg) ptr_reg!(dst), + val_lo = inout(reg) val.pair.lo => prev_lo, + val_hi = inout(reg) val.pair.hi => prev_hi, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(not(portable_atomic_pre_llvm_16))] + atomic_rmw!(or, order); + // LLVM supports FEAT_LSE128 instructions on LLVM 16+, so use .inst directive on old LLVM. + // https://github.com/llvm/llvm-project/commit/7fea6f2e0e606e5339c3359568f680eaf64aa306 + #[cfg(portable_atomic_pre_llvm_16)] + macro_rules! or { + ($order:tt, $_msvc_fence:tt) => { + asm!( + // ldsetp{,a,l,al} x2, x1, [x0] // atomic { _x = *x0; *x0 = _x | x2:x1; x2:x1 = _x } + concat!(".inst 0x19", $order, "13002"), + in("x0") ptr_reg!(dst), + inout("x2") val.pair.lo => prev_lo, + inout("x1") val.pair.hi => prev_hi, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(portable_atomic_pre_llvm_16)] + atomic_rmw_inst!(or, order); + U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole + } +} + +atomic_rmw_ll_sc_3! { + _atomic_xor_ldxp_stxp as atomic_xor (preserves_flags), + "eor {new_lo}, {prev_lo}, {val_lo}", // new_lo = prev_lo ^ val_lo + "eor {new_hi}, {prev_hi}, {val_hi}", // new_hi = prev_hi ^ val_hi +} +atomic_rmw_cas_3! { + _atomic_xor_casp as atomic_xor, + "eor x4, x6, {val_lo}", // x4 = x6 ^ val_lo + "eor x5, x7, {val_hi}", // x5 = x7 ^ val_hi +} + +atomic_rmw_ll_sc_2! { + _atomic_not_ldxp_stxp as atomic_not (preserves_flags), + "mvn {new_lo}, {prev_lo}", // new_lo = !prev_lo + "mvn {new_hi}, {prev_hi}", // new_hi = !prev_hi +} +atomic_rmw_cas_2! { + _atomic_not_casp as atomic_not, + "mvn x4, x6", // x4 = !x6 + "mvn x5, x7", // x5 = !x7 +} + +// Do not use `preserves_flags` because NEGS modifies the condition flags. +atomic_rmw_ll_sc_2! { + _atomic_neg_ldxp_stxp as atomic_neg, + select_le_or_be!("negs {new_lo}, {prev_lo}", "negs {new_hi}, {prev_hi}"), // if endian == little { new_lo = 0 - prev_lo } else { new_hi = 0 - prev_hi }; C = !borrow + select_le_or_be!("ngc {new_hi}, {prev_hi}", "ngc {new_lo}, {prev_lo}"), // if endian == little { new_hi = 0 - prev_hi - !C } else { new_lo = 0 - prev_lo - !C } +} +atomic_rmw_cas_2! { + _atomic_neg_casp as atomic_neg, + select_le_or_be!("negs x4, x6", "negs x5, x7"), // if endian == little { x4 = 0 - x6 } else { x5 = 0 - x7 }; C = !borrow + select_le_or_be!("ngc x5, x7", "ngc x4, x6"), // if endian == little { x5 = 0 - x7 - !C } else { x4 = 0 - x6 - !C } +} + +// Do not use `preserves_flags` because CMP and SBCS modify the condition flags. +atomic_rmw_ll_sc_3! { + _atomic_max_ldxp_stxp as atomic_max, + select_le_or_be!("cmp {val_lo}, {prev_lo}", "cmp {val_hi}, {prev_hi}"), // if endian == little { C = !(val_lo < prev_lo) } else { C = !(val_hi < prev_hi) } + select_le_or_be!("sbcs xzr, {val_hi}, {prev_hi}", "sbcs xzr, {val_lo}, {prev_lo}"), // if endian == little { (_, NZCV) = val_hi - prev_hi - !C } else { (_, NZCV) = val_lo - prev_lo - !C } + "csel {new_hi}, {prev_hi}, {val_hi}, lt", // if N != V { new_hi = prev_hi } else { new_hi = val_hi } + "csel {new_lo}, {prev_lo}, {val_lo}, lt", // if N != V { new_lo = prev_lo } else { new_lo = val_lo } +} +atomic_rmw_cas_3! { + _atomic_max_casp as atomic_max, + select_le_or_be!("cmp {val_lo}, x6", "cmp {val_hi}, x7"), // if endian == little { C = !(val_lo < x6) } else { C = !(val_hi < x7) } + select_le_or_be!("sbcs xzr, {val_hi}, x7", "sbcs xzr, {val_lo}, x6"), // if endian == little { (_, NZCV) = val_hi - x7 - !C } else { (_, NZCV) = val_lo - x6 - !C } + "csel x5, x7, {val_hi}, lt", // if N != V { x5 = x7 } else { x5 = val_hi } + "csel x4, x6, {val_lo}, lt", // if N != V { x4 = x6 } else { x4 = val_lo } +} + +// Do not use `preserves_flags` because CMP and SBCS modify the condition flags. +atomic_rmw_ll_sc_3! { + _atomic_umax_ldxp_stxp as atomic_umax, + select_le_or_be!("cmp {val_lo}, {prev_lo}", "cmp {val_hi}, {prev_hi}"), // if endian == little { C = !(val_lo < prev_lo) } else { C = !(val_hi < prev_hi) } + select_le_or_be!("sbcs xzr, {val_hi}, {prev_hi}", "sbcs xzr, {val_lo}, {prev_lo}"), // if endian == little { (_, NZCV) = val_hi - prev_hi - !C } else { (_, NZCV) = val_lo - prev_lo - !C } + "csel {new_hi}, {prev_hi}, {val_hi}, lo", // if C == 0 { new_hi = prev_hi } else { new_hi = val_hi } + "csel {new_lo}, {prev_lo}, {val_lo}, lo", // if C == 0 { new_hi = prev_hi } else { new_hi = val_hi } +} +atomic_rmw_cas_3! { + _atomic_umax_casp as atomic_umax, + select_le_or_be!("cmp {val_lo}, x6", "cmp {val_hi}, x7"), // if endian == little { C = !(val_lo < x6) } else { C = !(val_hi < x7) } + select_le_or_be!("sbcs xzr, {val_hi}, x7", "sbcs xzr, {val_lo}, x6"), // if endian == little { (_, NZCV) = val_hi - x7 - !C } else { (_, NZCV) = val_lo - x6 - !C } + "csel x5, x7, {val_hi}, lo", // if C == 0 { x5 = x7 } else { x5 = val_hi } + "csel x4, x6, {val_lo}, lo", // if C == 0 { x4 = x6 } else { x4 = val_lo } +} + +// Do not use `preserves_flags` because CMP and SBCS modify the condition flags. +atomic_rmw_ll_sc_3! { + _atomic_min_ldxp_stxp as atomic_min, + select_le_or_be!("cmp {val_lo}, {prev_lo}", "cmp {val_hi}, {prev_hi}"), // if endian == little { C = !(val_lo < prev_lo) } else { C = !(val_hi < prev_hi) } + select_le_or_be!("sbcs xzr, {val_hi}, {prev_hi}", "sbcs xzr, {val_lo}, {prev_lo}"), // if endian == little { (_, NZCV) = val_hi - prev_hi - !C } else { (_, NZCV) = val_lo - prev_lo - !C } + "csel {new_hi}, {prev_hi}, {val_hi}, ge", // if N == V { new_hi = prev_hi } else { new_hi = val_hi } + "csel {new_lo}, {prev_lo}, {val_lo}, ge", // if N == V { new_lo = prev_lo } else { new_lo = val_lo } +} +atomic_rmw_cas_3! { + _atomic_min_casp as atomic_min, + select_le_or_be!("cmp {val_lo}, x6", "cmp {val_hi}, x7"), // if endian == little { C = !(val_lo < x6) } else { C = !(val_hi < x7) } + select_le_or_be!("sbcs xzr, {val_hi}, x7", "sbcs xzr, {val_lo}, x6"), // if endian == little { (_, NZCV) = val_hi - x7 - !C } else { (_, NZCV) = val_lo - x6 - !C } + "csel x5, x7, {val_hi}, ge", // if N == V { x5 = x7 } else { x5 = val_hi } + "csel x4, x6, {val_lo}, ge", // if N == V { x4 = x6 } else { x4 = val_lo } +} + +// Do not use `preserves_flags` because CMP and SBCS modify the condition flags. +atomic_rmw_ll_sc_3! { + _atomic_umin_ldxp_stxp as atomic_umin, + select_le_or_be!("cmp {val_lo}, {prev_lo}", "cmp {val_hi}, {prev_hi}"), // if endian == little { C = !(val_lo < prev_lo) } else { C = !(val_hi < prev_hi) } + select_le_or_be!("sbcs xzr, {val_hi}, {prev_hi}", "sbcs xzr, {val_lo}, {prev_lo}"), // if endian == little { (_, NZCV) = val_hi - prev_hi - !C } else { (_, NZCV) = val_lo - prev_lo - !C } + "csel {new_hi}, {prev_hi}, {val_hi}, hs", // if C == 1 { new_hi = prev_hi } else { new_hi = val_hi } + "csel {new_lo}, {prev_lo}, {val_lo}, hs", // if C == 1 { new_lo = prev_lo } else { new_lo = val_lo } +} +atomic_rmw_cas_3! { + _atomic_umin_casp as atomic_umin, + select_le_or_be!("cmp {val_lo}, x6", "cmp {val_hi}, x7"), // if endian == little { C = !(val_lo < x6) } else { C = !(val_hi < x7) } + select_le_or_be!("sbcs xzr, {val_hi}, x7", "sbcs xzr, {val_lo}, x6"), // if endian == little { (_, NZCV) = val_hi - x7 - !C } else { (_, NZCV) = val_lo - x6 - !C } + "csel x5, x7, {val_hi}, hs", // if C == 1 { x5 = x7 } else { x5 = val_hi } + "csel x4, x6, {val_lo}, hs", // if C == 1 { x4 = x6 } else { x4 = val_lo } +} + +#[inline] +const fn is_lock_free() -> bool { + IS_ALWAYS_LOCK_FREE +} +const IS_ALWAYS_LOCK_FREE: bool = true; + +atomic128!(AtomicI128, i128, atomic_max, atomic_min); +atomic128!(AtomicU128, u128, atomic_umax, atomic_umin); + +#[cfg(test)] +mod tests { + use super::*; + + test_atomic_int!(i128); + test_atomic_int!(u128); + + // load/store/swap implementation is not affected by signedness, so it is + // enough to test only unsigned types. + stress_test!(u128); +} diff --git a/vendor/portable-atomic/src/imp/atomic128/intrinsics.rs b/vendor/portable-atomic/src/imp/atomic128/intrinsics.rs new file mode 100644 index 0000000..3f7bf80 --- /dev/null +++ b/vendor/portable-atomic/src/imp/atomic128/intrinsics.rs @@ -0,0 +1,508 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +128-bit atomic implementation without inline assembly. + +Adapted from https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs. + +Note: This module is currently only enabled on Miri and ThreadSanitizer which +do not support inline assembly. + +This uses `core::arch::x86_64::cmpxchg16b` on x86_64 and +`core::intrinsics::atomic_*` on aarch64, powerpc64, and s390x. + +See README.md of this directory for performance comparison with the +implementation with inline assembly. + +Note: +- This currently needs Rust 1.70 on x86_64, otherwise nightly compilers. +- On powerpc64, this requires LLVM 15+ and quadword-atomics target feature: + https://github.com/llvm/llvm-project/commit/549e118e93c666914a1045fde38a2cac33e1e445 +- On s390x, old LLVM (pre-18) generates libcalls for operations other than load/store/cmpxchg: + https://github.com/llvm/llvm-project/commit/c568927f3e2e7d9804ea74ecbf11c16c014ddcbc +- On aarch64 big-endian, LLVM (as of 17) generates broken code. (wrong result in stress test) + (on cfg(miri)/cfg(sanitize) it may be fine though) +- On powerpc64, LLVM (as of 17) doesn't support 128-bit atomic min/max: + https://github.com/llvm/llvm-project/issues/68390 +- On powerpc64le, LLVM (as of 17) generates broken code. (wrong result from fetch_add) +- On riscv64, LLVM does not automatically use 128-bit atomic instructions even if zacas feature is + enabled, because doing it changes the ABI. (If the ability to do that is provided by LLVM in the + future, it should probably be controlled by another ABI feature similar to forced-atomics.) +*/ + +include!("macros.rs"); + +#[allow(dead_code)] // we only use compare_exchange. +#[cfg(target_arch = "x86_64")] +#[cfg(not(target_feature = "cmpxchg16b"))] +#[path = "../fallback/outline_atomics.rs"] +mod fallback; + +#[cfg(target_arch = "x86_64")] +#[cfg(not(target_feature = "cmpxchg16b"))] +#[path = "../detect/x86_64.rs"] +mod detect; + +#[cfg(not(target_arch = "x86_64"))] +use core::intrinsics; +use core::sync::atomic::Ordering::{self, AcqRel, Acquire, Relaxed, Release, SeqCst}; + +#[cfg(target_arch = "x86_64")] +#[inline] +fn strongest_failure_ordering(order: Ordering) -> Ordering { + match order { + Release | Relaxed => Relaxed, + SeqCst => SeqCst, + Acquire | AcqRel => Acquire, + _ => unreachable!(), + } +} + +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 { + #[cfg(target_arch = "x86_64")] + // SAFETY: the caller must uphold the safety contract. + unsafe { + let fail_order = strongest_failure_ordering(order); + match atomic_compare_exchange(src, 0, 0, order, fail_order) { + Ok(v) | Err(v) => v, + } + } + #[cfg(not(target_arch = "x86_64"))] + // SAFETY: the caller must uphold the safety contract. + unsafe { + match order { + Acquire => intrinsics::atomic_load_acquire(src), + Relaxed => intrinsics::atomic_load_relaxed(src), + SeqCst => intrinsics::atomic_load_seqcst(src), + _ => unreachable!(), + } + } +} + +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) { + #[cfg(target_arch = "x86_64")] + // SAFETY: the caller must uphold the safety contract. + unsafe { + atomic_swap(dst, val, order); + } + #[cfg(not(target_arch = "x86_64"))] + // SAFETY: the caller must uphold the safety contract. + unsafe { + match order { + Release => intrinsics::atomic_store_release(dst, val), + Relaxed => intrinsics::atomic_store_relaxed(dst, val), + SeqCst => intrinsics::atomic_store_seqcst(dst, val), + _ => unreachable!(), + } + } +} + +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_compare_exchange( + dst: *mut u128, + old: u128, + new: u128, + success: Ordering, + failure: Ordering, +) -> Result { + #[cfg(target_arch = "x86_64")] + let (val, ok) = { + #[target_feature(enable = "cmpxchg16b")] + #[cfg_attr(target_feature = "cmpxchg16b", inline)] + #[cfg_attr(not(target_feature = "cmpxchg16b"), inline(never))] + unsafe fn cmpxchg16b( + dst: *mut u128, + old: u128, + new: u128, + success: Ordering, + failure: Ordering, + ) -> (u128, bool) { + #[cfg(portable_atomic_no_strict_provenance)] + use crate::utils::ptr::PtrExt as _; + debug_assert!(dst.addr() % 16 == 0); + #[cfg(not(target_feature = "cmpxchg16b"))] + { + debug_assert!(detect::detect().cmpxchg16b()); + } + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned (required by CMPXCHG16B), that there are no + // concurrent non-atomic operations, and that the CPU supports CMPXCHG16B. + let prev = unsafe { core::arch::x86_64::cmpxchg16b(dst, old, new, success, failure) }; + (prev, prev == old) + } + #[cfg(target_feature = "cmpxchg16b")] + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned, that there are no concurrent non-atomic operations, + // and cfg guarantees that CMPXCHG16B is available at compile-time. + unsafe { + cmpxchg16b(dst, old, new, success, failure) + } + #[cfg(not(target_feature = "cmpxchg16b"))] + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned, and that there are no different kinds of concurrent accesses. + unsafe { + ifunc!(unsafe fn( + dst: *mut u128, old: u128, new: u128, success: Ordering, failure: Ordering + ) -> (u128, bool) { + if detect::detect().cmpxchg16b() { + cmpxchg16b + } else { + fallback::atomic_compare_exchange + } + }) + } + }; + #[cfg(not(target_arch = "x86_64"))] + // SAFETY: the caller must uphold the safety contract. + let (val, ok) = unsafe { + match (success, failure) { + (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new), + (Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new), + (Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new), + (Acquire, Relaxed) => intrinsics::atomic_cxchg_acquire_relaxed(dst, old, new), + (Acquire, Acquire) => intrinsics::atomic_cxchg_acquire_acquire(dst, old, new), + (Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new), + (Release, Relaxed) => intrinsics::atomic_cxchg_release_relaxed(dst, old, new), + (Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new), + (Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new), + (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_relaxed(dst, old, new), + (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel_acquire(dst, old, new), + (AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new), + (SeqCst, Relaxed) => intrinsics::atomic_cxchg_seqcst_relaxed(dst, old, new), + (SeqCst, Acquire) => intrinsics::atomic_cxchg_seqcst_acquire(dst, old, new), + (SeqCst, SeqCst) => intrinsics::atomic_cxchg_seqcst_seqcst(dst, old, new), + _ => unreachable!(), + } + }; + if ok { Ok(val) } else { Err(val) } +} + +#[cfg(target_arch = "x86_64")] +use self::atomic_compare_exchange as atomic_compare_exchange_weak; +#[cfg(not(target_arch = "x86_64"))] +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_compare_exchange_weak( + dst: *mut u128, + old: u128, + new: u128, + success: Ordering, + failure: Ordering, +) -> Result { + // SAFETY: the caller must uphold the safety contract. + let (val, ok) = unsafe { + match (success, failure) { + (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed_relaxed(dst, old, new), + (Relaxed, Acquire) => intrinsics::atomic_cxchgweak_relaxed_acquire(dst, old, new), + (Relaxed, SeqCst) => intrinsics::atomic_cxchgweak_relaxed_seqcst(dst, old, new), + (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acquire_relaxed(dst, old, new), + (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acquire_acquire(dst, old, new), + (Acquire, SeqCst) => intrinsics::atomic_cxchgweak_acquire_seqcst(dst, old, new), + (Release, Relaxed) => intrinsics::atomic_cxchgweak_release_relaxed(dst, old, new), + (Release, Acquire) => intrinsics::atomic_cxchgweak_release_acquire(dst, old, new), + (Release, SeqCst) => intrinsics::atomic_cxchgweak_release_seqcst(dst, old, new), + (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_relaxed(dst, old, new), + (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel_acquire(dst, old, new), + (AcqRel, SeqCst) => intrinsics::atomic_cxchgweak_acqrel_seqcst(dst, old, new), + (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_seqcst_relaxed(dst, old, new), + (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_seqcst_acquire(dst, old, new), + (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak_seqcst_seqcst(dst, old, new), + _ => unreachable!(), + } + }; + if ok { Ok(val) } else { Err(val) } +} + +#[inline(always)] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_update(dst: *mut u128, order: Ordering, mut f: F) -> u128 +where + F: FnMut(u128) -> u128, +{ + // SAFETY: the caller must uphold the safety contract. + unsafe { + // This is a private function and all instances of `f` only operate on the value + // loaded, so there is no need to synchronize the first load/failed CAS. + let mut prev = atomic_load(dst, Ordering::Relaxed); + loop { + let next = f(prev); + match atomic_compare_exchange_weak(dst, prev, next, order, Ordering::Relaxed) { + Ok(x) => return x, + Err(x) => prev = x, + } + } + } +} + +// On x86_64, we use core::arch::x86_64::cmpxchg16b instead of core::intrinsics. +// - On s390x, old LLVM (pre-18) generates libcalls for operations other than load/store/cmpxchg (see also module-level comment). +#[cfg(any(target_arch = "x86_64", all(target_arch = "s390x", portable_atomic_pre_llvm_18)))] +atomic_rmw_by_atomic_update!(); +// On powerpc64, LLVM doesn't support 128-bit atomic min/max (see also module-level comment). +#[cfg(target_arch = "powerpc64")] +atomic_rmw_by_atomic_update!(cmp); + +#[cfg(not(any(target_arch = "x86_64", all(target_arch = "s390x", portable_atomic_pre_llvm_18))))] +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_swap(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { + match order { + Acquire => intrinsics::atomic_xchg_acquire(dst, val), + Release => intrinsics::atomic_xchg_release(dst, val), + AcqRel => intrinsics::atomic_xchg_acqrel(dst, val), + Relaxed => intrinsics::atomic_xchg_relaxed(dst, val), + SeqCst => intrinsics::atomic_xchg_seqcst(dst, val), + _ => unreachable!(), + } + } +} + +#[cfg(not(any(target_arch = "x86_64", all(target_arch = "s390x", portable_atomic_pre_llvm_18))))] +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_add(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { + match order { + Acquire => intrinsics::atomic_xadd_acquire(dst, val), + Release => intrinsics::atomic_xadd_release(dst, val), + AcqRel => intrinsics::atomic_xadd_acqrel(dst, val), + Relaxed => intrinsics::atomic_xadd_relaxed(dst, val), + SeqCst => intrinsics::atomic_xadd_seqcst(dst, val), + _ => unreachable!(), + } + } +} + +#[cfg(not(any(target_arch = "x86_64", all(target_arch = "s390x", portable_atomic_pre_llvm_18))))] +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_sub(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { + match order { + Acquire => intrinsics::atomic_xsub_acquire(dst, val), + Release => intrinsics::atomic_xsub_release(dst, val), + AcqRel => intrinsics::atomic_xsub_acqrel(dst, val), + Relaxed => intrinsics::atomic_xsub_relaxed(dst, val), + SeqCst => intrinsics::atomic_xsub_seqcst(dst, val), + _ => unreachable!(), + } + } +} + +#[cfg(not(any(target_arch = "x86_64", all(target_arch = "s390x", portable_atomic_pre_llvm_18))))] +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_and(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { + match order { + Acquire => intrinsics::atomic_and_acquire(dst, val), + Release => intrinsics::atomic_and_release(dst, val), + AcqRel => intrinsics::atomic_and_acqrel(dst, val), + Relaxed => intrinsics::atomic_and_relaxed(dst, val), + SeqCst => intrinsics::atomic_and_seqcst(dst, val), + _ => unreachable!(), + } + } +} + +#[cfg(not(any(target_arch = "x86_64", all(target_arch = "s390x", portable_atomic_pre_llvm_18))))] +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_nand(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { + match order { + Acquire => intrinsics::atomic_nand_acquire(dst, val), + Release => intrinsics::atomic_nand_release(dst, val), + AcqRel => intrinsics::atomic_nand_acqrel(dst, val), + Relaxed => intrinsics::atomic_nand_relaxed(dst, val), + SeqCst => intrinsics::atomic_nand_seqcst(dst, val), + _ => unreachable!(), + } + } +} + +#[cfg(not(any(target_arch = "x86_64", all(target_arch = "s390x", portable_atomic_pre_llvm_18))))] +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_or(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { + match order { + Acquire => intrinsics::atomic_or_acquire(dst, val), + Release => intrinsics::atomic_or_release(dst, val), + AcqRel => intrinsics::atomic_or_acqrel(dst, val), + Relaxed => intrinsics::atomic_or_relaxed(dst, val), + SeqCst => intrinsics::atomic_or_seqcst(dst, val), + _ => unreachable!(), + } + } +} + +#[cfg(not(any(target_arch = "x86_64", all(target_arch = "s390x", portable_atomic_pre_llvm_18))))] +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_xor(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { + match order { + Acquire => intrinsics::atomic_xor_acquire(dst, val), + Release => intrinsics::atomic_xor_release(dst, val), + AcqRel => intrinsics::atomic_xor_acqrel(dst, val), + Relaxed => intrinsics::atomic_xor_relaxed(dst, val), + SeqCst => intrinsics::atomic_xor_seqcst(dst, val), + _ => unreachable!(), + } + } +} + +#[cfg(not(any( + target_arch = "x86_64", + target_arch = "powerpc64", + all(target_arch = "s390x", portable_atomic_pre_llvm_18), +)))] +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_max(dst: *mut u128, val: u128, order: Ordering) -> i128 { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: the caller must uphold the safety contract. + unsafe { + match order { + Acquire => intrinsics::atomic_max_acquire(dst.cast::(), val as i128), + Release => intrinsics::atomic_max_release(dst.cast::(), val as i128), + AcqRel => intrinsics::atomic_max_acqrel(dst.cast::(), val as i128), + Relaxed => intrinsics::atomic_max_relaxed(dst.cast::(), val as i128), + SeqCst => intrinsics::atomic_max_seqcst(dst.cast::(), val as i128), + _ => unreachable!(), + } + } +} + +#[cfg(not(any( + target_arch = "x86_64", + target_arch = "powerpc64", + all(target_arch = "s390x", portable_atomic_pre_llvm_18), +)))] +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_min(dst: *mut u128, val: u128, order: Ordering) -> i128 { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: the caller must uphold the safety contract. + unsafe { + match order { + Acquire => intrinsics::atomic_min_acquire(dst.cast::(), val as i128), + Release => intrinsics::atomic_min_release(dst.cast::(), val as i128), + AcqRel => intrinsics::atomic_min_acqrel(dst.cast::(), val as i128), + Relaxed => intrinsics::atomic_min_relaxed(dst.cast::(), val as i128), + SeqCst => intrinsics::atomic_min_seqcst(dst.cast::(), val as i128), + _ => unreachable!(), + } + } +} + +#[cfg(not(any( + target_arch = "x86_64", + target_arch = "powerpc64", + all(target_arch = "s390x", portable_atomic_pre_llvm_18), +)))] +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_umax(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { + match order { + Acquire => intrinsics::atomic_umax_acquire(dst, val), + Release => intrinsics::atomic_umax_release(dst, val), + AcqRel => intrinsics::atomic_umax_acqrel(dst, val), + Relaxed => intrinsics::atomic_umax_relaxed(dst, val), + SeqCst => intrinsics::atomic_umax_seqcst(dst, val), + _ => unreachable!(), + } + } +} + +#[cfg(not(any( + target_arch = "x86_64", + target_arch = "powerpc64", + all(target_arch = "s390x", portable_atomic_pre_llvm_18), +)))] +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_umin(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { + match order { + Acquire => intrinsics::atomic_umin_acquire(dst, val), + Release => intrinsics::atomic_umin_release(dst, val), + AcqRel => intrinsics::atomic_umin_acqrel(dst, val), + Relaxed => intrinsics::atomic_umin_relaxed(dst, val), + SeqCst => intrinsics::atomic_umin_seqcst(dst, val), + _ => unreachable!(), + } + } +} + +#[cfg(not(any(target_arch = "x86_64", all(target_arch = "s390x", portable_atomic_pre_llvm_18))))] +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_not(dst: *mut u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { atomic_xor(dst, !0, order) } +} + +#[cfg(not(any(target_arch = "x86_64", all(target_arch = "s390x", portable_atomic_pre_llvm_18))))] +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +unsafe fn atomic_neg(dst: *mut u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { atomic_update(dst, order, u128::wrapping_neg) } +} + +#[cfg(not(target_arch = "x86_64"))] +#[inline] +const fn is_lock_free() -> bool { + IS_ALWAYS_LOCK_FREE +} +#[cfg(not(target_arch = "x86_64"))] +const IS_ALWAYS_LOCK_FREE: bool = true; + +#[cfg(target_arch = "x86_64")] +#[inline] +fn is_lock_free() -> bool { + #[cfg(target_feature = "cmpxchg16b")] + { + // CMPXCHG16B is available at compile-time. + true + } + #[cfg(not(target_feature = "cmpxchg16b"))] + { + detect::detect().cmpxchg16b() + } +} +#[cfg(target_arch = "x86_64")] +const IS_ALWAYS_LOCK_FREE: bool = cfg!(target_feature = "cmpxchg16b"); + +atomic128!(AtomicI128, i128, atomic_max, atomic_min); +atomic128!(AtomicU128, u128, atomic_umax, atomic_umin); + +#[cfg(test)] +mod tests { + use super::*; + + test_atomic_int!(i128); + test_atomic_int!(u128); + + // load/store/swap implementation is not affected by signedness, so it is + // enough to test only unsigned types. + stress_test!(u128); +} diff --git a/vendor/portable-atomic/src/imp/atomic128/macros.rs b/vendor/portable-atomic/src/imp/atomic128/macros.rs new file mode 100644 index 0000000..bde3270 --- /dev/null +++ b/vendor/portable-atomic/src/imp/atomic128/macros.rs @@ -0,0 +1,349 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +macro_rules! atomic128 { + ($atomic_type:ident, $int_type:ident, $atomic_max:ident, $atomic_min:ident) => { + #[repr(C, align(16))] + pub(crate) struct $atomic_type { + v: core::cell::UnsafeCell<$int_type>, + } + + // Send is implicitly implemented. + // SAFETY: any data races are prevented by atomic intrinsics. + unsafe impl Sync for $atomic_type {} + + impl_default_no_fetch_ops!($atomic_type, $int_type); + impl_default_bit_opts!($atomic_type, $int_type); + impl $atomic_type { + #[inline] + pub(crate) const fn new(v: $int_type) -> Self { + Self { v: core::cell::UnsafeCell::new(v) } + } + + #[inline] + pub(crate) fn is_lock_free() -> bool { + is_lock_free() + } + pub(crate) const IS_ALWAYS_LOCK_FREE: bool = IS_ALWAYS_LOCK_FREE; + + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn load(&self, order: Ordering) -> $int_type { + crate::utils::assert_load_ordering(order); + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + atomic_load(self.v.get().cast::(), order) as $int_type + } + } + + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn store(&self, val: $int_type, order: Ordering) { + crate::utils::assert_store_ordering(order); + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + atomic_store(self.v.get().cast::(), val as u128, order) + } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn swap(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + atomic_swap(self.v.get().cast::(), val as u128, order) as $int_type + } + } + + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn compare_exchange( + &self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering, + ) -> Result<$int_type, $int_type> { + crate::utils::assert_compare_exchange_ordering(success, failure); + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + match atomic_compare_exchange( + self.v.get().cast::(), + current as u128, + new as u128, + success, + failure, + ) { + Ok(v) => Ok(v as $int_type), + Err(v) => Err(v as $int_type), + } + } + } + + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn compare_exchange_weak( + &self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering, + ) -> Result<$int_type, $int_type> { + crate::utils::assert_compare_exchange_ordering(success, failure); + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + match atomic_compare_exchange_weak( + self.v.get().cast::(), + current as u128, + new as u128, + success, + failure, + ) { + Ok(v) => Ok(v as $int_type), + Err(v) => Err(v as $int_type), + } + } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + atomic_add(self.v.get().cast::(), val as u128, order) as $int_type + } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + atomic_sub(self.v.get().cast::(), val as u128, order) as $int_type + } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + atomic_and(self.v.get().cast::(), val as u128, order) as $int_type + } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + atomic_nand(self.v.get().cast::(), val as u128, order) as $int_type + } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + atomic_or(self.v.get().cast::(), val as u128, order) as $int_type + } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + atomic_xor(self.v.get().cast::(), val as u128, order) as $int_type + } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + $atomic_max(self.v.get().cast::(), val as u128, order) as $int_type + } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + $atomic_min(self.v.get().cast::(), val as u128, order) as $int_type + } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_not(&self, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + atomic_not(self.v.get().cast::(), order) as $int_type + } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn not(&self, order: Ordering) { + self.fetch_not(order); + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_neg(&self, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + atomic_neg(self.v.get().cast::(), order) as $int_type + } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn neg(&self, order: Ordering) { + self.fetch_neg(order); + } + + #[inline] + pub(crate) const fn as_ptr(&self) -> *mut $int_type { + self.v.get() + } + } + }; +} + +#[cfg(any(target_arch = "powerpc64", target_arch = "s390x", target_arch = "x86_64"))] +#[allow(unused_macros)] // also used by intrinsics.rs +macro_rules! atomic_rmw_by_atomic_update { + () => { + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn atomic_swap(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { atomic_update(dst, order, |_| val) } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn atomic_add(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { atomic_update(dst, order, |x| x.wrapping_add(val)) } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn atomic_sub(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { atomic_update(dst, order, |x| x.wrapping_sub(val)) } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn atomic_and(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { atomic_update(dst, order, |x| x & val) } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn atomic_nand(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { atomic_update(dst, order, |x| !(x & val)) } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn atomic_or(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { atomic_update(dst, order, |x| x | val) } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn atomic_xor(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { atomic_update(dst, order, |x| x ^ val) } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn atomic_not(dst: *mut u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { atomic_update(dst, order, |x| !x) } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn atomic_neg(dst: *mut u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { atomic_update(dst, order, u128::wrapping_neg) } + } + atomic_rmw_by_atomic_update!(cmp); + }; + (cmp) => { + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn atomic_max(dst: *mut u128, val: u128, order: Ordering) -> u128 { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: the caller must uphold the safety contract. + unsafe { + atomic_update(dst, order, |x| core::cmp::max(x as i128, val as i128) as u128) + } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn atomic_umax(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { atomic_update(dst, order, |x| core::cmp::max(x, val)) } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn atomic_min(dst: *mut u128, val: u128, order: Ordering) -> u128 { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: the caller must uphold the safety contract. + unsafe { + atomic_update(dst, order, |x| core::cmp::min(x as i128, val as i128) as u128) + } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn atomic_umin(dst: *mut u128, val: u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { atomic_update(dst, order, |x| core::cmp::min(x, val)) } + } + }; +} diff --git a/vendor/portable-atomic/src/imp/atomic128/mod.rs b/vendor/portable-atomic/src/imp/atomic128/mod.rs new file mode 100644 index 0000000..9664678 --- /dev/null +++ b/vendor/portable-atomic/src/imp/atomic128/mod.rs @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +128-bit atomic implementations on 64-bit architectures + +See README.md for details. +*/ + +// AArch64 +#[cfg(any( + all( + target_arch = "aarch64", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + ), + all( + target_arch = "arm64ec", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + ), +))] +// Use intrinsics.rs on Miri and Sanitizer that do not support inline assembly. +#[cfg_attr(any(miri, portable_atomic_sanitize_thread), path = "intrinsics.rs")] +pub(super) mod aarch64; + +// powerpc64 +#[cfg(all( + target_arch = "powerpc64", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + all( + feature = "fallback", + not(portable_atomic_no_outline_atomics), + any( + all( + target_os = "linux", + any( + all( + target_env = "gnu", + any(target_endian = "little", not(target_feature = "crt-static")), + ), + all( + target_env = "musl", + any(not(target_feature = "crt-static"), feature = "std"), + ), + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + portable_atomic_outline_atomics, + ), + ), + target_os = "android", + all( + target_os = "freebsd", + any( + target_endian = "little", + not(target_feature = "crt-static"), + portable_atomic_outline_atomics, + ), + ), + target_os = "openbsd", + all( + target_os = "aix", + not(portable_atomic_pre_llvm_20), + any(test, portable_atomic_outline_atomics), // TODO(aix): currently disabled by default + ), + ), + not(any(miri, portable_atomic_sanitize_thread)), + ), + ), +))] +// Use intrinsics.rs on Miri and Sanitizer that do not support inline assembly. +#[cfg_attr(any(miri, portable_atomic_sanitize_thread), path = "intrinsics.rs")] +pub(super) mod powerpc64; + +// riscv64 +#[cfg(all( + target_arch = "riscv64", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any( + target_feature = "zacas", + portable_atomic_target_feature = "zacas", + all( + feature = "fallback", + not(portable_atomic_no_outline_atomics), + any(target_os = "linux", target_os = "android"), + ), + ), +))] +pub(super) mod riscv64; + +// s390x +#[cfg(all( + target_arch = "s390x", + not(all(any(miri, portable_atomic_sanitize_thread), not(portable_atomic_atomic_intrinsics))), + not(portable_atomic_no_asm), +))] +// Use intrinsics.rs on Miri and Sanitizer that do not support inline assembly. +#[cfg_attr(any(miri, portable_atomic_sanitize_thread), path = "intrinsics.rs")] +pub(super) mod s390x; + +// x86_64 +#[cfg(all( + target_arch = "x86_64", + not(all(any(miri, portable_atomic_sanitize_thread), portable_atomic_no_cmpxchg16b_intrinsic)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any( + target_feature = "cmpxchg16b", + portable_atomic_target_feature = "cmpxchg16b", + all( + feature = "fallback", + not(portable_atomic_no_outline_atomics), + not(any(target_env = "sgx", miri)), + ), + ), +))] +// Use intrinsics.rs on Miri and Sanitizer that do not support inline assembly. +#[cfg_attr(any(miri, portable_atomic_sanitize_thread), path = "intrinsics.rs")] +pub(super) mod x86_64; diff --git a/vendor/portable-atomic/src/imp/atomic128/powerpc64.rs b/vendor/portable-atomic/src/imp/atomic128/powerpc64.rs new file mode 100644 index 0000000..cae6398 --- /dev/null +++ b/vendor/portable-atomic/src/imp/atomic128/powerpc64.rs @@ -0,0 +1,1046 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +128-bit atomic implementation on PowerPC64. + +This architecture provides the following 128-bit atomic instructions: + +- lq/stq: load/store (ISA 2.07 or later, included in the Linux Compliancy subset and AIX Compliancy subset) +- lqarx/stqcx.: LL/SC (ISA 2.07 or later, included in the Linux Compliancy subset and AIX Compliancy subset) +- plq/pstq: load/store (ISA 3.1 or later, included in the Linux Compliancy subset and AIX Compliancy subset) + +See "Atomic operation overview by architecture" in atomic-maybe-uninit for a more comprehensive and +detailed description of the atomic and synchronize instructions in this architecture: +https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#powerpc + +Note that we do not separate LL and SC into separate functions, but handle +them within a single asm block. This is because it is theoretically possible +for the compiler to insert operations that might clear the reservation between +LL and SC. See aarch64.rs for details. + +Note: On Miri and ThreadSanitizer which do not support inline assembly, we don't use +this module and use intrinsics.rs instead. + +Refs: +- Power ISA + https://openpowerfoundation.org/specifications/isa +- AIX Assembler language reference + https://www.ibm.com/docs/en/aix/7.3?topic=aix-assembler-language-reference +- atomic-maybe-uninit + https://github.com/taiki-e/atomic-maybe-uninit + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +include!("macros.rs"); + +#[cfg(not(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", +)))] +#[path = "../fallback/outline_atomics.rs"] +mod fallback; + +// On musl with static linking, it seems that getauxval is not always available. +// See detect/auxv.rs for more. +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(any( + test, + not(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + )), +))] +#[cfg(any( + all( + target_os = "linux", + any( + all( + target_env = "gnu", + any(target_endian = "little", not(target_feature = "crt-static")), + ), + all(target_env = "musl", any(not(target_feature = "crt-static"), feature = "std")), + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + portable_atomic_outline_atomics, + ), + ), + target_os = "android", + all( + target_os = "freebsd", + any( + target_endian = "little", + not(target_feature = "crt-static"), + portable_atomic_outline_atomics, + ), + ), + target_os = "openbsd", +))] +#[path = "../detect/auxv.rs"] +mod detect; +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(any( + test, + not(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + )), +))] +#[cfg(target_os = "aix")] +#[cfg(not(portable_atomic_pre_llvm_20))] // SIGTRAP on LLVM 19 +#[cfg(any(test, portable_atomic_outline_atomics))] // TODO(aix): currently disabled by default +#[path = "../detect/powerpc64_aix.rs"] +mod detect; + +use core::{arch::asm, sync::atomic::Ordering}; + +#[cfg(portable_atomic_no_strict_provenance)] +use crate::utils::ptr::PtrExt as _; +use crate::utils::{Pair, U128}; + +macro_rules! debug_assert_pwr8 { + () => { + #[cfg(not(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + )))] + { + debug_assert!(detect::detect().quadword_atomics()); + } + }; +} + +// Refs: https://www.ibm.com/docs/en/aix/7.3?topic=ops-machine-pseudo-op +// +// This is similar to #[target_feature(enable = "quadword-atomics")], except that there are +// no compiler guarantees regarding (un)inlining, and the scope is within an asm +// block rather than a function. We use this directive because #[target_feature(enable = "quadword-atomics")] +// is unstable and unavailable on old nightly and incompatible with rustc_codegen_cranelift: +// https://github.com/rust-lang/rustc_codegen_cranelift/issues/1400#issuecomment-1774599775 +// +// Note: start_pwr8 and end_pwr8 must be used in pairs. +// +// Note: If power8 instructions are not available at compile-time, we must guarantee that +// the function that uses it is not inlined into a function where it is not +// clear whether power8 instructions are available. Otherwise, (even if we checked whether +// power8 instructions are available at run-time) optimizations that reorder its +// instructions across the if condition might introduce undefined behavior. +// (see also https://rust-lang.github.io/rfcs/2045-target-feature.html#safely-inlining-target_feature-functions-on-more-contexts) +// However, our code uses the ifunc helper macro that works with function pointers, +// so we don't have to worry about this unless calling without helper macro. +macro_rules! start_pwr8 { + () => { + ".machine push\n.machine power8" + }; +} +macro_rules! end_pwr8 { + () => { + ".machine pop" + }; +} + +macro_rules! atomic_rmw { + ($op:ident, $order:ident) => { + match $order { + Ordering::Relaxed => $op!("", ""), + Ordering::Acquire => $op!("isync", ""), + Ordering::Release => $op!("", "lwsync"), + Ordering::AcqRel => $op!("isync", "lwsync"), + Ordering::SeqCst => $op!("isync", "sync"), + _ => unreachable!(), + } + }; +} +macro_rules! atomic_cas { + ($op:ident, $success:ident, $failure:ident) => { + if $failure == Ordering::Relaxed { + match $success { + Ordering::Relaxed => $op!("", "", ""), + Ordering::Acquire => $op!("", "isync", ""), + Ordering::Release => $op!("", "", "lwsync"), + Ordering::AcqRel => $op!("", "isync", "lwsync"), + Ordering::SeqCst => $op!("", "isync", "sync"), + _ => unreachable!(), + } + } else { + let order = crate::utils::upgrade_success_ordering($success, $failure); + match order { + // Relaxed and Release are covered in $failure == Relaxed branch. + Ordering::Acquire => $op!("isync", "", ""), + Ordering::AcqRel => $op!("isync", "", "lwsync"), + Ordering::SeqCst => $op!("isync", "", "sync"), + _ => unreachable!(), + } + } + }; +} + +// Extracts and checks the EQ bit of cr0. +#[inline] +fn test_cr0_eq(cr: u64) -> bool { + cr & 0x20000000 != 0 +} + +// If quadword-atomics is available at compile-time, we can always use pwr8_fn. +#[cfg(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", +))] +use self::atomic_load_pwr8 as atomic_load; +// Otherwise, we need to do run-time detection and can use pwr8_fn only if quadword-atomics is available. +#[cfg(not(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", +)))] +#[inline] +unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 { + fn_alias! { + // inline(never) is just a hint and also not strictly necessary + // because we use ifunc helper macro, but used for clarity. + #[inline(never)] + unsafe fn(src: *mut u128) -> u128; + atomic_load_pwr8_relaxed = atomic_load_pwr8(Ordering::Relaxed); + atomic_load_pwr8_acquire = atomic_load_pwr8(Ordering::Acquire); + atomic_load_pwr8_seqcst = atomic_load_pwr8(Ordering::SeqCst); + } + // SAFETY: the caller must uphold the safety contract. + // we only calls atomic_load_pwr8 if quadword-atomics is available. + unsafe { + match order { + Ordering::Relaxed => { + ifunc!(unsafe fn(src: *mut u128) -> u128 { + if detect::detect().quadword_atomics() { + atomic_load_pwr8_relaxed + } else { + fallback::atomic_load_non_seqcst + } + }) + } + Ordering::Acquire => { + ifunc!(unsafe fn(src: *mut u128) -> u128 { + if detect::detect().quadword_atomics() { + atomic_load_pwr8_acquire + } else { + fallback::atomic_load_non_seqcst + } + }) + } + Ordering::SeqCst => { + ifunc!(unsafe fn(src: *mut u128) -> u128 { + if detect::detect().quadword_atomics() { + atomic_load_pwr8_seqcst + } else { + fallback::atomic_load_seqcst + } + }) + } + _ => unreachable!(), + } + } +} +#[inline] +unsafe fn atomic_load_pwr8(src: *mut u128, order: Ordering) -> u128 { + debug_assert!(src.addr() % 16 == 0); + debug_assert_pwr8!(); + let (out_hi, out_lo); + + // SAFETY: the caller must uphold the safety contract. + // + // Refs: Section 3.3.4 "Fixed Point Load and Store Quadword Instructions" of Power ISA 3.1C Book I + unsafe { + macro_rules! atomic_load_acquire { + ($release:tt) => { + asm!( + start_pwr8!(), + $release, + "lq %r4, 0({src})", // atomic { r4:r5 = *src } + "cmpw %r4, %r4", // if r4 == r4 { cr0.EQ = 1 } else { cr0.EQ = 0 } + "bne- %cr0, 2f", // if unlikely(cr0.EQ == 0) { jump 'never } + "2:", // 'never: + "isync", // fence (works in combination with a branch that depends on the loaded value) + end_pwr8!(), + src = in(reg_nonzero) ptr_reg!(src), + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater. + out("r4") out_hi, + out("r5") out_lo, + out("cr0") _, + options(nostack, preserves_flags), + ) + }; + } + match order { + Ordering::Relaxed => { + asm!( + start_pwr8!(), + "lq %r4, 0({src})", // atomic { r4:r5 = *src } + end_pwr8!(), + src = in(reg_nonzero) ptr_reg!(src), + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater. + out("r4") out_hi, + out("r5") out_lo, + options(nostack, preserves_flags), + ); + } + Ordering::Acquire => atomic_load_acquire!(""), + Ordering::SeqCst => atomic_load_acquire!("sync"), + _ => unreachable!(), + } + U128 { pair: Pair { hi: out_hi, lo: out_lo } }.whole + } +} + +// If quadword-atomics is available at compile-time, we can always use pwr8_fn. +#[cfg(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", +))] +use self::atomic_store_pwr8 as atomic_store; +// Otherwise, we need to do run-time detection and can use pwr8_fn only if quadword-atomics is available. +#[cfg(not(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", +)))] +#[inline] +unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) { + fn_alias! { + // inline(never) is just a hint and also not strictly necessary + // because we use ifunc helper macro, but used for clarity. + #[inline(never)] + unsafe fn(dst: *mut u128, val: u128); + atomic_store_pwr8_relaxed = atomic_store_pwr8(Ordering::Relaxed); + atomic_store_pwr8_release = atomic_store_pwr8(Ordering::Release); + atomic_store_pwr8_seqcst = atomic_store_pwr8(Ordering::SeqCst); + } + // SAFETY: the caller must uphold the safety contract. + // we only calls atomic_store_pwr8 if quadword-atomics is available. + unsafe { + match order { + Ordering::Relaxed => { + ifunc!(unsafe fn(dst: *mut u128, val: u128) { + if detect::detect().quadword_atomics() { + atomic_store_pwr8_relaxed + } else { + fallback::atomic_store_non_seqcst + } + }); + } + Ordering::Release => { + ifunc!(unsafe fn(dst: *mut u128, val: u128) { + if detect::detect().quadword_atomics() { + atomic_store_pwr8_release + } else { + fallback::atomic_store_non_seqcst + } + }); + } + Ordering::SeqCst => { + ifunc!(unsafe fn(dst: *mut u128, val: u128) { + if detect::detect().quadword_atomics() { + atomic_store_pwr8_seqcst + } else { + fallback::atomic_store_seqcst + } + }); + } + _ => unreachable!(), + } + } +} +#[inline] +unsafe fn atomic_store_pwr8(dst: *mut u128, val: u128, order: Ordering) { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_pwr8!(); + let val = U128 { whole: val }; + + // SAFETY: the caller must uphold the safety contract. + // + // Refs: Section 3.3.4 "Fixed Point Load and Store Quadword Instructions" of Power ISA 3.1C Book I + unsafe { + macro_rules! atomic_store { + ($release:tt) => { + asm!( + start_pwr8!(), + $release, // fence + "stq %r4, 0({dst})", // atomic { *dst = r4:r5 } + end_pwr8!(), + dst = in(reg_nonzero) ptr_reg!(dst), + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater. + in("r4") val.pair.hi, + in("r5") val.pair.lo, + options(nostack, preserves_flags), + ) + }; + } + match order { + Ordering::Relaxed => atomic_store!(""), + Ordering::Release => atomic_store!("lwsync"), + Ordering::SeqCst => atomic_store!("sync"), + _ => unreachable!(), + } + } +} + +#[inline] +unsafe fn atomic_compare_exchange( + dst: *mut u128, + old: u128, + new: u128, + success: Ordering, + failure: Ordering, +) -> Result { + #[cfg(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + ))] + // SAFETY: the caller must uphold the safety contract. + // cfg guarantees that quadword atomics instructions are available at compile-time. + let (prev, ok) = unsafe { atomic_compare_exchange_pwr8(dst, old, new, success, failure) }; + #[cfg(not(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + )))] + // SAFETY: the caller must uphold the safety contract. + let (prev, ok) = { + fn_alias! { + // inline(never) is just a hint and also not strictly necessary + // because we use ifunc helper macro, but used for clarity. + #[inline(never)] + unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool); + pwr8_relaxed_fn = atomic_compare_exchange_pwr8(Ordering::Relaxed, Ordering::Relaxed); + pwr8_acquire_fn = atomic_compare_exchange_pwr8(Ordering::Acquire, Ordering::Acquire); + pwr8_release_fn = atomic_compare_exchange_pwr8(Ordering::Release, Ordering::Relaxed); + pwr8_acqrel_fn = atomic_compare_exchange_pwr8(Ordering::AcqRel, Ordering::Acquire); + pwr8_seqcst_fn = atomic_compare_exchange_pwr8(Ordering::SeqCst, Ordering::SeqCst); + } + // SAFETY: the caller must uphold the safety contract. + // we only calls pwr8_fn if quadword-atomics is available. + unsafe { + let success = crate::utils::upgrade_success_ordering(success, failure); + match success { + Ordering::Relaxed => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) { + if detect::detect().quadword_atomics() { + pwr8_relaxed_fn + } else { + fallback::atomic_compare_exchange_non_seqcst + } + }) + } + Ordering::Acquire => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) { + if detect::detect().quadword_atomics() { + pwr8_acquire_fn + } else { + fallback::atomic_compare_exchange_non_seqcst + } + }) + } + Ordering::Release => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) { + if detect::detect().quadword_atomics() { + pwr8_release_fn + } else { + fallback::atomic_compare_exchange_non_seqcst + } + }) + } + Ordering::AcqRel => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) { + if detect::detect().quadword_atomics() { + pwr8_acqrel_fn + } else { + fallback::atomic_compare_exchange_non_seqcst + } + }) + } + Ordering::SeqCst => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) { + if detect::detect().quadword_atomics() { + pwr8_seqcst_fn + } else { + fallback::atomic_compare_exchange_seqcst + } + }) + } + _ => unreachable!(), + } + } + }; + if ok { Ok(prev) } else { Err(prev) } +} +#[inline] +unsafe fn atomic_compare_exchange_pwr8( + dst: *mut u128, + old: u128, + new: u128, + success: Ordering, + failure: Ordering, +) -> (u128, bool) { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_pwr8!(); + let old = U128 { whole: old }; + let new = U128 { whole: new }; + let (mut prev_hi, mut prev_lo); + let mut r; + + // SAFETY: the caller must uphold the safety contract. + // + // Refs: Section 4.6.2.2 "128-bit Load And Reserve and Store Conditional Instructions" of Power ISA 3.1C Book II + unsafe { + macro_rules! cmpxchg { + ($acquire_always:tt, $acquire_success:tt, $release:tt) => { + asm!( + start_pwr8!(), + $release, // fence + "2:", // 'retry: + "lqarx %r8, 0, {dst}", // atomic { RESERVE = (dst, 16); r8:r9 = *dst } + "xor {tmp_lo}, %r9, {old_lo}", // tmp_lo = r9 ^ old_lo + "xor {tmp_hi}, %r8, {old_hi}", // tmp_hi = r8 ^ old_hi + "or. {tmp_lo}, {tmp_lo}, {tmp_hi}", // tmp_lo |= tmp_hi; if tmp_lo == 0 { cr0.EQ = 1 } else { cr0.EQ = 0 } + "bne %cr0, 3f", // if cr0.EQ == 0 { jump 'cmp-fail } + "stqcx. %r6, 0, {dst}", // atomic { if RESERVE == (dst, 16) { *dst = r6:r7; cr0.EQ = 1 } else { cr0.EQ = 0 }; RESERVE = None } + "bne %cr0, 2b", // if cr0.EQ == 0 { jump 'retry } + $acquire_success, // fence + "3:", // 'cmp-fail: + $acquire_always, // fence + "mfcr {tmp_lo}", // tmp_lo = zero_extend(cr) + end_pwr8!(), + dst = in(reg_nonzero) ptr_reg!(dst), + old_hi = in(reg) old.pair.hi, + old_lo = in(reg) old.pair.lo, + tmp_hi = out(reg) _, + tmp_lo = out(reg) r, + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater. + in("r6") new.pair.hi, + in("r7") new.pair.lo, + out("r8") prev_hi, + out("r9") prev_lo, + out("cr0") _, + options(nostack, preserves_flags), + ) + }; + } + atomic_cas!(cmpxchg, success, failure); + // if compare failed EQ bit is cleared, if store succeeds EQ bit is set. + (U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole, test_cr0_eq(r)) + } +} + +// Always use strong CAS for outline-atomics. +#[cfg(not(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", +)))] +use self::atomic_compare_exchange as atomic_compare_exchange_weak; +#[cfg(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", +))] +#[inline] +unsafe fn atomic_compare_exchange_weak( + dst: *mut u128, + old: u128, + new: u128, + success: Ordering, + failure: Ordering, +) -> Result { + // SAFETY: the caller must uphold the safety contract. + // cfg guarantees that quadword atomics instructions are available at compile-time. + let (prev, ok) = unsafe { atomic_compare_exchange_weak_pwr8(dst, old, new, success, failure) }; + if ok { Ok(prev) } else { Err(prev) } +} +#[cfg(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", +))] +#[inline] +unsafe fn atomic_compare_exchange_weak_pwr8( + dst: *mut u128, + old: u128, + new: u128, + success: Ordering, + failure: Ordering, +) -> (u128, bool) { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_pwr8!(); + let old = U128 { whole: old }; + let new = U128 { whole: new }; + let (mut prev_hi, mut prev_lo); + let mut r; + + // SAFETY: the caller must uphold the safety contract. + // + // Refs: Section 4.6.2.2 "128-bit Load And Reserve and Store Conditional Instructions" of Power ISA 3.1C Book II + unsafe { + macro_rules! cmpxchg_weak { + ($acquire_always:tt, $acquire_success:tt, $release:tt) => { + asm!( + start_pwr8!(), + $release, // fence + "lqarx %r8, 0, {dst}", // atomic { RESERVE = (dst, 16); r8:r9 = *dst } + "xor {tmp_lo}, %r9, {old_lo}", // tmp_lo = r9 ^ old_lo + "xor {tmp_hi}, %r8, {old_hi}", // tmp_hi = r8 ^ old_hi + "or. {tmp_lo}, {tmp_lo}, {tmp_hi}", // tmp_lo |= tmp_hi; if tmp_lo == 0 { cr0.EQ = 1 } else { cr0.EQ = 0 } + "bne %cr0, 3f", // if cr0.EQ == 0 { jump 'cmp-fail } + "stqcx. %r6, 0, {dst}", // atomic { if RESERVE == (dst, 16) { *dst = r6:r7; cr0.EQ = 1 } else { cr0.EQ = 0 }; RESERVE = None } + $acquire_success, // fence + "3:", // 'cmp-fail: + $acquire_always, // fence + "mfcr {tmp_lo}", // tmp_lo = zero_extend(cr) + end_pwr8!(), + dst = in(reg_nonzero) ptr_reg!(dst), + old_hi = in(reg) old.pair.hi, + old_lo = in(reg) old.pair.lo, + tmp_hi = out(reg) _, + tmp_lo = out(reg) r, + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater. + in("r6") new.pair.hi, + in("r7") new.pair.lo, + out("r8") prev_hi, + out("r9") prev_lo, + out("cr0") _, + options(nostack, preserves_flags), + ) + }; + } + atomic_cas!(cmpxchg_weak, success, failure); + // if compare or store failed EQ bit is cleared, if store succeeds EQ bit is set. + (U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole, test_cr0_eq(r)) + } +} + +// Do not use atomic_rmw_ll_sc_3 because it needs extra MR to implement swap. +#[inline] +unsafe fn atomic_swap_pwr8(dst: *mut u128, val: u128, order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_pwr8!(); + let val = U128 { whole: val }; + let (mut prev_hi, mut prev_lo); + + // SAFETY: the caller must uphold the safety contract. + unsafe { + macro_rules! swap { + ($acquire:tt, $release:tt) => { + asm!( + start_pwr8!(), + $release, // fence + "2:", // 'retry: + "lqarx %r6, 0, {dst}", // atomic { RESERVE = (dst, 16); r6:r7 = *dst } + "stqcx. %r8, 0, {dst}", // atomic { if RESERVE == (dst, 16) { *dst = r8:r9; cr0.EQ = 1 } else { cr0.EQ = 0 }; RESERVE = None } + "bne %cr0, 2b", // if cr0.EQ == 0 { jump 'retry } + $acquire, // fence + end_pwr8!(), + dst = in(reg_nonzero) ptr_reg!(dst), + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater. + out("r6") prev_hi, + out("r7") prev_lo, + in("r8") val.pair.hi, + in("r9") val.pair.lo, + out("cr0") _, + options(nostack, preserves_flags), + ) + }; + } + atomic_rmw!(swap, order); + U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole + } +} + +/// Atomic RMW by LL/SC loop (3 arguments) +/// `unsafe fn(dst: *mut u128, val: u128, order: Ordering) -> u128;` +/// +/// $op can use the following registers: +/// - val_hi/val_lo pair: val argument (read-only for `$op`) +/// - r6/r7 pair: previous value loaded by ll (read-only for `$op`) +/// - r8/r9 pair: new value that will be stored by sc +macro_rules! atomic_rmw_ll_sc_3 { + ($name:ident, [$($reg:tt)*], $($op:tt)*) => { + #[inline] + unsafe fn $name(dst: *mut u128, val: u128, order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_pwr8!(); + let val = U128 { whole: val }; + let (mut prev_hi, mut prev_lo); + + // SAFETY: the caller must uphold the safety contract. + unsafe { + macro_rules! op { + ($acquire:tt, $release:tt) => { + asm!( + start_pwr8!(), + $release, // fence + "2:", // 'retry: + "lqarx %r6, 0, {dst}", // atomic { RESERVE = (dst, 16); r6:r7 = *dst } + $($op)* + "stqcx. %r8, 0, {dst}", // atomic { if RESERVE == (dst, 16) { *dst = r8:r9; cr0.EQ = 1 } else { cr0.EQ = 0 }; RESERVE = None } + "bne %cr0, 2b", // if cr0.EQ == 0 { jump 'retry } + $acquire, // fence + end_pwr8!(), + dst = in(reg_nonzero) ptr_reg!(dst), + val_hi = in(reg) val.pair.hi, + val_lo = in(reg) val.pair.lo, + $($reg)* + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater. + out("r6") prev_hi, + out("r7") prev_lo, + out("r8") _, // new (hi) + out("r9") _, // new (lo) + out("cr0") _, + options(nostack, preserves_flags), + ) + }; + } + atomic_rmw!(op, order); + U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole + } + } + }; +} +/// Atomic RMW by LL/SC loop (2 arguments) +/// `unsafe fn(dst: *mut u128, order: Ordering) -> u128;` +/// +/// $op can use the following registers: +/// - r6/r7 pair: previous value loaded by ll (read-only for `$op`) +/// - r8/r9 pair: new value that will be stored by sc +macro_rules! atomic_rmw_ll_sc_2 { + ($name:ident, [$($reg:tt)*], $($op:tt)*) => { + #[inline] + unsafe fn $name(dst: *mut u128, order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_pwr8!(); + let (mut prev_hi, mut prev_lo); + + // SAFETY: the caller must uphold the safety contract. + unsafe { + macro_rules! op { + ($acquire:tt, $release:tt) => { + asm!( + start_pwr8!(), + $release, // fence + "2:", // 'retry: + "lqarx %r6, 0, {dst}", // atomic { RESERVE = (dst, 16); r6:r7 = *dst } + $($op)* + "stqcx. %r8, 0, {dst}", // atomic { if RESERVE == (dst, 16) { *dst = r8:r9; cr0.EQ = 1 } else { cr0.EQ = 0 }; RESERVE = None } + "bne %cr0, 2b", // if cr0.EQ == 0 { jump 'retry } + $acquire, // fence + end_pwr8!(), + dst = in(reg_nonzero) ptr_reg!(dst), + $($reg)* + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater. + out("r6") prev_hi, + out("r7") prev_lo, + out("r8") _, // new (hi) + out("r9") _, // new (lo) + out("cr0") _, + options(nostack, preserves_flags), + ) + }; + } + atomic_rmw!(op, order); + U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole + } + } + }; +} + +atomic_rmw_ll_sc_3! { + atomic_add_pwr8, [out("xer") _,], + "addc %r9, {val_lo}, %r7", // r9 = val_lo + r7; xer.CA = carry + "adde %r8, {val_hi}, %r6", // r8 = val_hi + r6 + xer.CA +} +atomic_rmw_ll_sc_3! { + atomic_sub_pwr8, [out("xer") _,], + "subc %r9, %r7, {val_lo}", // r9 = val_lo - r7; xer.CA = borrow + "subfe %r8, {val_hi}, %r6", // r8 = val_hi - r6 - xer.CA +} +atomic_rmw_ll_sc_3! { + atomic_and_pwr8, [], + "and %r9, {val_lo}, %r7", // r9 = val_lo & r7 + "and %r8, {val_hi}, %r6", // r8 = val_hi & r6 +} +atomic_rmw_ll_sc_3! { + atomic_nand_pwr8, [], + "nand %r9, {val_lo}, %r7", // r9 = !(val_lo & r7) + "nand %r8, {val_hi}, %r6", // r8 = !(val_hi & r6) +} +atomic_rmw_ll_sc_3! { + atomic_or_pwr8, [], + "or %r9, {val_lo}, %r7", // r9 = val_lo | r7 + "or %r8, {val_hi}, %r6", // r8 = val_hi | r6 +} +atomic_rmw_ll_sc_3! { + atomic_xor_pwr8, [], + "xor %r9, {val_lo}, %r7", // r9 = val_lo ^ r7 + "xor %r8, {val_hi}, %r6", // r8 = val_hi ^ r6 +} +atomic_rmw_ll_sc_3! { + atomic_max_pwr8, [out("cr1") _,], + "cmpld %r7, {val_lo}", // if r7(u) < val_lo(u) { cr0 = { LT: 1, ..0 } } else if r7(u) > val_lo(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } } + "iselgt %r9, %r7, {val_lo}", // if cr0.GT == 1 { r9 = r7 } else { r9 = val_lo } + "cmpd %cr1, %r6, {val_hi}", // if r6(i) < val_hi(i) { cr1 = { LT: 1, ..0 } } else if r6(i) > val_hi(i) { cr1 = { GT: 1, ..0 } } else { cr1 = { EQ: 1, ..0 } } + "isel %r8, %r7, {val_lo}, 5", // if cr1.GT == 1 { r8 = r7 } else { r8 = val_lo } + "cmpld %r6, {val_hi}", // if r6(u) < val_hi(u) { cr0 = { LT: 1, ..0 } } else if r6(u) > val_hi(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } } + "iseleq %r9, %r9, %r8", // if cr0.EQ == 1 { r9 = r9 } else { r9 = r8 } + "isel %r8, %r6, {val_hi}, 5", // if cr1.GT == 1 { r8 = r6 } else { r8 = val_hi } +} +atomic_rmw_ll_sc_3! { + atomic_umax_pwr8, [], + "cmpld %r7, {val_lo}", // if r7(u) < val_lo(u) { cr0 = { LT: 1, ..0 } } else if r7(u) > val_lo(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } } + "iselgt %r9, %r7, {val_lo}", // if cr0.GT == 1 { r9 = r7 } else { r9 = val_lo } + "cmpld %r6, {val_hi}", // if r6(u) < val_hi(u) { cr0 = { LT: 1, ..0 } } else if r6(u) > val_hi(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } } + "iselgt %r8, %r7, {val_lo}", // if cr0.GT == 1 { r8 = r7 } else { r8 = val_lo } + "iseleq %r9, %r9, %r8", // if cr0.EQ == 1 { r9 = r9 } else { r9 = r8 } + "iselgt %r8, %r6, {val_hi}", // if cr0.GT == 1 { r8 = r6 } else { r8 = val_hi } +} +atomic_rmw_ll_sc_3! { + atomic_min_pwr8, [out("cr1") _,], + "cmpld %r7, {val_lo}", // if r7(u) < val_lo(u) { cr0 = { LT: 1, ..0 } } else if r7(u) > val_lo(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } } + "isellt %r9, %r7, {val_lo}", // if cr0.LT == 1 { r9 = r7 } else { r9 = val_lo } + "cmpd %cr1, %r6, {val_hi}", // if r6(i) < val_hi(i) { cr1 = { LT: 1, ..0 } } else if r6(i) > val_hi(i) { cr1 = { GT: 1, ..0 } } else { cr1 = { EQ: 1, ..0 } } + "isel %r8, %r7, {val_lo}, 4", // if cr1.LT == 1 { r8 = r7 } else { r8 = val_lo } + "cmpld %r6, {val_hi}", // if r6(u) < val_hi(u) { cr0 = { LT: 1, ..0 } } else if r6(u) > val_hi(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } } + "iseleq %r9, %r9, %r8", // if cr0.EQ == 1 { r9 = r9 } else { r9 = r8 } + "isel %r8, %r6, {val_hi}, 4", // if cr1.LT == 1 { r8 = r6 } else { r8 = val_hi } +} +atomic_rmw_ll_sc_3! { + atomic_umin_pwr8, [], + "cmpld %r7, {val_lo}", // if r7(u) < val_lo(u) { cr0 = { LT: 1, ..0 } } else if r7(u) > val_lo(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } } + "isellt %r9, %r7, {val_lo}", // if cr0.LT == 1 { r9 = r7 } else { r9 = val_lo } + "cmpld %r6, {val_hi}", // if r6(u) < val_hi(u) { cr0 = { LT: 1, ..0 } } else if r6(u) > val_hi(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } } + "isellt %r8, %r7, {val_lo}", // if cr0.LT == 1 { r8 = r7 } else { r8 = val_lo } + "iseleq %r9, %r9, %r8", // if cr0.EQ == 1 { r9 = r9 } else { r9 = r8 } + "isellt %r8, %r6, {val_hi}", // if cr0.LT == 1 { r8 = r6 } else { r8 = val_hi } +} + +#[inline] +unsafe fn atomic_not_pwr8(dst: *mut u128, order: Ordering) -> u128 { + // SAFETY: the caller must uphold the safety contract. + unsafe { atomic_xor_pwr8(dst, !0, order) } +} + +#[cfg(not(portable_atomic_pre_llvm_16))] +atomic_rmw_ll_sc_2! { + atomic_neg_pwr8, [out("xer") _,], + "subfic %r9, %r7, 0", // r9 = 0 - r7; xer.CA = borrow + "subfze %r8, %r6", // r8 = 0 - r6 - xer.CA +} +// LLVM 15 miscompiles subfic. +#[cfg(portable_atomic_pre_llvm_16)] +atomic_rmw_ll_sc_2! { + atomic_neg_pwr8, [zero = in(reg) 0_u64, out("xer") _,], + "subc %r9, {zero}, %r7", // r9 = 0 - r7; xer.CA = borrow + "subfze %r8, %r6", // r8 = 0 - r6 - xer.CA +} + +macro_rules! select_atomic_rmw { + ( + unsafe fn $name:ident($($arg:tt)*) $(-> $ret_ty:ty)?; + pwr8 = $pwr8_fn:ident; + non_seqcst_fallback = $non_seqcst_fallback_fn:ident; + seqcst_fallback = $seqcst_fallback_fn:ident; + ) => { + // If quadword-atomics is available at compile-time, we can always use pwr8_fn. + #[cfg(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + ))] + use self::$pwr8_fn as $name; + // Otherwise, we need to do run-time detection and can use pwr8_fn only if quadword-atomics is available. + #[cfg(not(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + )))] + #[inline] + unsafe fn $name($($arg)*, order: Ordering) $(-> $ret_ty)? { + fn_alias! { + // inline(never) is just a hint and also not strictly necessary + // because we use ifunc helper macro, but used for clarity. + #[inline(never)] + unsafe fn($($arg)*) $(-> $ret_ty)?; + pwr8_relaxed_fn = $pwr8_fn(Ordering::Relaxed); + pwr8_acquire_fn = $pwr8_fn(Ordering::Acquire); + pwr8_release_fn = $pwr8_fn(Ordering::Release); + pwr8_acqrel_fn = $pwr8_fn(Ordering::AcqRel); + pwr8_seqcst_fn = $pwr8_fn(Ordering::SeqCst); + } + // SAFETY: the caller must uphold the safety contract. + // we only calls pwr8_fn if quadword-atomics is available. + unsafe { + match order { + Ordering::Relaxed => { + ifunc!(unsafe fn($($arg)*) $(-> $ret_ty)? { + if detect::detect().quadword_atomics() { + pwr8_relaxed_fn + } else { + fallback::$non_seqcst_fallback_fn + } + }) + } + Ordering::Acquire => { + ifunc!(unsafe fn($($arg)*) $(-> $ret_ty)? { + if detect::detect().quadword_atomics() { + pwr8_acquire_fn + } else { + fallback::$non_seqcst_fallback_fn + } + }) + } + Ordering::Release => { + ifunc!(unsafe fn($($arg)*) $(-> $ret_ty)? { + if detect::detect().quadword_atomics() { + pwr8_release_fn + } else { + fallback::$non_seqcst_fallback_fn + } + }) + } + Ordering::AcqRel => { + ifunc!(unsafe fn($($arg)*) $(-> $ret_ty)? { + if detect::detect().quadword_atomics() { + pwr8_acqrel_fn + } else { + fallback::$non_seqcst_fallback_fn + } + }) + } + Ordering::SeqCst => { + ifunc!(unsafe fn($($arg)*) $(-> $ret_ty)? { + if detect::detect().quadword_atomics() { + pwr8_seqcst_fn + } else { + fallback::$seqcst_fallback_fn + } + }) + } + _ => unreachable!(), + } + } + } + }; +} + +select_atomic_rmw! { + unsafe fn atomic_swap(dst: *mut u128, val: u128) -> u128; + pwr8 = atomic_swap_pwr8; + non_seqcst_fallback = atomic_swap_non_seqcst; + seqcst_fallback = atomic_swap_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_add(dst: *mut u128, val: u128) -> u128; + pwr8 = atomic_add_pwr8; + non_seqcst_fallback = atomic_add_non_seqcst; + seqcst_fallback = atomic_add_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_sub(dst: *mut u128, val: u128) -> u128; + pwr8 = atomic_sub_pwr8; + non_seqcst_fallback = atomic_sub_non_seqcst; + seqcst_fallback = atomic_sub_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_and(dst: *mut u128, val: u128) -> u128; + pwr8 = atomic_and_pwr8; + non_seqcst_fallback = atomic_and_non_seqcst; + seqcst_fallback = atomic_and_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_nand(dst: *mut u128, val: u128) -> u128; + pwr8 = atomic_nand_pwr8; + non_seqcst_fallback = atomic_nand_non_seqcst; + seqcst_fallback = atomic_nand_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_or(dst: *mut u128, val: u128) -> u128; + pwr8 = atomic_or_pwr8; + non_seqcst_fallback = atomic_or_non_seqcst; + seqcst_fallback = atomic_or_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_xor(dst: *mut u128, val: u128) -> u128; + pwr8 = atomic_xor_pwr8; + non_seqcst_fallback = atomic_xor_non_seqcst; + seqcst_fallback = atomic_xor_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_max(dst: *mut u128, val: u128) -> u128; + pwr8 = atomic_max_pwr8; + non_seqcst_fallback = atomic_max_non_seqcst; + seqcst_fallback = atomic_max_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_umax(dst: *mut u128, val: u128) -> u128; + pwr8 = atomic_umax_pwr8; + non_seqcst_fallback = atomic_umax_non_seqcst; + seqcst_fallback = atomic_umax_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_min(dst: *mut u128, val: u128) -> u128; + pwr8 = atomic_min_pwr8; + non_seqcst_fallback = atomic_min_non_seqcst; + seqcst_fallback = atomic_min_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_umin(dst: *mut u128, val: u128) -> u128; + pwr8 = atomic_umin_pwr8; + non_seqcst_fallback = atomic_umin_non_seqcst; + seqcst_fallback = atomic_umin_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_not(dst: *mut u128) -> u128; + pwr8 = atomic_not_pwr8; + non_seqcst_fallback = atomic_not_non_seqcst; + seqcst_fallback = atomic_not_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_neg(dst: *mut u128) -> u128; + pwr8 = atomic_neg_pwr8; + non_seqcst_fallback = atomic_neg_non_seqcst; + seqcst_fallback = atomic_neg_seqcst; +} + +#[inline] +fn is_lock_free() -> bool { + #[cfg(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + ))] + { + // lqarx and stqcx. instructions are statically available. + true + } + #[cfg(not(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + )))] + { + detect::detect().quadword_atomics() + } +} +const IS_ALWAYS_LOCK_FREE: bool = cfg!(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", +)); + +atomic128!(AtomicI128, i128, atomic_max, atomic_min); +atomic128!(AtomicU128, u128, atomic_umax, atomic_umin); + +#[cfg(not(valgrind))] // TODO(powerpc64): Hang (as of Valgrind 3.26) +#[cfg(test)] +mod tests { + use super::*; + + test_atomic_int!(i128); + test_atomic_int!(u128); + + // load/store/swap implementation is not affected by signedness, so it is + // enough to test only unsigned types. + stress_test!(u128); +} diff --git a/vendor/portable-atomic/src/imp/atomic128/riscv64.rs b/vendor/portable-atomic/src/imp/atomic128/riscv64.rs new file mode 100644 index 0000000..e43d061 --- /dev/null +++ b/vendor/portable-atomic/src/imp/atomic128/riscv64.rs @@ -0,0 +1,624 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +128-bit atomic implementation on riscv64. + +This architecture provides the following 128-bit atomic instructions: + +- amocas.q: CAS (Zacas extension) + +See "Atomic operation overview by architecture" in atomic-maybe-uninit for a more comprehensive and +detailed description of the atomic and synchronize instructions in this architecture: +https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#risc-v + +Note: On Miri and ThreadSanitizer which do not support inline assembly, we don't use +this module and use fallback implementation instead. + +Refs: +- RISC-V Instruction Set Manual + "Zacas" Extension for Atomic Compare-and-Swap (CAS) Instructions + https://docs.riscv.org/reference/isa/v20260120/unpriv/zacas.html +- RISC-V Atomics ABI Specification + https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/draft-20250812-301374e92976e298e676e7129a6212926b2299ce/riscv-atomic.adoc + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +include!("macros.rs"); + +#[cfg(not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")))] +#[path = "../fallback/outline_atomics.rs"] +mod fallback; + +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(any(test, not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas"))))] +#[cfg(any(target_os = "linux", target_os = "android"))] +#[path = "../detect/riscv_linux.rs"] +mod detect; + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; +use core::sync::atomic::Ordering; + +#[cfg(portable_atomic_no_strict_provenance)] +use crate::utils::ptr::PtrExt as _; +use crate::utils::{Pair, U128}; + +macro_rules! debug_assert_zacas { + () => { + #[cfg(not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")))] + { + debug_assert!(detect::detect().zacas()); + } + }; +} + +// `.option arch, +zacas` directive requires LLVM 20, so we use .4byte directive for old LLVM. +// Note that `.insn ` directive requires LLVM 19. +// https://github.com/llvm/llvm-project/commit/2a086dce691e3cc34a2fc27f4fb255bb2cbbfac9 +// https://github.com/riscv-non-isa/riscv-asm-manual/blob/v0.0.1/src/asm-manual.adoc#arch +#[cfg(not(portable_atomic_pre_llvm_20))] +macro_rules! start_zacas { + () => { + ".option push\n.option arch, +zacas" + }; +} +#[cfg(not(portable_atomic_pre_llvm_20))] +macro_rules! end_zacas { + () => { + ".option pop" + }; +} + +#[cfg(not(portable_atomic_pre_llvm_20))] +macro_rules! atomic_rmw_amocas_order { + ($op:ident, $order:ident) => { + atomic_rmw_amocas_order!($op, $order, failure = $order) + }; + ($op:ident, $order:ident, failure = $failure:ident) => { + match $order { + Ordering::Relaxed => $op!("", ""), + Ordering::Acquire => $op!("", ".aq"), + Ordering::Release => $op!("", ".rl"), + Ordering::AcqRel => $op!("", ".aqrl"), + Ordering::SeqCst if $failure == Ordering::SeqCst => $op!("fence rw,rw", ".aqrl"), + Ordering::SeqCst => $op!("", ".aqrl"), + _ => unreachable!(), + } + }; +} +#[cfg(portable_atomic_pre_llvm_20)] +macro_rules! atomic_rmw_amocas_order_insn { + ($op:ident, $order:ident) => { + atomic_rmw_amocas_order_insn!($op, $order, failure = $order) + }; + ($op:ident, $order:ident, failure = $failure:ident) => { + match $order { + Ordering::Relaxed => $op!("", "8"), + Ordering::Acquire => $op!("", "c"), + Ordering::Release => $op!("", "a"), + Ordering::AcqRel => $op!("", "e"), + Ordering::SeqCst if $failure == Ordering::SeqCst => $op!("fence rw,rw", "e"), + Ordering::SeqCst => $op!("", "e"), + _ => unreachable!(), + } + }; +} + +// If zacas is available at compile-time, we can always use zacas_fn. +#[cfg(any(target_feature = "zacas", portable_atomic_target_feature = "zacas"))] +use self::atomic_load_zacas as atomic_load; +// Otherwise, we need to do run-time detection and can use zacas_fn only if zacas is available. +#[cfg(not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")))] +#[inline] +unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 { + fn_alias! { + // inline(never) is just a hint and also not strictly necessary + // because we use ifunc helper macro, but used for clarity. + #[inline(never)] + unsafe fn(src: *mut u128) -> u128; + atomic_load_zacas_relaxed = atomic_load_zacas(Ordering::Relaxed); + atomic_load_zacas_acquire = atomic_load_zacas(Ordering::Acquire); + atomic_load_zacas_seqcst = atomic_load_zacas(Ordering::SeqCst); + } + // SAFETY: the caller must uphold the safety contract. + // we only calls atomic_load_zacas if zacas is available. + unsafe { + match order { + Ordering::Relaxed => { + ifunc!(unsafe fn(src: *mut u128) -> u128 { + if detect::detect().zacas() { + atomic_load_zacas_relaxed + } else { + fallback::atomic_load_non_seqcst + } + }) + } + Ordering::Acquire => { + ifunc!(unsafe fn(src: *mut u128) -> u128 { + if detect::detect().zacas() { + atomic_load_zacas_acquire + } else { + fallback::atomic_load_non_seqcst + } + }) + } + Ordering::SeqCst => { + ifunc!(unsafe fn(src: *mut u128) -> u128 { + if detect::detect().zacas() { + atomic_load_zacas_seqcst + } else { + fallback::atomic_load_seqcst + } + }) + } + _ => unreachable!(), + } + } +} +#[inline] +unsafe fn atomic_load_zacas(src: *mut u128, order: Ordering) -> u128 { + debug_assert!(src.addr() % 16 == 0); + debug_assert_zacas!(); + let (out_lo, out_hi); + + // SAFETY: the caller must uphold the safety contract. + unsafe { + #[cfg(not(portable_atomic_pre_llvm_20))] + macro_rules! load { + ($fence:tt, $asm_order:tt) => { + asm!( + start_zacas!(), + $fence, // fence + concat!("amocas.q", $asm_order, " a2, a2, 0({src})"), // atomic { if *dst == a2:a3 { *dst = a2:a3 } else { a2:a3 = *dst } } + end_zacas!(), + src = in(reg) ptr_reg!(src), + inout("a2") 0_u64 => out_lo, + inout("a3") 0_u64 => out_hi, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(not(portable_atomic_pre_llvm_20))] + atomic_rmw_amocas_order!(load, order); + #[cfg(portable_atomic_pre_llvm_20)] + macro_rules! load { + ($fence:tt, $insn_order:tt) => { + asm!( + $fence, // fence + // amocas.q{,.aq,.rl,.aqrl} a2, a2, (a0) // atomic { if *a0 == a2:a3 { *a0 = a2:a3 } else { a2:a3 = *a0 } } + concat!(".4byte 0x2", $insn_order, "c5462f"), + in("a0") ptr_reg!(src), + inout("a2") 0_u64 => out_lo, + inout("a3") 0_u64 => out_hi, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(portable_atomic_pre_llvm_20)] + atomic_rmw_amocas_order_insn!(load, order); + U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole + } +} + +#[inline] +unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) { + // SAFETY: the caller must uphold the safety contract. + unsafe { + atomic_swap(dst, val, order); + } +} + +#[inline] +unsafe fn atomic_compare_exchange( + dst: *mut u128, + old: u128, + new: u128, + success: Ordering, + failure: Ordering, +) -> Result { + #[cfg(any(target_feature = "zacas", portable_atomic_target_feature = "zacas"))] + // SAFETY: the caller must uphold the safety contract. + // cfg guarantees that zacas instructions are available at compile-time. + let (prev, ok) = unsafe { atomic_compare_exchange_zacas(dst, old, new, success, failure) }; + #[cfg(not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")))] + let (prev, ok) = { + fn_alias! { + // inline(never) is just a hint and also not strictly necessary + // because we use ifunc helper macro, but used for clarity. + #[inline(never)] + unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool); + zacas_relaxed_fn = atomic_compare_exchange_zacas(Ordering::Relaxed, Ordering::Relaxed); + zacas_acquire_fn = atomic_compare_exchange_zacas(Ordering::Acquire, Ordering::Acquire); + zacas_release_fn = atomic_compare_exchange_zacas(Ordering::Release, Ordering::Relaxed); + zacas_acqrel_fn = atomic_compare_exchange_zacas(Ordering::AcqRel, Ordering::Acquire); + zacas_seqcst_fn = atomic_compare_exchange_zacas(Ordering::SeqCst, Ordering::SeqCst); + } + let order = crate::utils::upgrade_success_ordering(success, failure); + // SAFETY: the caller must uphold the safety contract. + // we only calls atomic_compare_exchange_zacas if zacas is available. + unsafe { + match order { + Ordering::Relaxed => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) { + if detect::detect().zacas() { + zacas_relaxed_fn + } else { + fallback::atomic_compare_exchange_non_seqcst + } + }) + } + Ordering::Acquire => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) { + if detect::detect().zacas() { + zacas_acquire_fn + } else { + fallback::atomic_compare_exchange_non_seqcst + } + }) + } + Ordering::Release => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) { + if detect::detect().zacas() { + zacas_release_fn + } else { + fallback::atomic_compare_exchange_non_seqcst + } + }) + } + Ordering::AcqRel => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) { + if detect::detect().zacas() { + zacas_acqrel_fn + } else { + fallback::atomic_compare_exchange_non_seqcst + } + }) + } + Ordering::SeqCst => { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) { + if detect::detect().zacas() { + zacas_seqcst_fn + } else { + fallback::atomic_compare_exchange_seqcst + } + }) + } + _ => unreachable!(), + } + } + }; + if ok { Ok(prev) } else { Err(prev) } +} +#[inline] +unsafe fn atomic_compare_exchange_zacas( + dst: *mut u128, + old: u128, + new: u128, + success: Ordering, + failure: Ordering, +) -> (u128, bool) { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_zacas!(); + let order = crate::utils::upgrade_success_ordering(success, failure); + let old = U128 { whole: old }; + let new = U128 { whole: new }; + let (prev_lo, prev_hi); + + // SAFETY: the caller must uphold the safety contract. + unsafe { + #[cfg(not(portable_atomic_pre_llvm_20))] + macro_rules! cmpxchg { + ($fence:tt, $asm_order:tt) => { + asm!( + start_zacas!(), + $fence, // fence + concat!("amocas.q", $asm_order, " a4, a2, 0({dst})"), // atomic { if *dst == a4:a5 { *dst = a2:a3 } else { a4:a5 = *dst } } + end_zacas!(), + dst = in(reg) ptr_reg!(dst), + // must be allocated to even/odd register pair + inout("a4") old.pair.lo => prev_lo, + inout("a5") old.pair.hi => prev_hi, + // must be allocated to even/odd register pair + in("a2") new.pair.lo, + in("a3") new.pair.hi, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(not(portable_atomic_pre_llvm_20))] + atomic_rmw_amocas_order!(cmpxchg, order, failure = failure); + #[cfg(portable_atomic_pre_llvm_20)] + macro_rules! cmpxchg { + ($fence:tt, $insn_order:tt) => { + asm!( + $fence, // fence + // amocas.q{,.aq,.rl,.aqrl} a4, a2, (a0) // atomic { if *a0 == a4:a5 { *a0 = a2:a3 } else { a4:a5 = *a0 } } + concat!(".4byte 0x2", $insn_order, "c5472f"), + in("a0") ptr_reg!(dst), + // must be allocated to even/odd register pair + inout("a4") old.pair.lo => prev_lo, + inout("a5") old.pair.hi => prev_hi, + // must be allocated to even/odd register pair + in("a2") new.pair.lo, + in("a3") new.pair.hi, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(portable_atomic_pre_llvm_20)] + atomic_rmw_amocas_order_insn!(cmpxchg, order, failure = failure); + let prev = U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole; + (prev, prev == old.whole) + } +} + +// amocas is always strong. +use self::atomic_compare_exchange as atomic_compare_exchange_weak; + +// 128-bit atomic load by two 64-bit atomic loads. +#[inline] +unsafe fn byte_wise_atomic_load(src: *const u128) -> u128 { + let (out_lo, out_hi); + + // SAFETY: the caller must uphold the safety contract. + unsafe { + asm!( + "ld {out_lo}, ({src})", // atomic { out_lo = *src } + "ld {out_hi}, 8({src})", // atomic { out_hi = *src.byte_add(8) } + src = in(reg) ptr_reg!(src), + out_lo = out(reg) out_lo, + out_hi = out(reg) out_hi, + options(pure, nostack, preserves_flags, readonly), + ); + U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole + } +} + +macro_rules! select_atomic_rmw { + ( + unsafe fn $name:ident(dst: *mut u128 $(, $($arg:tt)*)?) $(-> $ret_ty:ty)? { + |$zacas_fn_binding:ident| $($zacas_fn_body:tt)* + } + zacas = $zacas_fn:ident; + non_seqcst_fallback = $non_seqcst_fallback_fn:ident; + seqcst_fallback = $seqcst_fallback_fn:ident; + ) => { + #[inline] + unsafe fn $zacas_fn(dst: *mut u128 $(, $($arg)*)?, order: Ordering) $(-> $ret_ty)? { + // SAFETY: the caller must uphold the safety contract. + unsafe { + // This is not single-copy atomic reads, but this is ok because subsequent + // CAS will check for consistency. + // + // Note that the C++20 memory model does not allow mixed-sized atomic access, + // so we must use inline assembly to implement byte_wise_atomic_load. + // (i.e., byte-wise atomic based on the standard library's atomic types + // cannot be used here). + let mut prev = byte_wise_atomic_load(dst); + loop { + let next = { + let $zacas_fn_binding = prev; + $($zacas_fn_body)* + }; + match atomic_compare_exchange_weak(dst, prev, next, order, Ordering::Relaxed) { + Ok(x) => return x, + Err(x) => prev = x, + } + } + } + } + // If zacas is available at compile-time, we can always use zacas_fn. + #[cfg(any(target_feature = "zacas", portable_atomic_target_feature = "zacas"))] + use self::$zacas_fn as $name; + // Otherwise, we need to do run-time detection and can use zacas_fn only if zacas is available. + #[cfg(not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")))] + #[inline] + unsafe fn $name(dst: *mut u128 $(, $($arg)*)?, order: Ordering) $(-> $ret_ty)? { + fn_alias! { + // inline(never) is just a hint and also not strictly necessary + // because we use ifunc helper macro, but used for clarity. + #[inline(never)] + unsafe fn(dst: *mut u128 $(, $($arg)*)?) $(-> $ret_ty)?; + zacas_relaxed_fn = $zacas_fn(Ordering::Relaxed); + zacas_acquire_fn = $zacas_fn(Ordering::Acquire); + zacas_release_fn = $zacas_fn(Ordering::Release); + zacas_acqrel_fn = $zacas_fn(Ordering::AcqRel); + zacas_seqcst_fn = $zacas_fn(Ordering::SeqCst); + } + // SAFETY: the caller must uphold the safety contract. + // we only calls zacas_fn if zacas is available. + unsafe { + match order { + Ordering::Relaxed => { + ifunc!(unsafe fn(dst: *mut u128 $(, $($arg)*)?) $(-> $ret_ty)? { + if detect::detect().zacas() { + zacas_relaxed_fn + } else { + fallback::$non_seqcst_fallback_fn + } + }) + } + Ordering::Acquire => { + ifunc!(unsafe fn(dst: *mut u128 $(, $($arg)*)?) $(-> $ret_ty)? { + if detect::detect().zacas() { + zacas_acquire_fn + } else { + fallback::$non_seqcst_fallback_fn + } + }) + } + Ordering::Release => { + ifunc!(unsafe fn(dst: *mut u128 $(, $($arg)*)?) $(-> $ret_ty)? { + if detect::detect().zacas() { + zacas_release_fn + } else { + fallback::$non_seqcst_fallback_fn + } + }) + } + Ordering::AcqRel => { + ifunc!(unsafe fn(dst: *mut u128 $(, $($arg)*)?) $(-> $ret_ty)? { + if detect::detect().zacas() { + zacas_acqrel_fn + } else { + fallback::$non_seqcst_fallback_fn + } + }) + } + Ordering::SeqCst => { + ifunc!(unsafe fn(dst: *mut u128 $(, $($arg)*)?) $(-> $ret_ty)? { + if detect::detect().zacas() { + zacas_seqcst_fn + } else { + fallback::$seqcst_fallback_fn + } + }) + } + _ => unreachable!(), + } + } + } + }; +} + +select_atomic_rmw! { + unsafe fn atomic_swap(dst: *mut u128, val: u128) -> u128 { + |_x| val + } + zacas = atomic_swap_zacas; + non_seqcst_fallback = atomic_swap_non_seqcst; + seqcst_fallback = atomic_swap_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_add(dst: *mut u128, val: u128) -> u128 { + |x| x.wrapping_add(val) + } + zacas = atomic_add_zacas; + non_seqcst_fallback = atomic_add_non_seqcst; + seqcst_fallback = atomic_add_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_sub(dst: *mut u128, val: u128) -> u128 { + |x| x.wrapping_sub(val) + } + zacas = atomic_sub_zacas; + non_seqcst_fallback = atomic_sub_non_seqcst; + seqcst_fallback = atomic_sub_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_and(dst: *mut u128, val: u128) -> u128 { + |x| x & val + } + zacas = atomic_and_zacas; + non_seqcst_fallback = atomic_and_non_seqcst; + seqcst_fallback = atomic_and_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_nand(dst: *mut u128, val: u128) -> u128 { + |x| !(x & val) + } + zacas = atomic_nand_zacas; + non_seqcst_fallback = atomic_nand_non_seqcst; + seqcst_fallback = atomic_nand_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_or(dst: *mut u128, val: u128) -> u128 { + |x| x | val + } + zacas = atomic_or_zacas; + non_seqcst_fallback = atomic_or_non_seqcst; + seqcst_fallback = atomic_or_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_xor(dst: *mut u128, val: u128) -> u128 { + |x| x ^ val + } + zacas = atomic_xor_zacas; + non_seqcst_fallback = atomic_xor_non_seqcst; + seqcst_fallback = atomic_xor_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_max(dst: *mut u128, val: u128) -> u128 { + |x| { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + { core::cmp::max(x as i128, val as i128) as u128 } + } + } + zacas = atomic_max_zacas; + non_seqcst_fallback = atomic_max_non_seqcst; + seqcst_fallback = atomic_max_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_umax(dst: *mut u128, val: u128) -> u128 { + |x| core::cmp::max(x, val) + } + zacas = atomic_umax_zacas; + non_seqcst_fallback = atomic_umax_non_seqcst; + seqcst_fallback = atomic_umax_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_min(dst: *mut u128, val: u128) -> u128 { + |x| { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + { core::cmp::min(x as i128, val as i128) as u128 } + } + } + zacas = atomic_min_zacas; + non_seqcst_fallback = atomic_min_non_seqcst; + seqcst_fallback = atomic_min_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_umin(dst: *mut u128, val: u128) -> u128 { + |x| core::cmp::min(x, val) + } + zacas = atomic_umin_zacas; + non_seqcst_fallback = atomic_umin_non_seqcst; + seqcst_fallback = atomic_umin_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_not(dst: *mut u128) -> u128 { + |x| !x + } + zacas = atomic_not_zacas; + non_seqcst_fallback = atomic_not_non_seqcst; + seqcst_fallback = atomic_not_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_neg(dst: *mut u128) -> u128 { + |x| x.wrapping_neg() + } + zacas = atomic_neg_zacas; + non_seqcst_fallback = atomic_neg_non_seqcst; + seqcst_fallback = atomic_neg_seqcst; +} + +#[inline] +fn is_lock_free() -> bool { + #[cfg(any(target_feature = "zacas", portable_atomic_target_feature = "zacas"))] + { + // zacas is available at compile-time. + true + } + #[cfg(not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")))] + { + detect::detect().zacas() + } +} +const IS_ALWAYS_LOCK_FREE: bool = + cfg!(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")); + +atomic128!(AtomicI128, i128, atomic_max, atomic_min); +atomic128!(AtomicU128, u128, atomic_umax, atomic_umin); + +#[cfg(test)] +mod tests { + use super::*; + + test_atomic_int!(i128); + test_atomic_int!(u128); + + // load/store/swap implementation is not affected by signedness, so it is + // enough to test only unsigned types. + stress_test!(u128); +} diff --git a/vendor/portable-atomic/src/imp/atomic128/s390x.rs b/vendor/portable-atomic/src/imp/atomic128/s390x.rs new file mode 100644 index 0000000..1b74d17 --- /dev/null +++ b/vendor/portable-atomic/src/imp/atomic128/s390x.rs @@ -0,0 +1,548 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +128-bit atomic implementation on s390x. + +This architecture provides the following 128-bit atomic instructions: + +- LPQ/STPQ: load/store (arch1 or later, i.e., baseline) +- CDSG: CAS (arch1 or later, i.e., baseline) + +See "Atomic operation overview by architecture" in atomic-maybe-uninit for a more comprehensive and +detailed description of the atomic and synchronize instructions in this architecture: +https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#s390x + +LLVM's minimal supported architecture level is arch8 (z10): +https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/SystemZ/SystemZProcessors.td#L16-L17 +This does not appear to have changed since the current s390x backend was added in LLVM 3.3: +https://github.com/llvm/llvm-project/commit/5f613dfd1f7edb0ae95d521b7107b582d9df5103#diff-cbaef692b3958312e80fd5507a7e2aff071f1acb086f10e8a96bc06a7bb289db + +We could use asm byte_wise_atomic_load + asm atomic_compare_exchange pattern for RMW here, but using an +inline assembly allows omitting the comparison of results and the storing/comparing of condition flags. + +Note: On Miri and ThreadSanitizer which do not support inline assembly, we don't use +this module and use intrinsics.rs instead. + +Refs: +- z/Architecture Principles of Operation, Fifteenth Edition (SA22-7832-14) + https://www.ibm.com/docs/en/module_1678991624569/pdf/SA22-7832-14.pdf +- atomic-maybe-uninit + https://github.com/taiki-e/atomic-maybe-uninit + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +include!("macros.rs"); + +use core::{arch::asm, sync::atomic::Ordering}; + +#[cfg(portable_atomic_no_strict_provenance)] +use crate::utils::ptr::PtrExt as _; +use crate::utils::{Pair, U128}; + +// bcr 14,0 requires fast-BCR-serialization facility added in arch9 (z196). +#[cfg(any( + target_feature = "fast-serialization", + portable_atomic_target_feature = "fast-serialization", +))] +macro_rules! serialization { + () => { + "bcr 14, 0" + }; +} +#[cfg(not(any( + target_feature = "fast-serialization", + portable_atomic_target_feature = "fast-serialization", +)))] +macro_rules! serialization { + () => { + "bcr 15, 0" + }; +} + +// Use distinct operands on z196 or later, otherwise split to lgr and $op. +#[cfg(any(target_feature = "distinct-ops", portable_atomic_target_feature = "distinct-ops"))] +macro_rules! distinct_op { + ($op:tt, $a0:tt, $a1:tt, $a2:tt) => { + concat!($op, "k ", $a0, ", ", $a1, ", ", $a2) + }; +} +#[cfg(not(any(target_feature = "distinct-ops", portable_atomic_target_feature = "distinct-ops")))] +macro_rules! distinct_op { + ($op:tt, $a0:tt, $a1:tt, $a2:tt) => { + concat!("lgr ", $a0, ", ", $a1, "\n", $op, " ", $a0, ", ", $a2) + }; +} + +// Use selgr$cond on z15 or later, otherwise split to locgr$cond and $op. +#[cfg(any( + target_feature = "miscellaneous-extensions-3", + portable_atomic_target_feature = "miscellaneous-extensions-3", +))] +#[cfg(any( + target_feature = "load-store-on-cond", + portable_atomic_target_feature = "load-store-on-cond", +))] +macro_rules! select_op { + ($cond:tt, $a0:tt, $a1:tt, $a2:tt) => { + concat!("selgr", $cond, " ", $a0, ", ", $a1, ", ", $a2) + }; +} +#[cfg(not(any( + target_feature = "miscellaneous-extensions-3", + portable_atomic_target_feature = "miscellaneous-extensions-3", +)))] +#[cfg(any( + target_feature = "load-store-on-cond", + portable_atomic_target_feature = "load-store-on-cond", +))] +macro_rules! select_op { + ($cond:tt, $a0:tt, $a1:tt, $a2:tt) => { + concat!("lgr ", $a0, ", ", $a2, "\n", "locgr", $cond, " ", $a0, ", ", $a1) + }; +} + +// Extracts and checks condition code. +#[inline] +fn extract_cc(r: i64) -> bool { + r.wrapping_add(-268435456) & (1 << 31) != 0 +} + +#[inline] +unsafe fn atomic_load(src: *mut u128, _order: Ordering) -> u128 { + debug_assert!(src.addr() % 16 == 0); + let (out_hi, out_lo); + + // SAFETY: the caller must uphold the safety contract. + unsafe { + // atomic load is always SeqCst. + asm!( + "lpq %r0, 0({src})", // atomic { r0:r1 = *src } + src = in(reg) ptr_reg!(src), + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + out("r0") out_hi, + out("r1") out_lo, + options(nostack, preserves_flags), + ); + U128 { pair: Pair { hi: out_hi, lo: out_lo } }.whole + } +} + +#[inline] +unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) { + debug_assert!(dst.addr() % 16 == 0); + let val = U128 { whole: val }; + + // SAFETY: the caller must uphold the safety contract. + unsafe { + macro_rules! atomic_store { + ($acquire:expr) => { + asm!( + "stpq %r0, 0({dst})", // atomic { *dst = r0:r1 } + $acquire, // fence + dst = in(reg) ptr_reg!(dst), + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + in("r0") val.pair.hi, + in("r1") val.pair.lo, + options(nostack, preserves_flags), + ) + }; + } + match order { + // Relaxed and Release stores are equivalent. + Ordering::Relaxed | Ordering::Release => atomic_store!(""), + Ordering::SeqCst => atomic_store!(serialization!()), + _ => unreachable!(), + } + } +} + +#[inline] +unsafe fn atomic_compare_exchange( + dst: *mut u128, + old: u128, + new: u128, + _success: Ordering, + _failure: Ordering, +) -> Result { + debug_assert!(dst.addr() % 16 == 0); + let old = U128 { whole: old }; + let new = U128 { whole: new }; + let (prev_hi, prev_lo); + let r; + + // SAFETY: the caller must uphold the safety contract. + // CDSG has SeqCst semantics. + let prev = unsafe { + macro_rules! cmpxchg { + ($new_hi:tt, $new_lo:tt) => { + asm!( + concat!("cdsg %r0, %", $new_hi, ", 0({dst})"), // atomic { if *dst == r0:r1 { cc = 0; *dst = new_hi:new_lo } else { cc = 1; r0:r1 = *dst } } + "ipm {r}", // r[:] = cc + dst = in(reg) ptr_reg!(dst), + r = lateout(reg) r, + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + inout("r0") old.pair.hi => prev_hi, + inout("r1") old.pair.lo => prev_lo, + in($new_hi) new.pair.hi, + in($new_lo) new.pair.lo, + // Do not use `preserves_flags` because CDSG modifies the condition code. + options(nostack), + ) + }; + } + // r4 is stack pointer on z/OS. + #[cfg(not(target_os = "zos"))] + cmpxchg!("r4", "r5"); + #[cfg(target_os = "zos")] + cmpxchg!("r12", "r13"); + U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole + }; + if extract_cc(r) { Ok(prev) } else { Err(prev) } +} + +// cdsg is always strong. +use self::atomic_compare_exchange as atomic_compare_exchange_weak; + +#[inline] +unsafe fn atomic_swap(dst: *mut u128, val: u128, _order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + let val = U128 { whole: val }; + let (mut prev_hi, mut prev_lo); + + // SAFETY: the caller must uphold the safety contract. + // CDSG has SeqCst semantics. + // + // Do not use atomic_rmw_cas_3 because it needs extra LGR to implement swap. + unsafe { + macro_rules! swap { + ($val_hi:tt, $val_lo:tt) => { + asm!( + "lg %r1, 8({dst})", // atomic { r1 = *dst.byte_add(8) } + "lg %r0, 0({dst})", // atomic { r0 = *dst } + "2:", // 'retry: + concat!("cdsg %r0, %", $val_hi, ", 0({dst})"), // atomic { if *dst == r0:r1 { cc = 0; *dst = val_hi:val_lo } else { cc = 1; r0:r1 = *dst } } + "jl 2b", // if cc == 1 { jump 'retry } + dst = in(reg) ptr_reg!(dst), + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + out("r0") prev_hi, + out("r1") prev_lo, + in($val_hi) val.pair.hi, + in($val_lo) val.pair.lo, + // Do not use `preserves_flags` because CDSG modifies the condition code. + options(nostack), + ) + }; + } + // r4 is stack pointer on z/OS. + #[cfg(not(target_os = "zos"))] + swap!("r4", "r5"); + #[cfg(target_os = "zos")] + swap!("r12", "r13"); + U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole + } +} + +/// Atomic RMW by CAS loop (3 arguments) +/// `unsafe fn(dst: *mut u128, val: u128, order: Ordering) -> u128;` +/// +/// `$op` can use the following registers: +/// - val_hi/val_lo pair: val argument (read-only for `$op`) +/// - r0/r1 pair: previous value loaded (read-only for `$op`) +/// - r12/r13 pair: new value that will be stored +macro_rules! atomic_rmw_cas_3 { + ($name:ident, [$($reg:tt)*], $($op:tt)*) => { + #[inline] + unsafe fn $name(dst: *mut u128, val: u128, _order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + let val = U128 { whole: val }; + let (mut prev_hi, mut prev_lo); + + // SAFETY: the caller must uphold the safety contract. + // CDSG has SeqCst semantics. + unsafe { + asm!( + "lg %r1, 8({dst})", // atomic { r1 = *dst.byte_add(8) } + "lg %r0, 0({dst})", // atomic { r0 = *dst } + "2:", // 'retry: + $($op)* + "cdsg %r0, %r12, 0({dst})", // atomic { if *dst == r0:r1 { cc = 0; *dst = r12:r13 } else { cc = 1; r0:r1 = *dst } } + "jl 2b", // if cc == 1 { jump 'retry } + dst = in(reg) ptr_reg!(dst), + val_hi = in(reg) val.pair.hi, + val_lo = in(reg) val.pair.lo, + $($reg)* + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + out("r0") prev_hi, + out("r1") prev_lo, + out("r12") _, + out("r13") _, + // Do not use `preserves_flags` because CDSG modifies the condition code. + options(nostack), + ); + U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole + } + } + }; +} +/// Atomic RMW by CAS loop (2 arguments) +/// `unsafe fn(dst: *mut u128, order: Ordering) -> u128;` +/// +/// `$op` can use the following registers: +/// - r0/r1 pair: previous value loaded (read-only for `$op`) +/// - r12/r13 pair: new value that will be stored +macro_rules! atomic_rmw_cas_2 { + ($name:ident, [$($reg:tt)*], $($op:tt)*) => { + #[inline] + unsafe fn $name(dst: *mut u128, _order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + let (mut prev_hi, mut prev_lo); + + // SAFETY: the caller must uphold the safety contract. + // CDSG has SeqCst semantics. + unsafe { + asm!( + "lg %r1, 8({dst})", // atomic { r1 = *dst.byte_add(8) } + "lg %r0, 0({dst})", // atomic { r0 = *dst } + "2:", // 'retry: + $($op)* + "cdsg %r0, %r12, 0({dst})", // atomic { if *dst == r0:r1 { cc = 0; *dst = r12:r13 } else { cc = 1; r0:r1 = *dst } } + "jl 2b", // if cc == 1 { jump 'retry } + dst = in(reg) ptr_reg!(dst), + $($reg)* + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + out("r0") prev_hi, + out("r1") prev_lo, + out("r12") _, + out("r13") _, + // Do not use `preserves_flags` because CDSG modifies the condition code. + options(nostack), + ); + U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole + } + } + }; +} + +atomic_rmw_cas_3! { + atomic_add, [], + distinct_op!("algr", "%r13", "%r1", "{val_lo}"), // r13 = r1 + val_lo; cc = zero | carry + "lgr %r12, %r0", // r12 = r0 + "alcgr %r12, {val_hi}", // r12 += val_hi + carry +} +atomic_rmw_cas_3! { + atomic_sub, [], + distinct_op!("slgr", "%r13", "%r1", "{val_lo}"), // r13 = r1 - val_lo; cc = zero | borrow + "lgr %r12, %r0", // r12 = r0 + "slbgr %r12, {val_hi}", // r12 -= val_hi + borrow +} +atomic_rmw_cas_3! { + atomic_and, [], + distinct_op!("ngr", "%r13", "%r1", "{val_lo}"), // r13 = r1 & val_lo + distinct_op!("ngr", "%r12", "%r0", "{val_hi}"), // r12 = r0 & val_hi +} + +// Use nngrk on z15 or later. +#[cfg(any( + target_feature = "miscellaneous-extensions-3", + portable_atomic_target_feature = "miscellaneous-extensions-3", +))] +atomic_rmw_cas_3! { + atomic_nand, [], + "nngrk %r13, %r1, {val_lo}", // r13 = !(r1 & val_lo) + "nngrk %r12, %r0, {val_hi}", // r12 = !(r0 & val_hi) +} +#[cfg(not(any( + target_feature = "miscellaneous-extensions-3", + portable_atomic_target_feature = "miscellaneous-extensions-3", +)))] +atomic_rmw_cas_3! { + atomic_nand, [], + distinct_op!("ngr", "%r13", "%r1", "{val_lo}"), // r13 = r1 & val_lo + distinct_op!("ngr", "%r12", "%r0", "{val_hi}"), // r12 = r0 & val_hi + "lcgr %r13, %r13", // r13 = !r13 + 1 + "aghi %r13, -1", // r13 -= 1 + "lcgr %r12, %r12", // r12 = !r12 + 1 + "aghi %r12, -1", // r12 -= 1 +} + +atomic_rmw_cas_3! { + atomic_or, [], + distinct_op!("ogr", "%r13", "%r1", "{val_lo}"), // r13 = r1 | val_lo + distinct_op!("ogr", "%r12", "%r0", "{val_hi}"), // r12 = r0 | val_hi +} +atomic_rmw_cas_3! { + atomic_xor, [], + distinct_op!("xgr", "%r13", "%r1", "{val_lo}"), // r13 = r1 ^ val_lo + distinct_op!("xgr", "%r12", "%r0", "{val_hi}"), // r12 = r0 ^ val_hi +} + +cfg_sel!({ + #[cfg(any( + target_feature = "load-store-on-cond", + portable_atomic_target_feature = "load-store-on-cond", + ))] + { + atomic_rmw_cas_3! { + atomic_max, [], + "clgr %r1, {val_lo}", // if r1(u) < val_lo(u) { cc = 1 } else if r1(u) > val_lo(u) { cc = 2 } else { cc = 0 } + select_op!("h", "%r12", "%r1", "{val_lo}"), // if cc == 2 { r12 = r1 } else { r12 = val_lo } + "cgr %r0, {val_hi}", // if r0(i) < val_hi(i) { cc = 1 } else if r0(i) > val_hi(i) { cc = 2 } else { cc = 0 } + select_op!("h", "%r13", "%r1", "{val_lo}"), // if cc == 2 { r13 = r1 } else { r13 = val_lo } + "locgre %r13, %r12", // if cc == 0 { r13 = r12 } + select_op!("h", "%r12", "%r0", "{val_hi}"), // if cc == 2 { r12 = r0 } else { r12 = val_hi } + } + atomic_rmw_cas_3! { + atomic_umax, [tmp = out(reg) _,], + "clgr %r1, {val_lo}", // if r1(u) < val_lo(u) { cc = 1 } else if r1(u) > val_lo(u) { cc = 2 } else { cc = 0 } + select_op!("h", "{tmp}", "%r1", "{val_lo}"), // if cc == 2 { tmp = r1 } else { tmp = val_lo } + "clgr %r0, {val_hi}", // if r0(u) < val_hi(u) { cc = 1 } else if r0(u) > val_hi(u) { cc = 2 } else { cc = 0 } + select_op!("h", "%r12", "%r0", "{val_hi}"), // if cc == 2 { r12 = r0 } else { r12 = val_hi } + select_op!("h", "%r13", "%r1", "{val_lo}"), // if cc == 2 { r13 = r1 } else { r13 = val_lo } + "cgr %r0, {val_hi}", // if r0(i) < val_hi(i) { cc = 1 } else if r0(i) > val_hi(i) { cc = 2 } else { cc = 0 } + "locgre %r13, {tmp}", // if cc == 0 { r13 = tmp } + } + atomic_rmw_cas_3! { + atomic_min, [], + "clgr %r1, {val_lo}", // if r1(u) < val_lo(u) { cc = 1 } else if r1(u) > val_lo(u) { cc = 2 } else { cc = 0 } + select_op!("l", "%r12", "%r1", "{val_lo}"), // if cc == 1 { r12 = r1 } else { r12 = val_lo } + "cgr %r0, {val_hi}", // if r0(i) < val_hi(i) { cc = 1 } else if r0(i) > val_hi(i) { cc = 2 } else { cc = 0 } + select_op!("l", "%r13", "%r1", "{val_lo}"), // if cc == 1 { r13 = r1 } else { r13 = val_lo } + "locgre %r13, %r12", // if cc == 0 { r13 = r12 } + select_op!("l", "%r12", "%r0", "{val_hi}"), // if cc == 1 { r12 = r0 } else { r12 = val_hi } + } + atomic_rmw_cas_3! { + atomic_umin, [tmp = out(reg) _,], + "clgr %r1, {val_lo}", // if r1(u) < val_lo(u) { cc = 1 } else if r1(u) > val_lo(u) { cc = 2 } else { cc = 0 } + select_op!("l", "{tmp}", "%r1", "{val_lo}"), // if cc == 1 { tmp = r1 } else { tmp = val_lo } + "clgr %r0, {val_hi}", // if r0(u) < val_hi(u) { cc = 1 } else if r0(u) > val_hi(u) { cc = 2 } else { cc = 0 } + select_op!("l", "%r12", "%r0", "{val_hi}"), // if cc == 1 { r12 = r0 } else { r12 = val_hi } + select_op!("l", "%r13", "%r1", "{val_lo}"), // if cc == 1 { r13 = r1 } else { r13 = val_lo } + "cgr %r0, {val_hi}", // if r0(i) < val_hi(i) { cc = 1 } else if r0(i) > val_hi(i) { cc = 2 } else { cc = 0 } + "locgre %r13, {tmp}", // if cc == 0 { r13 = tmp } + } + } + #[cfg(else)] + { + #[rustfmt::skip] + macro_rules! atomic_cmp { + ($name:ident, $cmp_hi1:tt, $cmp_hi2:tt, $cmp_lo:tt,) => { + #[inline] + unsafe fn $name(dst: *mut u128, val: u128, _order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + let val = U128 { whole: val }; + let (mut prev_hi, mut prev_lo); + + // SAFETY: the caller must uphold the safety contract. + // CDSG has SeqCst semantics. + unsafe { + macro_rules! cmp { + ($val_hi:tt, $val_lo:tt) => { + asm!( + "lg %r1, 8({dst})", // atomic { r1 = *dst.byte_add(8) } + "lg %r0, 0({dst})", // atomic { r0 = *dst } + "2:", // 'retry: + concat!($cmp_hi1, " %", $val_hi, ", %r0, 4f"), // if $cmp_hi1(val_hi, r0) { jump 'val } + concat!($cmp_hi2, " %", $val_hi, ", %r0, 3f"), // if $cmp_hi2(val_hi, r0) { jump 'prev } + concat!($cmp_lo, " %", $val_lo, ", %r1, 4f"), // if $cmp_lo(val_lo, r1) { jump 'val } + "3:", // 'prev: + "cdsg %r0, %r0, 0({dst})", // atomic { if *dst == r0:r1 { cc = 0; *dst = r0:r1 } else { cc = 1; r0:r1 = *dst } } + "jl 2b", // if cc == 1 { jump 'retry } + "j 5f", + "4:", // 'val: + concat!("cdsg %r0, %", $val_hi, ", 0({dst})"), // atomic { if *dst == r0:r1 { cc = 0; *dst = val_hi:val_lo } else { cc = 1; r0:r1 = *dst } } + "jl 2b", // if cc == 1 { jump 'retry } + "5:", + dst = in(reg) ptr_reg!(dst), + // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. + out("r0") prev_hi, + out("r1") prev_lo, + in($val_hi) val.pair.hi, + in($val_lo) val.pair.lo, + // Do not use `preserves_flags` because CDSG modifies the condition code. + options(nostack), + ) + }; + } + // r4 is stack pointer on z/OS. + #[cfg(not(target_os = "zos"))] + cmp!("r4", "r5"); + #[cfg(target_os = "zos")] + cmp!("r12", "r13"); + U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole + } + } + }; + } + // loc{,g}r requires z196 or later. + atomic_cmp! { + atomic_max, + "cgrjh", // signed > + "cgrjl", // signed < + "clgrjhe", // unsigned >= + } + atomic_cmp! { + atomic_umax, + "clgrjh", // unsigned > + "clgrjl", // unsigned < + "clgrjhe", // unsigned >= + } + atomic_cmp! { + atomic_min, + "cgrjl", // signed < + "cgrjh", // signed > + "clgrjle", // unsigned <= + } + atomic_cmp! { + atomic_umin, + "clgrjl", // unsigned < + "clgrjh", // unsigned > + "clgrjle", // unsigned <= + } + } +}); + +atomic_rmw_cas_2! { + atomic_not, [], + "lcgr %r13, %r1", // r13 = !r1 + 1 + "aghi %r13, -1", // r13 -= 1 + "lcgr %r12, %r0", // r12 = !r0 + 1 + "aghi %r12, -1", // r12 -= 1 +} + +#[cfg(any(target_feature = "distinct-ops", portable_atomic_target_feature = "distinct-ops"))] +atomic_rmw_cas_2! { + atomic_neg, [zero = in(reg) 0_u64,], + "slgrk %r13, {zero}, %r1", // r13 = 0 - r1; cc = zero | borrow + "lghi %r12, 0", // r12 = 0 + "slbgr %r12, %r0", // r12 -= r0 + borrow +} +#[cfg(not(any(target_feature = "distinct-ops", portable_atomic_target_feature = "distinct-ops")))] +atomic_rmw_cas_2! { + atomic_neg, [], + "lghi %r13, 0", // r13 = 0 + "slgr %r13, %r1", // r13 -= r1; cc = zero | borrow + "lghi %r12, 0", // r12 = 0 + "slbgr %r12, %r0", // r12 -= r0 + borrow +} + +#[inline] +const fn is_lock_free() -> bool { + IS_ALWAYS_LOCK_FREE +} +const IS_ALWAYS_LOCK_FREE: bool = true; + +atomic128!(AtomicI128, i128, atomic_max, atomic_min); +atomic128!(AtomicU128, u128, atomic_umax, atomic_umin); + +#[cfg(test)] +mod tests { + use super::*; + + test_atomic_int!(i128); + test_atomic_int!(u128); + + // load/store/swap implementation is not affected by signedness, so it is + // enough to test only unsigned types. + stress_test!(u128); +} diff --git a/vendor/portable-atomic/src/imp/atomic128/x86_64.rs b/vendor/portable-atomic/src/imp/atomic128/x86_64.rs new file mode 100644 index 0000000..1f10d3f --- /dev/null +++ b/vendor/portable-atomic/src/imp/atomic128/x86_64.rs @@ -0,0 +1,1009 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +128-bit atomic implementation on x86_64. + +This architecture provides the following 128-bit atomic instructions: + +- CMPXCHG16B: CAS (CMPXCHG16B) +- VMOVDQA: load/store (AVX) + +We could use asm byte_wise_atomic_load + asm atomic_compare_exchange pattern for RMW here, but using an +inline assembly allows omitting the comparison of results and the storing/comparing of flags. + +Note: On Miri and ThreadSanitizer which do not support inline assembly, we don't use +this module and use intrinsics.rs instead. + +Refs: +- x86 and amd64 instruction reference https://www.felixcloutier.com/x86 +- atomic-maybe-uninit https://github.com/taiki-e/atomic-maybe-uninit + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +// TODO: use core::arch::x86_64::cmpxchg16b where available and efficient than asm + +include!("macros.rs"); + +#[cfg(not(any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b")))] +#[path = "../fallback/outline_atomics.rs"] +mod fallback; + +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(not(target_env = "sgx"))] +#[cfg_attr( + not(target_feature = "sse"), + cfg(not(any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"))) +)] +#[cfg(any( + test, + not(all( + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + target_feature = "avx", + )), +))] +#[path = "../detect/x86_64.rs"] +mod detect; + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; +#[cfg(not(all( + not(target_feature = "avx"), + any(portable_atomic_no_outline_atomics, target_env = "sgx", not(target_feature = "sse")), +)))] +use core::arch::x86_64::__m128i; +use core::sync::atomic::Ordering; + +#[cfg(portable_atomic_no_strict_provenance)] +use crate::utils::ptr::PtrExt as _; +use crate::utils::{Pair, U128}; + +// Asserts that the function is called in the correct context. +macro_rules! debug_assert_cmpxchg16b { + () => { + #[cfg(not(any( + target_feature = "cmpxchg16b", + portable_atomic_target_feature = "cmpxchg16b", + )))] + { + debug_assert!(detect::detect().cmpxchg16b()); + } + }; +} +#[cfg(not(all( + not(target_feature = "avx"), + any(portable_atomic_no_outline_atomics, target_env = "sgx", not(target_feature = "sse")), +)))] +macro_rules! debug_assert_cmpxchg16b_avx { + () => {{ + debug_assert_cmpxchg16b!(); + #[cfg(not(target_feature = "avx"))] + { + debug_assert!(detect::detect().avx()); + } + }}; +} + +#[cfg(not(all( + not(target_feature = "avx"), + any(portable_atomic_no_outline_atomics, target_env = "sgx", not(target_feature = "sse")), +)))] +#[cfg(target_pointer_width = "32")] +macro_rules! ptr_modifier { + () => { + ":e" + }; +} +#[cfg(not(all( + not(target_feature = "avx"), + any(portable_atomic_no_outline_atomics, target_env = "sgx", not(target_feature = "sse")), +)))] +#[cfg(target_pointer_width = "64")] +macro_rules! ptr_modifier { + () => { + "" + }; +} + +// Unlike AArch64 and RISC-V, x86's assembler doesn't check instruction +// requirements for the currently enabled target features. In the first place, +// there is no option in the x86 assembly for such case, like Arm .arch_extension, +// RISC-V .option arch, PowerPC .machine, etc. +// However, we set target_feature(enable) when available (Rust 1.69+) in case a +// new codegen backend is added that checks for it in the future, or an option +// is added to the assembler to check for it. +#[cfg_attr( + not(portable_atomic_no_cmpxchg16b_target_feature), + target_feature(enable = "cmpxchg16b") +)] +#[inline] +unsafe fn cmpxchg16b(dst: *mut u128, old: u128, new: u128) -> (u128, bool) { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_cmpxchg16b!(); + + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned (required by CMPXCHG16B), that there are no + // concurrent non-atomic operations, and that the CPU supports CMPXCHG16B. + // + // If the value at `dst` (destination operand) and rdx:rax are equal, the + // 128-bit value in rcx:rbx is stored in the `dst`, otherwise the value at + // `dst` is loaded to rdx:rax. + // + // The ZF flag is set if the value at `dst` and rdx:rax are equal, + // otherwise it is cleared. Other flags are unaffected. + // + // Refs: https://www.felixcloutier.com/x86/cmpxchg8b:cmpxchg16b + unsafe { + // cmpxchg16b is always SeqCst. + let r: u8; + let old = U128 { whole: old }; + let new = U128 { whole: new }; + let (prev_lo, prev_hi); + macro_rules! cmpxchg16b { + ($dst:tt) => { + asm!( + "xchg r8, rbx", // save rbx which is reserved by LLVM + concat!("lock cmpxchg16b xmmword ptr [", $dst, "]"), + "setne cl", + "mov rbx, r8", // restore rbx + inout("r8") new.pair.lo => _, + in("rcx") new.pair.hi, + inout("rax") old.pair.lo => prev_lo, + inout("rdx") old.pair.hi => prev_hi, + in($dst) dst, + lateout("cl") r, + // Do not use `preserves_flags` because CMPXCHG16B modifies the ZF flag. + options(nostack), + ) + }; + } + // rdi and rsi are call-preserved on Windows. + #[cfg(not(windows))] + #[cfg(target_pointer_width = "32")] + cmpxchg16b!("esi"); + #[cfg(not(windows))] + #[cfg(target_pointer_width = "64")] + cmpxchg16b!("rsi"); + #[cfg(windows)] + #[cfg(target_pointer_width = "32")] + cmpxchg16b!("r11d"); + #[cfg(windows)] + #[cfg(target_pointer_width = "64")] + cmpxchg16b!("r11"); + crate::utils::assert_unchecked(r == 0 || r == 1); // needed to remove extra test + (U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole, r == 0) + } +} + +// VMOVDQA is atomic when AVX available. +// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104688 for details. +// Intel, AMD, and Zhaoxin officially guarantee this behavior (VIA has not responded), +// but both LLVM and Boost always treat VMOVDQA as atomic when AVX available. +// https://github.com/llvm/llvm-project/pull/74275 +// https://github.com/boostorg/atomic/commit/24a41db3e61627d99895f7e324b3d725d1be27c1 +// +// Refs: https://www.felixcloutier.com/x86/movdqa:vmovdqa32:vmovdqa64 +// +// Use cfg(target_feature = "sse") here -- SSE is included in the x86_64 +// baseline and is always available, but the SSE target feature is disabled for +// use cases such as kernels and firmware that should not use vector registers. +// So, do not use vector registers unless SSE target feature is enabled. +// Note that we cannot use cfg(target_abi = "softfloat") because cfg(target_abi) +// is unavailable on old rustc and target_abi = "softfloat" is not set for +// softfloat x86_64 targets as of Rust 1.95. +// See also https://github.com/rust-lang/rust/blob/1.84.0/src/doc/rustc/src/platform-support/x86_64-unknown-none.md. +#[cfg(not(all( + not(target_feature = "avx"), + any(portable_atomic_no_outline_atomics, target_env = "sgx", not(target_feature = "sse")), +)))] +#[target_feature(enable = "avx")] +#[inline] +unsafe fn _atomic_load_vmovdqa(src: *mut u128) -> u128 { + debug_assert!(src.addr() % 16 == 0); + debug_assert_cmpxchg16b_avx!(); + + // SAFETY: the caller must uphold the safety contract. + // + // atomic load by vmovdqa is always SeqCst. + unsafe { + let out: __m128i; + asm!( + concat!("vmovdqa {out}, xmmword ptr [{src", ptr_modifier!(), "}]"), + src = in(reg) src, + out = out(xmm_reg) out, + options(nostack, preserves_flags), + ); + core::mem::transmute(out) + } +} +#[cfg(not(all( + not(target_feature = "avx"), + any(portable_atomic_no_outline_atomics, target_env = "sgx", not(target_feature = "sse")), +)))] +#[target_feature(enable = "avx")] +#[inline] +unsafe fn _atomic_store_vmovdqa(dst: *mut u128, val: u128, order: Ordering) { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_cmpxchg16b_avx!(); + + // SAFETY: the caller must uphold the safety contract. + unsafe { + let val: __m128i = core::mem::transmute(val); + match order { + // Relaxed and Release stores are equivalent. + Ordering::Relaxed | Ordering::Release => { + asm!( + concat!("vmovdqa xmmword ptr [{dst", ptr_modifier!(), "}], {val}"), + dst = in(reg) dst, + val = in(xmm_reg) val, + options(nostack, preserves_flags), + ); + } + Ordering::SeqCst => { + let p = core::cell::UnsafeCell::new(core::mem::MaybeUninit::::uninit()); + asm!( + concat!("vmovdqa xmmword ptr [{dst", ptr_modifier!(), "}], {val}"), + // Equivalent to `mfence`, but is up to 3.1x faster on Coffee Lake and up to 2.4x faster on Raptor Lake-H at least in simple cases. + // - https://github.com/taiki-e/portable-atomic/pull/156 + // - LLVM uses `lock or` https://godbolt.org/z/vv6rjzfYd + // - Windows uses `xchg` for x86_32 for MemoryBarrier https://learn.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-memorybarrier + // - MSVC STL uses `lock inc` https://github.com/microsoft/STL/pull/740 + // - boost uses `lock or` https://github.com/boostorg/atomic/commit/559eba81af71386cedd99f170dc6101c6ad7bf22 + concat!("xchg qword ptr [{p", ptr_modifier!(), "}], {tmp}"), + dst = in(reg) dst, + val = in(xmm_reg) val, + p = in(reg) p.get(), + tmp = out(reg) _, + options(nostack, preserves_flags), + ); + } + _ => unreachable!(), + } + } +} + +#[cfg(not(all( + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + target_feature = "avx", +)))] +#[cfg(not(all( + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + any(portable_atomic_no_outline_atomics, target_env = "sgx", not(target_feature = "sse")), +)))] +macro_rules! load_store_detect { + ( + vmovdqa = $vmovdqa:ident + cmpxchg16b = $cmpxchg16b:ident + fallback = $fallback:ident + ) => {{ + let cpuid = detect::detect(); + #[cfg(not(any( + target_feature = "cmpxchg16b", + portable_atomic_target_feature = "cmpxchg16b", + )))] + { + // Check CMPXCHG16B first to prevent mixing atomic and non-atomic access. + if cpuid.cmpxchg16b() { + #[cfg(target_feature = "avx")] + { + $vmovdqa + } + // We only use VMOVDQA when SSE is enabled. See _atomic_load_vmovdqa() for more. + #[cfg(not(target_feature = "avx"))] + { + #[cfg(target_feature = "sse")] + { + if cpuid.avx() { $vmovdqa } else { $cmpxchg16b } + } + #[cfg(not(target_feature = "sse"))] + { + $cmpxchg16b + } + } + } else { + fallback::$fallback + } + } + #[cfg(any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"))] + { + if cpuid.avx() { $vmovdqa } else { $cmpxchg16b } + } + }}; +} + +#[inline] +unsafe fn atomic_load(src: *mut u128, _order: Ordering) -> u128 { + #[cfg(all( + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + target_feature = "avx", + ))] + // SAFETY: the caller must uphold the safety contract. + // cfg guarantees that CMPXCHG16B and AVX are available at compile-time. + unsafe { + _atomic_load_vmovdqa(src) + } + #[cfg(not(all( + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + target_feature = "avx", + )))] + { + // We only use VMOVDQA when SSE is enabled. See _atomic_load_vmovdqa() for more. + // SGX doesn't support CPUID. + #[cfg(all( + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + any( + portable_atomic_no_outline_atomics, + target_env = "sgx", + not(target_feature = "sse") + ), + ))] + // SAFETY: the caller must uphold the safety contract. + // cfg guarantees that CMPXCHG16B is available at compile-time. + unsafe { + // cmpxchg16b is always SeqCst. + _atomic_load_cmpxchg16b(src) + } + #[cfg(not(all( + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + any( + portable_atomic_no_outline_atomics, + target_env = "sgx", + not(target_feature = "sse") + ), + )))] + // SAFETY: the caller must uphold the safety contract. + unsafe { + ifunc!(unsafe fn(src: *mut u128) -> u128 { + load_store_detect! { + vmovdqa = _atomic_load_vmovdqa + cmpxchg16b = _atomic_load_cmpxchg16b + // Use SeqCst because cmpxchg16b and atomic load by vmovdqa is always SeqCst. + fallback = atomic_load_seqcst + } + }) + } + } +} +// See cmpxchg16b() for target_feature(enable). +#[cfg_attr( + not(portable_atomic_no_cmpxchg16b_target_feature), + target_feature(enable = "cmpxchg16b") +)] +#[inline] +unsafe fn _atomic_load_cmpxchg16b(src: *mut u128) -> u128 { + debug_assert!(src.addr() % 16 == 0); + debug_assert_cmpxchg16b!(); + + // SAFETY: the caller must guarantee that `src` is valid for both writes and + // reads, 16-byte aligned, and that there are no concurrent non-atomic operations. + // cfg guarantees that the CPU supports CMPXCHG16B. + // + // See cmpxchg16b function for more. + // + // We could use CAS loop by atomic_compare_exchange here, but using an inline assembly allows + // omitting the storing of condition flags and avoid use of xchg to handle rbx. + unsafe { + // cmpxchg16b is always SeqCst. + let (out_lo, out_hi); + macro_rules! cmpxchg16b { + ($dst:tt, $save:tt) => { + asm!( + concat!("mov ", $save, ", rbx"), // save rbx which is reserved by LLVM + "xor rbx, rbx", // zeroed rbx + concat!("lock cmpxchg16b xmmword ptr [", $dst, "]"), + concat!("mov rbx, ", $save), // restore rbx + // set old/new args of cmpxchg16b to 0 (rbx is zeroed after saved to rbx_tmp, to avoid xchg) + out($save) _, + in("rcx") 0_u64, + inout("rax") 0_u64 => out_lo, + inout("rdx") 0_u64 => out_hi, + in($dst) src, + // Do not use `preserves_flags` because CMPXCHG16B modifies the ZF flag. + options(nostack), + ) + }; + } + // rdi and rsi are call-preserved on Windows. + #[cfg(not(windows))] + #[cfg(target_pointer_width = "32")] + cmpxchg16b!("edi", "rsi"); + #[cfg(not(windows))] + #[cfg(target_pointer_width = "64")] + cmpxchg16b!("rdi", "rsi"); + #[cfg(windows)] + #[cfg(target_pointer_width = "32")] + cmpxchg16b!("r9d", "r8"); + #[cfg(windows)] + #[cfg(target_pointer_width = "64")] + cmpxchg16b!("r9", "r8"); + U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole + } +} + +#[inline] +unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) { + #[cfg(all( + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + target_feature = "avx", + ))] + // SAFETY: the caller must uphold the safety contract. + // cfg guarantees that CMPXCHG16B and AVX are available at compile-time. + unsafe { + _atomic_store_vmovdqa(dst, val, order); + } + #[cfg(not(all( + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + target_feature = "avx", + )))] + { + // We only use VMOVDQA when SSE is enabled. See _atomic_load_vmovdqa() for more. + // SGX doesn't support CPUID. + #[cfg(all( + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + any( + portable_atomic_no_outline_atomics, + target_env = "sgx", + not(target_feature = "sse") + ), + ))] + // SAFETY: the caller must uphold the safety contract. + // cfg guarantees that CMPXCHG16B is available at compile-time. + unsafe { + // cmpxchg16b is always SeqCst. + let _ = order; + _atomic_store_cmpxchg16b(dst, val); + } + #[cfg(not(all( + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + any( + portable_atomic_no_outline_atomics, + target_env = "sgx", + not(target_feature = "sse") + ), + )))] + // SAFETY: the caller must uphold the safety contract. + unsafe { + #[cfg(target_feature = "sse")] + fn_alias! { + #[target_feature(enable = "avx")] + unsafe fn(dst: *mut u128, val: u128); + // atomic store by vmovdqa has at least release semantics. + _atomic_store_vmovdqa_non_seqcst = _atomic_store_vmovdqa(Ordering::Release); + _atomic_store_vmovdqa_seqcst = _atomic_store_vmovdqa(Ordering::SeqCst); + } + match order { + // Relaxed and Release stores are equivalent in all implementations + // that may be called here (vmovdqa, asm-based cmpxchg16b, and fallback). + // core::arch's cmpxchg16b will never called here. + Ordering::Relaxed | Ordering::Release => { + ifunc!(unsafe fn(dst: *mut u128, val: u128) { + load_store_detect! { + vmovdqa = _atomic_store_vmovdqa_non_seqcst + cmpxchg16b = _atomic_store_cmpxchg16b + fallback = atomic_store_non_seqcst + } + }); + } + Ordering::SeqCst => { + ifunc!(unsafe fn(dst: *mut u128, val: u128) { + load_store_detect! { + vmovdqa = _atomic_store_vmovdqa_seqcst + cmpxchg16b = _atomic_store_cmpxchg16b + fallback = atomic_store_seqcst + } + }); + } + _ => unreachable!(), + } + } + } +} +// See cmpxchg16b() for target_feature(enable). +#[cfg_attr( + not(portable_atomic_no_cmpxchg16b_target_feature), + target_feature(enable = "cmpxchg16b") +)] +#[inline] +unsafe fn _atomic_store_cmpxchg16b(dst: *mut u128, val: u128) { + // SAFETY: the caller must uphold the safety contract. + unsafe { + // cmpxchg16b is always SeqCst. + atomic_swap_cmpxchg16b(dst, val, Ordering::SeqCst); + } +} + +#[inline] +unsafe fn atomic_compare_exchange( + dst: *mut u128, + old: u128, + new: u128, + _success: Ordering, + _failure: Ordering, +) -> Result { + #[cfg(any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"))] + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned, that there are no concurrent non-atomic operations, + // and cfg guarantees that CMPXCHG16B is available at compile-time. + let (prev, ok) = unsafe { cmpxchg16b(dst, old, new) }; + #[cfg(not(any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b")))] + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned, and that there are no different kinds of concurrent accesses. + let (prev, ok) = unsafe { + ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) { + if detect::detect().cmpxchg16b() { + cmpxchg16b + } else { + // Use SeqCst because cmpxchg16b is always SeqCst. + fallback::atomic_compare_exchange_seqcst + } + }) + }; + if ok { Ok(prev) } else { Err(prev) } +} + +// cmpxchg16b is always strong. +use self::atomic_compare_exchange as atomic_compare_exchange_weak; + +// See cmpxchg16b() for target_feature(enable). +#[cfg_attr( + not(portable_atomic_no_cmpxchg16b_target_feature), + target_feature(enable = "cmpxchg16b") +)] +#[inline] +unsafe fn atomic_swap_cmpxchg16b(dst: *mut u128, val: u128, _order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_cmpxchg16b!(); + + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned, and that there are no concurrent non-atomic operations. + // cfg guarantees that the CPU supports CMPXCHG16B. + // + // See cmpxchg16b function for more. + // + // We could use CAS loop by atomic_compare_exchange here, but using an inline assembly allows + // omitting the storing/comparing of condition flags and reducing uses of xchg/mov to handle rbx. + // + // Do not use atomic_rmw_cas_3 because it needs extra MOV to implement swap. + unsafe { + // cmpxchg16b is always SeqCst. + let val = U128 { whole: val }; + let (mut prev_lo, mut prev_hi); + macro_rules! cmpxchg16b { + ($dst:tt, $save:tt) => { + asm!( + concat!("xchg ", $save, ", rbx"), // save rbx which is reserved by LLVM + // This is not single-copy atomic reads, but this is ok because subsequent + // CAS will check for consistency. + // + // This is based on the code generated for the first load in DW RMWs by LLVM. + // + // Note that the C++20 memory model does not allow mixed-sized atomic access, + // so we must use inline assembly to implement this. + // (i.e., byte-wise atomic based on the standard library's atomic types + // cannot be used here). + concat!("mov rax, qword ptr [", $dst, "]"), + concat!("mov rdx, qword ptr [", $dst, " + 8]"), + "2:", + concat!("lock cmpxchg16b xmmword ptr [", $dst, "]"), + "jne 2b", + concat!("mov rbx, ", $save), // restore rbx + inout($save) val.pair.lo => _, + in("rcx") val.pair.hi, + out("rax") prev_lo, + out("rdx") prev_hi, + in($dst) dst, + // Do not use `preserves_flags` because CMPXCHG16B modifies the ZF flag. + options(nostack), + ) + }; + } + // rdi and rsi are call-preserved on Windows. + #[cfg(not(windows))] + #[cfg(target_pointer_width = "32")] + cmpxchg16b!("edi", "rsi"); + #[cfg(not(windows))] + #[cfg(target_pointer_width = "64")] + cmpxchg16b!("rdi", "rsi"); + #[cfg(windows)] + #[cfg(target_pointer_width = "32")] + cmpxchg16b!("r9d", "r8"); + #[cfg(windows)] + #[cfg(target_pointer_width = "64")] + cmpxchg16b!("r9", "r8"); + U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole + } +} + +/// Atomic RMW by CAS loop (3 arguments) +/// `unsafe fn(dst: *mut u128, val: u128, order: Ordering) -> u128;` +/// +/// `$op` can use the following registers: +/// - r8/r9 pair: val argument (read-only for `$op`) +/// - rax/rdx pair: previous value loaded (read-only for `$op`) +/// - rbx/rcx pair: new value that will be stored +// We could use CAS loop by atomic_compare_exchange here, but using an inline assembly allows +// omitting the storing/comparing of condition flags and reducing uses of xchg/mov to handle rbx. +macro_rules! atomic_rmw_cas_3 { + ($name:ident, $($op:tt)*) => { + // See cmpxchg16b() for target_feature(enable). + #[cfg_attr( + not(portable_atomic_no_cmpxchg16b_target_feature), + target_feature(enable = "cmpxchg16b") + )] + #[inline] + unsafe fn $name(dst: *mut u128, val: u128, _order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_cmpxchg16b!(); + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned, and that there are no concurrent non-atomic operations. + // cfg guarantees that the CPU supports CMPXCHG16B. + // + // See cmpxchg16b function for more. + unsafe { + // cmpxchg16b is always SeqCst. + let val = U128 { whole: val }; + let (mut prev_lo, mut prev_hi); + macro_rules! cmpxchg16b { + ($dst:tt, $save:tt) => { + asm!( + concat!("mov ", $save, ", rbx"), // save rbx which is reserved by LLVM + // This is not single-copy atomic reads, but this is ok because subsequent + // CAS will check for consistency. + // + // This is based on the code generated for the first load in DW RMWs by LLVM. + // + // Note that the C++20 memory model does not allow mixed-sized atomic access, + // so we must use inline assembly to implement this. + // (i.e., byte-wise atomic based on the standard library's atomic types + // cannot be used here). + concat!("mov rax, qword ptr [", $dst, "]"), + concat!("mov rdx, qword ptr [", $dst, " + 8]"), + "2:", + $($op)* + concat!("lock cmpxchg16b xmmword ptr [", $dst, "]"), + "jne 2b", + concat!("mov rbx, ", $save), // restore rbx + out($save) _, + out("rcx") _, + out("rax") prev_lo, + out("rdx") prev_hi, + in($dst) dst, + in("r8") val.pair.lo, + in("r9") val.pair.hi, + // Do not use `preserves_flags` because CMPXCHG16B modifies the ZF flag. + options(nostack), + ) + }; + } + // rdi and rsi are call-preserved on Windows. + #[cfg(not(windows))] + #[cfg(target_pointer_width = "32")] + cmpxchg16b!("edi", "r10"); + #[cfg(not(windows))] + #[cfg(target_pointer_width = "64")] + cmpxchg16b!("rdi", "r10"); + #[cfg(windows)] + #[cfg(target_pointer_width = "32")] + cmpxchg16b!("r10d", "r11"); + #[cfg(windows)] + #[cfg(target_pointer_width = "64")] + cmpxchg16b!("r10", "r11"); + U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole + } + } + }; +} +/// Atomic RMW by CAS loop (2 arguments) +/// `unsafe fn(dst: *mut u128, order: Ordering) -> u128;` +/// +/// `$op` can use the following registers: +/// - rax/rdx pair: previous value loaded (read-only for `$op`) +/// - rbx/rcx pair: new value that will be stored +// We could use CAS loop by atomic_compare_exchange here, but using an inline assembly allows +// omitting the storing of condition flags and avoid use of xchg to handle rbx. +macro_rules! atomic_rmw_cas_2 { + ($name:ident, $($op:tt)*) => { + // See cmpxchg16b() for target_feature(enable). + #[cfg_attr( + not(portable_atomic_no_cmpxchg16b_target_feature), + target_feature(enable = "cmpxchg16b") + )] + #[inline] + unsafe fn $name(dst: *mut u128, _order: Ordering) -> u128 { + debug_assert!(dst.addr() % 16 == 0); + debug_assert_cmpxchg16b!(); + // SAFETY: the caller must guarantee that `dst` is valid for both writes and + // reads, 16-byte aligned, and that there are no concurrent non-atomic operations. + // cfg guarantees that the CPU supports CMPXCHG16B. + // + // See cmpxchg16b function for more. + unsafe { + // cmpxchg16b is always SeqCst. + let (mut prev_lo, mut prev_hi); + macro_rules! cmpxchg16b { + ($dst:tt, $save:tt) => { + asm!( + concat!("mov ", $save, ", rbx"), // save rbx which is reserved by LLVM + // This is not single-copy atomic reads, but this is ok because subsequent + // CAS will check for consistency. + // + // This is based on the code generated for the first load in DW RMWs by LLVM. + // + // Note that the C++20 memory model does not allow mixed-sized atomic access, + // so we must use inline assembly to implement this. + // (i.e., byte-wise atomic based on the standard library's atomic types + // cannot be used here). + concat!("mov rax, qword ptr [", $dst, "]"), + concat!("mov rdx, qword ptr [", $dst, " + 8]"), + "2:", + $($op)* + concat!("lock cmpxchg16b xmmword ptr [", $dst, "]"), + "jne 2b", + concat!("mov rbx, ", $save), // restore rbx + out($save) _, + out("rcx") _, + out("rax") prev_lo, + out("rdx") prev_hi, + in($dst) dst, + // Do not use `preserves_flags` because CMPXCHG16B modifies the ZF flag. + options(nostack), + ) + }; + } + // rdi and rsi are call-preserved on Windows. + #[cfg(not(windows))] + #[cfg(target_pointer_width = "32")] + cmpxchg16b!("edi", "rsi"); + #[cfg(not(windows))] + #[cfg(target_pointer_width = "64")] + cmpxchg16b!("rdi", "rsi"); + #[cfg(windows)] + #[cfg(target_pointer_width = "32")] + cmpxchg16b!("r9d", "r8"); + #[cfg(windows)] + #[cfg(target_pointer_width = "64")] + cmpxchg16b!("r9", "r8"); + U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole + } + } + }; +} + +atomic_rmw_cas_3! { + atomic_add_cmpxchg16b, + "mov rbx, rax", + "add rbx, r8", + "mov rcx, rdx", + "adc rcx, r9", +} +atomic_rmw_cas_3! { + atomic_sub_cmpxchg16b, + "mov rbx, rax", + "sub rbx, r8", + "mov rcx, rdx", + "sbb rcx, r9", +} +atomic_rmw_cas_3! { + atomic_and_cmpxchg16b, + "mov rbx, rax", + "and rbx, r8", + "mov rcx, rdx", + "and rcx, r9", +} +atomic_rmw_cas_3! { + atomic_nand_cmpxchg16b, + "mov rbx, rax", + "and rbx, r8", + "not rbx", + "mov rcx, rdx", + "and rcx, r9", + "not rcx", +} +atomic_rmw_cas_3! { + atomic_or_cmpxchg16b, + "mov rbx, rax", + "or rbx, r8", + "mov rcx, rdx", + "or rcx, r9", +} +atomic_rmw_cas_3! { + atomic_xor_cmpxchg16b, + "mov rbx, rax", + "xor rbx, r8", + "mov rcx, rdx", + "xor rcx, r9", +} + +atomic_rmw_cas_2! { + atomic_not_cmpxchg16b, + "mov rbx, rax", + "not rbx", + "mov rcx, rdx", + "not rcx", +} +atomic_rmw_cas_2! { + atomic_neg_cmpxchg16b, + "mov rbx, rax", + "neg rbx", + "mov rcx, 0", + "sbb rcx, rdx", +} + +atomic_rmw_cas_3! { + atomic_max_cmpxchg16b, + "cmp r8, rax", + "mov rcx, r9", + "sbb rcx, rdx", + "mov rcx, r9", + "cmovl rcx, rdx", + "mov rbx, r8", + "cmovl rbx, rax", +} +atomic_rmw_cas_3! { + atomic_umax_cmpxchg16b, + "cmp r8, rax", + "mov rcx, r9", + "sbb rcx, rdx", + "mov rcx, r9", + "cmovb rcx, rdx", + "mov rbx, r8", + "cmovb rbx, rax", +} +atomic_rmw_cas_3! { + atomic_min_cmpxchg16b, + "cmp r8, rax", + "mov rcx, r9", + "sbb rcx, rdx", + "mov rcx, r9", + "cmovge rcx, rdx", + "mov rbx, r8", + "cmovge rbx, rax", +} +atomic_rmw_cas_3! { + atomic_umin_cmpxchg16b, + "cmp r8, rax", + "mov rcx, r9", + "sbb rcx, rdx", + "mov rcx, r9", + "cmovae rcx, rdx", + "mov rbx, r8", + "cmovae rbx, rax", +} + +macro_rules! select_atomic_rmw { + ( + unsafe fn $name:ident($($arg:tt)*) $(-> $ret_ty:ty)?; + cmpxchg16b = $cmpxchg16b_fn:ident; + fallback = $seqcst_fallback_fn:ident; + ) => { + // If cmpxchg16b is available at compile-time, we can always use cmpxchg16b_fn. + #[cfg(any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"))] + use self::$cmpxchg16b_fn as $name; + // Otherwise, we need to do run-time detection and can use cmpxchg16b_fn only if cmpxchg16b is available. + #[cfg(not(any( + target_feature = "cmpxchg16b", + portable_atomic_target_feature = "cmpxchg16b", + )))] + #[inline] + unsafe fn $name($($arg)*, _order: Ordering) $(-> $ret_ty)? { + fn_alias! { + // See cmpxchg16b() for target_feature(enable). + #[cfg_attr( + not(portable_atomic_no_cmpxchg16b_target_feature), + target_feature(enable = "cmpxchg16b") + )] + unsafe fn($($arg)*) $(-> $ret_ty)?; + // cmpxchg16b is always SeqCst. + cmpxchg16b_seqcst_fn = $cmpxchg16b_fn(Ordering::SeqCst); + } + // SAFETY: the caller must uphold the safety contract. + // we only calls cmpxchg16b_fn if cmpxchg16b is available. + unsafe { + ifunc!(unsafe fn($($arg)*) $(-> $ret_ty)? { + if detect::detect().cmpxchg16b() { + cmpxchg16b_seqcst_fn + } else { + // Use SeqCst because cmpxchg16b is always SeqCst. + fallback::$seqcst_fallback_fn + } + }) + } + } + }; +} + +select_atomic_rmw! { + unsafe fn atomic_swap(dst: *mut u128, val: u128) -> u128; + cmpxchg16b = atomic_swap_cmpxchg16b; + fallback = atomic_swap_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_add(dst: *mut u128, val: u128) -> u128; + cmpxchg16b = atomic_add_cmpxchg16b; + fallback = atomic_add_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_sub(dst: *mut u128, val: u128) -> u128; + cmpxchg16b = atomic_sub_cmpxchg16b; + fallback = atomic_sub_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_and(dst: *mut u128, val: u128) -> u128; + cmpxchg16b = atomic_and_cmpxchg16b; + fallback = atomic_and_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_nand(dst: *mut u128, val: u128) -> u128; + cmpxchg16b = atomic_nand_cmpxchg16b; + fallback = atomic_nand_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_or(dst: *mut u128, val: u128) -> u128; + cmpxchg16b = atomic_or_cmpxchg16b; + fallback = atomic_or_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_xor(dst: *mut u128, val: u128) -> u128; + cmpxchg16b = atomic_xor_cmpxchg16b; + fallback = atomic_xor_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_max(dst: *mut u128, val: u128) -> u128; + cmpxchg16b = atomic_max_cmpxchg16b; + fallback = atomic_max_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_umax(dst: *mut u128, val: u128) -> u128; + cmpxchg16b = atomic_umax_cmpxchg16b; + fallback = atomic_umax_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_min(dst: *mut u128, val: u128) -> u128; + cmpxchg16b = atomic_min_cmpxchg16b; + fallback = atomic_min_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_umin(dst: *mut u128, val: u128) -> u128; + cmpxchg16b = atomic_umin_cmpxchg16b; + fallback = atomic_umin_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_not(dst: *mut u128) -> u128; + cmpxchg16b = atomic_not_cmpxchg16b; + fallback = atomic_not_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_neg(dst: *mut u128) -> u128; + cmpxchg16b = atomic_neg_cmpxchg16b; + fallback = atomic_neg_seqcst; +} + +#[inline] +fn is_lock_free() -> bool { + #[cfg(any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"))] + { + // CMPXCHG16B is available at compile-time. + true + } + #[cfg(not(any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b")))] + { + detect::detect().cmpxchg16b() + } +} +const IS_ALWAYS_LOCK_FREE: bool = + cfg!(any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b")); + +atomic128!(AtomicI128, i128, atomic_max, atomic_min); +atomic128!(AtomicU128, u128, atomic_umax, atomic_umin); + +#[cfg(test)] +mod tests { + use super::*; + + test_atomic_int!(i128); + test_atomic_int!(u128); + + // load/store/swap implementation is not affected by signedness, so it is + // enough to test only unsigned types. + stress_test!(u128); +} diff --git a/vendor/portable-atomic/src/imp/atomic64/README.md b/vendor/portable-atomic/src/imp/atomic64/README.md new file mode 100644 index 0000000..82ca16d --- /dev/null +++ b/vendor/portable-atomic/src/imp/atomic64/README.md @@ -0,0 +1,24 @@ +# 64-bit atomic implementations on 32-bit architectures + +(See the [`atomic128` module](../atomic128) for 128-bit atomic implementations on 64-bit architectures.) + +## 64-bit atomic instructions + +Here is the table of targets that support 64-bit atomics and the instructions used: + +| target_arch | load | store | CAS | RMW | note | +| ----------- | ---- | ----- | --- | --- | ---- | +| x86 | cmpxchg8b or fild or movlps or movq | cmpxchg8b or fistp or movlps | cmpxchg8b | cmpxchg8b | provided by `core::sync::atomic` | +| arm | ldrexd | ldrexd/strexd | ldrexd/strexd | ldrexd/strexd | provided by `core::sync::atomic` for Armv6+, otherwise provided by us for Linux/Android using kuser_cmpxchg64 (see [arm_linux.rs](arm_linux.rs) for more) | +| riscv32 | amocas.d | amocas.d | amocas.d | amocas.d | Requires `zacas` target feature. Both compile-time and run-time detection are supported.
Requires Rust 1.59+ | +| hexagon | memd | memd | memd_locked | memd_locked | Unimplemented | +| sparc | ldx | stx | casx | casx | Unimplemented (unsupported in LLVM). Requires `v8plus` and `v9` target feature (Linux is v8plus+v9 by default) | +| m68k | cas2 | cas2 | cas2 | cas2 | Unimplemented (unsupported in LLVM). Requires M68020 or later (Linux is M68020 by default) | +| mips32r6 | llwp | llwp/scwp | llwp/scwp | llwp/scwp | Unimplemented (unsupported in LLVM). Requires Release 6 Paired LL/SC family of instructions | + +If `core::sync::atomic` provides 64-bit atomics, we use them. +On compiler versions or platforms where these are not supported, the fallback implementation is used. + +## Run-time CPU feature detection + +See the [`detect` module's readme](../detect/README.md) for run-time CPU feature detection. diff --git a/vendor/portable-atomic/src/imp/atomic64/arm_linux.rs b/vendor/portable-atomic/src/imp/atomic64/arm_linux.rs new file mode 100644 index 0000000..75432c9 --- /dev/null +++ b/vendor/portable-atomic/src/imp/atomic64/arm_linux.rs @@ -0,0 +1,330 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +64-bit atomic implementation using kuser_cmpxchg64 on pre-v6 Arm Linux/Android. + +See "Atomic operation overview by architecture" in atomic-maybe-uninit for a more comprehensive and +detailed description of the atomic and synchronize instructions in this architecture: +https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#arm + +Refs: +- https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/arm/kernel_user_helpers.rst +- https://github.com/rust-lang/compiler-builtins/blob/compiler_builtins-v0.1.124/src/arm_linux.rs +- https://github.com/taiki-e/atomic-maybe-uninit + +Note: __kuser_cmpxchg64 is always SeqCst. +https://github.com/taiki-e/atomic-maybe-uninit/blob/v0.3.21/src/arch/arm.rs#L230 + +Note: On Miri and ThreadSanitizer which do not support inline assembly, we don't use +this module and use fallback implementation instead. +*/ + +// TODO: Since Rust 1.64, the Linux kernel requirement for Rust when using std is 3.2+, so it should +// be possible to omit the dynamic kernel version check if the std feature is enabled on Rust 1.64+. +// https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements + +include!("macros.rs"); + +#[path = "../fallback/outline_atomics.rs"] +mod fallback; + +#[cfg(test)] // test-only (unused) +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(any( + all( + target_os = "linux", + any( + target_env = "gnu", + target_env = "musl", + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + ), + ), + target_os = "android", + target_os = "freebsd", + target_os = "openbsd", +))] +#[path = "../detect/auxv.rs"] +mod test_detect_auxv; + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; +use core::{mem, sync::atomic::Ordering}; + +#[cfg(portable_atomic_no_strict_provenance)] +use crate::utils::ptr::PtrExt as _; +use crate::utils::{Pair, U64}; + +// https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/arm/kernel_user_helpers.rst +const KUSER_HELPER_VERSION: usize = 0xFFFF0FFC; +// __kuser_helper_version >= 5 (kernel version 3.1+) +const KUSER_CMPXCHG64: usize = 0xFFFF0F60; +#[inline] +fn __kuser_helper_version() -> i32 { + // SAFETY: core assumes that at least __kuser_memory_barrier (__kuser_helper_version >= 3) is + // available on this platform. __kuser_helper_version is always available on such a platform. + unsafe { crate::utils::ptr::with_exposed_provenance::(KUSER_HELPER_VERSION).read() } +} +#[inline] +fn has_kuser_cmpxchg64() -> bool { + // Note: detect_false cfg is intended to make it easy for developers to test + // cases where features usually available is not available, and is not a public API. + if cfg!(portable_atomic_test_detect_false) { + return false; + } + __kuser_helper_version() >= 5 +} +#[inline] +unsafe fn __kuser_cmpxchg64(old_val: *const u64, new_val: *const u64, ptr: *mut u64) -> bool { + // SAFETY: kernel docs specify a known address with the given signature. + // And the caller must guarantee that the pointer is valid for read and write, + // aligned to the element size, and __kuser_helper_version >= 5. + unsafe { + let f: extern "C" fn(*const u64, *const u64, *mut u64) -> u32 = + mem::transmute(crate::utils::ptr::with_exposed_provenance::<()>(KUSER_CMPXCHG64)); + f(old_val, new_val, ptr) == 0 + } +} + +// 64-bit atomic load by two 32-bit atomic loads. +#[inline] +unsafe fn byte_wise_atomic_load(src: *const u64) -> u64 { + // SAFETY: the caller must uphold the safety contract. + unsafe { + let (out_lo, out_hi); + asm!( + "ldr {out_lo}, [{src}]", // atomic { out_lo = *src } + "ldr {out_hi}, [{src}, #4]", // atomic { out_hi = *src.byte_add(4) } + src = in(reg) src, + out_lo = out(reg) out_lo, + out_hi = out(reg) out_hi, + options(pure, nostack, preserves_flags, readonly), + ); + U64 { pair: Pair { lo: out_lo, hi: out_hi } }.whole + } +} + +macro_rules! select_atomic { + ( + unsafe fn $name:ident($dst:ident: *mut u64 $(, $($arg:tt)*)?) $(-> $ret_ty:ty)? { + |$kuser_cmpxchg64_fn_binding:ident| $($kuser_cmpxchg64_fn_body:tt)* + } + fallback = $seqcst_fallback_fn:ident + ) => { + #[inline] + unsafe fn $name($dst: *mut u64 $(, $($arg)*)?, _: Ordering) $(-> $ret_ty)? { + unsafe fn kuser_cmpxchg64_fn($dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)? { + debug_assert!($dst.addr() % 8 == 0); + debug_assert!(has_kuser_cmpxchg64()); + // SAFETY: the caller must uphold the safety contract. + unsafe { + loop { + // This is not single-copy atomic reads, but this is ok because subsequent + // CAS will check for consistency. + // + // Arm's memory model allow mixed-sized atomic access. + // https://github.com/rust-lang/unsafe-code-guidelines/issues/345#issuecomment-1172891466 + // + // Note that the C++20 memory model does not allow mixed-sized atomic access, + // so we must use inline assembly to implement byte_wise_atomic_load. + // (i.e., byte-wise atomic based on the standard library's atomic types + // cannot be used here). + let prev = byte_wise_atomic_load($dst); + let next = { + let $kuser_cmpxchg64_fn_binding = prev; + $($kuser_cmpxchg64_fn_body)* + }; + if __kuser_cmpxchg64(&prev, &next, $dst) { + return prev; + } + } + } + } + // SAFETY: the caller must uphold the safety contract. + // we only calls __kuser_cmpxchg64 if it is available. + unsafe { + ifunc!(unsafe fn($dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)? { + if has_kuser_cmpxchg64() { + kuser_cmpxchg64_fn + } else { + // Use SeqCst because __kuser_cmpxchg64 is always SeqCst. + fallback::$seqcst_fallback_fn + } + }) + } + } + }; +} + +select_atomic! { + unsafe fn atomic_load(src: *mut u64) -> u64 { + |old| old + } + fallback = atomic_load_seqcst +} +#[inline] +unsafe fn atomic_store(dst: *mut u64, val: u64, order: Ordering) { + // SAFETY: the caller must uphold the safety contract. + unsafe { + atomic_swap(dst, val, order); + } +} +select_atomic! { + unsafe fn atomic_swap(dst: *mut u64, val: u64) -> u64 { + |_x| val + } + fallback = atomic_swap_seqcst +} +#[inline] +unsafe fn atomic_compare_exchange( + dst: *mut u64, + old: u64, + new: u64, + _: Ordering, + _: Ordering, +) -> Result { + unsafe fn kuser_cmpxchg64_fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool) { + debug_assert!(dst.addr() % 8 == 0); + debug_assert!(has_kuser_cmpxchg64()); + // SAFETY: the caller must uphold the safety contract. + unsafe { + loop { + // See select_atomic! for more. + let prev = byte_wise_atomic_load(dst); + let next = if prev == old { new } else { prev }; + if __kuser_cmpxchg64(&prev, &next, dst) { + return (prev, prev == old); + } + } + } + } + // SAFETY: the caller must uphold the safety contract. + // we only calls __kuser_cmpxchg64 if it is available. + let (prev, ok) = unsafe { + ifunc!(unsafe fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool) { + if has_kuser_cmpxchg64() { + kuser_cmpxchg64_fn + } else { + // Use SeqCst because __kuser_cmpxchg64 is always SeqCst. + fallback::atomic_compare_exchange_seqcst + } + }) + }; + if ok { Ok(prev) } else { Err(prev) } +} +use self::atomic_compare_exchange as atomic_compare_exchange_weak; +select_atomic! { + unsafe fn atomic_add(dst: *mut u64, val: u64) -> u64 { + |x| x.wrapping_add(val) + } + fallback = atomic_add_seqcst +} +select_atomic! { + unsafe fn atomic_sub(dst: *mut u64, val: u64) -> u64 { + |x| x.wrapping_sub(val) + } + fallback = atomic_sub_seqcst +} +select_atomic! { + unsafe fn atomic_and(dst: *mut u64, val: u64) -> u64 { + |x| x & val + } + fallback = atomic_and_seqcst +} +select_atomic! { + unsafe fn atomic_nand(dst: *mut u64, val: u64) -> u64 { + |x| !(x & val) + } + fallback = atomic_nand_seqcst +} +select_atomic! { + unsafe fn atomic_or(dst: *mut u64, val: u64) -> u64 { + |x| x | val + } + fallback = atomic_or_seqcst +} +select_atomic! { + unsafe fn atomic_xor(dst: *mut u64, val: u64) -> u64 { + |x| x ^ val + } + fallback = atomic_xor_seqcst +} +select_atomic! { + unsafe fn atomic_max(dst: *mut u64, val: u64) -> u64 { + |x| { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + { core::cmp::max(x as i64, val as i64) as u64 } + } + } + fallback = atomic_max_seqcst +} +select_atomic! { + unsafe fn atomic_umax(dst: *mut u64, val: u64) -> u64 { + |x| core::cmp::max(x, val) + } + fallback = atomic_umax_seqcst +} +select_atomic! { + unsafe fn atomic_min(dst: *mut u64, val: u64) -> u64 { + |x| { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + { core::cmp::min(x as i64, val as i64) as u64 } + } + } + fallback = atomic_min_seqcst +} +select_atomic! { + unsafe fn atomic_umin(dst: *mut u64, val: u64) -> u64 { + |x| core::cmp::min(x, val) + } + fallback = atomic_umin_seqcst +} +select_atomic! { + unsafe fn atomic_not(dst: *mut u64) -> u64 { + |x| !x + } + fallback = atomic_not_seqcst +} +select_atomic! { + unsafe fn atomic_neg(dst: *mut u64) -> u64 { + |x| x.wrapping_neg() + } + fallback = atomic_neg_seqcst +} + +#[inline] +fn is_lock_free() -> bool { + has_kuser_cmpxchg64() +} +const IS_ALWAYS_LOCK_FREE: bool = false; + +atomic64!(AtomicI64, i64, atomic_max, atomic_min); +atomic64!(AtomicU64, u64, atomic_umax, atomic_umin); + +#[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks, + clippy::wildcard_imports +)] +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn kuser_helper_version() { + let version = __kuser_helper_version(); + assert!(version >= 5, "{:?}", version); + assert_eq!(version, unsafe { + crate::utils::ptr::with_exposed_provenance::(KUSER_HELPER_VERSION).read() + }); + } + + test_atomic_int!(i64); + test_atomic_int!(u64); + + // load/store/swap implementation is not affected by signedness, so it is + // enough to test only unsigned types. + stress_test!(u64); +} diff --git a/vendor/portable-atomic/src/imp/atomic64/macros.rs b/vendor/portable-atomic/src/imp/atomic64/macros.rs new file mode 100644 index 0000000..9f65a20 --- /dev/null +++ b/vendor/portable-atomic/src/imp/atomic64/macros.rs @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +macro_rules! atomic64 { + ($atomic_type:ident, $int_type:ident, $atomic_max:ident, $atomic_min:ident) => { + #[repr(C, align(8))] + pub(crate) struct $atomic_type { + v: core::cell::UnsafeCell<$int_type>, + } + + // Send is implicitly implemented. + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock. + unsafe impl Sync for $atomic_type {} + + impl_default_no_fetch_ops!($atomic_type, $int_type); + impl_default_bit_opts!($atomic_type, $int_type); + impl $atomic_type { + #[inline] + pub(crate) const fn new(v: $int_type) -> Self { + Self { v: core::cell::UnsafeCell::new(v) } + } + + #[inline] + pub(crate) fn is_lock_free() -> bool { + is_lock_free() + } + pub(crate) const IS_ALWAYS_LOCK_FREE: bool = IS_ALWAYS_LOCK_FREE; + + #[inline] + #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] + pub(crate) fn load(&self, order: Ordering) -> $int_type { + crate::utils::assert_load_ordering(order); + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + atomic_load(self.v.get().cast::(), order) as $int_type + } + } + + #[inline] + #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] + pub(crate) fn store(&self, val: $int_type, order: Ordering) { + crate::utils::assert_store_ordering(order); + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + atomic_store(self.v.get().cast::(), val as u64, order) + } + } + + #[inline] + pub(crate) fn swap(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + atomic_swap(self.v.get().cast::(), val as u64, order) as $int_type + } + } + + #[inline] + #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] + pub(crate) fn compare_exchange( + &self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering, + ) -> Result<$int_type, $int_type> { + crate::utils::assert_compare_exchange_ordering(success, failure); + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + match atomic_compare_exchange( + self.v.get().cast::(), + current as u64, + new as u64, + success, + failure, + ) { + Ok(v) => Ok(v as $int_type), + Err(v) => Err(v as $int_type), + } + } + } + + #[inline] + #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] + pub(crate) fn compare_exchange_weak( + &self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering, + ) -> Result<$int_type, $int_type> { + crate::utils::assert_compare_exchange_ordering(success, failure); + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + match atomic_compare_exchange_weak( + self.v.get().cast::(), + current as u64, + new as u64, + success, + failure, + ) { + Ok(v) => Ok(v as $int_type), + Err(v) => Err(v as $int_type), + } + } + } + + #[inline] + pub(crate) fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + atomic_add(self.v.get().cast::(), val as u64, order) as $int_type + } + } + + #[inline] + pub(crate) fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + atomic_sub(self.v.get().cast::(), val as u64, order) as $int_type + } + } + + #[inline] + pub(crate) fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + atomic_and(self.v.get().cast::(), val as u64, order) as $int_type + } + } + + #[inline] + pub(crate) fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + atomic_nand(self.v.get().cast::(), val as u64, order) as $int_type + } + } + + #[inline] + pub(crate) fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + atomic_or(self.v.get().cast::(), val as u64, order) as $int_type + } + } + + #[inline] + pub(crate) fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + atomic_xor(self.v.get().cast::(), val as u64, order) as $int_type + } + } + + #[inline] + pub(crate) fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + $atomic_max(self.v.get().cast::(), val as u64, order) as $int_type + } + } + + #[inline] + pub(crate) fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + $atomic_min(self.v.get().cast::(), val as u64, order) as $int_type + } + } + + #[inline] + pub(crate) fn fetch_not(&self, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + atomic_not(self.v.get().cast::(), order) as $int_type + } + } + #[inline] + pub(crate) fn not(&self, order: Ordering) { + self.fetch_not(order); + } + + #[inline] + pub(crate) fn fetch_neg(&self, order: Ordering) -> $int_type { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock + // and the raw pointer passed in is valid because we got it from a reference. + unsafe { + atomic_neg(self.v.get().cast::(), order) as $int_type + } + } + #[inline] + pub(crate) fn neg(&self, order: Ordering) { + self.fetch_neg(order); + } + + #[inline] + pub(crate) const fn as_ptr(&self) -> *mut $int_type { + self.v.get() + } + } + }; +} diff --git a/vendor/portable-atomic/src/imp/atomic64/mod.rs b/vendor/portable-atomic/src/imp/atomic64/mod.rs new file mode 100644 index 0000000..f17e9cb --- /dev/null +++ b/vendor/portable-atomic/src/imp/atomic64/mod.rs @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +64-bit atomic implementations on 32-bit architectures + +See README.md for details. +*/ + +// pre-v6 Arm Linux +// Miri and Sanitizer do not support inline assembly. +#[cfg(all( + feature = "fallback", + target_arch = "arm", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_os = "linux", target_os = "android"), + any(test, not(any(target_feature = "v6", portable_atomic_target_feature = "v6"))), + not(portable_atomic_no_outline_atomics), +))] +#[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(any(test, portable_atomic_no_atomic_64)))] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any(test, not(target_has_atomic = "64"))) +)] +pub(super) mod arm_linux; + +// riscv32 +// Miri and Sanitizer do not support inline assembly. +#[cfg(all( + target_arch = "riscv32", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any( + target_feature = "zacas", + portable_atomic_target_feature = "zacas", + all( + feature = "fallback", + not(portable_atomic_no_outline_atomics), + any(target_os = "linux", target_os = "android"), + ), + ), +))] +pub(super) mod riscv32; diff --git a/vendor/portable-atomic/src/imp/atomic64/riscv32.rs b/vendor/portable-atomic/src/imp/atomic64/riscv32.rs new file mode 100644 index 0000000..c0e9280 --- /dev/null +++ b/vendor/portable-atomic/src/imp/atomic64/riscv32.rs @@ -0,0 +1,626 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +64-bit atomic implementation on riscv32. + +This architecture provides the following 64-bit atomic instructions: + +- amocas.d: CAS (Zacas extension) + +See "Atomic operation overview by architecture" in atomic-maybe-uninit for a more comprehensive and +detailed description of the atomic and synchronize instructions in this architecture: +https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#risc-v + +Note: On Miri and ThreadSanitizer which do not support inline assembly, we don't use +this module and use fallback implementation instead. + +Refs: +- RISC-V Instruction Set Manual + "Zacas" Extension for Atomic Compare-and-Swap (CAS) Instructions + https://docs.riscv.org/reference/isa/v20260120/unpriv/zacas.html +- RISC-V Atomics ABI Specification + https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/draft-20250812-301374e92976e298e676e7129a6212926b2299ce/riscv-atomic.adoc + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +// TODO: merge duplicated code with atomic128/riscv64.rs + +include!("macros.rs"); + +#[cfg(not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")))] +#[path = "../fallback/outline_atomics.rs"] +mod fallback; + +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(any(test, not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas"))))] +#[cfg(any(target_os = "linux", target_os = "android"))] +#[path = "../detect/riscv_linux.rs"] +mod detect; + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; +use core::sync::atomic::Ordering; + +#[cfg(portable_atomic_no_strict_provenance)] +use crate::utils::ptr::PtrExt as _; +use crate::utils::{Pair, U64}; + +macro_rules! debug_assert_zacas { + () => { + #[cfg(not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")))] + { + debug_assert!(detect::detect().zacas()); + } + }; +} + +// `.option arch, +zacas` directive requires LLVM 20, so we use .4byte directive for old LLVM. +// Note that `.insn ` directive requires LLVM 19. +// https://github.com/llvm/llvm-project/commit/2a086dce691e3cc34a2fc27f4fb255bb2cbbfac9 +// https://github.com/riscv-non-isa/riscv-asm-manual/blob/v0.0.1/src/asm-manual.adoc#arch +#[cfg(not(portable_atomic_pre_llvm_20))] +macro_rules! start_zacas { + () => { + ".option push\n.option arch, +zacas" + }; +} +#[cfg(not(portable_atomic_pre_llvm_20))] +macro_rules! end_zacas { + () => { + ".option pop" + }; +} + +#[cfg(not(portable_atomic_pre_llvm_20))] +macro_rules! atomic_rmw_amocas_order { + ($op:ident, $order:ident) => { + atomic_rmw_amocas_order!($op, $order, failure = $order) + }; + ($op:ident, $order:ident, failure = $failure:ident) => { + match $order { + Ordering::Relaxed => $op!("", ""), + Ordering::Acquire => $op!("", ".aq"), + Ordering::Release => $op!("", ".rl"), + Ordering::AcqRel => $op!("", ".aqrl"), + Ordering::SeqCst if $failure == Ordering::SeqCst => $op!("fence rw,rw", ".aqrl"), + Ordering::SeqCst => $op!("", ".aqrl"), + _ => unreachable!(), + } + }; +} +#[cfg(portable_atomic_pre_llvm_20)] +macro_rules! atomic_rmw_amocas_order_insn { + ($op:ident, $order:ident) => { + atomic_rmw_amocas_order_insn!($op, $order, failure = $order) + }; + ($op:ident, $order:ident, failure = $failure:ident) => { + match $order { + Ordering::Relaxed => $op!("", "8"), + Ordering::Acquire => $op!("", "c"), + Ordering::Release => $op!("", "a"), + Ordering::AcqRel => $op!("", "e"), + Ordering::SeqCst if $failure == Ordering::SeqCst => $op!("fence rw,rw", "e"), + Ordering::SeqCst => $op!("", "e"), + _ => unreachable!(), + } + }; +} + +// If zacas is available at compile-time, we can always use zacas_fn. +#[cfg(any(target_feature = "zacas", portable_atomic_target_feature = "zacas"))] +use self::atomic_load_zacas as atomic_load; +// Otherwise, we need to do run-time detection and can use zacas_fn only if zacas is available. +#[cfg(not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")))] +#[inline] +unsafe fn atomic_load(src: *mut u64, order: Ordering) -> u64 { + fn_alias! { + // inline(never) is just a hint and also not strictly necessary + // because we use ifunc helper macro, but used for clarity. + #[inline(never)] + unsafe fn(src: *mut u64) -> u64; + atomic_load_zacas_relaxed = atomic_load_zacas(Ordering::Relaxed); + atomic_load_zacas_acquire = atomic_load_zacas(Ordering::Acquire); + atomic_load_zacas_seqcst = atomic_load_zacas(Ordering::SeqCst); + } + // SAFETY: the caller must uphold the safety contract. + // we only calls atomic_load_zacas if zacas is available. + unsafe { + match order { + Ordering::Relaxed => { + ifunc!(unsafe fn(src: *mut u64) -> u64 { + if detect::detect().zacas() { + atomic_load_zacas_relaxed + } else { + fallback::atomic_load_non_seqcst + } + }) + } + Ordering::Acquire => { + ifunc!(unsafe fn(src: *mut u64) -> u64 { + if detect::detect().zacas() { + atomic_load_zacas_acquire + } else { + fallback::atomic_load_non_seqcst + } + }) + } + Ordering::SeqCst => { + ifunc!(unsafe fn(src: *mut u64) -> u64 { + if detect::detect().zacas() { + atomic_load_zacas_seqcst + } else { + fallback::atomic_load_seqcst + } + }) + } + _ => unreachable!(), + } + } +} +#[inline] +unsafe fn atomic_load_zacas(src: *mut u64, order: Ordering) -> u64 { + debug_assert!(src.addr() % 8 == 0); + debug_assert_zacas!(); + let (out_lo, out_hi); + + // SAFETY: the caller must uphold the safety contract. + unsafe { + #[cfg(not(portable_atomic_pre_llvm_20))] + macro_rules! load { + ($fence:tt, $asm_order:tt) => { + asm!( + start_zacas!(), + $fence, // fence + concat!("amocas.d", $asm_order, " a2, a2, 0({src})"), // atomic { if *dst == a2:a3 { *dst = a2:a3 } else { a2:a3 = *dst } } + end_zacas!(), + src = in(reg) ptr_reg!(src), + inout("a2") 0_u32 => out_lo, + inout("a3") 0_u32 => out_hi, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(not(portable_atomic_pre_llvm_20))] + atomic_rmw_amocas_order!(load, order); + #[cfg(portable_atomic_pre_llvm_20)] + macro_rules! load { + ($fence:tt, $insn_order:tt) => { + asm!( + $fence, // fence + // amocas.d{,.aq,.rl,.aqrl} a2, a2, (a0) // atomic { if *a0 == a2:a3 { *a0 = a2:a3 } else { a2:a3 = *a0 } } + concat!(".4byte 0x2", $insn_order, "c5362f"), + in("a0") ptr_reg!(src), + inout("a2") 0_u32 => out_lo, + inout("a3") 0_u32 => out_hi, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(portable_atomic_pre_llvm_20)] + atomic_rmw_amocas_order_insn!(load, order); + U64 { pair: Pair { lo: out_lo, hi: out_hi } }.whole + } +} + +#[inline] +unsafe fn atomic_store(dst: *mut u64, val: u64, order: Ordering) { + // SAFETY: the caller must uphold the safety contract. + unsafe { + atomic_swap(dst, val, order); + } +} + +#[inline] +unsafe fn atomic_compare_exchange( + dst: *mut u64, + old: u64, + new: u64, + success: Ordering, + failure: Ordering, +) -> Result { + #[cfg(any(target_feature = "zacas", portable_atomic_target_feature = "zacas"))] + // SAFETY: the caller must uphold the safety contract. + // cfg guarantees that zacas instructions are available at compile-time. + let (prev, ok) = unsafe { atomic_compare_exchange_zacas(dst, old, new, success, failure) }; + #[cfg(not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")))] + let (prev, ok) = { + fn_alias! { + // inline(never) is just a hint and also not strictly necessary + // because we use ifunc helper macro, but used for clarity. + #[inline(never)] + unsafe fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool); + zacas_relaxed_fn = atomic_compare_exchange_zacas(Ordering::Relaxed, Ordering::Relaxed); + zacas_acquire_fn = atomic_compare_exchange_zacas(Ordering::Acquire, Ordering::Acquire); + zacas_release_fn = atomic_compare_exchange_zacas(Ordering::Release, Ordering::Relaxed); + zacas_acqrel_fn = atomic_compare_exchange_zacas(Ordering::AcqRel, Ordering::Acquire); + zacas_seqcst_fn = atomic_compare_exchange_zacas(Ordering::SeqCst, Ordering::SeqCst); + } + let order = crate::utils::upgrade_success_ordering(success, failure); + // SAFETY: the caller must uphold the safety contract. + // we only calls atomic_compare_exchange_zacas if zacas is available. + unsafe { + match order { + Ordering::Relaxed => { + ifunc!(unsafe fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool) { + if detect::detect().zacas() { + zacas_relaxed_fn + } else { + fallback::atomic_compare_exchange_non_seqcst + } + }) + } + Ordering::Acquire => { + ifunc!(unsafe fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool) { + if detect::detect().zacas() { + zacas_acquire_fn + } else { + fallback::atomic_compare_exchange_non_seqcst + } + }) + } + Ordering::Release => { + ifunc!(unsafe fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool) { + if detect::detect().zacas() { + zacas_release_fn + } else { + fallback::atomic_compare_exchange_non_seqcst + } + }) + } + Ordering::AcqRel => { + ifunc!(unsafe fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool) { + if detect::detect().zacas() { + zacas_acqrel_fn + } else { + fallback::atomic_compare_exchange_non_seqcst + } + }) + } + Ordering::SeqCst => { + ifunc!(unsafe fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool) { + if detect::detect().zacas() { + zacas_seqcst_fn + } else { + fallback::atomic_compare_exchange_seqcst + } + }) + } + _ => unreachable!(), + } + } + }; + if ok { Ok(prev) } else { Err(prev) } +} +#[inline] +unsafe fn atomic_compare_exchange_zacas( + dst: *mut u64, + old: u64, + new: u64, + success: Ordering, + failure: Ordering, +) -> (u64, bool) { + debug_assert!(dst.addr() % 8 == 0); + debug_assert_zacas!(); + let order = crate::utils::upgrade_success_ordering(success, failure); + let old = U64 { whole: old }; + let new = U64 { whole: new }; + let (prev_lo, prev_hi); + + // SAFETY: the caller must uphold the safety contract. + unsafe { + #[cfg(not(portable_atomic_pre_llvm_20))] + macro_rules! cmpxchg { + ($fence:tt, $asm_order:tt) => { + asm!( + start_zacas!(), + $fence, // fence + concat!("amocas.d", $asm_order, " a4, a2, 0({dst})"), // atomic { if *dst == a4:a5 { *dst = a2:a3 } else { a4:a5 = *dst } } + end_zacas!(), + dst = in(reg) ptr_reg!(dst), + // must be allocated to even/odd register pair + inout("a4") old.pair.lo => prev_lo, + inout("a5") old.pair.hi => prev_hi, + // must be allocated to even/odd register pair + in("a2") new.pair.lo, + in("a3") new.pair.hi, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(not(portable_atomic_pre_llvm_20))] + atomic_rmw_amocas_order!(cmpxchg, order, failure = failure); + #[cfg(portable_atomic_pre_llvm_20)] + macro_rules! cmpxchg { + ($fence:tt, $insn_order:tt) => { + asm!( + $fence, // fence + // amocas.d{,.aq,.rl,.aqrl} a4, a2, (a0) // atomic { if *a0 == a4:a5 { *a0 = a2:a3 } else { a4:a5 = *a0 } } + concat!(".4byte 0x2", $insn_order, "c5372f"), + in("a0") ptr_reg!(dst), + // must be allocated to even/odd register pair + inout("a4") old.pair.lo => prev_lo, + inout("a5") old.pair.hi => prev_hi, + // must be allocated to even/odd register pair + in("a2") new.pair.lo, + in("a3") new.pair.hi, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(portable_atomic_pre_llvm_20)] + atomic_rmw_amocas_order_insn!(cmpxchg, order, failure = failure); + let prev = U64 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole; + (prev, prev == old.whole) + } +} + +// amocas is always strong. +use self::atomic_compare_exchange as atomic_compare_exchange_weak; + +// 64-bit atomic load by two 32-bit atomic loads. +#[inline] +unsafe fn byte_wise_atomic_load(src: *const u64) -> u64 { + let (out_lo, out_hi); + + // SAFETY: the caller must uphold the safety contract. + unsafe { + asm!( + "lw {out_lo}, ({src})", // atomic { out_lo = *src } + "lw {out_hi}, 4({src})", // atomic { out_hi = *src.byte_add(4) } + src = in(reg) ptr_reg!(src), + out_lo = out(reg) out_lo, + out_hi = out(reg) out_hi, + options(pure, nostack, preserves_flags, readonly), + ); + U64 { pair: Pair { lo: out_lo, hi: out_hi } }.whole + } +} + +macro_rules! select_atomic_rmw { + ( + unsafe fn $name:ident(dst: *mut u64 $(, $($arg:tt)*)?) $(-> $ret_ty:ty)? { + |$zacas_fn_binding:ident| $($zacas_fn_body:tt)* + } + zacas = $zacas_fn:ident; + non_seqcst_fallback = $non_seqcst_fallback_fn:ident; + seqcst_fallback = $seqcst_fallback_fn:ident; + ) => { + #[inline] + unsafe fn $zacas_fn(dst: *mut u64 $(, $($arg)*)?, order: Ordering) $(-> $ret_ty)? { + // SAFETY: the caller must uphold the safety contract. + unsafe { + // This is not single-copy atomic reads, but this is ok because subsequent + // CAS will check for consistency. + // + // Note that the C++20 memory model does not allow mixed-sized atomic access, + // so we must use inline assembly to implement byte_wise_atomic_load. + // (i.e., byte-wise atomic based on the standard library's atomic types + // cannot be used here). + let mut prev = byte_wise_atomic_load(dst); + loop { + let next = { + let $zacas_fn_binding = prev; + $($zacas_fn_body)* + }; + match atomic_compare_exchange_weak(dst, prev, next, order, Ordering::Relaxed) { + Ok(x) => return x, + Err(x) => prev = x, + } + } + } + } + // If zacas is available at compile-time, we can always use zacas_fn. + #[cfg(any(target_feature = "zacas", portable_atomic_target_feature = "zacas"))] + use self::$zacas_fn as $name; + // Otherwise, we need to do run-time detection and can use zacas_fn only if zacas is available. + #[cfg(not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")))] + #[inline] + unsafe fn $name(dst: *mut u64 $(, $($arg)*)?, order: Ordering) $(-> $ret_ty)? { + fn_alias! { + // inline(never) is just a hint and also not strictly necessary + // because we use ifunc helper macro, but used for clarity. + #[inline(never)] + unsafe fn(dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)?; + zacas_relaxed_fn = $zacas_fn(Ordering::Relaxed); + zacas_acquire_fn = $zacas_fn(Ordering::Acquire); + zacas_release_fn = $zacas_fn(Ordering::Release); + zacas_acqrel_fn = $zacas_fn(Ordering::AcqRel); + zacas_seqcst_fn = $zacas_fn(Ordering::SeqCst); + } + // SAFETY: the caller must uphold the safety contract. + // we only calls zacas_fn if zacas is available. + unsafe { + match order { + Ordering::Relaxed => { + ifunc!(unsafe fn(dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)? { + if detect::detect().zacas() { + zacas_relaxed_fn + } else { + fallback::$non_seqcst_fallback_fn + } + }) + } + Ordering::Acquire => { + ifunc!(unsafe fn(dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)? { + if detect::detect().zacas() { + zacas_acquire_fn + } else { + fallback::$non_seqcst_fallback_fn + } + }) + } + Ordering::Release => { + ifunc!(unsafe fn(dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)? { + if detect::detect().zacas() { + zacas_release_fn + } else { + fallback::$non_seqcst_fallback_fn + } + }) + } + Ordering::AcqRel => { + ifunc!(unsafe fn(dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)? { + if detect::detect().zacas() { + zacas_acqrel_fn + } else { + fallback::$non_seqcst_fallback_fn + } + }) + } + Ordering::SeqCst => { + ifunc!(unsafe fn(dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)? { + if detect::detect().zacas() { + zacas_seqcst_fn + } else { + fallback::$seqcst_fallback_fn + } + }) + } + _ => unreachable!(), + } + } + } + }; +} + +select_atomic_rmw! { + unsafe fn atomic_swap(dst: *mut u64, val: u64) -> u64 { + |_x| val + } + zacas = atomic_swap_zacas; + non_seqcst_fallback = atomic_swap_non_seqcst; + seqcst_fallback = atomic_swap_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_add(dst: *mut u64, val: u64) -> u64 { + |x| x.wrapping_add(val) + } + zacas = atomic_add_zacas; + non_seqcst_fallback = atomic_add_non_seqcst; + seqcst_fallback = atomic_add_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_sub(dst: *mut u64, val: u64) -> u64 { + |x| x.wrapping_sub(val) + } + zacas = atomic_sub_zacas; + non_seqcst_fallback = atomic_sub_non_seqcst; + seqcst_fallback = atomic_sub_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_and(dst: *mut u64, val: u64) -> u64 { + |x| x & val + } + zacas = atomic_and_zacas; + non_seqcst_fallback = atomic_and_non_seqcst; + seqcst_fallback = atomic_and_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_nand(dst: *mut u64, val: u64) -> u64 { + |x| !(x & val) + } + zacas = atomic_nand_zacas; + non_seqcst_fallback = atomic_nand_non_seqcst; + seqcst_fallback = atomic_nand_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_or(dst: *mut u64, val: u64) -> u64 { + |x| x | val + } + zacas = atomic_or_zacas; + non_seqcst_fallback = atomic_or_non_seqcst; + seqcst_fallback = atomic_or_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_xor(dst: *mut u64, val: u64) -> u64 { + |x| x ^ val + } + zacas = atomic_xor_zacas; + non_seqcst_fallback = atomic_xor_non_seqcst; + seqcst_fallback = atomic_xor_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_max(dst: *mut u64, val: u64) -> u64 { + |x| { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + { core::cmp::max(x as i64, val as i64) as u64 } + } + } + zacas = atomic_max_zacas; + non_seqcst_fallback = atomic_max_non_seqcst; + seqcst_fallback = atomic_max_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_umax(dst: *mut u64, val: u64) -> u64 { + |x| core::cmp::max(x, val) + } + zacas = atomic_umax_zacas; + non_seqcst_fallback = atomic_umax_non_seqcst; + seqcst_fallback = atomic_umax_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_min(dst: *mut u64, val: u64) -> u64 { + |x| { + #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + { core::cmp::min(x as i64, val as i64) as u64 } + } + } + zacas = atomic_min_zacas; + non_seqcst_fallback = atomic_min_non_seqcst; + seqcst_fallback = atomic_min_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_umin(dst: *mut u64, val: u64) -> u64 { + |x| core::cmp::min(x, val) + } + zacas = atomic_umin_zacas; + non_seqcst_fallback = atomic_umin_non_seqcst; + seqcst_fallback = atomic_umin_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_not(dst: *mut u64) -> u64 { + |x| !x + } + zacas = atomic_not_zacas; + non_seqcst_fallback = atomic_not_non_seqcst; + seqcst_fallback = atomic_not_seqcst; +} +select_atomic_rmw! { + unsafe fn atomic_neg(dst: *mut u64) -> u64 { + |x| x.wrapping_neg() + } + zacas = atomic_neg_zacas; + non_seqcst_fallback = atomic_neg_non_seqcst; + seqcst_fallback = atomic_neg_seqcst; +} + +#[inline] +fn is_lock_free() -> bool { + #[cfg(any(target_feature = "zacas", portable_atomic_target_feature = "zacas"))] + { + // zacas is available at compile-time. + true + } + #[cfg(not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")))] + { + detect::detect().zacas() + } +} +const IS_ALWAYS_LOCK_FREE: bool = + cfg!(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")); + +atomic64!(AtomicI64, i64, atomic_max, atomic_min); +atomic64!(AtomicU64, u64, atomic_umax, atomic_umin); + +#[cfg(test)] +mod tests { + use super::*; + + test_atomic_int!(i64); + test_atomic_int!(u64); + + // load/store/swap implementation is not affected by signedness, so it is + // enough to test only unsigned types. + stress_test!(u64); +} diff --git a/vendor/portable-atomic/src/imp/avr.rs b/vendor/portable-atomic/src/imp/avr.rs new file mode 100644 index 0000000..d98c179 --- /dev/null +++ b/vendor/portable-atomic/src/imp/avr.rs @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Atomic load/store implementation on AVR. + +Operations not supported here are provided by disabling interrupts. +See also src/imp/interrupt/avr.rs. + +See "Atomic operation overview by architecture" in atomic-maybe-uninit for a more comprehensive and +detailed description of the atomic and synchronize instructions in this architecture: +https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#avr + +Note: Ordering is always SeqCst. + +Refs: +- AVR® Instruction Set Manual, Rev. DS40002198B + https://ww1.microchip.com/downloads/en/DeviceDoc/AVR-InstructionSet-Manual-DS40002198.pdf +- atomic-maybe-uninit + https://github.com/taiki-e/atomic-maybe-uninit + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +use core::{arch::asm, cell::UnsafeCell, sync::atomic::Ordering}; + +macro_rules! atomic8 { + ($atomic_type:ident, $value_type:ty) => { + #[repr(transparent)] + pub(crate) struct $atomic_type { + v: UnsafeCell<$value_type>, + } + + // Send is implicitly implemented for atomic integers, but not for atomic pointers. + // SAFETY: any data races are prevented by atomic operations. + unsafe impl Send for $atomic_type {} + // SAFETY: any data races are prevented by atomic operations. + unsafe impl Sync for $atomic_type {} + + impl $atomic_type { + #[inline] + #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] + pub(crate) fn load(&self, order: Ordering) -> $value_type { + crate::utils::assert_load_ordering(order); + let src = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + let out; + asm!( + "ld {out}, Z", // atomic { out = *Z } + out = out(reg) out, + in("Z") src, + options(nostack, preserves_flags), + ); + out + } + } + + #[inline] + #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] + pub(crate) fn store(&self, val: $value_type, order: Ordering) { + crate::utils::assert_store_ordering(order); + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + asm!( + "st Z, {val}", // atomic { *Z = val } + val = in(reg) val, + in("Z") dst, + options(nostack, preserves_flags), + ); + } + } + } + + #[cfg(any(target_feature = "rmw", portable_atomic_target_feature = "rmw"))] + impl $atomic_type { + #[inline] + pub(crate) fn swap(&self, val: $value_type, _order: Ordering) -> $value_type { + let dst = self.v.get(); + let out; + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + // cfg guarantee that the CPU supports RMW instructions. + unsafe { + asm!( + "xch Z, {val}", // atomic { _x = *Z; *Z = val; val = _x } + val = inout(reg) val => out, + in("Z") dst, + options(nostack, preserves_flags), + ); + } + out + } + + #[inline] + pub(crate) fn fetch_and(&self, val: $value_type, _order: Ordering) -> $value_type { + let dst = self.v.get(); + let out; + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + // cfg guarantee that the CPU supports RMW instructions. + unsafe { + asm!( + "lac Z, {val}", // atomic { _x = *Z; *Z &= !val; val = _x } + val = inout(reg) !val => out, + in("Z") dst, + options(nostack, preserves_flags), + ); + } + out + } + + #[inline] + pub(crate) fn fetch_or(&self, val: $value_type, _order: Ordering) -> $value_type { + let dst = self.v.get(); + let out; + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + // cfg guarantee that the CPU supports RMW instructions. + unsafe { + asm!( + "las Z, {val}", // atomic { _x = *Z; *Z |= val; val = _x } + val = inout(reg) val => out, + in("Z") dst, + options(nostack, preserves_flags), + ); + } + out + } + + #[inline] + pub(crate) fn fetch_xor(&self, val: $value_type, _order: Ordering) -> $value_type { + let dst = self.v.get(); + let out; + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + // cfg guarantee that the CPU supports RMW instructions. + unsafe { + asm!( + "lat Z, {val}", // atomic { _x = *Z; *Z ^= val; val = _x } + val = inout(reg) val => out, + in("Z") dst, + options(nostack, preserves_flags), + ); + } + out + } + + #[inline] + pub(crate) fn fetch_not(&self, order: Ordering) -> $value_type { + self.fetch_xor(!0, order) + } + } + }; +} + +atomic8!(AtomicI8, i8); +atomic8!(AtomicU8, u8); diff --git a/vendor/portable-atomic/src/imp/core_atomic.rs b/vendor/portable-atomic/src/imp/core_atomic.rs new file mode 100644 index 0000000..e104305 --- /dev/null +++ b/vendor/portable-atomic/src/imp/core_atomic.rs @@ -0,0 +1,574 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Wrap the standard library's atomic types in newtype. + +This is not a reexport, because we want to backport changes like +https://github.com/rust-lang/rust/pull/98383 to old compilers. +*/ + +use core::{cell::UnsafeCell, marker::PhantomData, sync::atomic::Ordering}; + +// core::panic::RefUnwindSafe is only available on Rust 1.56+, so on pre-1.56 +// Rust, we implement RefUnwindSafe when "std" feature is enabled. +// However, on pre-1.56 Rust, the standard library's atomic types implement +// RefUnwindSafe when "linked to std", and that's behavior that our other atomic +// implementations can't emulate, so use PhantomData to match +// conditions where our other atomic implementations implement RefUnwindSafe. +// +// If we do not do this, for example, downstream that is only tested on x86_64 +// may incorrectly assume that AtomicU64 always implements RefUnwindSafe even on +// older rustc, and may be broken on platforms where std AtomicU64 is not available. +struct NotRefUnwindSafe(UnsafeCell<()>); +// SAFETY: this is a marker type and we'll never access the value. +unsafe impl Sync for NotRefUnwindSafe {} + +#[repr(transparent)] +pub(crate) struct AtomicPtr { + pub(super) inner: core::sync::atomic::AtomicPtr, + // Prevent RefUnwindSafe from being propagated from the std atomic type. See NotRefUnwindSafe for more. + _not_ref_unwind_safe: PhantomData, +} +impl AtomicPtr { + #[inline] + pub(crate) const fn new(v: *mut T) -> Self { + Self { inner: core::sync::atomic::AtomicPtr::new(v), _not_ref_unwind_safe: PhantomData } + } + #[inline] + pub(crate) fn is_lock_free() -> bool { + Self::IS_ALWAYS_LOCK_FREE + } + pub(crate) const IS_ALWAYS_LOCK_FREE: bool = true; + const_fn! { + const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))]; + #[inline] + pub(crate) const fn as_ptr(&self) -> *mut *mut T { + // SAFETY: Self is #[repr(C)] and internally UnsafeCell<*mut T>. + // See also https://github.com/rust-lang/rust/pull/66705 and + // https://github.com/rust-lang/rust/issues/66136#issuecomment-557867116. + unsafe { (*(self as *const Self as *const UnsafeCell<*mut T>)).get() } + } + } +} +#[cfg(not(all( + target_arch = "arm", + not(any(miri, portable_atomic_sanitize_thread)), + any(target_os = "linux", target_os = "android"), + not(any(target_feature = "v6", portable_atomic_target_feature = "v6")), +)))] +impl AtomicPtr { + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn load(&self, order: Ordering) -> *mut T { + crate::utils::assert_load_ordering(order); // for track_caller (compiler can omit double check) + self.inner.load(order) + } + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn store(&self, ptr: *mut T, order: Ordering) { + crate::utils::assert_store_ordering(order); // for track_caller (compiler can omit double check) + self.inner.store(ptr, order); + } +} +#[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(not(portable_atomic_no_atomic_cas)))] +#[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg(target_has_atomic = "ptr"))] +items!({ + #[cfg(not(all( + target_arch = "arm", + not(any(miri, portable_atomic_sanitize_thread)), + any(target_os = "linux", target_os = "android"), + not(any(target_feature = "v6", portable_atomic_target_feature = "v6")), + )))] + impl AtomicPtr { + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn compare_exchange( + &self, + current: *mut T, + new: *mut T, + success: Ordering, + failure: Ordering, + ) -> Result<*mut T, *mut T> { + crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check) + #[cfg(portable_atomic_no_stronger_failure_ordering)] + let success = crate::utils::upgrade_success_ordering(success, failure); + self.inner.compare_exchange(current, new, success, failure) + } + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn compare_exchange_weak( + &self, + current: *mut T, + new: *mut T, + success: Ordering, + failure: Ordering, + ) -> Result<*mut T, *mut T> { + crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check) + #[cfg(portable_atomic_no_stronger_failure_ordering)] + let success = crate::utils::upgrade_success_ordering(success, failure); + self.inner.compare_exchange_weak(current, new, success, failure) + } + } + // Ideally, we would always use AtomicPtr::fetch_* since it is strict-provenance + // compatible, but it requires 1.91+. So, for now emulate it only on cfg(miri). + // Code using AtomicUsize::fetch_* via casts is still permissive-provenance + // compatible and is sound. + #[cfg(portable_atomic_no_strict_provenance_atomic_ptr)] + impl AtomicPtr { + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T { + #[cfg(miri)] + { + #[cfg(portable_atomic_no_strict_provenance)] + use crate::utils::ptr::PtrExt as _; + self.fetch_update_(order, |x| x.with_addr(x.addr().wrapping_add(val))) + } + #[cfg(not(miri))] + { + crate::utils::ptr::with_exposed_provenance_mut( + self.as_atomic_usize().fetch_add(val, order), + ) + } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T { + #[cfg(miri)] + { + #[cfg(portable_atomic_no_strict_provenance)] + use crate::utils::ptr::PtrExt as _; + self.fetch_update_(order, |x| x.with_addr(x.addr().wrapping_sub(val))) + } + #[cfg(not(miri))] + { + crate::utils::ptr::with_exposed_provenance_mut( + self.as_atomic_usize().fetch_sub(val, order), + ) + } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_or(&self, val: usize, order: Ordering) -> *mut T { + #[cfg(miri)] + { + #[cfg(portable_atomic_no_strict_provenance)] + use crate::utils::ptr::PtrExt as _; + self.fetch_update_(order, |x| x.with_addr(x.addr() | val)) + } + #[cfg(not(miri))] + { + crate::utils::ptr::with_exposed_provenance_mut( + self.as_atomic_usize().fetch_or(val, order), + ) + } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_and(&self, val: usize, order: Ordering) -> *mut T { + #[cfg(miri)] + { + #[cfg(portable_atomic_no_strict_provenance)] + use crate::utils::ptr::PtrExt as _; + self.fetch_update_(order, |x| x.with_addr(x.addr() & val)) + } + #[cfg(not(miri))] + { + crate::utils::ptr::with_exposed_provenance_mut( + self.as_atomic_usize().fetch_and(val, order), + ) + } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T { + #[cfg(miri)] + { + #[cfg(portable_atomic_no_strict_provenance)] + use crate::utils::ptr::PtrExt as _; + self.fetch_update_(order, |x| x.with_addr(x.addr() ^ val)) + } + #[cfg(not(miri))] + { + crate::utils::ptr::with_exposed_provenance_mut( + self.as_atomic_usize().fetch_xor(val, order), + ) + } + } + #[cfg(miri)] + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + fn fetch_update_(&self, order: Ordering, mut f: F) -> *mut T + where + F: FnMut(*mut T) -> *mut T, + { + // This is a private function and all instances of `f` only operate on the value + // loaded, so there is no need to synchronize the first load/failed CAS. + let mut prev = self.load(Ordering::Relaxed); + loop { + let next = f(prev); + match self.compare_exchange_weak(prev, next, order, Ordering::Relaxed) { + Ok(x) => return x, + Err(next_prev) => prev = next_prev, + } + } + } + #[cfg(not(miri))] + #[inline(always)] + fn as_atomic_usize(&self) -> &AtomicUsize { + static_assert!( + core::mem::size_of::>() == core::mem::size_of::() + ); + static_assert!( + core::mem::align_of::>() == core::mem::align_of::() + ); + // SAFETY: AtomicPtr and AtomicUsize have the same layout, + // and both access data in the same way. + unsafe { &*(self as *const Self as *const AtomicUsize) } + } + } + #[cfg(not(all( + any(target_arch = "x86", target_arch = "x86_64"), + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + )))] + impl_default_bit_opts!(AtomicPtr, usize); +}); +impl core::ops::Deref for AtomicPtr { + type Target = core::sync::atomic::AtomicPtr; + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +// NB: Sync with atomic_int! macro in arm_linux.rs +macro_rules! atomic_int { + ($atomic_type:ident, $int_type:ident) => { + #[repr(transparent)] + pub(crate) struct $atomic_type { + pub(super) inner: core::sync::atomic::$atomic_type, + // Prevent RefUnwindSafe from being propagated from the std atomic type. See NotRefUnwindSafe for more. + _not_ref_unwind_safe: PhantomData, + } + impl $atomic_type { + #[inline] + pub(crate) const fn new(v: $int_type) -> Self { + Self { + inner: core::sync::atomic::$atomic_type::new(v), + _not_ref_unwind_safe: PhantomData, + } + } + #[inline] + pub(crate) fn is_lock_free() -> bool { + Self::IS_ALWAYS_LOCK_FREE + } + // ESP-IDF targets' 64-bit atomics are not lock-free. + // https://github.com/rust-lang/rust/pull/115577#issuecomment-1732259297 + pub(crate) const IS_ALWAYS_LOCK_FREE: bool = cfg!(not(all( + any(target_arch = "riscv32", target_arch = "xtensa"), + target_os = "espidf", + ))) | (core::mem::size_of::<$int_type>() + < 8); + const_fn! { + const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))]; + #[inline] + pub(crate) const fn as_ptr(&self) -> *mut $int_type { + // SAFETY: Self is #[repr(C)] and internally UnsafeCell<$int_type>. + // See also https://github.com/rust-lang/rust/pull/66705 and + // https://github.com/rust-lang/rust/issues/66136#issuecomment-557867116. + unsafe { + (*(self as *const Self as *const UnsafeCell<$int_type>)).get() + } + } + } + } + #[cfg(not(all( + target_arch = "arm", + not(any(miri, portable_atomic_sanitize_thread)), + any(target_os = "linux", target_os = "android"), + not(any(target_feature = "v6", portable_atomic_target_feature = "v6")), + )))] + impl $atomic_type { + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn load(&self, order: Ordering) -> $int_type { + crate::utils::assert_load_ordering(order); // for track_caller (compiler can omit double check) + self.inner.load(order) + } + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn store(&self, val: $int_type, order: Ordering) { + crate::utils::assert_store_ordering(order); // for track_caller (compiler can omit double check) + self.inner.store(val, order); + } + } + #[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(not(portable_atomic_no_atomic_cas)) + )] + #[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg(target_has_atomic = "ptr"))] + items!({ + impl_default_no_fetch_ops!($atomic_type, $int_type); + #[cfg(not(all( + target_arch = "arm", + not(any(miri, portable_atomic_sanitize_thread)), + any(target_os = "linux", target_os = "android"), + not(any(target_feature = "v6", portable_atomic_target_feature = "v6")), + )))] + impl $atomic_type { + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn compare_exchange( + &self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering, + ) -> Result<$int_type, $int_type> { + crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check) + #[cfg(portable_atomic_no_stronger_failure_ordering)] + let success = crate::utils::upgrade_success_ordering(success, failure); + self.inner.compare_exchange(current, new, success, failure) + } + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn compare_exchange_weak( + &self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering, + ) -> Result<$int_type, $int_type> { + crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check) + #[cfg(portable_atomic_no_stronger_failure_ordering)] + let success = crate::utils::upgrade_success_ordering(success, failure); + self.inner.compare_exchange_weak(current, new, success, failure) + } + } + impl $atomic_type { + #[allow(dead_code)] + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + fn fetch_update_(&self, order: Ordering, mut f: F) -> $int_type + where + F: FnMut($int_type) -> $int_type, + { + // This is a private function and all instances of `f` only operate on the value + // loaded, so there is no need to synchronize the first load/failed CAS. + let mut prev = self.load(Ordering::Relaxed); + loop { + let next = f(prev); + match self.compare_exchange_weak(prev, next, order, Ordering::Relaxed) { + Ok(x) => return x, + Err(next_prev) => prev = next_prev, + } + } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { + #[cfg(not(portable_atomic_no_atomic_min_max))] + { + #[cfg(any( + all( + any(target_arch = "aarch64", target_arch = "arm64ec"), + any( + target_feature = "lse", + portable_atomic_target_feature = "lse", + ), + ), + all( + target_arch = "arm", + not(any( + target_feature = "v6", + portable_atomic_target_feature = "v6", + )), + ), + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "powerpc", + target_arch = "powerpc64", + ))] + { + // HACK: the following operations are currently broken (at least on qemu-user): + // - aarch64's `AtomicI{8,16}::fetch_{max,min}` (release mode + lse) + // - armv5te's `Atomic{I,U}{8,16}::fetch_{max,min}` + // - mips's `AtomicI8::fetch_{max,min}` (release mode) + // - mipsel's `AtomicI{8,16}::fetch_{max,min}` (debug mode, at least) + // - mips64's `AtomicI8::fetch_{max,min}` (release mode) + // - mips64el's `AtomicI{8,16}::fetch_{max,min}` (debug mode, at least) + // - powerpc's `AtomicI{8,16}::fetch_{max,min}` + // - powerpc64's `AtomicI{8,16}::fetch_{max,min}` (debug mode, at least) + // - powerpc64le's `AtomicU{8,16}::fetch_{max,min}` (release mode + fat LTO) + // See also: + // https://github.com/llvm/llvm-project/issues/61880 + // https://github.com/llvm/llvm-project/issues/61881 + // https://github.com/llvm/llvm-project/issues/61882 + // https://github.com/taiki-e/portable-atomic/issues/2 + // https://github.com/rust-lang/rust/issues/100650 + if core::mem::size_of::<$int_type>() <= 2 { + return self.fetch_update_(order, |x| core::cmp::max(x, val)); + } + } + self.inner.fetch_max(val, order) + } + #[cfg(portable_atomic_no_atomic_min_max)] + { + self.fetch_update_(order, |x| core::cmp::max(x, val)) + } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { + #[cfg(not(portable_atomic_no_atomic_min_max))] + { + #[cfg(any( + all( + any(target_arch = "aarch64", target_arch = "arm64ec"), + any( + target_feature = "lse", + portable_atomic_target_feature = "lse", + ), + ), + all( + target_arch = "arm", + not(any( + target_feature = "v6", + portable_atomic_target_feature = "v6", + )), + ), + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "powerpc", + target_arch = "powerpc64", + ))] + { + // HACK: the following operations are currently broken (at least on qemu-user): + // - aarch64's `AtomicI{8,16}::fetch_{max,min}` (release mode + lse) + // - armv5te's `Atomic{I,U}{8,16}::fetch_{max,min}` + // - mips's `AtomicI8::fetch_{max,min}` (release mode) + // - mipsel's `AtomicI{8,16}::fetch_{max,min}` (debug mode, at least) + // - mips64's `AtomicI8::fetch_{max,min}` (release mode) + // - mips64el's `AtomicI{8,16}::fetch_{max,min}` (debug mode, at least) + // - powerpc's `AtomicI{8,16}::fetch_{max,min}` + // - powerpc64's `AtomicI{8,16}::fetch_{max,min}` (debug mode, at least) + // - powerpc64le's `AtomicU{8,16}::fetch_{max,min}` (release mode + fat LTO) + // See also: + // https://github.com/llvm/llvm-project/issues/61880 + // https://github.com/llvm/llvm-project/issues/61881 + // https://github.com/llvm/llvm-project/issues/61882 + // https://github.com/taiki-e/portable-atomic/issues/2 + // https://github.com/rust-lang/rust/issues/100650 + if core::mem::size_of::<$int_type>() <= 2 { + return self.fetch_update_(order, |x| core::cmp::min(x, val)); + } + } + self.inner.fetch_min(val, order) + } + #[cfg(portable_atomic_no_atomic_min_max)] + { + self.fetch_update_(order, |x| core::cmp::min(x, val)) + } + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_not(&self, order: Ordering) -> $int_type { + self.fetch_xor(!0, order) + } + // TODO: provide asm-based implementation on AArch64 without FEAT_LSE, Armv7, RISC-V, etc. + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_neg(&self, order: Ordering) -> $int_type { + self.fetch_update_(order, $int_type::wrapping_neg) + } + } + #[cfg(not(all( + any(target_arch = "x86", target_arch = "x86_64"), + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + )))] + items!({ + impl_default_bit_opts!($atomic_type, $int_type); + impl $atomic_type { + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn not(&self, order: Ordering) { + self.fetch_not(order); + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn neg(&self, order: Ordering) { + self.fetch_neg(order); + } + } + }); + }); + impl core::ops::Deref for $atomic_type { + type Target = core::sync::atomic::$atomic_type; + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + fn deref(&self) -> &Self::Target { + &self.inner + } + } + }; +} + +atomic_int!(AtomicIsize, isize); +atomic_int!(AtomicUsize, usize); +#[cfg(not(portable_atomic_no_atomic_load_store))] +atomic_int!(AtomicI8, i8); +#[cfg(not(portable_atomic_no_atomic_load_store))] +atomic_int!(AtomicU8, u8); +#[cfg(not(portable_atomic_no_atomic_load_store))] +atomic_int!(AtomicI16, i16); +#[cfg(not(portable_atomic_no_atomic_load_store))] +atomic_int!(AtomicU16, u16); +#[cfg(not(portable_atomic_no_atomic_load_store))] +#[cfg(not(target_pointer_width = "16"))] +atomic_int!(AtomicI32, i32); +#[cfg(not(portable_atomic_no_atomic_load_store))] +#[cfg(not(target_pointer_width = "16"))] +atomic_int!(AtomicU32, u32); +#[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(not(portable_atomic_no_atomic_64)))] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any( + target_has_atomic = "64", + not(any(target_pointer_width = "16", target_pointer_width = "32")), + )) +)] +items!({ + atomic_int!(AtomicI64, i64); + atomic_int!(AtomicU64, u64); +}); diff --git a/vendor/portable-atomic/src/imp/detect/README.md b/vendor/portable-atomic/src/imp/detect/README.md new file mode 100644 index 0000000..b0ee5ac --- /dev/null +++ b/vendor/portable-atomic/src/imp/detect/README.md @@ -0,0 +1,38 @@ +# Run-time CPU feature detection + +This module has run-time CPU feature detection implementations. + +Here is the table of targets that support run-time CPU feature detection and the instruction or API used: + +| target_arch | target_os/target_env | instruction/API | features | note | +| ----------- | -------------------- | --------------- | -------- | ---- | +| x86_64 | all (except for sgx) | cpuid | all | Enabled by default | +| aarch64 | linux (gnu/ohos/uclibc) | getauxval | all | Enabled by default (dlsym is used by default if needed for compatibility with older versions) | +| aarch64 | linux (musl) | getauxval | all | Only enabled by default when dynamic linking or `std` feature enabled (both disabled by default, see [auxv.rs](auxv.rs)) | +| aarch64 | android | getauxval | all | Enabled by default | +| aarch64 | freebsd | elf_aux_info | all | Enabled by default | +| aarch64 | netbsd | sysctlbyname | all | Enabled by default | +| aarch64 | openbsd | sysctl | all | Enabled by default | +| aarch64 | macos/ios/tvos/watchos/visionos | sysctlbyname | all | Enabled by default | +| aarch64 | illumos | getisax | lse, lse2 | Enabled by default | +| aarch64/arm64ec | windows | IsProcessorFeaturePresent | lse, lse2 | Enabled by default | +| aarch64 | fuchsia | zx_system_get_features | lse | Enabled by default | +| riscv32/riscv64 | linux/android | riscv_hwprobe | all | Enabled by default | +| powerpc64 | linux (gnu/ohos/uclibc) | getauxval | all | Enabled by default (dlsym is used by default if needed for compatibility with older versions) | +| powerpc64 | linux (musl) | getauxval | all | Only enabled by default when dynamic linking or `std` feature enabled (both disabled by default, see [auxv.rs](auxv.rs)) | +| powerpc64 | freebsd | elf_aux_info | all | Enabled by default (dlsym is used by default for compatibility with older versions) | +| powerpc64 | openbsd | elf_aux_info | all | Enabled by default (dlsym is used by default for compatibility with older versions) | +| powerpc64 | aix | getsystemcfg | all | Requires LLVM 20+. Disabled by default (see [powerpc64_aix.rs](powerpc64_aix.rs)) | + +Run-time detection is enabled by default on most targets and can be disabled with `--cfg portable_atomic_no_outline_atomics`. + +On some targets, run-time detection is disabled by default mainly for compatibility with incomplete build environments or support for it is experimental, and can be enabled by `--cfg portable_atomic_outline_atomics`. (When both cfg are enabled, `*_no_*` cfg is preferred.) + +`dlsym` usually not working with static linking, so detection using implementations that use `dlsym` for compatibility will be disabled if static linking is enabled. +You can use `--cfg portable_atomic_outline_atomics` to force the use of non-`dlsym` implementations and enable run-time detection in such an environment. + +For targets not included in the above table, run-time detection is always disabled and works the same as when `--cfg portable_atomic_no_outline_atomics` is set. + +See [auxv.rs](auxv.rs) module-level comments for more details on Linux/Android/FreeBSD/OpenBSD. + +See also [docs about `portable_atomic_no_outline_atomics` cfg](https://github.com/taiki-e/portable-atomic/blob/HEAD/README.md#optional-cfg-no-outline-atomics) in the top-level readme. diff --git a/vendor/portable-atomic/src/imp/detect/aarch64_aa64reg.rs b/vendor/portable-atomic/src/imp/detect/aarch64_aa64reg.rs new file mode 100644 index 0000000..de3144b --- /dev/null +++ b/vendor/portable-atomic/src/imp/detect/aarch64_aa64reg.rs @@ -0,0 +1,492 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Run-time CPU feature detection on AArch64 Linux/Android/FreeBSD/NetBSD/OpenBSD by parsing system registers. + +As of Rust 1.94, is_aarch64_feature_detected doesn't support run-time detection on NetBSD. +https://github.com/rust-lang/rust/blob/1.94.0/library/std_detect/src/detect/mod.rs +Run-time detection on OpenBSD by is_aarch64_feature_detected is supported on Rust 1.70+. +https://github.com/rust-lang/stdarch/pull/1374 + +Refs: +- https://developer.arm.com/documentation/ddi0601/2025-06/AArch64-Registers +- https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/arm64/cpu-feature-registers.rst +- https://github.com/rust-lang/stdarch/blob/a0c30f3e3c75adcd6ee7efc94014ebcead61c507/crates/std_detect/src/detect/os/aarch64.rs + +Supported platforms: +- Linux 4.11+ (emulate mrs instruction) + https://github.com/torvalds/linux/commit/77c97b4ee21290f5f083173d957843b615abbff2 +- FreeBSD 12.0+ (emulate mrs instruction) + https://github.com/freebsd/freebsd-src/commit/398810619cb32abf349f8de23f29510b2ee0839b +- NetBSD 9.0+ (through sysctl/sysctlbyname) + https://github.com/NetBSD/src/commit/0e9d25528729f7fea53e78275d1bc5039dfe8ffb + sysctl/sysctlbyname returns an unsupported error if operation is not supported, + so we can safely use this on older versions. +- OpenBSD 7.1+ (through sysctl) + https://github.com/openbsd/src/commit/d335af936b9d7dd9cf655cae1ce19560c45de6c8 + sysctl returns an unsupported error if operation is not supported, + so we can safely use this on older versions. + +For now, this module is only used on NetBSD/OpenBSD. + +On Linux/Android/FreeBSD, we use auxv.rs and this module is test-only because: +- On Linux/Android, this approach requires a higher kernel version than Rust supports, + and also does not work with qemu-user (as of QEMU 7.2) and Valgrind (as of Valgrind 3.24). + (Looking into HWCAP_CPUID in auxvec, it appears that Valgrind is setting it + to false correctly, but qemu-user is setting it to true.) + - qemu-user issue seem to be fixed as of QEMU 9.2. +- On FreeBSD, this approach does not work on FreeBSD 12 on QEMU (confirmed on + FreeBSD 12.{2,3,4}), and we got SIGILL (worked on FreeBSD 13 and 14). +*/ + +include!("common.rs"); + +#[cfg_attr(test, derive(Debug, PartialEq))] +struct AA64Reg { + aa64isar0: u64, + aa64isar1: u64, + #[cfg(test)] + aa64isar3: u64, + aa64mmfr2: u64, +} + +#[cold] +#[must_use] +fn _detect(mut info: CpuInfo) -> CpuInfo { + let AA64Reg { + aa64isar0, + aa64isar1, + #[cfg(test)] + aa64isar3, + aa64mmfr2, + } = imp::aa64reg(); + + // ID_AA64ISAR0_EL1, AArch64 Instruction Set Attribute Register 0 + // https://developer.arm.com/documentation/ddi0601/2025-06/AArch64-Registers/ID-AA64ISAR0-EL1--AArch64-Instruction-Set-Attribute-Register-0 + // Atomic, bits [23:20] + // > FEAT_LSE implements the functionality identified by the value 0b0010. + // > FEAT_LSE128 implements the functionality identified by the value 0b0011. + // > From Armv8.1, the value 0b0000 is not permitted. + let atomic = extract(aa64isar0, 23, 20); + if atomic >= 0b0010 { + info.set(CpuInfoFlag::lse); + if atomic >= 0b0011 { + info.set(CpuInfoFlag::lse128); + } + } + // ID_AA64ISAR1_EL1, AArch64 Instruction Set Attribute Register 1 + // https://developer.arm.com/documentation/ddi0601/2025-06/AArch64-Registers/ID-AA64ISAR1-EL1--AArch64-Instruction-Set-Attribute-Register-1 + // LRCPC, bits [23:20] + // > FEAT_LRCPC implements the functionality identified by the value 0b0001. + // > FEAT_LRCPC2 implements the functionality identified by the value 0b0010. + // > FEAT_LRCPC3 implements the functionality identified by the value 0b0011. + // > From Armv8.3, the value 0b0000 is not permitted. + // > From Armv8.4, the value 0b0001 is not permitted. + let lrcpc = extract(aa64isar1, 23, 20); + if lrcpc >= 0b0011 { + info.set(CpuInfoFlag::rcpc3); + } + #[cfg(test)] + if lrcpc >= 0b0001 { + info.set(CpuInfoFlag::rcpc); + if lrcpc >= 0b0010 { + info.set(CpuInfoFlag::rcpc2); + } + } + // LS64, bits [63:60] + // > FEAT_LS64 implements the functionality identified by 0b0001. + // > FEAT_LS64_V implements the functionality identified by 0b0010. + // > FEAT_LS64_ACCDATA implements the functionality identified by 0b0011. + // > FEAT_LS64WB implements the functionality identified by 0b0100. + #[cfg(test)] + if extract(aa64isar1, 63, 60) >= 0b0100 { + info.set(CpuInfoFlag::ls64wb); + } + // ID_AA64ISAR3_EL1, AArch64 Instruction Set Attribute Register 3 + // https://developer.arm.com/documentation/ddi0601/2025-06/AArch64-Registers/ID-AA64ISAR3-EL1--AArch64-Instruction-Set-Attribute-Register-3 + // LSFE, bits [19:16] + // > FEAT_LSFE implements the functionality identified by the value 0b0001 + #[cfg(test)] + if extract(aa64isar3, 19, 16) >= 0b0001 { + info.set(CpuInfoFlag::lsfe); + } + // ID_AA64MMFR2_EL1, AArch64 Memory Model Feature Register 2 + // https://developer.arm.com/documentation/ddi0601/2025-06/AArch64-Registers/ID-AA64MMFR2-EL1--AArch64-Memory-Model-Feature-Register-2 + // AT, bits [35:32] + // > FEAT_LSE2 implements the functionality identified by the value 0b0001. + // > From Armv8.4, the value 0b0000 is not permitted. + if extract(aa64mmfr2, 35, 32) >= 0b0001 { + info.set(CpuInfoFlag::lse2); + } + info +} + +fn extract(x: u64, high: usize, low: usize) -> u64 { + (x >> low) & ((1 << (high - low + 1)) - 1) +} + +#[cfg(not(any(target_os = "netbsd", target_os = "openbsd")))] +mod imp { + // This module is test-only. See parent module docs for details. + + #[cfg(not(portable_atomic_no_asm))] + use core::arch::asm; + + use super::AA64Reg; + + pub(super) fn aa64reg() -> AA64Reg { + // SAFETY: This is safe on FreeBSD 12.0+. FreeBSD 11 was EoL on 2021-09-30. + // Note that stdarch has been doing the same thing since before FreeBSD 11 was EoL. + // https://github.com/rust-lang/stdarch/pull/611 + unsafe { + let aa64isar0: u64; + asm!( + "mrs {}, ID_AA64ISAR0_EL1", + out(reg) aa64isar0, + options(pure, nomem, nostack, preserves_flags), + ); + let aa64isar1: u64; + asm!( + "mrs {}, ID_AA64ISAR1_EL1", + out(reg) aa64isar1, + options(pure, nomem, nostack, preserves_flags), + ); + #[cfg(test)] + #[cfg(not(portable_atomic_pre_llvm_18))] + let aa64isar3: u64; + // ID_AA64ISAR3_EL1 is only recognized on LLVM 18+. + // https://github.com/llvm/llvm-project/commit/17baba9fa2728b1b1134f9dccb9318debd5a9a1b + #[cfg(test)] + #[cfg(not(portable_atomic_pre_llvm_18))] + asm!( + "mrs {}, ID_AA64ISAR3_EL1", + out(reg) aa64isar3, + options(pure, nomem, nostack, preserves_flags), + ); + let aa64mmfr2: u64; + asm!( + "mrs {}, ID_AA64MMFR2_EL1", + out(reg) aa64mmfr2, + options(pure, nomem, nostack, preserves_flags), + ); + AA64Reg { + aa64isar0, + aa64isar1, + #[cfg(test)] + #[cfg(not(portable_atomic_pre_llvm_18))] + aa64isar3, + #[cfg(test)] + #[cfg(portable_atomic_pre_llvm_18)] + aa64isar3: 0, + aa64mmfr2, + } + } + } +} +#[cfg(target_os = "netbsd")] +mod imp { + // NetBSD doesn't trap the mrs instruction, but exposes the system registers through sysctl. + // https://github.com/NetBSD/src/commit/0e9d25528729f7fea53e78275d1bc5039dfe8ffb + // https://github.com/golang/sys/commit/ef9fd89ba245e184bdd308f7f2b4f3c551fa5b0f + + use core::{mem, ptr}; + + use super::AA64Reg; + + // libc requires Rust 1.63 + #[allow(non_camel_case_types)] + pub(super) mod ffi { + pub(crate) use crate::utils::ffi::{CStr, c_char, c_int, c_size_t, c_void}; + + sys_struct!({ + // Defined in machine/armreg.h. + // https://github.com/NetBSD/src/blob/121914f187d0f46c2ce43f00531d2c500d8e81e5/sys/arch/aarch64/include/armreg.h#L1863 + pub(crate) struct aarch64_sysctl_cpu_id { + // NetBSD 9.0+ + // https://github.com/NetBSD/src/commit/0e9d25528729f7fea53e78275d1bc5039dfe8ffb + pub(crate) ac_midr: u64, + pub(crate) ac_revidr: u64, + pub(crate) ac_mpidr: u64, + pub(crate) ac_aa64dfr0: u64, + pub(crate) ac_aa64dfr1: u64, + pub(crate) ac_aa64isar0: u64, + pub(crate) ac_aa64isar1: u64, + pub(crate) ac_aa64mmfr0: u64, + pub(crate) ac_aa64mmfr1: u64, + pub(crate) ac_aa64mmfr2: u64, + pub(crate) ac_aa64pfr0: u64, + pub(crate) ac_aa64pfr1: u64, + pub(crate) ac_aa64zfr0: u64, + pub(crate) ac_mvfr0: u32, + pub(crate) ac_mvfr1: u32, + pub(crate) ac_mvfr2: u32, + // NetBSD 10.0+ + // https://github.com/NetBSD/src/commit/0c7bdc13f0e332cccec56e307f023b4888638973 + pub(crate) ac_pad: u32, + pub(crate) ac_clidr: u64, + pub(crate) ac_ctr: u64, + } + }); + + sys_fn!({ + extern "C" { + // Defined in sys/sysctl.h. + // https://man.netbsd.org/sysctl.3 + // https://github.com/NetBSD/src/blob/121914f187d0f46c2ce43f00531d2c500d8e81e5/sys/sys/sysctl.h + pub(crate) fn sysctlbyname( + name: *const c_char, + old_p: *mut c_void, + old_len_p: *mut c_size_t, + new_p: *const c_void, + new_len: c_size_t, + ) -> c_int; + } + }); + } + + pub(super) fn sysctl_cpu_id(name: &ffi::CStr) -> Option { + const OUT_LEN: ffi::c_size_t = + mem::size_of::() as ffi::c_size_t; + + // SAFETY: all fields of aarch64_sysctl_cpu_id are zero-able and we use + // the result when machdep.cpuN.cpu_id sysctl was successful. + let mut buf: ffi::aarch64_sysctl_cpu_id = unsafe { mem::zeroed() }; + let mut out_len = OUT_LEN; + // SAFETY: + // - `name` a valid C string. + // - `out_len` does not exceed the size of the value at `buf`. + // - `sysctlbyname` is thread-safe. + let res = unsafe { + ffi::sysctlbyname( + name.as_ptr(), + (&mut buf as *mut ffi::aarch64_sysctl_cpu_id).cast::(), + &mut out_len, + ptr::null_mut(), + 0, + ) + }; + if res != 0 { + return None; + } + Some(AA64Reg { + aa64isar0: buf.ac_aa64isar0, + aa64isar1: buf.ac_aa64isar1, + #[cfg(test)] + aa64isar3: 0, + aa64mmfr2: buf.ac_aa64mmfr2, + }) + } + + pub(super) fn aa64reg() -> AA64Reg { + // Get system registers for cpu0. + // If failed, returns default because machdep.cpuN.cpu_id sysctl is not available. + // machdep.cpuN.cpu_id sysctl was added in NetBSD 9.0 so it is not available on older versions. + // It is ok to check only cpu0, even if there are more CPUs. + // https://github.com/NetBSD/src/commit/bd9707e06ea7d21b5c24df6dfc14cb37c2819416 + // https://github.com/golang/sys/commit/ef9fd89ba245e184bdd308f7f2b4f3c551fa5b0f + match sysctl_cpu_id(c!("machdep.cpu0.cpu_id")) { + Some(cpu_id) => cpu_id, + None => AA64Reg { + aa64isar0: 0, + aa64isar1: 0, + #[cfg(test)] + aa64isar3: 0, + aa64mmfr2: 0, + }, + } + } +} +#[cfg(target_os = "openbsd")] +mod imp { + // OpenBSD doesn't trap the mrs instruction, but exposes the system registers through sysctl. + // https://github.com/openbsd/src/commit/d335af936b9d7dd9cf655cae1ce19560c45de6c8 + // https://github.com/golang/go/commit/cd54ef1f61945459486e9eea2f016d99ef1da925 + + use core::{mem, ptr}; + + use super::AA64Reg; + + // libc requires Rust 1.63 + pub(super) mod ffi { + pub(crate) use crate::utils::ffi::{c_int, c_size_t, c_uint, c_void}; + + sys_const!({ + // Defined in sys/sysctl.h. + // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/sys/sysctl.h + pub(crate) const CTL_MACHDEP: c_int = 7; + + // Defined in machine/cpu.h. + // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/arch/arm64/include/cpu.h + // OpenBSD 7.1+ + // https://github.com/openbsd/src/commit/d335af936b9d7dd9cf655cae1ce19560c45de6c8 + pub(crate) const CPU_ID_AA64ISAR0: c_int = 2; + pub(crate) const CPU_ID_AA64ISAR1: c_int = 3; + // OpenBSD 7.3+ + // https://github.com/openbsd/src/commit/c7654cd65262d532212f65123ee3905ba200365c + // However, on OpenBSD 7.3-7.5, querying CPU_ID_AA64MMFR2 always returns 0. + // https://github.com/openbsd/src/commit/e8331b74e5c20302d4bd948c9db722af688ccfc1 + pub(crate) const CPU_ID_AA64MMFR2: c_int = 7; + }); + + sys_fn!({ + extern "C" { + // Defined in sys/sysctl.h. + // https://man.openbsd.org/sysctl.2 + // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/sys/sysctl.h + pub(crate) fn sysctl( + name: *const c_int, + name_len: c_uint, + old_p: *mut c_void, + old_len_p: *mut c_size_t, + new_p: *mut c_void, + new_len: c_size_t, + ) -> c_int; + } + }); + } + + // sysctl returns an unsupported error if operation is not supported, + // so we can safely use this function on older versions of OpenBSD. + pub(super) fn aa64reg() -> AA64Reg { + let aa64isar0 = sysctl64(&[ffi::CTL_MACHDEP, ffi::CPU_ID_AA64ISAR0]).unwrap_or(0); + let aa64isar1 = sysctl64(&[ffi::CTL_MACHDEP, ffi::CPU_ID_AA64ISAR1]).unwrap_or(0); + let aa64mmfr2 = sysctl64(&[ffi::CTL_MACHDEP, ffi::CPU_ID_AA64MMFR2]).unwrap_or(0); + AA64Reg { + aa64isar0, + aa64isar1, + #[cfg(test)] + aa64isar3: 0, + aa64mmfr2, + } + } + + fn sysctl64(mib: &[ffi::c_int]) -> Option { + const OUT_LEN: ffi::c_size_t = mem::size_of::() as ffi::c_size_t; + let mut out = 0_u64; + let mut out_len = OUT_LEN; + #[allow(clippy::cast_possible_truncation)] + let mib_len = mib.len() as ffi::c_uint; + // SAFETY: + // - `mib_len` does not exceed the size of `mib`. + // - `out_len` does not exceed the size of `out`. + // - `sysctl` is thread-safe. + let res = unsafe { + ffi::sysctl( + mib.as_ptr(), + mib_len, + (&mut out as *mut u64).cast::(), + &mut out_len, + ptr::null_mut(), + 0, + ) + }; + // OpenBSD sysctl returns -1 on failure. + if res == -1 { + return None; + } + debug_assert_eq!(out_len, OUT_LEN); + Some(out) + } +} + +#[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks, + clippy::wildcard_imports +)] +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[cfg_attr(portable_atomic_test_detect_false, ignore = "detection disabled")] + fn test_aa64reg() { + let AA64Reg { aa64isar0, aa64isar1, aa64isar3, aa64mmfr2 } = imp::aa64reg(); + test_helper::eprintln_nocapture!( + "aa64isar0={},aa64isar1={},aa64isar3={},aa64mmfr2={}", + aa64isar0, + aa64isar1, + aa64isar3, + aa64mmfr2, + ); + let atomic = extract(aa64isar0, 23, 20); + if detect().lse() { + if detect().lse128() { + assert_eq!(atomic, 0b0011); + } else { + assert_eq!(atomic, 0b0010); + } + } else { + assert_eq!(atomic, 0b0000); + } + let lrcpc = extract(aa64isar1, 23, 20); + if detect().rcpc() { + if detect().rcpc2() { + if detect().rcpc3() { + assert_eq!(lrcpc, 0b0011); + } else { + assert_eq!(lrcpc, 0b0010); + } + } else { + assert_eq!(lrcpc, 0b0001); + } + } else { + assert_eq!(lrcpc, 0b0000); + } + let ls64 = extract(aa64isar1, 63, 60); + if detect().ls64wb() { + assert_eq!(ls64, 0b0100); + } else { + assert!(ls64 < 0b0100, "{}", ls64); + } + let lsfe = extract(aa64isar3, 19, 16); + if detect().lsfe() { + assert_eq!(lsfe, 0b0001); + } else { + assert_eq!(lsfe, 0b0000); + } + let at = extract(aa64mmfr2, 35, 32); + if detect().lse2() { + assert_eq!(at, 0b0001); + } else { + assert_eq!(at, 0b0000); + } + } + + #[cfg(target_os = "openbsd")] + #[test] + fn test_alternative() { + use std::{format, process::Command, string::String}; + + // Call sysctl command instead of libc API. + // + // This is used only for testing. + struct SysctlMachdepOutput(String); + impl SysctlMachdepOutput { + fn new() -> Self { + let output = Command::new("sysctl").arg("machdep").output().unwrap(); + assert!(output.status.success()); + let stdout = String::from_utf8(output.stdout).unwrap(); + Self(stdout) + } + fn field(&self, name: &str) -> Option { + Some( + self.0 + .lines() + .find_map(|s| s.strip_prefix(&format!("{}=", name)))? + .parse() + .unwrap(), + ) + } + } + + let AA64Reg { aa64isar0, aa64isar1, aa64isar3, aa64mmfr2 } = imp::aa64reg(); + let sysctl_output = SysctlMachdepOutput::new(); + assert_eq!(aa64isar0, sysctl_output.field("machdep.id_aa64isar0").unwrap_or(0)); + assert_eq!(aa64isar1, sysctl_output.field("machdep.id_aa64isar1").unwrap_or(0)); + assert_eq!(aa64isar3, sysctl_output.field("machdep.id_aa64isar3").unwrap_or(0)); + assert_eq!(aa64mmfr2, sysctl_output.field("machdep.id_aa64mmfr2").unwrap_or(0)); + } +} diff --git a/vendor/portable-atomic/src/imp/detect/aarch64_apple.rs b/vendor/portable-atomic/src/imp/detect/aarch64_apple.rs new file mode 100644 index 0000000..ad16f2f --- /dev/null +++ b/vendor/portable-atomic/src/imp/detect/aarch64_apple.rs @@ -0,0 +1,217 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Run-time CPU feature detection on AArch64 Apple targets by using sysctlbyname. + +On macOS, this module is currently only enabled on tests because there are no +instructions that were not available on the M1 but are now available on the +latest Apple hardware and this library currently wants to use: + +```console +$ LC_ALL=C comm -23 <(rustc --print cfg --target aarch64-apple-darwin -C target-cpu=apple-m5 | grep -F target_feature) <(rustc --print cfg --target aarch64-apple-darwin | grep -F target_feature) +target_feature="bf16" +target_feature="bti" +target_feature="cssc" +target_feature="ecv" +target_feature="hbc" +target_feature="i8mm" +target_feature="mte" +target_feature="sme" +target_feature="sme-b16b16" +target_feature="sme-f16f16" +target_feature="sme-f64f64" +target_feature="sme-i16i64" +target_feature="sme2" +target_feature="sme2p1" +target_feature="sve-b16b16" +target_feature="v8.5a" +target_feature="v8.6a" +target_feature="v8.7a" +target_feature="wfxt" +``` + +Non-macOS targets doesn't always supports FEAT_LSE2, so we use this module on them. +As used in the example in https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Enable-DIT-for-constant-time-cryptographic-operations, +sysctlbyname is supported on all Apple platforms. + +Refs: https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics +*/ + +include!("common.rs"); + +use core::{mem, ptr}; + +// libc requires Rust 1.63 +mod ffi { + pub(crate) use crate::utils::ffi::{CStr, c_char, c_int, c_size_t, c_void}; + + #[cfg(test)] // test-only + sys_const!({ + // https://github.com/apple-oss-distributions/xnu/blob/xnu-12377.121.6/osfmk/arm/cpu_capabilities_public.h + pub(crate) const CAP_BIT_FEAT_LSE: usize = 6; + pub(crate) const CAP_BIT_FEAT_LRCPC: usize = 15; + pub(crate) const CAP_BIT_FEAT_LRCPC2: usize = 16; + pub(crate) const CAP_BIT_FEAT_LSE2: usize = 30; + pub(crate) const CAP_BIT_NB: usize = 92; + }); + + sys_fn!({ + extern "C" { + // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname + // https://github.com/apple-oss-distributions/xnu/blob/xnu-12377.121.6/bsd/sys/sysctl.h + pub(crate) fn sysctlbyname( + name: *const c_char, + old_p: *mut c_void, + old_len_p: *mut c_size_t, + new_p: *mut c_void, + new_len: c_size_t, + ) -> c_int; + } + }); +} + +fn sysctlbyname32(name: &ffi::CStr) -> Option { + const OUT_LEN: ffi::c_size_t = mem::size_of::() as ffi::c_size_t; + + let mut out = 0_u32; + let mut out_len = OUT_LEN; + // SAFETY: + // - `name` a valid C string. + // - `out_len` does not exceed the size of `out`. + // - `sysctlbyname` is thread-safe. + let res = unsafe { + ffi::sysctlbyname( + name.as_ptr(), + (&mut out as *mut u32).cast::(), + &mut out_len, + ptr::null_mut(), + 0, + ) + }; + if res != 0 { + return None; + } + debug_assert_eq!(out_len, OUT_LEN); + Some(out) +} + +#[cold] +#[must_use] +fn _detect(mut info: CpuInfo) -> CpuInfo { + macro_rules! check { + ($flag:ident, $($name:tt) ||+) => { + if $(sysctlbyname32(c!($name)).unwrap_or(0) != 0) ||+ { + info.set(CpuInfoFlag::$flag); + } + }; + } + + // On macOS, AArch64 support was added in macOS 11, + // hw.optional.armv8_1_atomics is available on macOS 11+, + // hw.optional.arm.FEAT_* are only available on macOS 12+. + // Query both names in case future versions of macOS remove the old name. + // https://github.com/golang/go/commit/c15593197453b8bf90fc3a9080ba2afeaf7934ea + // https://github.com/google/boringssl/commit/91e0b11eba517d83b910b20fe3740eeb39ecb37e + // hw.optional.arm.caps is available on macOS 15+. + // https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/apple.inc#L56 + check!(lse, "hw.optional.arm.FEAT_LSE" || "hw.optional.armv8_1_atomics"); + check!(lse2, "hw.optional.arm.FEAT_LSE2"); + #[cfg(test)] + check!(rcpc, "hw.optional.arm.FEAT_LRCPC"); + #[cfg(test)] + check!(rcpc2, "hw.optional.arm.FEAT_LRCPC2"); + info +} + +#[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks, + clippy::wildcard_imports +)] +#[cfg(test)] +mod tests { + use std::{format, process::Command, str, string::String}; + + use super::*; + + #[test] + fn test_alternative() { + use crate::utils::ffi::*; + + const CAPS_LEN: usize = (ffi::CAP_BIT_NB + 63) / 64; + fn arm_caps(caps: &mut [u64; CAPS_LEN]) -> bool { + let mut caps_len = CAPS_LEN * 8; + // SAFETY: + // - name a valid C string. + // - `caps_len` does not exceed the size of `caps`. + // - `sysctlbyname` is thread-safe. + let res = unsafe { + ffi::sysctlbyname( + c!("hw.optional.arm.caps").as_ptr(), + caps.as_mut_ptr().cast::(), + &mut caps_len, + ptr::null_mut(), + 0, + ) + }; + res == 0 + } + + // Call sysctl command instead of libc API. + // + // This is used only for testing. + struct SysctlHwOptionalOutput(String); + impl SysctlHwOptionalOutput { + fn new() -> Self { + let output = Command::new("sysctl").arg("hw.optional").output().unwrap(); + assert!(output.status.success()); + let stdout = String::from_utf8(output.stdout).unwrap(); + test_helper::eprintln_nocapture!("sysctl hw.optional:\n{}", stdout); + Self(stdout) + } + fn field(&self, name: &CStr) -> Option { + let name = name.to_bytes_with_nul(); + let name = str::from_utf8(&name[..name.len() - 1]).unwrap(); + let prefix = format!("{}: ", name); + Some(self.0.lines().find_map(|s| s.strip_prefix(&prefix))?.parse().unwrap()) + } + } + + let mut caps = [0_u64; CAPS_LEN]; + let has_caps = arm_caps(&mut caps); + let sysctl_output = SysctlHwOptionalOutput::new(); + for (name, expected_on_macos, cap_bit) in [ + (c!("hw.optional.arm.FEAT_LSE"), Some(1), ffi::CAP_BIT_FEAT_LSE), + (c!("hw.optional.armv8_1_atomics"), Some(1), ffi::CAP_BIT_FEAT_LSE), + (c!("hw.optional.arm.FEAT_LSE2"), Some(1), ffi::CAP_BIT_FEAT_LSE2), + (c!("hw.optional.arm.FEAT_LSE128"), None, 0), + (c!("hw.optional.arm.FEAT_LSFE"), None, 0), + (c!("hw.optional.arm.FEAT_LRCPC"), Some(1), ffi::CAP_BIT_FEAT_LRCPC), + (c!("hw.optional.arm.FEAT_LRCPC2"), Some(1), ffi::CAP_BIT_FEAT_LRCPC2), + (c!("hw.optional.arm.FEAT_LRCPC3"), None, 0), + ] { + let res = sysctlbyname32(name); + if res.is_none() { + assert_eq!(std::io::Error::last_os_error().kind(), std::io::ErrorKind::NotFound); + } + if cfg!(any(target_os = "macos", target_abi = "macabi")) { + assert_eq!( + res, + expected_on_macos, + "{}", + str::from_utf8(name.to_bytes_with_nul()).unwrap() + ); + } + if let Some(res) = res { + assert_eq!(res, sysctl_output.field(name).unwrap()); + if has_caps { + assert_eq!(caps[cap_bit / 64] & (1 << (cap_bit & 63)) != 0, res != 0); + } + } else { + assert!(sysctl_output.field(name).is_none()); + } + } + } +} diff --git a/vendor/portable-atomic/src/imp/detect/aarch64_fuchsia.rs b/vendor/portable-atomic/src/imp/detect/aarch64_fuchsia.rs new file mode 100644 index 0000000..5f74cef --- /dev/null +++ b/vendor/portable-atomic/src/imp/detect/aarch64_fuchsia.rs @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Run-time CPU feature detection on AArch64 Fuchsia by using zx_system_get_features. + +As of Rust 1.94, is_aarch64_feature_detected doesn't support run-time detection on Fuchsia. +https://github.com/rust-lang/rust/blob/1.94.0/library/std_detect/src/detect/mod.rs + +Refs: +- https://fuchsia.dev/reference/syscalls/system_get_features +- https://github.com/llvm/llvm-project/commit/4e731abc55681751b5d736b613f7720e50eb1ad4 +*/ + +include!("common.rs"); + +#[allow(non_camel_case_types)] +mod ffi { + sys_type!({ + // https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/zircon/system/public/zircon/types.h + pub(crate) type zx_status_t = i32; + }); + + sys_const!({ + // https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/zircon/system/public/zircon/errors.h + pub(crate) const ZX_OK: zx_status_t = 0; + + // https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/zircon/system/public/zircon/features.h + pub(crate) const ZX_FEATURE_KIND_CPU: u32 = 0; + pub(crate) const ZX_ARM64_FEATURE_ISA_ATOMICS: u32 = 1 << 8; + }); + + // TODO: use sys_fn! + #[link(name = "zircon")] + extern "C" { + // https://fuchsia.dev/reference/syscalls/system_get_features + pub(crate) fn zx_system_get_features(kind: u32, features: *mut u32) -> zx_status_t; + } +} + +fn zx_system_get_features(kind: u32) -> u32 { + let mut out = 0_u32; + // SAFETY: the pointer is valid because we got it from a reference. + let res = unsafe { ffi::zx_system_get_features(kind, &mut out) }; + if res != ffi::ZX_OK { + return 0; + } + out +} + +#[cold] +#[must_use] +fn _detect(mut info: CpuInfo) -> CpuInfo { + let features = zx_system_get_features(ffi::ZX_FEATURE_KIND_CPU); + macro_rules! check { + ($flag:ident, $bit:ident) => { + if features & ffi::$bit != 0 { + info.set(CpuInfoFlag::$flag); + } + }; + } + check!(lse, ZX_ARM64_FEATURE_ISA_ATOMICS); + info +} + +#[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks, + clippy::wildcard_imports +)] +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_fuchsia() { + let features = zx_system_get_features(ffi::ZX_FEATURE_KIND_CPU); + test_helper::eprintln_nocapture!( + "zx_system_get_features(ZX_FEATURE_KIND_CPU): {:b}", + features + ); + assert_ne!(features, 0); + } +} diff --git a/vendor/portable-atomic/src/imp/detect/aarch64_illumos.rs b/vendor/portable-atomic/src/imp/detect/aarch64_illumos.rs new file mode 100644 index 0000000..aeec75a --- /dev/null +++ b/vendor/portable-atomic/src/imp/detect/aarch64_illumos.rs @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Run-time CPU feature detection on AArch64 illumos by using getisax. + +As of Rust 1.94, is_aarch64_feature_detected doesn't support run-time detection on illumos. +https://github.com/rust-lang/rust/blob/1.94.0/library/std_detect/src/detect/mod.rs +*/ + +include!("common.rs"); + +// libc requires Rust 1.63 +mod ffi { + pub(crate) use crate::utils::ffi::c_uint; + + sys_const!({ + // Defined in sys/auxv_aarch64.h. + // https://github.com/richlowe/illumos-gate/blob/arm64-gate/usr/src/uts/common/sys/auxv_aarch64.h + pub(crate) const AV_AARCH64_LSE: u32 = 1 << 15; + #[cfg(test)] + pub(crate) const AV_AARCH64_LRCPC: u32 = 1 << 28; + #[cfg(test)] + pub(crate) const AV_AARCH64_2_ILRCPC: u32 = 1 << 1; + pub(crate) const AV_AARCH64_2_LSE2: u32 = 1 << 2; + }); + + sys_fn!({ + extern "C" { + // Defined in sys/auxv.h. + // https://illumos.org/man/2/getisax + // https://github.com/richlowe/illumos-gate/blob/arm64-gate/usr/src/uts/common/sys/auxv.h + pub(crate) fn getisax(array: *mut u32, n: c_uint) -> c_uint; + } + }); +} + +#[cold] +#[must_use] +fn _detect(mut info: CpuInfo) -> CpuInfo { + const OUT_LEN: ffi::c_uint = 2; + let mut out = [0_u32; OUT_LEN as usize]; + // SAFETY: the pointer is valid because we got it from a reference. + unsafe { + ffi::getisax(out.as_mut_ptr(), OUT_LEN); + } + macro_rules! check { + ($x:ident, $flag:ident, $bit:ident) => { + if $x & ffi::$bit != 0 { + info.set(CpuInfoFlag::$flag); + } + }; + } + let v1 = out[0]; + check!(v1, lse, AV_AARCH64_LSE); + #[cfg(test)] + check!(v1, rcpc, AV_AARCH64_LRCPC); + let v2 = out[1]; + #[cfg(test)] + check!(v2, rcpc2, AV_AARCH64_2_ILRCPC); + check!(v2, lse2, AV_AARCH64_2_LSE2); + info +} diff --git a/vendor/portable-atomic/src/imp/detect/aarch64_windows.rs b/vendor/portable-atomic/src/imp/detect/aarch64_windows.rs new file mode 100644 index 0000000..195626b --- /dev/null +++ b/vendor/portable-atomic/src/imp/detect/aarch64_windows.rs @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Run-time CPU feature detection on AArch64 Windows by using IsProcessorFeaturePresent. + +Run-time detection of FEAT_LSE on Windows by is_aarch64_feature_detected is supported on Rust 1.70+. +https://github.com/rust-lang/stdarch/pull/1373 + +Refs: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent +*/ + +include!("common.rs"); + +// windows-sys requires Rust 1.71 +#[allow(non_camel_case_types, clippy::upper_case_acronyms)] +mod ffi { + sys_type!({ + pub(crate) type [Win32::System::Threading] PROCESSOR_FEATURE_ID = u32; + pub(crate) type [core] BOOL = i32; + }); + + sys_const!({ + pub(crate) const [Win32::Foundation] FALSE: BOOL = 0; + + // Defined in winnt.h of Windows SDK. + pub(crate) const [Win32::System::Threading] + PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE: PROCESSOR_FEATURE_ID = 34; + #[cfg(test)] + pub(crate) const [Win32::System::Threading] + PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE: PROCESSOR_FEATURE_ID = 45; + }); + // TODO: put in sys_const! once windows-sys updated. + pub(crate) const PF_ARM_LSE2_AVAILABLE: PROCESSOR_FEATURE_ID = 62; + + sys_fn!({ + extern "system" { + // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent + pub(crate) fn [Win32::System::Threading] IsProcessorFeaturePresent( + ProcessorFeature: PROCESSOR_FEATURE_ID, + ) -> BOOL; + } + }); +} + +#[cold] +#[must_use] +fn _detect(mut info: CpuInfo) -> CpuInfo { + macro_rules! check { + ($flag:ident, $bit:ident) => { + // SAFETY: calling IsProcessorFeaturePresent is safe, and FALSE is also + // returned if the HAL does not support detection of the specified feature. + if unsafe { ffi::IsProcessorFeaturePresent(ffi::$bit) != ffi::FALSE } { + info.set(CpuInfoFlag::$flag); + } + }; + } + check!(lse, PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE); + check!(lse2, PF_ARM_LSE2_AVAILABLE); + #[cfg(test)] + check!(rcpc, PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE); + info +} diff --git a/vendor/portable-atomic/src/imp/detect/auxv.rs b/vendor/portable-atomic/src/imp/detect/auxv.rs new file mode 100644 index 0000000..7ee3088 --- /dev/null +++ b/vendor/portable-atomic/src/imp/detect/auxv.rs @@ -0,0 +1,1083 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Run-time CPU feature detection on AArch64/Arm/PowerPC64 Linux/Android/FreeBSD/OpenBSD by parsing ELF auxiliary vectors. + +Supported platforms: +- Linux 6.4+ (through prctl) + https://github.com/torvalds/linux/commit/ddc65971bb677aa9f6a4c21f76d3133e106f88eb + prctl returns an unsupported error if operation is not supported, + so we can safely use this on older versions. +- glibc 2.16+ (through getauxval) + https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS;hb=glibc-2.16#l83 + Always available on: + - aarch64 (glibc 2.17+ https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS;hb=glibc-2.17#l36) + - powerpc64 (le) (glibc 2.19+ or RHEL/CentOS's patched glibc 2.17+ https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS;hb=glibc-2.19#l108) + Not always available on: + - arm (glibc 2.1+ https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS;hb=glibc-2.1#l97) + - powerpc64 (be) (glibc 2.3+ https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS;hb=glibc-2.3#l56) + Since Rust 1.64, std requires glibc 2.17+ https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements +- musl 1.1.0+ (through getauxval) + https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?h=v1.1.0#n1197 + Always available on: + - aarch64 (musl 1.1.7+ https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?h=v1.1.7#n1422) + - powerpc64 (musl 1.1.15+ https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?h=v1.1.15#n1702) + Not always available on: + - arm (musl 0.8.3+ https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?h=v0.8.3#n354) + At least since Rust 1.15, std requires musl 1.1.14+ https://github.com/rust-lang/rust/blob/1.15.0/src/ci/docker/x86_64-musl/build-musl.sh#L15 + Since Rust 1.18, std requires musl 1.1.16+ https://github.com/rust-lang/rust/pull/41089 + Since Rust 1.23, std requires musl 1.1.17+ https://github.com/rust-lang/rust/pull/45393 + Since Rust 1.25, std requires musl 1.1.18+ https://github.com/rust-lang/rust/pull/47283 + Since Rust 1.29, std requires musl 1.1.19+ https://github.com/rust-lang/rust/pull/52087 + Since Rust 1.31, std requires musl 1.1.20+ https://github.com/rust-lang/rust/pull/54430 + Since Rust 1.37, std requires musl 1.1.22+ https://github.com/rust-lang/rust/pull/61252 + Since Rust 1.46, std requires musl 1.1.24+ https://github.com/rust-lang/rust/pull/73089 + Since Rust 1.71, std requires musl 1.2.3+ https://blog.rust-lang.org/2023/05/09/Updating-musl-targets + Since Rust 1.93, std requires musl 1.2.5+ https://blog.rust-lang.org/2025/12/05/Updating-musl-1.2.5/ + OpenHarmony uses a fork of musl 1.2 https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/native-lib/musl.md +- uClibc-ng 1.0.43+ (through getauxval) + https://github.com/wbx-github/uclibc-ng/commit/d869bb1600942c01a77539128f9ba5b5b55ad647 + Not always available on: + - aarch64 (uClibc-ng 1.0.22+ https://github.com/wbx-github/uclibc-ng/commit/dba942c80dc2cfa5768a856fff98e22a755fdd27) + - arm (uClibc-ng 1.0.0+ https://github.com/wbx-github/uclibc-ng/tree/v1.0.0/libc/sysdeps/linux) + (powerpc64 is not supported https://github.com/wbx-github/uclibc-ng/commit/d4d4f37fda7fa57e57132ff2f0d735ce7cc2178e) +- Picolibc 1.4.6+ (through getauxval) + https://github.com/picolibc/picolibc/commit/19bfe51d62ad7e32533c7f664b5bca8e26286e31 + The implementation always return 0 (as of 1.8.12): https://github.com/picolibc/picolibc/blob/1.8.12/libc/misc/getauxval.c +- Android 4.3+ (API level 18+) (through getauxval) + https://android.googlesource.com/platform/bionic.git/+/2c5153b043b44e9935a334ae9b2d5a4bc5258b40 + https://android.googlesource.com/platform/bionic.git/+/655e430b28d7404f763e7ebefe84fba5a387666d + Always available on: + - 64-bit architectures (Android 5.0+ (API level 21+) https://android-developers.googleblog.com/2014/10/whats-new-in-android-50-lollipop.html) + Not always available on: + - arm + Since Rust 1.68, std requires API level 19+ https://blog.rust-lang.org/2023/01/09/android-ndk-update-r25 + Since Rust 1.82, std requires API level 21+ https://github.com/rust-lang/rust/pull/120593 +- FreeBSD 12.0+ and 11.4+ (through elf_aux_info) + https://github.com/freebsd/freebsd-src/commit/0b08ae2120cdd08c20a2b806e2fcef4d0a36c470 + https://github.com/freebsd/freebsd-src/blob/release/11.4.0/sys/sys/auxv.h + Always available on: + - arm (v7) (FreeBSD 12.0+ https://www.freebsd.org/releases/12.0R/announce, https://man.freebsd.org/cgi/man.cgi?arch) + - powerpc64 (le) (FreeBSD 12.4+ https://www.freebsd.org/releases/12.4R/announce, https://man.freebsd.org/cgi/man.cgi?arch) + Not always available on: + - aarch64 (FreeBSD 11.0+ https://www.freebsd.org/releases/11.0R/announce, https://man.freebsd.org/cgi/man.cgi?arch) + - arm (v6) (FreeBSD 10.1+ https://www.freebsd.org/releases/10.1R/announce, https://man.freebsd.org/cgi/man.cgi?arch) + - powerpc64 (be) (FreeBSD 9.0+ https://www.freebsd.org/releases/9.0R/announce, https://man.freebsd.org/cgi/man.cgi?arch) + Since Rust 1.75, std requires FreeBSD 12+ https://github.com/rust-lang/rust/pull/114521 + Since Rust 1.97, std requires FreeBSD 14+ https://github.com/rust-lang/rust/pull/156607 +- OpenBSD 7.6+ (through elf_aux_info) + https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d + Not always available on: + - aarch64 (OpenBSD 6.1+ https://www.openbsd.org/61.html) + - arm (OpenBSD 6.0+ https://www.openbsd.org/60.html) + - powerpc64 (OpenBSD 6.8+ https://www.openbsd.org/68.html) + +On L4Re which uses uClibc-ng, a dummy getauxval was added first in 2020 that always returns 0 (https://github.com/kernkonzept/l4re-core/commit/e88fa67198074d3e6b4983c5c8af1538e2089ff3), +then implemented in 2024 (https://github.com/kernkonzept/l4re-core/commit/3ee2a50dd1b3bc22955e593004990887a0a5b4a3). +However, getauxval(AT_HWCAP*) always returns 0 (as of 2025-12-25). (see tests/l4re test) +On Redox, getauxval is available since 0.5.0 (https://github.com/redox-os/relibc/commit/f9f752d74c4f1f56a89c0fcdd5cab63d2380fe09), +but the implementation always return 0 (as of 2026-08-08): https://github.com/redox-os/relibc/blob/49aeb9470a885030ed43a70d0b708f3caec19478/src/header/sys_auxv/mod.rs + +On platforms that we can assume that getauxval/elf_aux_info is always available, we directly call +them on except for musl with static linking. (At this time, we also retain compatibility with +versions that reached EoL or no longer supported by `std`, with the exception of AArch64 FreeBSD described below.) + +On musl with static linking, it seems that getauxval is not always available, independent of version +requirements: https://github.com/rust-lang/rust/issues/89626 +(That problem may have been fixed in https://github.com/rust-lang/rust/commit/9a04ae4997493e9260352064163285cddc43de3c, +but even in the version containing that patch, [there is report](https://github.com/rust-lang/rust/issues/89626#issuecomment-1242636038) +of the same error.) +This seems to be due to the fact that compiler-builtins is built before libc (which is a dependency +of std) links musl. And the std and its dependent can use getauxval without this problem at least +since the rust-lang/rust patch mentioned above: +https://github.com/rust-lang/rust/blob/1.85.0/library/std/src/sys/pal/unix/stack_overflow.rs#L268 +(According to https://github.com/rust-lang/rust/issues/89626#issuecomment-2420469392, this problem +may have been fixed in https://github.com/rust-lang/rust/commit/9ed0d11efbec18a1fa4155576a3bcb685676d23c.) +See also https://github.com/rust-lang/stdarch/pull/1746. +So as for musl with static linking, we assume that getauxval is always available also when `std` feature enabled. + +On platforms that we cannot assume that getauxval/elf_aux_info is always available, so we use dlsym +instead of directly calling getauxval/elf_aux_info. (You can force getauxval/elf_aux_info to be +called directly instead of using dlsym by `--cfg portable_atomic_outline_atomics`). + +Also, note that dlsym usually not working with static linking. + +# Linux/Android + +As of Rust 1.69, is_aarch64_feature_detected always uses dlsym by default +on AArch64 Linux/Android, but on some platforms, we can safely assume +getauxval is linked to the binary (see the above). + +See also https://github.com/rust-lang/stdarch/pull/1375 + +See tests::test_alternative and aarch64_aa64reg.rs for (test-only) alternative implementations. + +# FreeBSD + +As of Rust 1.94, is_aarch64_feature_detected always uses mrs on +AArch64 FreeBSD. However, they do not work on FreeBSD 12 on QEMU (confirmed +on FreeBSD 12.{2,3,4}), and we got SIGILL (worked on FreeBSD 13 and 14). + +So use elf_aux_info instead of mrs like compiler-rt does. +https://reviews.llvm.org/D109330 + +elf_aux_info is available on FreeBSD 12.0+ and 11.4+: +https://github.com/freebsd/freebsd-src/commit/0b08ae2120cdd08c20a2b806e2fcef4d0a36c470 +https://github.com/freebsd/freebsd-src/blob/release/11.4.0/sys/sys/auxv.h +On FreeBSD, [AArch64 support is available on FreeBSD 11.0+](https://www.freebsd.org/releases/11.0R/announce), +but FreeBSD 11 (11.4) was EoL on 2021-09-30, and FreeBSD 11.3 was EoL on 2020-09-30: +https://www.freebsd.org/security/unsupported +See also https://github.com/rust-lang/stdarch/pull/611#issuecomment-445464613 + +See tests::test_alternative and aarch64_aa64reg.rs for (test-only) alternative implementations. + +# OpenBSD + +elf_aux_info is available on OpenBSD 7.6+: +https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d + +On AArch64, there is an alternative that available on older version, +so we use it (see aarch64_aa64reg.rs). + +*/ + +include!("common.rs"); + +use self::os::ffi; +#[cfg(any(target_os = "linux", target_os = "android"))] +mod os { + // libc requires Rust 1.63 + #[cfg_attr(test, allow(dead_code))] + pub(super) mod ffi { + pub(crate) use crate::utils::ffi::c_ulong; + #[allow(unused_imports)] + pub(crate) use crate::utils::ffi::{c_char, c_int, c_void}; + + sys_const!({ + // https://github.com/torvalds/linux/blob/v6.19/include/uapi/linux/auxvec.h + pub(crate) const AT_HWCAP: c_ulong = 16; + #[cfg(any( + test, + all(target_arch = "aarch64", target_pointer_width = "64"), + target_arch = "powerpc64", + ))] + pub(crate) const AT_HWCAP2: c_ulong = 26; + // Linux 6.9+ + // https://github.com/torvalds/linux/commit/3281366a8e79a512956382885091565db1036b64 + #[cfg(test)] + #[cfg(not(all(target_arch = "aarch64", target_pointer_width = "32")))] + pub(crate) const AT_HWCAP3: c_ulong = 29; + #[cfg(test)] + #[cfg(not(all(target_arch = "aarch64", target_pointer_width = "32")))] + pub(crate) const AT_HWCAP4: c_ulong = 30; + + // Defined in dlfcn.h. + // https://sourceware.org/git/?p=glibc.git;a=blob;f=dlfcn/dlfcn.h;hb=glibc-2.43 + // https://git.musl-libc.org/cgit/musl/tree/include/dlfcn.h?h=v1.2.5 + // https://github.com/wbx-github/uclibc-ng/blob/v1.0.47/include/dlfcn.h + // https://github.com/kernkonzept/l4re-core/blob/r-2026-W07/libc/uclibc-ng/contrib/uclibc/include/dlfcn.h + // https://android.googlesource.com/platform/bionic.git/+/refs/tags/android-16.0.0_r1/libc/include/dlfcn.h + #[cfg(any( + test, + not(any( + all( + target_os = "linux", + any( + all( + target_env = "gnu", + any( + target_arch = "aarch64", + all(target_arch = "powerpc64", target_endian = "little"), + ), + ), + target_env = "musl", + target_env = "ohos", + ), + ), + all(target_os = "android", target_pointer_width = "64"), + portable_atomic_outline_atomics, + )), + ))] + #[cfg(not(all(target_os = "android", target_pointer_width = "32")))] + pub(crate) const RTLD_DEFAULT: *mut c_void = core::ptr::null_mut(); + #[cfg(all(target_os = "android", target_pointer_width = "32"))] + #[allow(clippy::cast_sign_loss)] + pub(crate) const RTLD_DEFAULT: *mut c_void = + crate::utils::ptr::without_provenance_mut(-1_isize as usize); + + // Defined in sys/system_properties.h. + // https://android.googlesource.com/platform/bionic.git/+/refs/tags/android-16.0.0_r1/libc/include/sys/system_properties.h + #[cfg(all(target_arch = "aarch64", target_os = "android"))] + pub(crate) const PROP_VALUE_MAX: c_int = 92; + }); + + sys_fn!({ + extern "C" { + // Defined in sys/auxv.h. + // https://man7.org/linux/man-pages/man3/getauxval.3.html + // https://sourceware.org/git/?p=glibc.git;a=blob;f=misc/sys/auxv.h;hb=glibc-2.43 + // https://git.musl-libc.org/cgit/musl/tree/include/sys/auxv.h?h=v1.2.5 + // https://github.com/wbx-github/uclibc-ng/blob/v1.0.47/include/sys/auxv.h + // https://github.com/kernkonzept/l4re-core/blob/r-2026-W07/libc/uclibc-ng/contrib/uclibc/include/sys/auxv.h + // https://android.googlesource.com/platform/bionic.git/+/refs/tags/android-16.0.0_r1/libc/include/sys/auxv.h + // https://github.com/picolibc/picolibc/blob/1.8.12/libc/include/sys/auxv.h + #[cfg(any( + test, + all( + target_os = "linux", + any( + all( + target_env = "gnu", + any( + target_arch = "aarch64", + all(target_arch = "powerpc64", target_endian = "little"), + ), + ), + target_env = "musl", + target_env = "ohos", + ), + ), + all(target_os = "android", target_pointer_width = "64"), + portable_atomic_outline_atomics, + ))] + pub(crate) fn getauxval(type_: c_ulong) -> c_ulong; + + // Defined in dlfcn.h. + // https://man7.org/linux/man-pages/man3/dlsym.3.html + // https://sourceware.org/git/?p=glibc.git;a=blob;f=dlfcn/dlfcn.h;hb=glibc-2.43 + // https://git.musl-libc.org/cgit/musl/tree/include/dlfcn.h?h=v1.2.5 + // https://github.com/wbx-github/uclibc-ng/blob/v1.0.47/include/dlfcn.h + // https://github.com/kernkonzept/l4re-core/blob/r-2026-W07/libc/uclibc-ng/contrib/uclibc/include/dlfcn.h + // https://android.googlesource.com/platform/bionic.git/+/refs/tags/android-16.0.0_r1/libc/include/dlfcn.h + #[cfg(any( + test, + not(any( + all( + target_os = "linux", + any( + all( + target_env = "gnu", + any( + target_arch = "aarch64", + all(target_arch = "powerpc64", target_endian = "little"), + ), + ), + target_env = "musl", + target_env = "ohos", + ), + ), + all(target_os = "android", target_pointer_width = "64"), + portable_atomic_outline_atomics, + )), + ))] + pub(crate) fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void; + + // Defined in sys/system_properties.h. + // https://android.googlesource.com/platform/bionic.git/+/refs/tags/android-16.0.0_r1/libc/include/sys/system_properties.h + #[cfg(all(target_arch = "aarch64", target_os = "android"))] + pub(crate) fn __system_property_get( + name: *const c_char, + value: *mut c_char, + ) -> c_int; + } + }); + } + + pub(super) type GetauxvalTy = unsafe extern "C" fn(ffi::c_ulong) -> ffi::c_ulong; + pub(super) fn getauxval(type_: ffi::c_ulong) -> ffi::c_ulong { + cfg_sel!({ + #[cfg(any( + all( + target_os = "linux", + any( + all( + target_env = "gnu", + any( + target_arch = "aarch64", + all(target_arch = "powerpc64", target_endian = "little"), + ), + ), + target_env = "musl", + target_env = "ohos", + ), + ), + all(target_os = "android", target_pointer_width = "64"), + portable_atomic_outline_atomics, + ))] + { + let getauxval: GetauxvalTy = ffi::getauxval; + } + #[cfg(else)] + { + // SAFETY: we passed a valid C string to dlsym, and a pointer returned by dlsym + // is a valid pointer to the function if it is non-null. + let getauxval: GetauxvalTy = unsafe { + let ptr = ffi::dlsym(ffi::RTLD_DEFAULT, c!("getauxval").as_ptr()); + if ptr.is_null() { + return 0; + } + core::mem::transmute::<*mut ffi::c_void, GetauxvalTy>(ptr) + }; + } + }); + + // SAFETY: `getauxval` is thread-safe. + unsafe { getauxval(type_) } + } +} +#[cfg(any(target_os = "freebsd", target_os = "openbsd"))] +mod os { + use core::mem; + + // libc requires Rust 1.63 + #[cfg_attr(test, allow(dead_code))] + pub(super) mod ffi { + #[allow(unused_imports)] + pub(crate) use crate::utils::ffi::c_char; + pub(crate) use crate::utils::ffi::{c_int, c_ulong, c_void}; + + sys_const!({ + // FreeBSD + // Defined in sys/elf_common.h. + // https://github.com/freebsd/freebsd-src/blob/release/15.1.0/sys/sys/elf_common.h + // OpenBSD + // Defined in sys/auxv.h. + // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/sys/auxv.h + pub(crate) const AT_HWCAP: c_int = 25; + #[cfg(any( + test, + all(target_os = "freebsd", target_arch = "aarch64", target_pointer_width = "64"), + target_arch = "powerpc64", + ))] + pub(crate) const AT_HWCAP2: c_int = 26; + // FreeBSD 15.0+ + // https://github.com/freebsd/freebsd-src/commit/85007872d1227006adf2ce119fe30de856cbe12d + #[cfg(test)] + #[cfg(not(target_os = "openbsd"))] + pub(crate) const AT_HWCAP3: c_int = 38; + #[cfg(test)] + #[cfg(not(target_os = "openbsd"))] + pub(crate) const AT_HWCAP4: c_int = 39; + + // FreeBSD + // Defined in dlfcn.h. + // https://man.freebsd.org/dlsym(3) + // https://github.com/freebsd/freebsd-src/blob/release/15.1.0/include/dlfcn.h + // OpenBSD + // Defined in dlfcn.h. + // https://man.openbsd.org/dlsym.3 + // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/include/dlfcn.h + #[cfg(any( + test, + not(any( + all( + target_os = "freebsd", + any( + target_arch = "aarch64", + all(target_arch = "powerpc64", target_endian = "little"), + ), + ), + portable_atomic_outline_atomics, + )), + ))] + #[allow(clippy::cast_sign_loss)] + pub(crate) const RTLD_DEFAULT: *mut c_void = + crate::utils::ptr::without_provenance_mut(-2_isize as usize); + }); + + sys_fn!({ + extern "C" { + // FreeBSD + // Defined in sys/auxv.h. + // https://man.freebsd.org/elf_aux_info(3) + // https://github.com/freebsd/freebsd-src/blob/release/15.1.0/sys/sys/auxv.h + // OpenBSD + // Defined in sys/auxv.h. + // https://man.openbsd.org/elf_aux_info.3 + // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/sys/auxv.h + #[cfg(any( + test, + any( + all( + target_os = "freebsd", + any( + target_arch = "aarch64", + all(target_arch = "powerpc64", target_endian = "little"), + ), + ), + portable_atomic_outline_atomics, + ), + ))] + pub(crate) fn elf_aux_info(aux: c_int, buf: *mut c_void, buf_len: c_int) -> c_int; + + // FreeBSD + // Defined in dlfcn.h. + // https://man.freebsd.org/dlsym(3) + // https://github.com/freebsd/freebsd-src/blob/release/15.1.0/include/dlfcn.h + // OpenBSD + // Defined in dlfcn.h. + // https://man.openbsd.org/dlsym.3 + // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/include/dlfcn.h + #[cfg(any( + test, + not(any( + all( + target_os = "freebsd", + any( + target_arch = "aarch64", + all(target_arch = "powerpc64", target_endian = "little"), + ), + ), + portable_atomic_outline_atomics, + )), + ))] + pub(crate) fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void; + } + }); + } + + pub(super) type ElfAuxInfoTy = + unsafe extern "C" fn(ffi::c_int, *mut ffi::c_void, ffi::c_int) -> ffi::c_int; + pub(super) fn getauxval(aux: ffi::c_int) -> ffi::c_ulong { + #[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)] + const OUT_LEN: ffi::c_int = mem::size_of::() as ffi::c_int; + + cfg_sel!({ + #[cfg(any( + all( + target_os = "freebsd", + any( + target_arch = "aarch64", + all(target_arch = "powerpc64", target_endian = "little"), + ), + ), + portable_atomic_outline_atomics, + ))] + { + let elf_aux_info: ElfAuxInfoTy = ffi::elf_aux_info; + } + #[cfg(else)] + { + // SAFETY: we passed a valid C string to dlsym, and a pointer returned by dlsym + // is a valid pointer to the function if it is non-null. + let elf_aux_info: ElfAuxInfoTy = unsafe { + let ptr = ffi::dlsym(ffi::RTLD_DEFAULT, c!("elf_aux_info").as_ptr()); + if ptr.is_null() { + return 0; + } + mem::transmute::<*mut ffi::c_void, ElfAuxInfoTy>(ptr) + }; + } + }); + + let mut out: ffi::c_ulong = 0; + // SAFETY: + // - the pointer is valid because we got it from a reference. + // - `OUT_LEN` is the same as the size of `out`. + // - `elf_aux_info` is thread-safe. + let res = unsafe { + elf_aux_info(aux, (&mut out as *mut ffi::c_ulong).cast::(), OUT_LEN) + }; + // If elf_aux_info fails, `out` will be left at zero (which is the proper default value). + debug_assert!(res == 0 || out == 0); + out + } +} + +// Basically, Linux/FreeBSD/OpenBSD use the same hwcap values. +// FreeBSD and OpenBSD usually support a subset of the hwcap values supported by Linux. +use self::arch::_detect; +#[cfg(target_arch = "aarch64")] +mod arch { + use super::{CpuInfo, CpuInfoFlag, ffi, os}; + + sys_const!({ + // Linux + // https://github.com/torvalds/linux/blob/v6.19/arch/arm64/include/uapi/asm/hwcap.h + // https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/arm64/elf_hwcaps.rst + // FreeBSD + // Defined in machine/elf.h. + // https://github.com/freebsd/freebsd-src/blob/release/15.1.0/sys/arm64/include/elf.h + // OpenBSD + // Defined in machine/elf.h. + // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/arch/arm64/include/elf.h + // Linux 4.3+ + // https://github.com/torvalds/linux/commit/40a1db2434a1b62332b1af25cfa14d7b8c0301fe + // FreeBSD 13.0+/12.2+ + // https://github.com/freebsd/freebsd-src/blob/release/13.0.0/sys/arm64/include/elf.h + // https://github.com/freebsd/freebsd-src/blob/release/12.2.0/sys/arm64/include/elf.h + // OpenBSD 7.6+ + // https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d + pub(crate) const HWCAP_ATOMICS: ffi::c_ulong = 1 << 8; + // Linux 4.11+ + // https://github.com/torvalds/linux/commit/77c97b4ee21290f5f083173d957843b615abbff2 + // FreeBSD 13.0+/12.2+ + // https://github.com/freebsd/freebsd-src/blob/release/13.0.0/sys/arm64/include/elf.h + // https://github.com/freebsd/freebsd-src/blob/release/12.2.0/sys/arm64/include/elf.h + // OpenBSD 7.6+ + // https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d + #[cfg(test)] + pub(crate) const HWCAP_CPUID: ffi::c_ulong = 1 << 11; + // Linux 4.12+ + // https://github.com/torvalds/linux/commit/c651aae5a7732287c1c9bc974ece4ed798780544 + // FreeBSD 13.0+/12.2+ + // https://github.com/freebsd/freebsd-src/blob/release/13.0.0/sys/arm64/include/elf.h + // https://github.com/freebsd/freebsd-src/blob/release/12.2.0/sys/arm64/include/elf.h + // OpenBSD 7.6+ + // https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d + #[cfg(test)] + pub(crate) const HWCAP_LRCPC: ffi::c_ulong = 1 << 15; + // Linux 4.17+ + // https://github.com/torvalds/linux/commit/7206dc93a58fb76421c4411eefa3c003337bcb2d + // FreeBSD 13.0+/12.2+ + // https://github.com/freebsd/freebsd-src/blob/release/13.0.0/sys/arm64/include/elf.h + // https://github.com/freebsd/freebsd-src/blob/release/12.2.0/sys/arm64/include/elf.h + // OpenBSD 7.6+ + // https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d + pub(crate) const HWCAP_USCAT: ffi::c_ulong = 1 << 25; + #[cfg(test)] + pub(crate) const HWCAP_ILRCPC: ffi::c_ulong = 1 << 26; + // Linux 6.7+ + // https://github.com/torvalds/linux/commit/338a835f40a849cd89b993e342bd9fbd5684825c + // FreeBSD 15.0+ + // https://github.com/freebsd/freebsd-src/commit/94686b081fdb0c1bb0fc1dfeda14bd53f26ce7c5 + #[cfg(not(target_os = "openbsd"))] + #[cfg(target_pointer_width = "64")] + pub(crate) const HWCAP2_LRCPC3: ffi::c_ulong = 1 << 46; + // Linux 6.7+ + // https://github.com/torvalds/linux/commit/94d0657f9f0d311489606589133ebf49e28104d8 + // FreeBSD 15.0+ + // https://github.com/freebsd/freebsd-src/commit/94686b081fdb0c1bb0fc1dfeda14bd53f26ce7c5 + #[cfg(not(target_os = "openbsd"))] + #[cfg(target_pointer_width = "64")] + pub(crate) const HWCAP2_LSE128: ffi::c_ulong = 1 << 47; + // Linux 6.18+ + // https://github.com/torvalds/linux/commit/220928e52cb03d223b3acad3888baf0687486d21 + // FreeBSD 16.0+ + // https://github.com/freebsd/freebsd-src/commit/3a960425df759a7bb8f946d23f035c63f3a5de7a + #[cfg(test)] + #[cfg(not(target_os = "openbsd"))] + #[cfg(target_pointer_width = "64")] + pub(crate) const HWCAP3_LSFE: ffi::c_ulong = 1 << 2; + }); + + #[cold] + #[must_use] + pub(crate) fn _detect(mut info: CpuInfo) -> CpuInfo { + #[cfg(target_os = "android")] + { + // Samsung Exynos 9810 has a bug that big and little cores have different + // ISAs. And on older Android (pre-9), the kernel incorrectly reports + // that features available only on some cores are available on all cores. + // https://reviews.llvm.org/D114523 + let mut arch = [0_u8; ffi::PROP_VALUE_MAX as usize]; + // SAFETY: we've passed a valid C string and a buffer with max length. + let len = unsafe { + ffi::__system_property_get( + c!("ro.arch").as_ptr(), + arch.as_mut_ptr().cast::(), + ) + }; + // On Exynos, ro.arch is not available on Android 12+, but it is fine + // because Android 9+ includes the fix. + if len > 0 && arch.starts_with(b"exynos9810") { + return info; + } + } + + macro_rules! check { + ($x:ident, $flag:ident, $bit:ident) => { + if $x & $bit != 0 { + info.set(CpuInfoFlag::$flag); + } + }; + } + let hwcap = os::getauxval(ffi::AT_HWCAP); + check!(hwcap, lse, HWCAP_ATOMICS); + check!(hwcap, lse2, HWCAP_USCAT); + #[cfg(test)] + check!(hwcap, rcpc, HWCAP_LRCPC); + #[cfg(test)] + check!(hwcap, rcpc2, HWCAP_ILRCPC); + #[cfg(test)] + check!(hwcap, cpuid, HWCAP_CPUID); + #[cfg(not(target_os = "openbsd"))] + // HWCAP2 is not yet available on ILP32: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/tree/arch/arm64/include/uapi/asm/hwcap.h?h=staging/ilp32-5.1 + #[cfg(target_pointer_width = "64")] + { + let hwcap2 = os::getauxval(ffi::AT_HWCAP2); + check!(hwcap2, rcpc3, HWCAP2_LRCPC3); + check!(hwcap2, lse128, HWCAP2_LSE128); + #[cfg(test)] + { + let hwcap3 = os::getauxval(ffi::AT_HWCAP3); + check!(hwcap3, lsfe, HWCAP3_LSFE); + } + } + info + } +} +#[cfg(target_arch = "arm")] +mod arch { + use super::{CpuInfo, CpuInfoFlag, ffi, os}; + + sys_const!({ + // Linux + // https://github.com/torvalds/linux/blob/v6.19/arch/arm/include/uapi/asm/hwcap.h + // FreeBSD + // Defined in machine/elf.h. + // https://github.com/freebsd/freebsd-src/blob/release/15.1.0/sys/arm/include/elf.h + // OpenBSD + // Defined in machine/elf.h. + // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/arch/arm/include/elf.h + // Linux 3.11+ + // https://github.com/torvalds/linux/commit/a469abd0f868c902b75532579bf87553dcf1b360 + // FreeBSD 12.0+/11.2+ + // https://github.com/freebsd/freebsd-src/commit/0cbf724ed03571bc90ed22c3b4bf8c6c7b2da564 + // https://github.com/freebsd/freebsd-src/blob/release/11.2.0/sys/arm/include/elf.h + // OpenBSD 7.6+ + // https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d + #[cfg(test)] + pub(crate) const HWCAP_LPAE: ffi::c_ulong = 1 << 20; + }); + + #[cold] + #[must_use] + pub(crate) fn _detect(mut info: CpuInfo) -> CpuInfo { + macro_rules! check { + ($x:ident, $flag:ident, $($bit:ident) ||+) => { + if $x & ($($bit) |+) != 0 { + info.set(CpuInfoFlag::$flag); + } + }; + ($x:ident, $flag:ident, $($bit:ident) &&+) => { + if $x & ($($bit) |+) == ($($bit) |+) { + info.set(CpuInfoFlag::$flag); + } + }; + } + let hwcap = os::getauxval(ffi::AT_HWCAP); + #[cfg(test)] + check!(hwcap, lpae, HWCAP_LPAE); + info + } +} +#[cfg(target_arch = "powerpc64")] +mod arch { + use super::{CpuInfo, CpuInfoFlag, ffi, os}; + + sys_const!({ + // Linux + // https://github.com/torvalds/linux/blob/v6.19/arch/powerpc/include/uapi/asm/cputable.h + // https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/powerpc/elf_hwcaps.rst + // FreeBSD + // Defined in machine/cpu.h. + // https://github.com/freebsd/freebsd-src/blob/release/15.1.0/sys/powerpc/include/cpu.h + // OpenBSD + // Defined in machine/elf.h. + // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/arch/powerpc64/include/elf.h + // Linux 2.6.16+ + // https://github.com/torvalds/linux/commit/80f15dc703b3677d0b025bafd215f1f3664c8978 + // FreeBSD 11.0+ + // https://github.com/freebsd/freebsd-src/commit/b0bf7fcd298133457991b27625bbed766e612730 + // OpenBSD 7.6+ + // https://github.com/openbsd/src/commit/0b0568a19fc4c197871ceafbabc91fabf17ca152 + pub(crate) const PPC_FEATURE_BOOKE: ffi::c_ulong = 0x00008000; + // Linux 3.10+ + // https://github.com/torvalds/linux/commit/cbbc6f1b1433ef553d57826eee87a84ca49645ce + // FreeBSD 11.0+ + // https://github.com/freebsd/freebsd-src/commit/b0bf7fcd298133457991b27625bbed766e612730 + // OpenBSD 7.6+ + // https://github.com/openbsd/src/commit/0b0568a19fc4c197871ceafbabc91fabf17ca152 + pub(crate) const PPC_FEATURE2_ARCH_2_07: ffi::c_ulong = 0x80000000; + // Linux 4.5+ + // https://github.com/torvalds/linux/commit/e708c24cd01ce80b1609d8baccee40ccc3608a01 + // FreeBSD 12.0+ + // https://github.com/freebsd/freebsd-src/commit/18f48e0c72f91bc2d4373078a3f1ab1bcab4d8b3 + // OpenBSD 7.6+ + // https://github.com/openbsd/src/commit/0b0568a19fc4c197871ceafbabc91fabf17ca152 + pub(crate) const PPC_FEATURE2_ARCH_3_00: ffi::c_ulong = 0x00800000; + // Linux 5.8+ + // https://github.com/torvalds/linux/commit/ee988c11acf6f9464b7b44e9a091bf6afb3b3a49 + // FreeBSD 15.0+/14.2+ + // https://github.com/freebsd/freebsd-src/commit/1e434da3b065ef96b389e5e0b604ae05a51e794e + // https://github.com/freebsd/freebsd-src/blob/release/14.2.0/sys/powerpc/include/cpu.h + // OpenBSD 7.7+ + // https://github.com/openbsd/src/commit/483a78e15aaa23c010911940770c1c97db5c1287 + pub(crate) const PPC_FEATURE2_ARCH_3_1: ffi::c_ulong = 0x00040000; + }); + + #[cold] + #[must_use] + pub(crate) fn _detect(mut info: CpuInfo) -> CpuInfo { + let hwcap = os::getauxval(ffi::AT_HWCAP); + if hwcap & PPC_FEATURE_BOOKE != 0 { + // quadword-atomics (Load/Store Quadword category in ISA 2.07) is requirement of ISA 2.07 + // server processors. It is always optional in ISA 2.07 BookE (embedded category) + // processors and there is no corresponding HWCAP bit. (Although there are no ISA 2.07 + // BookE processors that appear to be supported on these platforms.) + // Refs: Appendix B "Platform Support Requirements" of Power ISA 2.07B + // https://ibm.ent.box.com/s/jd5w15gz301s5b5dt375mshpq9c3lh4u + return info; + } + let hwcap2 = os::getauxval(ffi::AT_HWCAP2); + // Check both 2_07 and later ISAs (which are superset of 2_07) because + // OpenBSD (as of 8.0-beta) doesn't set 2_07 even when 3_00 is set. + // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/arch/powerpc64/powerpc64/cpu.c#L222-L238 + // Other OSes should be fine, but check all OSs in the same way just in case. + let isa_2_07_or_later = + PPC_FEATURE2_ARCH_2_07 | PPC_FEATURE2_ARCH_3_00 | PPC_FEATURE2_ARCH_3_1; + if hwcap2 & isa_2_07_or_later != 0 { + info.set(CpuInfoFlag::quadword_atomics); + } + info + } +} + +#[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks, + clippy::wildcard_imports +)] +#[cfg(test)] +mod tests { + use std::mem; + + use super::*; + + #[allow(clippy::cast_sign_loss)] + #[cfg(all(target_arch = "aarch64", target_os = "android"))] + #[test] + fn test_android() { + use std::{slice, str}; + unsafe { + let mut arch = [1; ffi::PROP_VALUE_MAX as usize]; + let len = ffi::__system_property_get( + c!("ro.arch").as_ptr(), + arch.as_mut_ptr().cast::(), + ); + assert!(len >= 0); + test_helper::eprintln_nocapture!("ro.arch=raw={:?},len={}", arch, len); + test_helper::eprintln_nocapture!( + "ro.arch={:?}", + str::from_utf8(slice::from_raw_parts(arch.as_ptr(), len as usize)).unwrap() + ); + } + } + + #[cfg(any(target_os = "linux", target_os = "android"))] + #[test] + fn test_dlsym_getauxval() { + unsafe { + let ptr = ffi::dlsym(ffi::RTLD_DEFAULT, c!("getauxval").as_ptr()); + if cfg!(target_feature = "crt-static") { + assert!(ptr.is_null()); + } else if cfg!(any( + all( + target_os = "linux", + any(target_env = "gnu", target_env = "musl", target_env = "ohos"), + ), + target_os = "android", + )) { + assert!(!ptr.is_null()); + } else if option_env!("CI").is_some() { + assert!(ptr.is_null()); + } + if ptr.is_null() { + return; + } + let dlsym_getauxval = mem::transmute::<*mut ffi::c_void, os::GetauxvalTy>(ptr); + for &at in &[ffi::AT_HWCAP, ffi::AT_HWCAP2] { + assert_eq!(dlsym_getauxval(at), ffi::getauxval(at)); + } + #[cfg(not(all(target_arch = "aarch64", target_pointer_width = "32")))] + for &at in &[ffi::AT_HWCAP3, ffi::AT_HWCAP4] { + assert_eq!(dlsym_getauxval(at), ffi::getauxval(at)); + } + } + } + #[cfg(any(target_os = "freebsd", target_os = "openbsd"))] + #[test] + fn test_dlsym_elf_aux_info() { + unsafe { + let ptr = ffi::dlsym(ffi::RTLD_DEFAULT, c!("elf_aux_info").as_ptr()); + if cfg!(target_feature = "crt-static") { + assert!(ptr.is_null()); + } else if cfg!(target_os = "freebsd") || option_env!("CI").is_some() { + assert!(!ptr.is_null()); + } + if ptr.is_null() { + return; + } + let dlsym_elf_aux_info = mem::transmute::<*mut ffi::c_void, os::ElfAuxInfoTy>(ptr); + #[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)] + let out_len = mem::size_of::() as ffi::c_int; + for &at in &[ffi::AT_HWCAP, ffi::AT_HWCAP2] { + let mut out: ffi::c_ulong = 0; + let mut dlsym_out: ffi::c_ulong = 0; + assert_eq!( + ffi::elf_aux_info( + at, + (&mut out as *mut ffi::c_ulong).cast::(), + out_len, + ), + dlsym_elf_aux_info( + at, + (&mut dlsym_out as *mut ffi::c_ulong).cast::(), + out_len, + ), + ); + assert_eq!(out, dlsym_out); + } + #[cfg(not(target_os = "openbsd"))] + for &at in &[ffi::AT_HWCAP3, ffi::AT_HWCAP4] { + let mut out: ffi::c_ulong = 0; + let mut dlsym_out: ffi::c_ulong = 0; + assert_eq!( + ffi::elf_aux_info( + at, + (&mut out as *mut ffi::c_ulong).cast::(), + out_len, + ), + dlsym_elf_aux_info( + at, + (&mut dlsym_out as *mut ffi::c_ulong).cast::(), + out_len, + ), + ); + assert_eq!(out, dlsym_out); + } + } + } + + #[cfg(any(target_os = "linux", target_os = "android"))] + #[cfg(not(all(target_arch = "aarch64", target_pointer_width = "32")))] // no PR_GET_AUXV + #[test] + fn test_alternative() { + use std::{eprintln, str, vec}; + + #[cfg(target_pointer_width = "32")] + use sys::Elf32_auxv_t as Elf_auxv_t; + #[cfg(target_pointer_width = "64")] + use sys::Elf64_auxv_t as Elf_auxv_t; + use test_helper::sys; + + use crate::utils::ffi::*; + + // Linux kernel 6.4 has added a way to read auxv without depending on either libc or mrs trap. + // https://github.com/torvalds/linux/commit/ddc65971bb677aa9f6a4c21f76d3133e106f88eb + // (Actually 6.5? https://github.com/torvalds/linux/commit/636e348353a7cc52609fdba5ff3270065da140d5) + // + // This is currently used only for testing. + #[cfg(not(target_os = "android"))] + #[cfg(not(portable_atomic_no_asm_syscall))] + fn getauxval_pr_get_auxv_no_libc(type_: c_ulong) -> Result { + use crate::utils::{RegISize, RegSize}; + + unsafe fn prctl_get_auxv(out: *mut c_void, len: usize) -> Result { + #[cfg_attr(target_arch = "arm", allow(unused_variables))] + let number = sys::__NR_prctl as RegSize; + let arg1 = sys::PR_GET_AUXV as RegSize; + let arg2 = ptr_reg!(out); + let arg3 = len as RegSize; + let arg4: RegSize = 0; + let arg5: RegSize = 0; + let r: RegISize; + // SAFETY: the caller must uphold the safety contract. + // we've extended the syscall number and arguments to the register size. + unsafe { + #[cfg(target_arch = "arm")] + asm_syscall!(sys::__NR_prctl, 172, r, arg1, arg2, arg3, arg4, arg5); + // POWER9+ has fast syscall using SCV, but since detection is cold path, + // there’s no need to consider it here. + #[cfg(not(target_arch = "arm"))] + asm_syscall!(number, r, arg1, arg2, arg3, arg4, arg5); + } + #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] + if (r as c_int) < 0 { Err(r as c_int) } else { Ok(r as usize) } + } + + let mut auxv = vec![unsafe { mem::zeroed::() }; 38]; + + let old_len = auxv.len() * mem::size_of::(); + + // SAFETY: + // - `out_len` does not exceed the size of `auxv`. + let _len = unsafe { prctl_get_auxv(auxv.as_mut_ptr().cast::(), old_len)? }; + + for aux in &auxv { + if aux.a_type == type_ { + // SAFETY: aux.a_un is #[repr(C)] union and all fields have + // the same size and can be safely transmuted to integers. + return Ok(unsafe { aux.a_un.a_val }); + } + } + Err(0) + } + // Similar to the above, but call libc prctl instead of syscall using asm. + // + // This is used only for testing. + fn getauxval_pr_get_auxv_libc(type_: c_ulong) -> Result { + unsafe fn prctl_get_auxv(out: *mut c_void, len: usize) -> Result { + // arg4 and arg5 must be zero. + #[allow(clippy::cast_possible_wrap)] + let r = unsafe { libc::prctl(sys::PR_GET_AUXV as c_int, out, len, 0, 0) }; + #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] + if (r as c_int) < 0 { Err(r as c_int) } else { Ok(r as usize) } + } + + let mut auxv = vec![unsafe { mem::zeroed::() }; 38]; + + let old_len = auxv.len() * mem::size_of::(); + + // SAFETY: + // - `out_len` does not exceed the size of `auxv`. + let _len = unsafe { prctl_get_auxv(auxv.as_mut_ptr().cast::(), old_len)? }; + + for aux in &auxv { + if aux.a_type == type_ { + // SAFETY: aux.a_un is #[repr(C)] union and all fields have + // the same size and can be safely transmuted to integers. + return Ok(unsafe { aux.a_un.a_val }); + } + } + Err(0) + } + + unsafe { + let mut u = mem::zeroed(); + assert_eq!(libc::uname(&mut u), 0); + let release = std::ffi::CStr::from_ptr(u.release.as_ptr()); + let release = str::from_utf8(release.to_bytes()).unwrap(); + let mut digits = release.split('.'); + let major = digits.next().unwrap().parse::().unwrap(); + let minor = digits.next().unwrap().parse::().unwrap(); + // TODO: qemu-user bug (fails even on kernel >= 6.4) (as of 9.2) + if (major, minor) < (6, 4) || cfg!(qemu) { + eprintln!("kernel version: {}.{} (no pr_get_auxv)", major, minor); + for &at in &[ffi::AT_HWCAP, ffi::AT_HWCAP2, ffi::AT_HWCAP3, ffi::AT_HWCAP4] { + assert_eq!(getauxval_pr_get_auxv_libc(at).unwrap_err(), -1); + #[cfg(not(target_os = "android"))] + #[cfg(not(portable_atomic_no_asm_syscall))] + assert_eq!(getauxval_pr_get_auxv_no_libc(at).unwrap_err(), -libc::EINVAL); + } + } else { + eprintln!("kernel version: {}.{} (has pr_get_auxv)", major, minor); + for &at in &[ffi::AT_HWCAP, ffi::AT_HWCAP2] { + if cfg!(all(valgrind, target_arch = "powerpc64")) { + // TODO: valgrind bug (as of Valgrind 3.26) + assert_eq!(getauxval_pr_get_auxv_libc(at).unwrap_err(), -1); + #[cfg(not(target_os = "android"))] + #[cfg(not(portable_atomic_no_asm_syscall))] + assert_eq!(getauxval_pr_get_auxv_no_libc(at).unwrap_err(), -libc::EINVAL); + } else if cfg!(all(valgrind, target_arch = "aarch64")) + || cfg!(all(valgrind, target_arch = "arm")) && at == ffi::AT_HWCAP2 + { + // TODO: valgrind bug (result value mismatch) (as of Valgrind 3.26) + assert_ne!(os::getauxval(at), getauxval_pr_get_auxv_libc(at).unwrap()); + #[cfg(not(target_os = "android"))] + #[cfg(not(portable_atomic_no_asm_syscall))] + assert_ne!(os::getauxval(at), getauxval_pr_get_auxv_no_libc(at).unwrap()); + } else { + assert_eq!(os::getauxval(at), getauxval_pr_get_auxv_libc(at).unwrap()); + #[cfg(not(target_os = "android"))] + #[cfg(not(portable_atomic_no_asm_syscall))] + assert_eq!(os::getauxval(at), getauxval_pr_get_auxv_no_libc(at).unwrap()); + } + } + for &at in &[ffi::AT_HWCAP3, ffi::AT_HWCAP4] { + assert_eq!( + os::getauxval(at), + getauxval_pr_get_auxv_libc(at).unwrap_or_default() + ); + #[cfg(not(target_os = "android"))] + #[cfg(not(portable_atomic_no_asm_syscall))] + assert_eq!( + os::getauxval(at), + getauxval_pr_get_auxv_no_libc(at).unwrap_or_default() + ); + } + } + } + } + #[allow(clippy::cast_possible_wrap)] + #[cfg(target_os = "freebsd")] + #[test] + fn test_alternative() { + use std::ptr; + + use test_helper::sys; + + use crate::utils::ffi::*; + + // This is almost equivalent to what elf_aux_info does. + // https://man.freebsd.org/elf_aux_info(3) + // On FreeBSD, [AArch64 support is available on FreeBSD 11.0+](https://www.freebsd.org/releases/11.0R/announce), + // but elf_aux_info is available on FreeBSD 12.0+ and 11.4+: + // https://github.com/freebsd/freebsd-src/commit/0b08ae2120cdd08c20a2b806e2fcef4d0a36c470 + // https://github.com/freebsd/freebsd-src/blob/release/11.4.0/sys/sys/auxv.h + // so use sysctl instead of elf_aux_info. + // Note that FreeBSD 11 (11.4) was EoL on 2021-09-30, and FreeBSD 11.3 was EoL on 2020-09-30: + // https://www.freebsd.org/security/unsupported + // + // This is currently used only for testing. + // If you want us to use this implementation for compatibility with the older FreeBSD + // version that came to EoL a few years ago, please open an issue. + fn getauxval_sysctl_libc(type_: ffi::c_int) -> Result { + let mut auxv: [sys::Elf_Auxinfo; sys::AT_COUNT as usize] = unsafe { mem::zeroed() }; + + let mut len = mem::size_of_val(&auxv) as c_size_t; + + // SAFETY: calling getpid is safe. + let pid = unsafe { libc::getpid() }; + let mib = [ + sys::CTL_KERN as c_int, + sys::KERN_PROC as c_int, + sys::KERN_PROC_AUXV as c_int, + pid, + ]; + #[allow(clippy::cast_possible_truncation)] + let mib_len = mib.len() as c_uint; + // SAFETY: + // - `mib_len` does not exceed the size of `mib`. + // - `len` does not exceed the size of `auxv`. + // - `sysctl` is thread-safe. + let res = unsafe { + libc::sysctl( + mib.as_ptr(), + mib_len, + auxv.as_mut_ptr().cast::(), + &mut len, + ptr::null_mut(), + 0, + ) + }; + // FreeBSD sysctl returns 0 on success, -1 on failure. + if res != 0 { + return Err(res); + } + + for aux in &auxv { + #[allow(clippy::cast_sign_loss)] + if aux.a_type == type_ as c_long { + // SAFETY: aux.a_un is #[repr(C)] union and all fields have + // the same size and can be safely transmuted to integers. + return Ok(unsafe { aux.a_un.a_val as c_ulong }); + } + } + Err(0) + } + + // AT_HWCAP2 is only available on FreeBSD 13+ on AArch64. + let hwcap2_else = |e| if cfg!(target_arch = "aarch64") { 0 } else { panic!("{:?}", e) }; + let at = ffi::AT_HWCAP; + assert_eq!(os::getauxval(at), getauxval_sysctl_libc(at).unwrap()); + let at = ffi::AT_HWCAP2; + assert_eq!(os::getauxval(at), getauxval_sysctl_libc(at).unwrap_or_else(hwcap2_else)); + for &at in &[ffi::AT_HWCAP3, ffi::AT_HWCAP4] { + assert_eq!(os::getauxval(at), getauxval_sysctl_libc(at).unwrap_or_default()); + } + } +} diff --git a/vendor/portable-atomic/src/imp/detect/common.rs b/vendor/portable-atomic/src/imp/detect/common.rs new file mode 100644 index 0000000..d00998f --- /dev/null +++ b/vendor/portable-atomic/src/imp/detect/common.rs @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +#[derive(Clone, Copy)] +#[repr(transparent)] +pub(crate) struct CpuInfo(u32); + +impl CpuInfo { + #[inline] + fn set(&mut self, bit: CpuInfoFlag) { + self.0 = set(self.0, bit as u32); + } + #[inline] + #[must_use] + fn test(self, bit: CpuInfoFlag) -> bool { + test(self.0, bit as u32) + } +} + +#[inline] +#[must_use] +fn set(x: u32, bit: u32) -> u32 { + x | (1 << bit) +} +#[inline] +#[must_use] +fn test(x: u32, bit: u32) -> bool { + x & (1 << bit) != 0 +} + +#[inline] +pub(crate) fn detect() -> CpuInfo { + use core::sync::atomic::{AtomicU32, Ordering}; + + static CACHE: AtomicU32 = AtomicU32::new(0); + let mut info = CpuInfo(CACHE.load(Ordering::Relaxed)); + if info.0 != 0 { + return info; + } + info.set(CpuInfoFlag::Init); + // Note: detect_false cfg is intended to make it easy for developers to test + // cases where features usually available is not available, and is not a public API. + if !cfg!(portable_atomic_test_detect_false) { + info = _detect(info); + } + if cfg!(any( + all( + target_arch = "x86_64", + not(any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b")), + ), + all( + target_arch = "powerpc64", + not(any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + )), + ), + all( + any(target_arch = "riscv32", target_arch = "riscv64"), + not(any(target_feature = "zacas", portable_atomic_target_feature = "zacas")), + ), + )) { + // Use CAS if the detection result affects lock-freeness. + match CACHE.compare_exchange(0, info.0, Ordering::Relaxed, Ordering::Relaxed) { + Ok(_) => info, + Err(info) => { + debug_assert_ne!(info, 0); + CpuInfo(info) + } + } + } else { + CACHE.store(info.0, Ordering::Relaxed); + info + } +} + +macro_rules! flags { + ($( + $(#[$attr:meta])* + $func:ident($name:literal, any($($cfg:ident),*)), + )*) => { + #[allow(dead_code, non_camel_case_types)] + #[derive(Clone, Copy)] + #[cfg_attr(test, derive(PartialEq, Eq, PartialOrd, Ord))] + #[repr(u32)] + enum CpuInfoFlag { + Init = 0, + $($func,)* + } + impl CpuInfo { + $( + $(#[$attr])* + #[cfg(any(test, not(any($($cfg = $name),*))))] + #[inline] + #[must_use] + pub(crate) fn $func(self) -> bool { + self.test(CpuInfoFlag::$func) + } + )* + #[cfg(test)] // for test + const ALL_FLAGS: &'static [(&'static str, CpuInfoFlag, bool)] = &[$( + ($name, CpuInfoFlag::$func, cfg!(any($($cfg = $name),*))), + )*]; + } + #[test] + #[cfg_attr(portable_atomic_test_detect_false, ignore = "detection disabled")] + fn test_detect() {$( + $(#[$attr])* + { + const _: u32 = 1_u32 << CpuInfoFlag::$func as u32; + assert_eq!($name.replace(|c: char| c == '-' || c == '.', "_"), stringify!($func)); + if detect().$func() { + assert!(detect().test(CpuInfoFlag::$func)); + } else { + assert!(!detect().test(CpuInfoFlag::$func)); + } + } + )*} + }; +} + +// rustc definitions: https://github.com/rust-lang/rust/blob/ddaf12390d3ffb7d5ba74491a48f3cd528e5d777/compiler/rustc_target/src/target_features.rs + +// LLVM definitions: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/AArch64/AArch64Features.td +#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] +flags! { + // The Armv8.1 architecture extension + // https://developer.arm.com/documentation/109697/2025_06/Feature-descriptions/The-Armv8-1-architecture-extension + // FEAT_LSE, Large System Extensions + // > This feature is supported in AArch64 state only. + // > FEAT_LSE is OPTIONAL from Armv8.0. + // > FEAT_LSE is mandatory from Armv8.1. + lse("lse", any(target_feature /* 1.61+ */, portable_atomic_target_feature)), + + // The Armv8.3 architecture extension + // https://developer.arm.com/documentation/109697/2025_06/Feature-descriptions/The-Armv8-3-architecture-extension + // FEAT_LRCPC, Load-Acquire RCpc instructions + // > These instructions are added to the A64 instruction set only. + // > FEAT_LRCPC is OPTIONAL from Armv8.2. + // > FEAT_LRCPC is mandatory from Armv8.3. + #[cfg(test)] // test-only + rcpc("rcpc", any(target_feature /* 1.61+ */)), + + // The Armv8.4 architecture extension + // https://developer.arm.com/documentation/109697/2025_06/Feature-descriptions/The-Armv8-4-architecture-extension + // FEAT_LSE2, Large System Extensions version 2 + // > This feature is supported in AArch64 state only. + // > FEAT_LSE2 is OPTIONAL from Armv8.2. + // > FEAT_LSE2 is mandatory from Armv8.4. + #[cfg_attr(not(test), allow(dead_code))] + lse2("lse2", any(target_feature /* nightly */, portable_atomic_target_feature)), + // FEAT_LRCPC2, Load-Acquire RCpc instructions version 2 + // > These instructions are added to the A64 instruction set only. + // > FEAT_LRCPC2 is OPTIONAL from Armv8.2. + // > FEAT_LRCPC2 is mandatory from Armv8.4. + // > If FEAT_LRCPC2 is implemented, then FEAT_LRCPC is implemented. + #[cfg(test)] // test-only + rcpc2("rcpc2", any(target_feature /* 1.61+ */)), + + // The Armv8.9 architecture extension + // https://developer.arm.com/documentation/109697/2025_06/Feature-descriptions/The-Armv8-9-architecture-extension + // FEAT_LRCPC3, Load-Acquire RCpc instructions version 3 + // > This feature is supported in AArch64 state only. + // > FEAT_LRCPC3 is OPTIONAL from Armv8.2. + // > If FEAT_LRCPC3 is implemented, then FEAT_LRCPC2 is implemented. + #[cfg_attr(not(test), allow(dead_code))] + rcpc3("rcpc3", any(target_feature /* nightly */, portable_atomic_target_feature)), + + // The Armv9.4 architecture extension + // https://developer.arm.com/documentation/109697/2025_06/Feature-descriptions/The-Armv9-4-architecture-extension + // FEAT_LSE128, 128-bit Atomics + // > This feature is supported in AArch64 state only. + // > FEAT_LSE128 is OPTIONAL from Armv9.3. + // > If FEAT_LSE128 is implemented, then FEAT_LSE is implemented. + #[cfg_attr(not(test), allow(dead_code))] + lse128("lse128", any(target_feature /* nightly */, portable_atomic_target_feature)), + + // The Armv9.6 architecture extension + // https://developer.arm.com/documentation/109697/2025_06/Feature-descriptions/The-Armv9-6-architecture-extension + // FEAT_LS64WB, LS64 for Write-back cacheable memory + // > This feature is supported in AArch64 state only. + // > FEAT_LS64WB is OPTIONAL from Armv9.2. + // > If FEAT_LS64WB is implemented, then FEAT_LS64_ACCDATA is implemented. + #[cfg(test)] // test-only + ls64wb("ls64wb", any(/* no corresponding target feature */)), + // FEAT_LSFE, Large System Float Extension + // > This feature is supported in AArch64 state only. + // > FEAT_LSFE is OPTIONAL from Armv9.3. + // > If FEAT_LSFE is implemented, then FEAT_FP is implemented. + #[cfg(test)] // test-only + lsfe("lsfe", any(target_feature /* N/A */, portable_atomic_target_feature)), + + #[cfg(test)] // test-only + cpuid("cpuid", any(/* no corresponding target feature */)), +} + +// LLVM definitions: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/ARM/ARMFeatures.td +#[cfg(target_arch = "arm")] +flags! { + #[cfg(test)] // test-only + lpae("lpae", any(/* no corresponding target feature */)), +} + +// LLVM definitions: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/PowerPC/PPC.td +#[cfg(target_arch = "powerpc64")] +flags! { + // lqarx and stqcx. + quadword_atomics("quadword-atomics", any(target_feature /* nightly */, portable_atomic_target_feature)), +} + +// LLVM definitions: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/RISCV/RISCVFeatures.td +#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] +flags! { + // amocas.{w,d,q} + zacas("zacas", any(target_feature /* 1.94+ */, portable_atomic_target_feature)), + #[cfg(test)] // test-only + zabha("zabha", any(target_feature /* 1.94+ */, portable_atomic_target_feature)), + #[cfg(test)] // test-only + zalasr("zalasr", any(/* no corresponding target feature */)), +} + +// LLVM definitions: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/X86/X86.td +#[cfg(target_arch = "x86_64")] +flags! { + // avx + #[cfg(target_feature = "sse")] + avx("avx", any(target_feature)), + // cmpxchg16b + cmpxchg16b("cmpxchg16b", any(target_feature /* 1.69+ */, portable_atomic_target_feature)), +} + +#[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks, + clippy::wildcard_imports +)] +#[cfg(test)] +mod tests_common { + use std::{collections::BTreeSet, vec}; + + use super::*; + + #[test] + fn test_bit_flags() { + let mut flags = vec![("init", CpuInfoFlag::Init)]; + flags.extend(CpuInfo::ALL_FLAGS.iter().map(|&(name, flag, _)| (name, flag))); + let flag_set = flags.iter().map(|(_, flag)| flag).collect::>(); + let name_set = flags.iter().map(|(name, _)| name).collect::>(); + if flag_set.len() != flags.len() { + panic!("CpuInfo flag values must be unique") + } + if name_set.len() != flags.len() { + panic!("CpuInfo flag names must be unique") + } + + let mut x = CpuInfo(0); + for &(_, f) in &flags { + assert!(!x.test(f)); + } + for i in 0..flags.len() { + x.set(flags[i].1); + for &(_, f) in &flags[..i + 1] { + assert!(x.test(f)); + } + for &(_, f) in &flags[i + 1..] { + assert!(!x.test(f)); + } + } + for &(_, f) in &flags { + assert!(x.test(f)); + } + } + + #[test] + fn print_features() { + use std::{fmt::Write as _, string::String}; + + let mut features = String::new(); + features.push_str("\nfeatures:\n"); + for &(name, flag, compile_time) in CpuInfo::ALL_FLAGS { + let run_time = detect().test(flag); + if run_time == compile_time { + let _ = writeln!(features, " {}: {}", name, run_time); + } else { + let _ = writeln!( + features, + " {}: {} (compile-time), {} (run-time)", + name, compile_time, run_time + ); + } + } + test_helper::eprintln_nocapture!("{}", features); + } + + // Static assertions for C type definitions. + // Assertions with core::ffi types are in crate::utils::ffi module. + #[cfg(not(any(windows, target_arch = "x86", target_arch = "x86_64")))] + const _: fn() = || { + use test_helper::sys; + let _: crate::utils::ffi::c_char = 0 as sys::c_char; + }; +} diff --git a/vendor/portable-atomic/src/imp/detect/powerpc64_aix.rs b/vendor/portable-atomic/src/imp/detect/powerpc64_aix.rs new file mode 100644 index 0000000..41bfc71 --- /dev/null +++ b/vendor/portable-atomic/src/imp/detect/powerpc64_aix.rs @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Run-time CPU feature detection on PowerPC64 AIX by using getsystemcfg. + +Refs: +- https://github.com/golang/go/blob/go1.26.0/src/internal/cpu/cpu_ppc64x_aix.go + +As of Rust 1.94, is_powerpc_feature_detected doesn't support run-time detection on AIX. +https://github.com/rust-lang/rust/blob/1.94.0/library/std_detect/src/detect/mod.rs + +Run-time detection on PowerPC64 AIX is currently disabled by default as experimental +because we cannot run tests on the VM or real machine. +*/ + +include!("common.rs"); + +// libc requires Rust 1.63 +mod ffi { + pub(crate) use crate::utils::ffi::{c_int, c_ulong}; + + sys_const!({ + // https://github.com/rust-lang/libc/blob/0.2.158/src/unix/aix/mod.rs#L2058 + // https://github.com/golang/go/blob/go1.26.0/src/internal/cpu/cpu_ppc64x_aix.go + pub(crate) const SC_IMPL: c_int = 2; + pub(crate) const POWER_8: c_ulong = 0x10000; + pub(crate) const POWER_9: c_ulong = 0x20000; + }); + // TODO: use sys_const! once libc crate defined it. + pub(crate) const POWER_10: c_ulong = 0x40000; + + sys_fn!({ + extern "C" { + // https://www.ibm.com/docs/en/aix/7.3?topic=g-getsystemcfg-subroutine + // https://github.com/rust-lang/libc/blob/0.2.158/src/unix/aix/powerpc64.rs#L643 + pub(crate) fn getsystemcfg(name: c_int) -> c_ulong; + } + }); +} + +#[cold] +#[must_use] +fn _detect(mut info: CpuInfo) -> CpuInfo { + // SAFETY: calling getsystemcfg is safe. + let impl_ = unsafe { ffi::getsystemcfg(ffi::SC_IMPL) }; + if impl_ == ffi::c_ulong::MAX { + return info; + } + // Check both POWER_8 and later ISAs (which are superset of POWER_8) because + // AIX currently doesn't set POWER_8 when POWER_9 is set. + // https://github.com/golang/go/commit/51859ec2292d9c1d82a7054ec672ff551a0d7497 + if impl_ & (ffi::POWER_8 | ffi::POWER_9 | ffi::POWER_10) != 0 { + info.set(CpuInfoFlag::quadword_atomics); + } + info +} diff --git a/vendor/portable-atomic/src/imp/detect/riscv_linux.rs b/vendor/portable-atomic/src/imp/detect/riscv_linux.rs new file mode 100644 index 0000000..2bb37aa --- /dev/null +++ b/vendor/portable-atomic/src/imp/detect/riscv_linux.rs @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Run-time CPU feature detection on RISC-V Linux/Android by using riscv_hwprobe. + +On RISC-V, detection using auxv only supports single-letter extensions. +So, we use riscv_hwprobe that supports multi-letter extensions. + +Refs: https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/riscv/hwprobe.rst +*/ + +include!("common.rs"); + +use core::ptr; + +// libc requires Rust 1.63 +#[allow(non_camel_case_types, non_upper_case_globals)] +mod ffi { + pub(crate) use crate::utils::ffi::{c_long, c_size_t, c_uint, c_ulong}; + + sys_struct!({ + // https://github.com/torvalds/linux/blob/v6.19/arch/riscv/include/uapi/asm/hwprobe.h + pub(crate) struct riscv_hwprobe { + pub(crate) key: i64, + pub(crate) value: u64, + } + }); + + sys_const!({ + pub(crate) const __NR_riscv_hwprobe: c_long = 258; + + // https://github.com/torvalds/linux/blob/v6.19/arch/riscv/include/uapi/asm/hwprobe.h + // Linux 6.4+ + // https://github.com/torvalds/linux/commit/00e76e2c6a2bd3976d44d4a1fdd0b7a3c2566607 + pub(crate) const RISCV_HWPROBE_KEY_BASE_BEHAVIOR: i64 = 3; + pub(crate) const RISCV_HWPROBE_BASE_BEHAVIOR_IMA: u64 = 1 << 0; + pub(crate) const RISCV_HWPROBE_KEY_IMA_EXT_0: i64 = 4; + // Linux 6.8+ + // https://github.com/torvalds/linux/commit/154a3706122978eeb34d8223d49285ed4f3c61fa + pub(crate) const RISCV_HWPROBE_EXT_ZACAS: u64 = 1 << 34; + // Linux 6.16+ + // https://github.com/torvalds/linux/commit/415a8c81da3dab0a585bd4f8d505a11ad5a171a7 + #[cfg(test)] + pub(crate) const RISCV_HWPROBE_EXT_ZABHA: u64 = 1 << 58; + // Linux 6.19+ + // https://github.com/torvalds/linux/commit/f4922b69165735e81752ee47d174f873e989a449 + #[cfg(test)] + pub(crate) const RISCV_HWPROBE_EXT_ZALASR: u64 = 1 << 59; + }); + + cfg_sel!({ + // Use asm-based syscall on Linux for compatibility with non-libc targets if possible. + // Do not use this on Android. See comments on syscall_helper module in src/utils.rs for details. + #[cfg(all( + target_os = "linux", + any( + target_arch = "riscv32", + all(target_arch = "riscv64", target_pointer_width = "64"), + ), + not(portable_atomic_no_asm_syscall), + ))] + { + use crate::utils::{RegISize, RegSize}; + + #[inline] + pub(crate) unsafe fn syscall5( + number: c_long, + arg1: *mut riscv_hwprobe, + arg2: c_size_t, + arg3: c_size_t, + arg4: *mut c_ulong, + arg5: c_uint, + ) -> c_long { + #[allow(clippy::cast_possible_truncation)] + let number = number as RegISize; + let arg1 = ptr_reg!(arg1); + let arg2 = arg2 as RegSize; + let arg3 = arg3 as RegSize; + let arg4 = ptr_reg!(arg4); + let arg5 = arg5 as RegSize; + let r: RegISize; + // SAFETY: the caller must uphold the safety contract. + // we've extended the syscall number and arguments to the register size. + unsafe { + asm_syscall!(number, r, arg1, arg2, arg3, arg4, arg5); + } + #[allow(clippy::cast_possible_truncation)] + { + r as c_long + } + } + } + #[cfg(else)] + { + sys_fn!({ + extern "C" { + // https://man7.org/linux/man-pages/man2/syscall.2.html + pub(crate) fn syscall(number: c_long, ...) -> c_long; + } + }); + pub(crate) use self::syscall as syscall5; + } + }); + + // https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/riscv/hwprobe.rst + pub(crate) unsafe fn __riscv_hwprobe( + pairs: *mut riscv_hwprobe, + pair_count: c_size_t, + cpu_set_size: c_size_t, + cpus: *mut c_ulong, + flags: c_uint, + ) -> c_long { + // SAFETY: the caller must uphold the safety contract. + unsafe { syscall5(__NR_riscv_hwprobe, pairs, pair_count, cpu_set_size, cpus, flags) } + } +} + +// syscall returns an unsupported error if riscv_hwprobe is not supported, +// so we can safely use this function on older versions of Linux. +fn riscv_hwprobe(out: &mut [ffi::riscv_hwprobe]) -> bool { + let len = out.len(); + // SAFETY: We've passed the valid pointer and length, + // passing null ptr for cpus is safe because cpu_set_size is zero. + unsafe { ffi::__riscv_hwprobe(out.as_mut_ptr(), len, 0, ptr::null_mut(), 0) == 0 } +} + +#[cold] +#[must_use] +fn _detect(mut info: CpuInfo) -> CpuInfo { + let mut out = [ + ffi::riscv_hwprobe { key: ffi::RISCV_HWPROBE_KEY_BASE_BEHAVIOR, value: 0 }, + ffi::riscv_hwprobe { key: ffi::RISCV_HWPROBE_KEY_IMA_EXT_0, value: 0 }, + ]; + if riscv_hwprobe(&mut out) + && out[0].key != -1 + && out[0].value & ffi::RISCV_HWPROBE_BASE_BEHAVIOR_IMA != 0 + && out[1].key != -1 + { + let value = out[1].value; + macro_rules! check { + ($flag:ident, $bit:ident) => { + if value & ffi::$bit != 0 { + info.set(CpuInfoFlag::$flag); + } + }; + } + check!(zacas, RISCV_HWPROBE_EXT_ZACAS); + #[cfg(test)] + check!(zabha, RISCV_HWPROBE_EXT_ZABHA); + #[cfg(test)] + check!(zalasr, RISCV_HWPROBE_EXT_ZALASR); + } + info +} + +#[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks, + clippy::wildcard_imports +)] +#[cfg(test)] +mod tests { + use super::*; + + // We use asm-based syscall for compatibility with non-libc targets. + // This test tests that our ones and libc::syscall returns the same result. + #[test] + fn test_alternative() { + unsafe fn __riscv_hwprobe_libc( + pairs: *mut ffi::riscv_hwprobe, + pair_count: ffi::c_size_t, + cpu_set_size: ffi::c_size_t, + cpus: *mut ffi::c_ulong, + flags: ffi::c_uint, + ) -> ffi::c_long { + // SAFETY: the caller must uphold the safety contract. + unsafe { + libc::syscall(ffi::__NR_riscv_hwprobe, pairs, pair_count, cpu_set_size, cpus, flags) + } + } + fn riscv_hwprobe_libc(out: &mut [ffi::riscv_hwprobe]) -> bool { + let len = out.len(); + unsafe { __riscv_hwprobe_libc(out.as_mut_ptr(), len, 0, ptr::null_mut(), 0) == 0 } + } + let mut out = [ + ffi::riscv_hwprobe { key: ffi::RISCV_HWPROBE_KEY_BASE_BEHAVIOR, value: 0 }, + ffi::riscv_hwprobe { key: ffi::RISCV_HWPROBE_KEY_IMA_EXT_0, value: 0 }, + ]; + let mut libc_out = out; + assert_eq!(riscv_hwprobe(&mut out), riscv_hwprobe_libc(&mut libc_out)); + assert_eq!(out, libc_out); + } +} diff --git a/vendor/portable-atomic/src/imp/detect/x86_64.rs b/vendor/portable-atomic/src/imp/detect/x86_64.rs new file mode 100644 index 0000000..18d51eb --- /dev/null +++ b/vendor/portable-atomic/src/imp/detect/x86_64.rs @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Run-time CPU feature detection on x86_64 by using CPUID. + +Adapted from https://github.com/rust-lang/rust/blob/1.92.0/library/std_detect/src/detect/os/x86.rs. +*/ + +#![cfg_attr(portable_atomic_sanitize_thread, allow(dead_code))] + +// Miri doesn't support inline assembly used in __cpuid: https://github.com/rust-lang/miri/issues/932 +// SGX doesn't support CPUID: https://github.com/rust-lang/rust/blob/1.92.0/library/std_detect/src/detect/os/x86.rs#L30-L33 +#[cfg(any(target_env = "sgx", miri))] +compile_error!("internal error: this module is not supported on this environment"); + +include!("common.rs"); + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; +use core::arch::x86_64::CpuidResult; + +// Workaround for https://github.com/rust-lang/rust/issues/101346 +// It is not clear if our use cases are affected, but we implement this just in case. +// +// Refs: +// - https://www.felixcloutier.com/x86/cpuid +// - https://en.wikipedia.org/wiki/CPUID +// - https://github.com/rust-lang/stdarch/blob/a0c30f3e3c75adcd6ee7efc94014ebcead61c507/crates/core_arch/src/x86/cpuid.rs +#[cfg(not(target_env = "sgx"))] +fn __cpuid(leaf: u32) -> CpuidResult { + let eax; + let mut ebx; + let ecx; + let edx; + // SAFETY: Calling `__cpuid` is safe on all x86_64 CPUs except for SGX, + // which doesn't support `cpuid`. + // https://github.com/rust-lang/stdarch/blob/a0c30f3e3c75adcd6ee7efc94014ebcead61c507/crates/core_arch/src/x86/cpuid.rs#L102-L109 + unsafe { + asm!( + "mov r8, rbx", // save rbx which is reserved by LLVM + "cpuid", + "xchg r8, rbx", // restore rbx + out("r8") ebx, + inout("eax") leaf => eax, + inout("ecx") 0 => ecx, + out("edx") edx, + options(nostack, preserves_flags), + ); + } + CpuidResult { eax, ebx, ecx, edx } +} + +#[cold] +#[must_use] +fn _detect(mut info: CpuInfo) -> CpuInfo { + let CpuidResult { ecx: proc_info_ecx, .. } = __cpuid(1); + + // https://github.com/rust-lang/rust/blob/1.92.0/library/std_detect/src/detect/os/x86.rs#L104 + if test(proc_info_ecx, 13) { + info.set(CpuInfoFlag::cmpxchg16b); + } + + // We only use VMOVDQA when SSE is enabled. See _atomic_load_vmovdqa() in atomic128/x86_64.rs for more. + #[cfg(target_feature = "sse")] + { + use core::arch::x86_64::_xgetbv; + + // https://github.com/rust-lang/rust/blob/1.92.0/library/std_detect/src/detect/os/x86.rs#L166-L236 + let cpu_xsave = test(proc_info_ecx, 26); + if cpu_xsave { + let cpu_osxsave = test(proc_info_ecx, 27); + if cpu_osxsave { + // SAFETY: Calling `_xgetbv` is safe because the CPU has `xsave` support + // and OS has set `osxsave`. + let xcr0 = unsafe { _xgetbv(0) }; + let os_avx_support = xcr0 & 6 == 6; + if os_avx_support && test(proc_info_ecx, 28) { + info.set(CpuInfoFlag::avx); + } + } + } + } + info +} + +#[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks, + clippy::wildcard_imports +)] +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[cfg_attr(portable_atomic_test_detect_false, ignore = "detection disabled")] + fn test_cpuid() { + // The recent Rosetta 2 unofficially implements AVX support. + // (The OS reports it as unsupported, likely due to poor performance.) + #[cfg(target_vendor = "apple")] + assert_eq!( + std::is_x86_feature_detected!("avx"), + detect().avx() || cfg!(target_feature = "avx") + ); + #[cfg(not(target_vendor = "apple"))] + assert_eq!(std::is_x86_feature_detected!("avx"), detect().avx()); + assert_eq!(std::is_x86_feature_detected!("cmpxchg16b"), detect().cmpxchg16b()); + } +} diff --git a/vendor/portable-atomic/src/imp/fallback/mod.rs b/vendor/portable-atomic/src/imp/fallback/mod.rs new file mode 100644 index 0000000..9580ea3 --- /dev/null +++ b/vendor/portable-atomic/src/imp/fallback/mod.rs @@ -0,0 +1,580 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Fallback implementation using global locks. + +This implementation uses seqlock for global locks. + +This is basically based on global locks in crossbeam-utils's `AtomicCell`, +but seqlock is implemented in a way that does not depend on UB +(see comments in optimistic_read method in atomic! macro for details). + +Note that we cannot use a lock per atomic type, since the in-memory representation of the atomic +type and the value type must be the same. +*/ + +#![cfg_attr( + any( + all( + target_arch = "riscv32", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + not(portable_atomic_no_outline_atomics), + any(target_os = "linux", target_os = "android"), + ), + all( + target_arch = "arm", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_os = "linux", target_os = "android"), + any(test, not(any(target_feature = "v6", portable_atomic_target_feature = "v6"))), + not(portable_atomic_no_outline_atomics), + ), + ), + allow(dead_code) +)] + +// This module requires CAS and this crate only provides atomics up to 128-bit. +// I don't believe there are any 16-bit multi-core systems with CAS, and +// at least no such architecture is currently supported in Rust. +// 128-bit targets that lack atomic usize CAS also do not reach this module. +#[cfg(target_pointer_width = "16")] +compile_error!( + "internal error: unreachable since atomics for 16-bit targets can always be provided by disable interrupts" +); +#[cfg(target_pointer_width = "128")] +compile_error!( + "internal error: unreachable since 128-bit target either has atomic CAS for the pointer width or does not have CAS" +); + +mod utils; + +// Use "wide" sequence lock if the pointer width <= 32 for preventing its counter against wrap +// around. +// +// Some 64-bit architectures have ABI with 32-bit pointer width (e.g., x86_64 X32 ABI, +// AArch64 ILP32 ABI, mips64 N32 ABI). On those targets, AtomicU64 is available and fast, +// so use it to implement normal sequence lock and reduce chunks of byte-wise atomic memcpy. +cfg_has_fast_atomic_64!({ + mod seq_lock; + type AtomicChunk = core::sync::atomic::AtomicU64; + type Chunk = u64; +}); +cfg_no_fast_atomic_64!({ + #[path = "seq_lock_wide.rs"] + mod seq_lock; + type AtomicChunk = core::sync::atomic::AtomicU32; + type Chunk = u32; +}); + +use core::{cell::UnsafeCell, mem, sync::atomic::Ordering}; + +use self::{ + seq_lock::{SeqLock, SeqLockWriteGuard}, + utils::CachePadded, +}; +#[cfg(portable_atomic_no_strict_provenance)] +use crate::utils::ptr::PtrExt as _; +use crate::utils::unlikely; + +// Adapted from https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/atomic/atomic_cell.rs#L970-L1010. +#[inline] +#[must_use] +fn lock(addr: usize) -> &'static SeqLock { + // The number of locks is a prime number because we want to make sure `addr % LEN` gets + // dispersed across all locks. + const LEN: usize = 67; + const L: CachePadded = CachePadded::new(SeqLock::new()); + static LOCKS: [CachePadded; LEN] = [ + L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, + L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, + L, L, L, L, L, L, L, + ]; + + // If the modulus is a constant number, the compiler will use crazy math to transform this into + // a sequence of cheap arithmetic operations rather than using the slow modulo instruction. + &LOCKS[addr % LEN] +} + +// Emit SeqCst fence to ensure SeqCst semantics when ordering is SeqCst. +#[must_use] +struct ScFenceGuard; +impl ScFenceGuard { + #[inline] + fn new(emit_sc_fence: bool) -> Option { + if unlikely(emit_sc_fence) { + crate::fence(Ordering::SeqCst); + Some(ScFenceGuard) + } else { + None + } + } +} +impl Drop for ScFenceGuard { + #[inline] + fn drop(&mut self) { + crate::fence(Ordering::SeqCst); + } +} + +macro_rules! atomic { + ($atomic_type:ident, $int_type:ident, $align:literal) => { + #[repr(C, align($align))] + pub(crate) struct $atomic_type { + v: UnsafeCell<$int_type>, + } + + impl $atomic_type { + const LEN: usize = mem::size_of::<$int_type>() / mem::size_of::(); + + #[inline] + unsafe fn chunks(&self) -> &[AtomicChunk; Self::LEN] { + static_assert!($atomic_type::LEN > 1); + static_assert!(mem::size_of::<$int_type>() % mem::size_of::() == 0); + + // SAFETY: the caller must uphold the safety contract for `chunks`. + unsafe { &*(self.v.get() as *const $int_type as *const [AtomicChunk; Self::LEN]) } + } + + #[inline] + fn optimistic_read(&self) -> $int_type { + // Using `MaybeUninit<[usize; Self::LEN]>` here doesn't change codegen: https://godbolt.org/z/86f8s733M + let mut dst: [Chunk; Self::LEN] = [0; Self::LEN]; + // SAFETY: + // - There are no threads that perform non-atomic concurrent write operations. + // - There is no writer that updates the value using atomic operations of different granularity. + // + // If the atomic operation is not used here, it will cause a data race + // when `write` performs concurrent write operation. + // Such a data race is sometimes considered virtually unproblematic + // in SeqLock implementations: + // + // - https://github.com/Amanieu/seqlock/issues/2 + // - https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/atomic/atomic_cell.rs#L1063-L1069 + // - https://rust-lang.zulipchat.com/#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/avoiding.20UB.20due.20to.20races.20by.20discarding.20result.3F + // + // However, in our use case, the implementation that loads/stores value as + // chunks of usize is enough fast and sound, so we use that implementation. + // + // See also atomic-memcpy crate, a generic implementation of this pattern: + // https://github.com/taiki-e/atomic-memcpy + let chunks = unsafe { self.chunks() }; + for i in 0..Self::LEN { + dst[i] = chunks[i].load(Ordering::Relaxed); + } + // SAFETY: integers are plain old data types so we can always transmute to them. + unsafe { mem::transmute::<[Chunk; Self::LEN], $int_type>(dst) } + } + + #[inline] + fn read(&self, _guard: &SeqLockWriteGuard<'static>) -> $int_type { + // This calls optimistic_read that can return teared value, but the resulting value + // is guaranteed not to be teared because we hold the lock to write. + self.optimistic_read() + } + + #[inline] + fn write(&self, val: $int_type, _guard: &SeqLockWriteGuard<'static>) { + // SAFETY: integers are plain old data types so we can always transmute them to arrays of integers. + let val = unsafe { mem::transmute::<$int_type, [Chunk; Self::LEN]>(val) }; + // SAFETY: + // - The guard guarantees that we hold the lock to write. + // - There are no threads that perform non-atomic concurrent read or write operations. + // + // See optimistic_read for the reason that atomic operations are used here. + let chunks = unsafe { self.chunks() }; + for i in 0..Self::LEN { + chunks[i].store(val[i], Ordering::Relaxed); + } + } + } + + // Send is implicitly implemented. + // SAFETY: any data races are prevented by the lock and atomic operation. + unsafe impl Sync for $atomic_type {} + + #[cfg(any( + test, + not(any( + all( + target_arch = "x86_64", + not(all( + any(miri, portable_atomic_sanitize_thread), + portable_atomic_no_cmpxchg16b_intrinsic, + )), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + not(portable_atomic_no_outline_atomics), + not(any(target_env = "sgx", miri)), + ), + all( + target_arch = "powerpc64", + not(portable_atomic_no_asm), + not(portable_atomic_no_outline_atomics), + any( + all( + target_os = "linux", + any( + all( + target_env = "gnu", + any(target_endian = "little", not(target_feature = "crt-static")), + ), + all( + target_env = "musl", + any(not(target_feature = "crt-static"), feature = "std"), + ), + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + portable_atomic_outline_atomics, + ), + ), + target_os = "android", + all( + target_os = "freebsd", + any( + target_endian = "little", + not(target_feature = "crt-static"), + portable_atomic_outline_atomics, + ), + ), + target_os = "openbsd", + all( + target_os = "aix", + not(portable_atomic_pre_llvm_20), + portable_atomic_outline_atomics, // TODO(aix): currently disabled by default + ), + ), + not(any(miri, portable_atomic_sanitize_thread)), + ), + all( + target_arch = "riscv64", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + not(portable_atomic_no_outline_atomics), + any(target_os = "linux", target_os = "android"), + ), + )), + ))] + items!({ + impl_default_no_fetch_ops!($atomic_type, $int_type); + impl_default_bit_opts!($atomic_type, $int_type); + impl $atomic_type { + #[inline] + pub(crate) const fn new(v: $int_type) -> Self { + Self { v: UnsafeCell::new(v) } + } + + #[inline] + pub(crate) fn is_lock_free() -> bool { + Self::IS_ALWAYS_LOCK_FREE + } + pub(crate) const IS_ALWAYS_LOCK_FREE: bool = false; + + #[inline] + #[cfg_attr( + all(debug_assertions, not(portable_atomic_no_track_caller)), + track_caller + )] + pub(crate) fn compare_exchange_weak( + &self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering, + ) -> Result<$int_type, $int_type> { + self.compare_exchange(current, new, success, failure) + } + + #[inline] + pub(crate) fn not(&self, order: Ordering) { + self.fetch_not(order); + } + #[inline] + pub(crate) fn neg(&self, order: Ordering) { + self.fetch_neg(order); + } + + #[inline] + pub(crate) const fn as_ptr(&self) -> *mut $int_type { + self.v.get() + } + } + }); + #[cfg_attr( + any( + all( + target_arch = "x86_64", + not(all( + any(miri, portable_atomic_sanitize_thread), + portable_atomic_no_cmpxchg16b_intrinsic, + )), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + not(portable_atomic_no_outline_atomics), + not(any(target_env = "sgx", miri)), + ), + all( + target_arch = "powerpc64", + not(portable_atomic_no_asm), + not(portable_atomic_no_outline_atomics), + any( + all( + target_os = "linux", + any( + all( + target_env = "gnu", + any(target_endian = "little", not(target_feature = "crt-static")), + ), + all( + target_env = "musl", + any(not(target_feature = "crt-static"), feature = "std"), + ), + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + portable_atomic_outline_atomics, + ), + ), + target_os = "android", + all( + target_os = "freebsd", + any( + target_endian = "little", + not(target_feature = "crt-static"), + portable_atomic_outline_atomics, + ), + ), + target_os = "openbsd", + all( + target_os = "aix", + not(portable_atomic_pre_llvm_20), + portable_atomic_outline_atomics, // TODO(aix): currently disabled by default + ), + ), + not(any(miri, portable_atomic_sanitize_thread)), + ), + all( + target_arch = "riscv64", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + not(portable_atomic_no_outline_atomics), + any(target_os = "linux", target_os = "android"), + ), + ), + allow(dead_code) + )] + impl $atomic_type { + #[inline] + #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] + pub(crate) fn load(&self, order: Ordering) -> $int_type { + crate::utils::assert_load_ordering(order); + let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst); + let lock = lock(self.v.get().addr()); + + // Try doing an optimistic read first. + if let Some(stamp) = lock.optimistic_read() { + let val = self.optimistic_read(); + + if lock.validate_read(stamp) { + return val; + } + } + + // Grab a regular write lock so that writers don't starve this load. + let guard = lock.write(); + let val = self.read(&guard); + // The value hasn't been changed. Drop the guard without incrementing the stamp. + guard.abort(); + val + } + + #[inline] + #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] + pub(crate) fn store(&self, val: $int_type, order: Ordering) { + crate::utils::assert_store_ordering(order); + let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst); + let guard = lock(self.v.get().addr()).write(); + self.write(val, &guard) + } + + #[inline] + pub(crate) fn swap(&self, val: $int_type, order: Ordering) -> $int_type { + let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst); + let guard = lock(self.v.get().addr()).write(); + let prev = self.read(&guard); + self.write(val, &guard); + prev + } + + #[inline] + #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] + pub(crate) fn compare_exchange( + &self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering, + ) -> Result<$int_type, $int_type> { + crate::utils::assert_compare_exchange_ordering(success, failure); + let _sc_fence = ScFenceGuard::new( + success == Ordering::SeqCst || failure == Ordering::SeqCst + ); + let guard = lock(self.v.get().addr()).write(); + let prev = self.read(&guard); + if prev == current { + self.write(new, &guard); + Ok(prev) + } else { + // The value hasn't been changed. Drop the guard without incrementing the stamp. + guard.abort(); + Err(prev) + } + } + + #[inline] + pub(crate) fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { + let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst); + let guard = lock(self.v.get().addr()).write(); + let prev = self.read(&guard); + self.write(prev.wrapping_add(val), &guard); + prev + } + + #[inline] + pub(crate) fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { + let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst); + let guard = lock(self.v.get().addr()).write(); + let prev = self.read(&guard); + self.write(prev.wrapping_sub(val), &guard); + prev + } + + #[inline] + pub(crate) fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { + let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst); + let guard = lock(self.v.get().addr()).write(); + let prev = self.read(&guard); + self.write(prev & val, &guard); + prev + } + + #[inline] + pub(crate) fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { + let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst); + let guard = lock(self.v.get().addr()).write(); + let prev = self.read(&guard); + self.write(!(prev & val), &guard); + prev + } + + #[inline] + pub(crate) fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { + let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst); + let guard = lock(self.v.get().addr()).write(); + let prev = self.read(&guard); + self.write(prev | val, &guard); + prev + } + + #[inline] + pub(crate) fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { + let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst); + let guard = lock(self.v.get().addr()).write(); + let prev = self.read(&guard); + self.write(prev ^ val, &guard); + prev + } + + #[inline] + pub(crate) fn fetch_not(&self, order: Ordering) -> $int_type { + let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst); + let guard = lock(self.v.get().addr()).write(); + let prev = self.read(&guard); + self.write(!prev, &guard); + prev + } + + #[inline] + pub(crate) fn fetch_neg(&self, order: Ordering) -> $int_type { + let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst); + let guard = lock(self.v.get().addr()).write(); + let prev = self.read(&guard); + self.write(prev.wrapping_neg(), &guard); + prev + } + } + impl $atomic_type { + #[inline] + pub(crate) fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { + let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst); + let guard = lock(self.v.get().addr()).write(); + let prev = self.read(&guard); + self.write(core::cmp::max(prev, val), &guard); + prev + } + + #[inline] + pub(crate) fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { + let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst); + let guard = lock(self.v.get().addr()).write(); + let prev = self.read(&guard); + self.write(core::cmp::min(prev, val), &guard); + prev + } + } + }; +} + +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any( + test, + not(any( + not(portable_atomic_no_atomic_64), + all( + target_arch = "riscv32", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_feature = "zacas", portable_atomic_target_feature = "zacas"), + ), + )) + )) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any( + test, + not(any( + target_has_atomic = "64", + all( + target_arch = "riscv32", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_feature = "zacas", portable_atomic_target_feature = "zacas"), + ), + )) + )) +)] +cfg_no_fast_atomic_64!({ + atomic!(AtomicI64, i64, 8); + atomic!(AtomicU64, u64, 8); +}); + +atomic!(AtomicI128, i128, 16); +atomic!(AtomicU128, u128, 16); + +#[cfg(test)] +mod tests { + use super::*; + + cfg_no_fast_atomic_64!({ + test_atomic_int!(i64); + test_atomic_int!(u64); + }); + test_atomic_int!(i128); + test_atomic_int!(u128); + + // load/store/swap implementation is not affected by signedness, so it is + // enough to test only unsigned types. + cfg_no_fast_atomic_64!({ + stress_test!(u64); + }); + stress_test!(u128); +} diff --git a/vendor/portable-atomic/src/imp/fallback/outline_atomics.rs b/vendor/portable-atomic/src/imp/fallback/outline_atomics.rs new file mode 100644 index 0000000..a949d7b --- /dev/null +++ b/vendor/portable-atomic/src/imp/fallback/outline_atomics.rs @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Helper for outline-atomics. + +On architectures where DW atomics are not supported on older CPUs, we use +fallback implementation when DW atomic instructions are not supported and +outline-atomics is enabled. + +This module provides helpers to implement them. +*/ + +use core::sync::atomic::Ordering; + +#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64", target_arch = "riscv64"))] +pub(crate) type Udw = u128; +#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64", target_arch = "riscv64"))] +pub(crate) type AtomicUdw = super::super::super::fallback::AtomicU128; +#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64", target_arch = "riscv64"))] +pub(crate) type AtomicIdw = super::super::super::fallback::AtomicI128; + +#[cfg(any(target_arch = "arm", target_arch = "riscv32"))] +pub(crate) type Udw = u64; +#[cfg(any(target_arch = "arm", target_arch = "riscv32"))] +pub(crate) type AtomicUdw = super::super::super::fallback::AtomicU64; +#[cfg(any(target_arch = "arm", target_arch = "riscv32"))] +pub(crate) type AtomicIdw = super::super::super::fallback::AtomicI64; + +// Asserts that the function is called in the correct context. +macro_rules! debug_assert_outline_atomics { + () => { + #[cfg(target_arch = "x86_64")] + { + debug_assert!(!super::detect::detect().cmpxchg16b()); + } + #[cfg(target_arch = "powerpc64")] + { + debug_assert!(!super::detect::detect().quadword_atomics()); + } + #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + { + debug_assert!(!super::detect::detect().zacas()); + } + #[cfg(target_arch = "arm")] + { + debug_assert!(!super::has_kuser_cmpxchg64()); + } + }; +} + +#[cold] +pub(crate) unsafe fn atomic_load(src: *mut Udw, order: Ordering) -> Udw { + debug_assert_outline_atomics!(); + #[allow(clippy::cast_ptr_alignment)] + // SAFETY: the caller must uphold the safety contract. + unsafe { + (*(src as *const AtomicUdw)).load(order) + } +} +fn_alias! { + #[cold] + pub(crate) unsafe fn(src: *mut Udw) -> Udw; + // fallback's atomic load has at least acquire semantics. + #[cfg(not(any(target_arch = "arm", target_arch = "x86_64")))] + atomic_load_non_seqcst = atomic_load(Ordering::Acquire); + atomic_load_seqcst = atomic_load(Ordering::SeqCst); +} + +#[cfg(not(any(target_arch = "arm", target_arch = "riscv32", target_arch = "riscv64")))] +#[cold] +pub(crate) unsafe fn atomic_store(dst: *mut Udw, val: Udw, order: Ordering) { + debug_assert_outline_atomics!(); + #[allow(clippy::cast_ptr_alignment)] + // SAFETY: the caller must uphold the safety contract. + unsafe { + (*(dst as *const AtomicUdw)).store(val, order); + } +} +#[cfg(not(any(target_arch = "arm", target_arch = "riscv32", target_arch = "riscv64")))] +fn_alias! { + #[cold] + pub(crate) unsafe fn(dst: *mut Udw, val: Udw); + // fallback's atomic store has at least release semantics. + atomic_store_non_seqcst = atomic_store(Ordering::Release); + atomic_store_seqcst = atomic_store(Ordering::SeqCst); +} + +#[cold] +pub(crate) unsafe fn atomic_compare_exchange( + dst: *mut Udw, + old: Udw, + new: Udw, + success: Ordering, + failure: Ordering, +) -> (Udw, bool) { + debug_assert_outline_atomics!(); + #[allow(clippy::cast_ptr_alignment)] + // SAFETY: the caller must uphold the safety contract. + unsafe { + match (*(dst as *const AtomicUdw)).compare_exchange(old, new, success, failure) { + Ok(v) => (v, true), + Err(v) => (v, false), + } + } +} +fn_alias! { + #[cold] + pub(crate) unsafe fn(dst: *mut Udw, old: Udw, new: Udw) -> (Udw, bool); + // fallback's atomic CAS has at least AcqRel semantics. + #[cfg(not(any(target_arch = "arm", target_arch = "x86_64")))] + atomic_compare_exchange_non_seqcst + = atomic_compare_exchange(Ordering::AcqRel, Ordering::Acquire); + atomic_compare_exchange_seqcst + = atomic_compare_exchange(Ordering::SeqCst, Ordering::SeqCst); +} + +macro_rules! atomic_rmw_3 { + ( + $name:ident($atomic_type:ident::$method_name:ident), + $non_seqcst_alias:ident, $seqcst_alias:ident + ) => { + #[cold] + pub(crate) unsafe fn $name(dst: *mut Udw, val: Udw, order: Ordering) -> Udw { + debug_assert_outline_atomics!(); + #[allow( + clippy::as_underscore, + clippy::cast_possible_wrap, + clippy::cast_ptr_alignment, + clippy::cast_sign_loss + )] + // SAFETY: the caller must uphold the safety contract. + unsafe { + (*(dst as *const $atomic_type)).$method_name(val as _, order) as Udw + } + } + fn_alias! { + #[cold] + pub(crate) unsafe fn(dst: *mut Udw, val: Udw) -> Udw; + // fallback's atomic RMW has at least AcqRel semantics. + #[cfg(not(any(target_arch = "arm", target_arch = "x86_64")))] + $non_seqcst_alias = $name(Ordering::AcqRel); + $seqcst_alias = $name(Ordering::SeqCst); + } + }; +} +macro_rules! atomic_rmw_2 { + ( + $name:ident($atomic_type:ident::$method_name:ident), + $non_seqcst_alias:ident, $seqcst_alias:ident + ) => { + #[cold] + pub(crate) unsafe fn $name(dst: *mut Udw, order: Ordering) -> Udw { + debug_assert_outline_atomics!(); + #[allow(clippy::cast_ptr_alignment)] + // SAFETY: the caller must uphold the safety contract. + unsafe { + (*(dst as *const $atomic_type)).$method_name(order) as Udw + } + } + fn_alias! { + #[cold] + pub(crate) unsafe fn(dst: *mut Udw) -> Udw; + // fallback's atomic RMW has at least AcqRel semantics. + #[cfg(not(any(target_arch = "arm", target_arch = "x86_64")))] + $non_seqcst_alias = $name(Ordering::AcqRel); + $seqcst_alias = $name(Ordering::SeqCst); + } + }; +} + +atomic_rmw_3!(atomic_swap(AtomicUdw::swap), atomic_swap_non_seqcst, atomic_swap_seqcst); +atomic_rmw_3!(atomic_add(AtomicUdw::fetch_add), atomic_add_non_seqcst, atomic_add_seqcst); +atomic_rmw_3!(atomic_sub(AtomicUdw::fetch_sub), atomic_sub_non_seqcst, atomic_sub_seqcst); +atomic_rmw_3!(atomic_and(AtomicUdw::fetch_and), atomic_and_non_seqcst, atomic_and_seqcst); +atomic_rmw_3!(atomic_nand(AtomicUdw::fetch_nand), atomic_nand_non_seqcst, atomic_nand_seqcst); +atomic_rmw_3!(atomic_or(AtomicUdw::fetch_or), atomic_or_non_seqcst, atomic_or_seqcst); +atomic_rmw_3!(atomic_xor(AtomicUdw::fetch_xor), atomic_xor_non_seqcst, atomic_xor_seqcst); +atomic_rmw_3!(atomic_max(AtomicIdw::fetch_max), atomic_max_non_seqcst, atomic_max_seqcst); +atomic_rmw_3!(atomic_umax(AtomicUdw::fetch_max), atomic_umax_non_seqcst, atomic_umax_seqcst); +atomic_rmw_3!(atomic_min(AtomicIdw::fetch_min), atomic_min_non_seqcst, atomic_min_seqcst); +atomic_rmw_3!(atomic_umin(AtomicUdw::fetch_min), atomic_umin_non_seqcst, atomic_umin_seqcst); + +atomic_rmw_2!(atomic_not(AtomicUdw::fetch_not), atomic_not_non_seqcst, atomic_not_seqcst); +atomic_rmw_2!(atomic_neg(AtomicUdw::fetch_neg), atomic_neg_non_seqcst, atomic_neg_seqcst); diff --git a/vendor/portable-atomic/src/imp/fallback/seq_lock.rs b/vendor/portable-atomic/src/imp/fallback/seq_lock.rs new file mode 100644 index 0000000..6b4ec05 --- /dev/null +++ b/vendor/portable-atomic/src/imp/fallback/seq_lock.rs @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +// Adapted from https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/atomic/seq_lock.rs. + +include!("seq_lock_common.rs"); + +use crate::imp::core_atomic::AtomicU64; + +pub(super) type State = u64; + +/// A simple stamped lock. +pub(super) struct SeqLock { + /// The current state of the lock. + /// + /// All bits except the least significant one hold the current stamp. When locked, the state + /// equals 1 and doesn't contain a valid stamp. + state: AtomicU64, +} + +impl SeqLock { + #[inline] + pub(super) const fn new() -> Self { + Self { state: AtomicU64::new(0) } + } + + /// If not locked, returns the current stamp. + /// + /// This method should be called before optimistic reads. + #[inline] + pub(super) fn optimistic_read(&self) -> Option { + // The acquire load from `state` synchronizes with the release stores in + // `SeqLockWriteGuard::drop` and `SeqLockWriteGuard::abort`. + let state = self.state.load(Ordering::Acquire); + if state == LOCKED { None } else { Some(state) } + } + + /// Returns `true` if the current stamp is equal to `stamp`. + /// + /// This method should be called after optimistic reads to check whether they are valid. The + /// argument `stamp` should correspond to the one returned by method `optimistic_read`. + #[inline] + pub(super) fn validate_read(&self, stamp: State) -> bool { + // Thanks to the fence, if we're noticing any modification to the data at the critical + // section of `stamp`, then the critical section's write of 1 to state + // should be visible. + crate::fence(Ordering::Acquire); + self.state.load(Ordering::Relaxed) == stamp + } +} + +impl SeqLockWriteGuard<'_> { + #[inline] + fn next_stamp(&self) -> State { + self.state.wrapping_add(2) + } +} diff --git a/vendor/portable-atomic/src/imp/fallback/seq_lock_common.rs b/vendor/portable-atomic/src/imp/fallback/seq_lock_common.rs new file mode 100644 index 0000000..d6293d7 --- /dev/null +++ b/vendor/portable-atomic/src/imp/fallback/seq_lock_common.rs @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +// Adapted from https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/atomic/seq_lock.rs +// and https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/atomic/seq_lock_wide.rs. + +use core::{mem::ManuallyDrop, sync::atomic::Ordering}; + +use super::utils::Backoff; +#[cfg(portable_atomic_unsafe_assume_privileged)] +use crate::imp::interrupt::arch as interrupt; + +const LOCKED: State = 1; + +impl SeqLock { + /// Grabs the lock for writing. + #[inline] + pub(super) fn write(&self) -> SeqLockWriteGuard<'_> { + // Get current interrupt state and disable interrupts when the user + // explicitly declares that privileged instructions are available. + #[cfg(portable_atomic_unsafe_assume_privileged)] + let interrupt_state = interrupt::disable(); + + let mut backoff = Backoff::new(); + loop { + let previous = self.state.swap(LOCKED, Ordering::Acquire); + + if previous != LOCKED { + // To synchronize with the acquire fence in `validate_read` via any modification to + // the data at the critical section of `previous` (seq_lock.rs) or `(state_hi, previous)` + // (seq_lock_wide.rs). + crate::fence(Ordering::Release); + + return SeqLockWriteGuard { + lock: self, + state: previous, + #[cfg(portable_atomic_unsafe_assume_privileged)] + interrupt_state, + }; + } + + while self.state.load(Ordering::Relaxed) == LOCKED { + backoff.snooze(); + } + } + } +} + +/// An RAII guard that releases the lock and increments the stamp when dropped. +#[must_use] +pub(crate) struct SeqLockWriteGuard<'a> { + /// The parent lock. + lock: &'a SeqLock, + + /// The stamp before locking. + state: State, + + /// The interrupt state before disabling. + #[cfg(portable_atomic_unsafe_assume_privileged)] + interrupt_state: interrupt::State, +} + +impl SeqLockWriteGuard<'_> { + /// Releases the lock without incrementing the stamp. + #[inline] + pub(crate) fn abort(self) { + // We specifically don't want to call drop(), since that's + // what increments the stamp. + let this = ManuallyDrop::new(self); + + // Restore the stamp. + // + // Release ordering for synchronizing with `optimistic_read`. + this.lock.state.store(this.state, Ordering::Release); + + // Restore interrupt state. + // SAFETY: the state was retrieved by the previous `disable`. + #[cfg(portable_atomic_unsafe_assume_privileged)] + unsafe { + interrupt::restore(this.interrupt_state); + } + } +} + +impl Drop for SeqLockWriteGuard<'_> { + #[inline] + fn drop(&mut self) { + let state = self.next_stamp(); + + // Release the lock and increment the stamp. + // + // Release ordering for synchronizing with `optimistic_read`. + self.lock.state.store(state, Ordering::Release); + + // Restore interrupt state. + // SAFETY: the state was retrieved by the previous `disable`. + #[cfg(portable_atomic_unsafe_assume_privileged)] + unsafe { + interrupt::restore(self.interrupt_state); + } + } +} + +#[cfg(test)] +#[allow(clippy::items_after_test_module)] +mod tests { + use core::sync::atomic::Ordering; + + use super::SeqLock; + + #[test] + fn smoke() { + let lock = SeqLock::new(); + let before = lock.optimistic_read().unwrap(); + assert!(lock.validate_read(before)); + { + let _guard = lock.write(); + assert!(lock.optimistic_read().is_none()); + } + assert!(!lock.validate_read(before)); + let after = lock.optimistic_read().unwrap(); + assert_ne!(before, after); + } + + #[test] + fn test_wrap() { + let lock = SeqLock::new(); + let zero = lock.optimistic_read().unwrap(); + lock.state.store(0xFFFF_FFFE, Ordering::Relaxed); // u32::MAX & !1 + let before = lock.optimistic_read().unwrap(); + assert!(lock.validate_read(before)); + { + let _guard = lock.write(); + assert!(lock.optimistic_read().is_none()); + } + assert!(!lock.validate_read(before)); + let after = lock.optimistic_read().unwrap(); + assert_ne!(before, after); + assert_ne!(after, zero); + #[allow(clippy::identity_op)] + { + assert_eq!(lock.state.load(Ordering::Relaxed) & 0xFFFF_FFFF, 0); + } + } + + #[test] + fn test_abort() { + let lock = SeqLock::new(); + let before = lock.optimistic_read().unwrap(); + { + let guard = lock.write(); + assert!(lock.optimistic_read().is_none()); + guard.abort(); + } + let after = lock.optimistic_read().unwrap(); + assert_eq!(before, after, "aborted write does not update the stamp"); + } +} diff --git a/vendor/portable-atomic/src/imp/fallback/seq_lock_wide.rs b/vendor/portable-atomic/src/imp/fallback/seq_lock_wide.rs new file mode 100644 index 0000000..05aa6df --- /dev/null +++ b/vendor/portable-atomic/src/imp/fallback/seq_lock_wide.rs @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +// Adapted from https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/atomic/seq_lock_wide.rs. + +include!("seq_lock_common.rs"); + +use crate::imp::core_atomic::AtomicU32; + +pub(super) type State = u32; + +/// A simple stamped lock. +/// +/// The state is represented as two `AtomicU32`: `state_hi` for high bits and `state_lo` for low +/// bits. +pub(super) struct SeqLock { + /// The high bits of the current state of the lock. + state_hi: AtomicU32, + + /// The low bits of the current state of the lock. + /// + /// All bits except the least significant one hold the current stamp. When locked, the state_lo + /// equals 1 and doesn't contain a valid stamp. + state: AtomicU32, +} + +impl SeqLock { + #[inline] + pub(super) const fn new() -> Self { + Self { state_hi: AtomicU32::new(0), state: AtomicU32::new(0) } + } + + /// If not locked, returns the current stamp. + /// + /// This method should be called before optimistic reads. + #[inline] + pub(super) fn optimistic_read(&self) -> Option<(State, State)> { + // The acquire loads from `state_hi` and `state_lo` synchronize with the release stores in + // `SeqLockWriteGuard::drop` and `SeqLockWriteGuard::abort`. + // + // As a consequence, we can make sure that (1) all writes within the era of `state_hi - 1` + // happens before now; and therefore, (2) if `state_lo` is even, all writes within the + // critical section of (`state_hi`, `state_lo`) happens before now. + let state_hi = self.state_hi.load(Ordering::Acquire); + let state_lo = self.state.load(Ordering::Acquire); + if state_lo == LOCKED { None } else { Some((state_hi, state_lo)) } + } + + /// Returns `true` if the current stamp is equal to `stamp`. + /// + /// This method should be called after optimistic reads to check whether they are valid. The + /// argument `stamp` should correspond to the one returned by method `optimistic_read`. + #[inline] + pub(super) fn validate_read(&self, stamp: (State, State)) -> bool { + // Thanks to the fence, if we're noticing any modification to the data at the critical + // section of `(stamp.0, stamp.1)`, then the critical section's write of 1 to state_lo + // should be visible. + crate::fence(Ordering::Acquire); + + // So if `state_lo` coincides with `stamp.1`, then either (1) we're noticing no modification + // to the data after the critical section of `(stamp.0, stamp.1)`, or (2) `state_lo` wrapped + // around. + // + // If (2) is the case, the acquire ordering ensures we see the new value of `state_hi`. + let state_lo = self.state.load(Ordering::Acquire); + + // If (2) is the case and `state_hi` coincides with `stamp.0`, then `state_hi` also wrapped + // around, which we give up to correctly validate the read. + let state_hi = self.state_hi.load(Ordering::Relaxed); + + // Except for the case that both `state_hi` and `state_lo` wrapped around, the following + // condition implies that we're noticing no modification to the data after the critical + // section of `(stamp.0, stamp.1)`. + (state_hi, state_lo) == stamp + } +} + +impl SeqLockWriteGuard<'_> { + #[inline] + fn next_stamp(&self) -> State { + let state_lo = self.state.wrapping_add(2); + + // Increase the high bits if the low bits wrap around. + // + // Release ordering for synchronizing with `optimistic_read`. + if state_lo == 0 { + let state_hi = self.lock.state_hi.load(Ordering::Relaxed); + self.lock.state_hi.store(state_hi.wrapping_add(1), Ordering::Release); + } + + state_lo + } +} diff --git a/vendor/portable-atomic/src/imp/fallback/utils.rs b/vendor/portable-atomic/src/imp/fallback/utils.rs new file mode 100644 index 0000000..b5f21b4 --- /dev/null +++ b/vendor/portable-atomic/src/imp/fallback/utils.rs @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +use core::ops; + +// Adapted from https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/cache_padded.rs. +/// Pads and aligns a value to the length of a cache line. +// Starting from Intel's Sandy Bridge, spatial prefetcher is now pulling pairs of 64-byte cache +// lines at a time, so we have to align to 128 bytes rather than 64. +// +// Sources: +// - https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf +// - https://github.com/facebook/folly/blob/1b5288e6eea6df074758f877c849b6e73bbb9fbb/folly/lang/Align.h#L107 +// +// aarch64/arm64ec's big.LITTLE architecture has asymmetric cores and "big" cores have 128-byte cache line size. +// +// Sources: +// - https://www.mono-project.com/news/2016/09/12/arm64-icache/ +// +// powerpc64 has 128-byte cache line size. +// +// Sources: +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_ppc64x.go#L9 +// - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/powerpc/include/asm/cache.h#L26 +#[cfg_attr( + any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "arm64ec", + target_arch = "powerpc64", + ), + repr(align(128)) +)] +// arm, mips, mips64, sparc, and hexagon have 32-byte cache line size. +// +// Sources: +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_arm.go#L7 +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips.go#L7 +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mipsle.go#L7 +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips64x.go#L9 +// - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/sparc/include/asm/cache.h#L17 +// - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/hexagon/include/asm/cache.h#L12 +#[cfg_attr( + any( + target_arch = "arm", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "sparc", + target_arch = "hexagon", + ), + repr(align(32)) +)] +// m68k has 16-byte cache line size. +// +// Sources: +// - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/m68k/include/asm/cache.h#L9 +#[cfg_attr(target_arch = "m68k", repr(align(16)))] +// s390x has 256-byte cache line size. +// +// Sources: +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_s390x.go#L7 +// - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/s390/include/asm/cache.h#L13 +#[cfg_attr(target_arch = "s390x", repr(align(256)))] +// x86, wasm, riscv, and sparc64 have 64-byte cache line size. +// +// Sources: +// - https://github.com/golang/go/blob/dda2991c2ea0c5914714469c4defc2562a907230/src/internal/cpu/cpu_x86.go#L9 +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_wasm.go#L7 +// - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/riscv/include/asm/cache.h#L10 +// - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/sparc/include/asm/cache.h#L19 +// +// All others are assumed to have 64-byte cache line size. +#[cfg_attr( + not(any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "arm64ec", + target_arch = "powerpc64", + target_arch = "arm", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "sparc", + target_arch = "hexagon", + target_arch = "m68k", + target_arch = "s390x", + )), + repr(align(64)) +)] +#[repr(C)] +pub(crate) struct CachePadded { + value: T, +} + +impl CachePadded { + #[inline] + pub(crate) const fn new(value: T) -> Self { + Self { value } + } +} + +impl ops::Deref for CachePadded { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.value + } +} + +// Adapted from https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/backoff.rs. +// Adjusted to reduce spinning. +/// Performs exponential backoff in spin loops. +pub(crate) struct Backoff { + step: u32, +} + +// https://github.com/oneapi-src/oneTBB/blob/v2021.5.0/include/oneapi/tbb/detail/_utils.h#L46-L48 +const SPIN_LIMIT: u32 = 4; + +impl Backoff { + #[inline] + pub(crate) const fn new() -> Self { + Self { step: 0 } + } + + #[inline] + pub(crate) fn snooze(&mut self) { + if self.step <= SPIN_LIMIT { + for _ in 0..1 << self.step { + #[allow(deprecated)] + core::sync::atomic::spin_loop_hint(); + } + self.step += 1; + } else { + #[cfg(not(feature = "std"))] + for _ in 0..1 << self.step { + #[allow(deprecated)] + core::sync::atomic::spin_loop_hint(); + } + + #[cfg(feature = "std")] + std::thread::yield_now(); + } + } +} diff --git a/vendor/portable-atomic/src/imp/float/aarch64.rs b/vendor/portable-atomic/src/imp/float/aarch64.rs new file mode 100644 index 0000000..293df3e --- /dev/null +++ b/vendor/portable-atomic/src/imp/float/aarch64.rs @@ -0,0 +1,263 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Atomic float implementation based on AArch64 with FEAT_LSFE. + +This module provides atomic float implementations using FEAT_LSFE instructions. + +Generated asm: +- aarch64 (+lsfe) https://godbolt.org/z/7vaxeofv1 +*/ + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; +use core::sync::atomic::Ordering; + +#[cfg(portable_atomic_unstable_f16)] +use super::int::AtomicF16; +#[cfg(portable_atomic_unstable_f128)] +use super::int::AtomicF128; +use super::int::{AtomicF32, AtomicF64}; + +// TODO: optimize no return cases: +// https://developer.arm.com/documentation/ddi0602/2025-06/SIMD-FP-Instructions/STFADD--STFADDL--Floating-point-atomic-add-in-memory--without-return- +// https://developer.arm.com/documentation/ddi0602/2025-06/SIMD-FP-Instructions/STFMAXNM--STFMAXNML--Floating-point-atomic-maximum-number-in-memory--without-return- +// https://developer.arm.com/documentation/ddi0602/2025-06/SIMD-FP-Instructions/STFMINNM--STFMINNML--Floating-point-atomic-minimum-number-in-memory--without-return- + +#[cfg(not(portable_atomic_pre_llvm_20))] +macro_rules! start_lsfe { + () => { + ".arch_extension lsfe" + }; +} + +#[cfg(not(portable_atomic_pre_llvm_20))] +macro_rules! atomic_rmw { + ($op:ident, $order:ident) => { + atomic_rmw!($op, $order, write = $order) + }; + ($op:ident, $order:ident, write = $write:ident) => { + match $order { + Ordering::Relaxed => $op!("", "", ""), + Ordering::Acquire => $op!("a", "", ""), + Ordering::Release => $op!("", "l", ""), + Ordering::AcqRel => $op!("a", "l", ""), + // In MSVC environments, SeqCst stores/writes by non-LSE* instructions needs fences after writes. + // https://reviews.llvm.org/D141748 + // https://github.com/llvm/llvm-project/commit/1ea201d73be2fdf03347e9c6be09ebed5f8e0e00 + #[cfg(target_env = "msvc")] + Ordering::SeqCst if $write == Ordering::SeqCst => $op!("a", "l", "dmb ish"), + // AcqRel and SeqCst RMWs are equivalent in non-MSVC environments. + Ordering::SeqCst => $op!("a", "l", ""), + _ => unreachable!(), + } + }; +} +#[cfg(portable_atomic_pre_llvm_20)] +macro_rules! atomic_rmw_inst { + ($op:ident, $order:ident) => { + atomic_rmw_inst!($op, $order, write = $order) + }; + ($op:ident, $order:ident, write = $write:ident) => { + match $order { + Ordering::Relaxed => $op!("2", ""), // "" + Ordering::Acquire => $op!("a", ""), // "a" + Ordering::Release => $op!("6", ""), // "l" + Ordering::AcqRel => $op!("e", ""), // "al" + // In MSVC environments, SeqCst stores/writes by non-LSE* instructions needs fences after writes. + // https://reviews.llvm.org/D141748 + // https://github.com/llvm/llvm-project/commit/1ea201d73be2fdf03347e9c6be09ebed5f8e0e00 + #[cfg(target_env = "msvc")] + Ordering::SeqCst if $write == Ordering::SeqCst => $op!("e", "dmb ish"), + // AcqRel and SeqCst RMWs are equivalent in non-MSVC environments. + Ordering::SeqCst => $op!("e", ""), + _ => unreachable!(), + } + }; +} + +#[rustfmt::skip] +macro_rules! atomic_float { + ($atomic_type:ident, $float_type:ident, $modifier:tt, $inst_modifier:tt) => { + impl $atomic_type { + #[inline] + pub(crate) fn fetch_add(&self, val: $float_type, order: Ordering) -> $float_type { + let dst = self.as_ptr(); + let out; + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + // + // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/SIMD-FP-Instructions/LDFADD--LDFADDA--LDFADDAL--LDFADDL--Floating-point-atomic-add-in-memory- + unsafe { + #[cfg(not(portable_atomic_pre_llvm_20))] + macro_rules! add { + ($acquire:tt, $release:tt, $_msvc_fence:tt) => { + asm!( + start_lsfe!(), + concat!("ldfadd", $acquire, $release, " {val:", $modifier, "}, {out:", $modifier, "}, [{dst}]"), // atomic { _x = *dst; *dst = _x + val; out = _x } + dst = in(reg) ptr_reg!(dst), + val = in(vreg) val, + out = lateout(vreg) out, + options(nostack), + ) + }; + } + #[cfg(not(portable_atomic_pre_llvm_20))] + atomic_rmw!(add, order); + // LLVM supports FEAT_LSFE instructions on LLVM 20+, so use .inst directive on old LLVM. + // https://github.com/llvm/llvm-project/commit/67ff5ba9af9754261abe11d762af11532a816126 + #[cfg(portable_atomic_pre_llvm_20)] + macro_rules! add { + ($order:tt, $_msvc_fence:tt) => { + asm!( + // ldfadd{,a,l,al} {h,s,d}0, {h,s,d}1, [x2] // atomic { _x = *x2; *x2 = _x + {h,s,d}0; {h,s,d}1 = _x } + concat!(".inst 0x", $inst_modifier, "c", $order, "00041"), + in("x2") ptr_reg!(dst), + in("v0") val, + out("v1") out, + options(nostack), + ) + }; + } + #[cfg(portable_atomic_pre_llvm_20)] + atomic_rmw_inst!(add, order); + } + out + } + #[inline] + pub(crate) fn fetch_sub(&self, val: $float_type, order: Ordering) -> $float_type { + // There is no atomic sub instruction, so add `-val`. + self.fetch_add(-val, order) + } + #[inline] + pub(crate) fn fetch_max(&self, val: $float_type, order: Ordering) -> $float_type { + let dst = self.as_ptr(); + let out; + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + // + // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/SIMD-FP-Instructions/LDFMAXNM--LDFMAXNMA--LDFMAXNMAL--LDFMAXNML--Floating-point-atomic-maximum-number-in-memory- + unsafe { + #[cfg(not(portable_atomic_pre_llvm_20))] + macro_rules! max { + ($acquire:tt, $release:tt, $_msvc_fence:tt) => { + asm!( + start_lsfe!(), + concat!("ldfmaxnm", $acquire, $release, " {val:", $modifier, "}, {out:", $modifier, "}, [{dst}]"), // atomic { _x = *dst; *dst = _x.max(val); out = _x } + dst = in(reg) ptr_reg!(dst), + val = in(vreg) val, + out = lateout(vreg) out, + options(nostack), + ) + }; + } + #[cfg(not(portable_atomic_pre_llvm_20))] + atomic_rmw!(max, order); + // LLVM supports FEAT_LSFE instructions on LLVM 20+, so use .inst directive on old LLVM. + // https://github.com/llvm/llvm-project/commit/67ff5ba9af9754261abe11d762af11532a816126 + #[cfg(portable_atomic_pre_llvm_20)] + macro_rules! max { + ($order:tt, $_msvc_fence:tt) => { + asm!( + // ldfmaxnm{,a,l,al} {h,s,d}0, {h,s,d}1, [x2] // atomic { _x = *x2; *x2 = _x.max({h,s,d}0); {h,s,d}1 = _x } + concat!(".inst 0x", $inst_modifier, "c", $order, "06041"), + in("x2") ptr_reg!(dst), + in("v0") val, + out("v1") out, + options(nostack), + ) + }; + } + #[cfg(portable_atomic_pre_llvm_20)] + atomic_rmw_inst!(max, order); + } + out + } + #[inline] + pub(crate) fn fetch_min(&self, val: $float_type, order: Ordering) -> $float_type { + let dst = self.as_ptr(); + let out; + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + // + // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/SIMD-FP-Instructions/LDFMINNM--LDFMINNMA--LDFMINNMAL--LDFMINNML--Floating-point-atomic-minimum-number-in-memory- + unsafe { + #[cfg(not(portable_atomic_pre_llvm_20))] + macro_rules! min { + ($acquire:tt, $release:tt, $_msvc_fence:tt) => { + asm!( + start_lsfe!(), + concat!("ldfminnm", $acquire, $release, " {val:", $modifier, "}, {out:", $modifier, "}, [{dst}]"), // atomic { _x = *dst; *dst = _x.min(val); out = _x } + dst = in(reg) ptr_reg!(dst), + val = in(vreg) val, + out = lateout(vreg) out, + options(nostack), + ) + }; + } + #[cfg(not(portable_atomic_pre_llvm_20))] + atomic_rmw!(min, order); + // LLVM supports FEAT_LSFE instructions on LLVM 20+, so use .inst directive on old LLVM. + // https://github.com/llvm/llvm-project/commit/67ff5ba9af9754261abe11d762af11532a816126 + #[cfg(portable_atomic_pre_llvm_20)] + macro_rules! min { + ($order:tt, $_msvc_fence:tt) => { + asm!( + // ldfminnm{,a,l,al} {h,s,d}0, {h,s,d}1, [x2] // atomic { _x = *x2; *x2 = _x.min({h,s,d}0); {h,s,d}1 = _x } + concat!(".inst 0x", $inst_modifier, "c", $order, "07041"), + in("x2") ptr_reg!(dst), + in("v0") val, + out("v1") out, + options(nostack), + ) + }; + } + #[cfg(portable_atomic_pre_llvm_20)] + atomic_rmw_inst!(min, order); + } + out + } + } + }; +} + +#[cfg(portable_atomic_unstable_f16)] +atomic_float!(AtomicF16, f16, "h", "7"); +atomic_float!(AtomicF32, f32, "s", "b"); +atomic_float!(AtomicF64, f64, "d", "f"); + +#[cfg(portable_atomic_unstable_f128)] +impl AtomicF128 { + #[inline] + pub(crate) fn fetch_add(&self, val: f128, order: Ordering) -> f128 { + self.fetch_update_(order, |x| x + val) + } + #[inline] + pub(crate) fn fetch_sub(&self, val: f128, order: Ordering) -> f128 { + self.fetch_update_(order, |x| x - val) + } + #[inline] + pub(super) fn fetch_update_(&self, order: Ordering, mut f: F) -> f128 + where + F: FnMut(f128) -> f128, + { + // This is a private function and all instances of `f` only operate on the value + // loaded, so there is no need to synchronize the first load/failed CAS. + let mut prev = self.load(Ordering::Relaxed); + loop { + let next = f(prev); + match self.compare_exchange_weak(prev, next, order, Ordering::Relaxed) { + Ok(x) => return x, + Err(next_prev) => prev = next_prev, + } + } + } + #[inline] + pub(crate) fn fetch_max(&self, val: f128, order: Ordering) -> f128 { + self.fetch_update_(order, |x| x.max(val)) + } + #[inline] + pub(crate) fn fetch_min(&self, val: f128, order: Ordering) -> f128 { + self.fetch_update_(order, |x| x.min(val)) + } +} diff --git a/vendor/portable-atomic/src/imp/float/int.rs b/vendor/portable-atomic/src/imp/float/int.rs new file mode 100644 index 0000000..1ce70a1 --- /dev/null +++ b/vendor/portable-atomic/src/imp/float/int.rs @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Atomic float implementation based on atomic integer. + +This module provides atomic float implementations using atomic integer. + +Note that most of `fetch_*` operations of atomic floats are implemented using +CAS loops, which can be slower than equivalent operations of atomic integers. + +AArch64 with FEAT_LSFE and GPU targets have atomic instructions for float. +See aarch64.rs for AArch64 with FEAT_LSFE. +GPU targets will also use architecture-specific implementations instead of this implementation in the +future: https://github.com/taiki-e/portable-atomic/issues/34 / https://github.com/taiki-e/portable-atomic/pull/45 +*/ + +// TODO: fetch_{minimum,maximum}* https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3008r2.html / https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0493r5.pdf + +#![cfg_attr( + all(target_pointer_width = "16", not(feature = "fallback")), + allow(unused_imports, unused_macros) +)] + +use core::{cell::UnsafeCell, sync::atomic::Ordering}; + +macro_rules! atomic_float { + ( + $atomic_type:ident, $float_type:ident, $atomic_int_type:ident, $int_type:ident, + $align:literal + ) => { + #[repr(C, align($align))] + pub(crate) struct $atomic_type { + v: UnsafeCell<$float_type>, + } + + // Send is implicitly implemented. + // SAFETY: any data races are prevented by atomic operations. + unsafe impl Sync for $atomic_type {} + + impl $atomic_type { + #[inline] + pub(crate) const fn new(v: $float_type) -> Self { + Self { v: UnsafeCell::new(v) } + } + + #[inline] + pub(crate) fn is_lock_free() -> bool { + crate::$atomic_int_type::is_lock_free() + } + pub(crate) const IS_ALWAYS_LOCK_FREE: bool = + crate::$atomic_int_type::is_always_lock_free(); + + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn load(&self, order: Ordering) -> $float_type { + $float_type::from_bits(self.as_bits().load(order)) + } + + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn store(&self, val: $float_type, order: Ordering) { + self.as_bits().store(val.to_bits(), order) + } + + const_fn! { + const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))]; + #[inline(always)] + pub(crate) const fn as_bits(&self) -> &crate::$atomic_int_type { + // SAFETY: $atomic_type and $atomic_int_type have the same layout, + // and there is no concurrent access to the value that does not go through this method. + unsafe { &*(self as *const Self as *const crate::$atomic_int_type) } + } + } + + #[inline] + pub(crate) const fn as_ptr(&self) -> *mut $float_type { + self.v.get() + } + } + + cfg_has_atomic_cas_or_amo32! { + impl $atomic_type { + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn swap(&self, val: $float_type, order: Ordering) -> $float_type { + $float_type::from_bits(self.as_bits().swap(val.to_bits(), order)) + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_neg(&self, order: Ordering) -> $float_type { + const NEG_MASK: $int_type = !0 / 2 + 1; + $float_type::from_bits(self.as_bits().fetch_xor(NEG_MASK, order)) + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_abs(&self, order: Ordering) -> $float_type { + const ABS_MASK: $int_type = !0 / 2; + $float_type::from_bits(self.as_bits().fetch_and(ABS_MASK, order)) + } + } + cfg_has_atomic_cas! { + impl $atomic_type { + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn compare_exchange( + &self, + current: $float_type, + new: $float_type, + success: Ordering, + failure: Ordering, + ) -> Result<$float_type, $float_type> { + match self.as_bits().compare_exchange( + current.to_bits(), + new.to_bits(), + success, + failure, + ) { + Ok(v) => Ok($float_type::from_bits(v)), + Err(v) => Err($float_type::from_bits(v)), + } + } + + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub(crate) fn compare_exchange_weak( + &self, + current: $float_type, + new: $float_type, + success: Ordering, + failure: Ordering, + ) -> Result<$float_type, $float_type> { + match self.as_bits().compare_exchange_weak( + current.to_bits(), + new.to_bits(), + success, + failure, + ) { + Ok(v) => Ok($float_type::from_bits(v)), + Err(v) => Err($float_type::from_bits(v)), + } + } + } + #[cfg(not(all( + any(target_arch = "aarch64", target_arch = "arm64ec"), + any(target_feature = "lsfe", portable_atomic_target_feature = "lsfe"), + target_feature = "neon", // for vreg + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + )))] + impl $atomic_type { + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_add(&self, val: $float_type, order: Ordering) -> $float_type { + self.fetch_update_(order, |x| x + val) + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_sub(&self, val: $float_type, order: Ordering) -> $float_type { + self.fetch_update_(order, |x| x - val) + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + fn fetch_update_(&self, order: Ordering, mut f: F) -> $float_type + where + F: FnMut($float_type) -> $float_type, + { + // This is a private function and all instances of `f` only operate on the value + // loaded, so there is no need to synchronize the first load/failed CAS. + let mut prev = self.load(Ordering::Relaxed); + loop { + let next = f(prev); + match self.compare_exchange_weak(prev, next, order, Ordering::Relaxed) { + Ok(x) => return x, + Err(next_prev) => prev = next_prev, + } + } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_max(&self, val: $float_type, order: Ordering) -> $float_type { + self.fetch_update_(order, |x| x.max(val)) + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn fetch_min(&self, val: $float_type, order: Ordering) -> $float_type { + self.fetch_update_(order, |x| x.min(val)) + } + } + } // cfg_has_atomic_cas! + } // cfg_has_atomic_cas_or_amo32! + }; +} + +#[cfg(portable_atomic_unstable_f16)] +cfg_has_atomic_16! { + atomic_float!(AtomicF16, f16, AtomicU16, u16, 2); +} +cfg_has_atomic_32! { + atomic_float!(AtomicF32, f32, AtomicU32, u32, 4); +} +cfg_has_atomic_64! { + atomic_float!(AtomicF64, f64, AtomicU64, u64, 8); +} +#[cfg(portable_atomic_unstable_f128)] +cfg_has_atomic_128! { + atomic_float!(AtomicF128, f128, AtomicU128, u128, 16); +} diff --git a/vendor/portable-atomic/src/imp/float/mod.rs b/vendor/portable-atomic/src/imp/float/mod.rs new file mode 100644 index 0000000..cfd6433 --- /dev/null +++ b/vendor/portable-atomic/src/imp/float/mod.rs @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Atomic float implementations +*/ + +#![allow(clippy::float_arithmetic)] + +mod int; + +#[cfg(all( + any(target_arch = "aarch64", target_arch = "arm64ec"), + any(target_feature = "lsfe", portable_atomic_target_feature = "lsfe"), + target_feature = "neon", // for vreg + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), +))] +mod aarch64; + +#[cfg(portable_atomic_unstable_f16)] +cfg_has_atomic_16! { + pub(crate) use self::int::AtomicF16; +} +cfg_has_atomic_32! { + pub(crate) use self::int::AtomicF32; +} +cfg_has_atomic_64! { + pub(crate) use self::int::AtomicF64; +} +#[cfg(portable_atomic_unstable_f128)] +cfg_has_atomic_128! { + pub(crate) use self::int::AtomicF128; +} diff --git a/vendor/portable-atomic/src/imp/interrupt/README.md b/vendor/portable-atomic/src/imp/interrupt/README.md new file mode 100644 index 0000000..ba60380 --- /dev/null +++ b/vendor/portable-atomic/src/imp/interrupt/README.md @@ -0,0 +1,42 @@ +# Fallback implementation based on disabling interrupts or critical-section + +This module supports two different critical section implementations: + +- Built-in "disable all interrupts". + - On MSP430 and AVR, they are always single-core and has no unprivileged mode, so this is enabled by default. + - On Armv6-M (thumbv6m), pre-v6 Arm (e.g., thumbv4t, thumbv5te), RISC-V without A-extension, and Xtensa, they could be multi-core or unprivileged mode, so this is enabled when the user explicitly declares that the system is single-core and that privileged instructions are available using `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg). +- Call into the `critical-section` crate (which allows the user to plug any implementation). + - This is enabled when the user asks for it with the [`critical-section` feature](../../../README.md#optional-features-critical-section). + +`unsafe-assume-privileged` feature (`portable_atomic_unsafe_assume_privileged` cfg) also uses this module's interrupt disable implementation part. + +The `unsafe-assume-single-core` implementation uses privileged instructions to disable interrupts, so it usually doesn't work on unprivileged mode. +Enabling this feature in an environment where privileged instructions are not available, or if the instructions used are not sufficient to disable interrupts in the system, it is also usually considered **unsound**, although the details are system-dependent. + +Consider using the [`critical-section` feature](../../../README.md#optional-features-critical-section) for systems that cannot use the `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg). + +For some targets, the implementation can be changed by explicitly enabling features. + +- On Arm M-Profile architectures, this disables interrupts by modifying the PRIMASK register. +- On Arm (except for M-Profile architectures), this disables interrupts by modifying the I (IRQ mask) bit of the CPSR. +- On Arm (except for M-Profile architectures) with the `disable-fiq` feature (or `portable_atomic_disable_fiq` cfg), this disables interrupts by modifying the I (IRQ mask) bit and F (FIQ mask) bit of the CPSR. +- On RISC-V, this disables interrupts by modifying the MIE (Machine Interrupt Enable) bit of the `mstatus` register. +- On RISC-V with the `s-mode` feature (or `portable_atomic_s_mode` cfg), this disables interrupts by modifying the SIE (Supervisor Interrupt Enable) bit of the `sstatus` register. +- On RISC-V with the `zaamo` target feature (or `force-amo` feature or `portable_atomic_force_amo` cfg), this uses AMO instructions for RMWs that have corresponding AMO instructions even if A-extension is disabled. For other RMWs, this disables interrupts as usual. +- On MSP430, this disables interrupts by modifying the GIE (Global Interrupt Enable) bit of the status register (SR). +- On AVR, this disables interrupts by modifying the I (Global Interrupt Enable) bit of the status register (SREG). +- On Xtensa, this disables interrupts by modifying the PS special register. + +Some operations don't require disabling interrupts: + +- On architectures except for AVR: loads and stores with pointer size or smaller +- On AVR: 8-bit loads and stores +- On AVR with `rmw` target feature additionally: 8-bit `swap` +- On MSP430 additionally: {8,16}-bit `add,sub,and,or,xor,not` +- On RISC-V with the `zaamo` target feature (or `portable_atomic_target_feature="zaamo"` cfg or `force-amo` feature or `portable_atomic_force_amo` cfg) additionally: 32-bit(RV32)/{32,64}-bit(RV64) `swap,fetch_{add,sub,and,or,xor,not,max,min},add,sub,and,or,xor,not`, {8,16}-bit `fetch_{and,or,xor,not},and,or,xor,not`[^1], and all operations of `AtomicBool` + +However, when the `critical-section` feature is enabled, critical sections are taken for all atomic operations. + +Feel free to submit an issue if your target is not supported yet. + +[^1]: With the `zabha` target feature, {8,16}-bit `swap,fetch_{add,sub,max,min},add,sub` too. diff --git a/vendor/portable-atomic/src/imp/interrupt/armv4t.rs b/vendor/portable-atomic/src/imp/interrupt/armv4t.rs new file mode 100644 index 0000000..7d3567f --- /dev/null +++ b/vendor/portable-atomic/src/imp/interrupt/armv4t.rs @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Arm A-Profile Architectures, Arm R-Profile Architectures, Legacy Arm Architectures + +Refs: https://developer.arm.com/documentation/ddi0406/cb/System-Level-Architecture/The-System-Level-Programmers--Model/ARM-processor-modes-and-ARM-core-registers/Program-Status-Registers--PSRs- + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; + +// - 0x80 - I (IRQ mask) bit (1 << 7) +// - 0x40 - F (FIQ mask) bit (1 << 6) +// We disable only IRQs by default. See also https://github.com/taiki-e/portable-atomic/pull/28#issuecomment-1214146912. +#[cfg(not(portable_atomic_disable_fiq))] +macro_rules! mask { + () => { + "0x80" + }; +} +#[cfg(portable_atomic_disable_fiq)] +macro_rules! mask { + () => { + "0xC0" // 0x80 | 0x40 + }; +} + +pub(crate) type State = u32; + +/// Disables interrupts and returns the previous interrupt state. +#[inline] +#[cfg_attr( + not(any(target_feature = "v7", portable_atomic_target_feature = "v7")), + instruction_set(arm::a32) +)] +pub(crate) fn disable() -> State { + let cpsr: State; + // SAFETY: reading CPSR and disabling interrupts are safe. + // (see module-level comments of interrupt/mod.rs on the safety of using privileged instructions) + unsafe { + asm!( + "mrs {prev}, cpsr", // prev = CPSR + concat!("orr {new}, {prev}, ", mask!()), // new = prev | mask + "msr cpsr_c, {new}", // CPSR.{I,F,T,M} = new.{I,F,T,M} + prev = out(reg) cpsr, + new = out(reg) _, + // Do not use `nomem` and `readonly` because prevent subsequent memory accesses from being reordered before interrupts are disabled. + options(nostack, preserves_flags), + ); + } + cpsr +} + +/// Restores the previous interrupt state. +/// +/// # Safety +/// +/// The state must be the one retrieved by the previous `disable`. +#[inline] +#[cfg_attr( + not(any(target_feature = "v7", portable_atomic_target_feature = "v7")), + instruction_set(arm::a32) +)] +pub(crate) unsafe fn restore(prev_cpsr: State) { + // SAFETY: the caller must guarantee that the state was retrieved by the previous `disable`, + // + // This clobbers the control field mask byte of CPSR. See msp430.rs for safety on this. + // (preserves_flags is fine because we can clobber only the I, F, T, and M bits of CPSR.) + // + // Refs: https://developer.arm.com/documentation/dui0473/m/arm-and-thumb-instructions/msr--general-purpose-register-to-psr- + unsafe { + asm!( + "msr cpsr_c, {prev_cpsr}", // CPSR.{I,F,T,M} = prev_cpsr.{I,F,T,M} + prev_cpsr = in(reg) prev_cpsr, + // Do not use `nomem` and `readonly` because prevent preceding memory accesses from being reordered after interrupts are enabled. + options(nostack, preserves_flags), + ); + } +} + +// On pre-v6 Arm, we cannot use core::sync::atomic here because they call the +// `__sync_*` builtins for non-relaxed load/store (because pre-v6 Arm doesn't +// have Data Memory Barrier). +#[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(any(test, portable_atomic_no_atomic_cas)))] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any(test, not(target_has_atomic = "ptr"))) +)] +pub(super) mod atomic { + #[cfg(not(portable_atomic_no_asm))] + use core::arch::asm; + use core::{cell::UnsafeCell, sync::atomic::Ordering}; + + macro_rules! atomic { + ($([$($generics:tt)*])? $atomic_type:ident, $value_type:ty, $suffix:tt) => { + #[repr(transparent)] + pub(crate) struct $atomic_type $(<$($generics)*>)? { + v: UnsafeCell<$value_type>, + } + + // Send is implicitly implemented for atomic integers, but not for atomic pointers. + // SAFETY: any data races are prevented by atomic operations. + unsafe impl $(<$($generics)*>)? Send for $atomic_type $(<$($generics)*>)? {} + // SAFETY: any data races are prevented by atomic operations. + unsafe impl $(<$($generics)*>)? Sync for $atomic_type $(<$($generics)*>)? {} + + impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? { + #[inline] + pub(crate) fn load(&self, _order: Ordering) -> $value_type { + let src = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + let out; + // inline asm without nomem/readonly implies compiler fence. + // And compiler fence is fine because the user explicitly declares that + // the system is single-core by using an unsafe cfg. + asm!( + concat!("ldr", $suffix, " {out}, [{src}]"), // atomic { out = *src } + src = in(reg) src, + out = lateout(reg) out, + options(nostack, preserves_flags), + ); + out + } + } + + #[inline] + pub(crate) fn store(&self, val: $value_type, _order: Ordering) { + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + // inline asm without nomem/readonly implies compiler fence. + // And compiler fence is fine because the user explicitly declares that + // the system is single-core by using an unsafe cfg. + asm!( + concat!("str", $suffix, " {val}, [{dst}]"), // atomic { *dst = val } + dst = in(reg) dst, + val = in(reg) val, + options(nostack, preserves_flags), + ); + } + } + } + }; + } + + atomic!(AtomicI8, i8, "b"); + atomic!(AtomicU8, u8, "b"); + atomic!(AtomicI16, i16, "h"); + atomic!(AtomicU16, u16, "h"); + atomic!(AtomicI32, i32, ""); + atomic!(AtomicU32, u32, ""); + atomic!(AtomicIsize, isize, ""); + atomic!(AtomicUsize, usize, ""); + atomic!([T] AtomicPtr, *mut T, ""); +} diff --git a/vendor/portable-atomic/src/imp/interrupt/armv6m.rs b/vendor/portable-atomic/src/imp/interrupt/armv6m.rs new file mode 100644 index 0000000..29ccee2 --- /dev/null +++ b/vendor/portable-atomic/src/imp/interrupt/armv6m.rs @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Arm M-Profile Architectures + +Adapted from https://github.com/rust-embedded/cortex-m. + +Refs: https://developer.arm.com/documentation/ddi0419/c/System-Level-Architecture/System-Level-Programmers--Model/Registers/The-special-purpose-mask-register--PRIMASK + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any(test, portable_atomic_no_atomic_cas)) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any(test, not(target_has_atomic = "ptr"))) +)] +pub(super) use core::sync::atomic; + +pub(crate) type State = u32; + +/// Disables interrupts and returns the previous interrupt state. +#[inline(always)] +pub(crate) fn disable() -> State { + let primask: State; + // SAFETY: reading the priority mask register and disabling interrupts are safe. + // (see module-level comments of interrupt/mod.rs on the safety of using privileged instructions) + unsafe { + asm!( + "mrs {primask}, PRIMASK", // primask = PRIMASK + "cpsid i", // PRIMASK.PM = 1 + primask = out(reg) primask, + // Do not use `nomem` and `readonly` because prevent subsequent memory accesses from being reordered before interrupts are disabled. + options(nostack, preserves_flags), + ); + } + primask +} + +/// Restores the previous interrupt state. +/// +/// # Safety +/// +/// The state must be the one retrieved by the previous `disable`. +#[inline(always)] +pub(crate) unsafe fn restore(prev_primask: State) { + // SAFETY: the caller must guarantee that the state was retrieved by the previous `disable`, + // and we've checked that interrupts were enabled before disabling interrupts. + // + // This clobbers the entire PRIMASK register. See msp430.rs for safety on this. + unsafe { + asm!( + "msr PRIMASK, {prev_primask}", // PRIMASK = prev_primask + prev_primask = in(reg) prev_primask, + // Do not use `nomem` and `readonly` because prevent preceding memory accesses from being reordered after interrupts are enabled. + options(nostack, preserves_flags), + ); + } +} diff --git a/vendor/portable-atomic/src/imp/interrupt/avr.rs b/vendor/portable-atomic/src/imp/interrupt/avr.rs new file mode 100644 index 0000000..30d4b0c --- /dev/null +++ b/vendor/portable-atomic/src/imp/interrupt/avr.rs @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Adapted from https://github.com/Rahix/avr-device. + +See also src/imp/avr.rs. + +Refs: +- AVR® Instruction Set Manual, Rev. DS40002198B + https://ww1.microchip.com/downloads/en/DeviceDoc/AVR-InstructionSet-Manual-DS40002198.pdf + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; + +#[cfg(not(portable_atomic_no_asm))] +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any(test, portable_atomic_no_atomic_cas)) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any(test, not(target_has_atomic = "ptr"))) +)] +pub(super) use super::super::avr as atomic; + +pub(crate) type State = u8; + +/// Disables interrupts and returns the previous interrupt state. +#[inline(always)] +pub(crate) fn disable() -> State { + let sreg: State; + // SAFETY: reading the status register (SREG) and disabling interrupts are safe. + // (see module-level comments of interrupt/mod.rs on the safety of using privileged instructions) + unsafe { + // Refs: https://ww1.microchip.com/downloads/en/DeviceDoc/AVR-InstructionSet-Manual-DS40002198.pdf#page=58 + #[cfg(not(portable_atomic_no_asm))] + asm!( + "in {sreg}, 0x3F", // sreg = SREG + "cli", // SREG.I = 0 + sreg = out(reg) sreg, + // Do not use `nomem` and `readonly` because prevent subsequent memory accesses from being reordered before interrupts are disabled. + // Do not use `preserves_flags` because CLI modifies the I bit of the status register (SREG). + options(nostack), + ); + #[cfg(portable_atomic_no_asm)] + { + llvm_asm!("in $0, 0x3F" : "=r"(sreg) ::: "volatile"); + llvm_asm!("cli" ::: "memory" : "volatile"); + } + } + sreg +} + +/// Restores the previous interrupt state. +/// +/// # Safety +/// +/// The state must be the one retrieved by the previous `disable`. +#[inline(always)] +pub(crate) unsafe fn restore(prev_sreg: State) { + // SAFETY: the caller must guarantee that the state was retrieved by the previous `disable`. + // + // This clobbers the entire status register, but all other flags are the arithmetic flags that + // are changed as a side effect of arithmetic operations, etc., which LLVM recognizes unless + // preserves_flags is set, so it is safe to clobber them here. + // See also the discussion at https://github.com/taiki-e/portable-atomic/pull/40. + unsafe { + #[cfg(not(portable_atomic_no_asm))] + asm!( + "out 0x3F, {prev_sreg}", // SREG = prev_sreg + prev_sreg = in(reg) prev_sreg, + // Do not use `nomem` and `readonly` because prevent preceding memory accesses from being reordered after interrupts are enabled. + // Do not use `preserves_flags` because OUT modifies the status register (SREG). + options(nostack), + ); + #[cfg(portable_atomic_no_asm)] + llvm_asm!("out 0x3F, $0" :: "r"(prev_sreg) : "memory" : "volatile"); + } +} diff --git a/vendor/portable-atomic/src/imp/interrupt/mod.rs b/vendor/portable-atomic/src/imp/interrupt/mod.rs new file mode 100644 index 0000000..6562409 --- /dev/null +++ b/vendor/portable-atomic/src/imp/interrupt/mod.rs @@ -0,0 +1,696 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Fallback implementation based on disabling interrupts or critical-section + +- mod.rs contains critical section based fallback implementations. +- Each architecture modules contain implementations of disabling interrupts. + +See README.md of this directory for details. +*/ + +#[cfg(not(feature = "critical-section"))] +#[cfg_attr( + all( + target_arch = "arm", + any(target_feature = "mclass", portable_atomic_target_feature = "mclass"), + ), + path = "armv6m.rs" +)] +#[cfg_attr( + all( + target_arch = "arm", + not(any(target_feature = "mclass", portable_atomic_target_feature = "mclass")), + ), + path = "armv4t.rs" +)] +#[cfg_attr(target_arch = "avr", path = "avr.rs")] +#[cfg_attr(target_arch = "msp430", path = "msp430.rs")] +#[cfg_attr(any(target_arch = "riscv32", target_arch = "riscv64"), path = "riscv.rs")] +#[cfg_attr(target_arch = "xtensa", path = "xtensa.rs")] +pub(super) mod arch; + +#[cfg(not(all( + portable_atomic_unsafe_assume_privileged, + not(portable_atomic_unsafe_assume_single_core), +)))] +items!({ + use core::{cell::UnsafeCell, sync::atomic::Ordering}; + + // critical-section implementations might use locks internally. + #[cfg(feature = "critical-section")] + const IS_ALWAYS_LOCK_FREE: bool = false; + // Consider atomic operations based on disabling interrupts on single-core + // systems are lock-free. (We consider the pre-v6 Arm Linux's atomic operations + // provided in a similar way by the Linux kernel to be lock-free.) + #[cfg(not(feature = "critical-section"))] + const IS_ALWAYS_LOCK_FREE: bool = true; + + // Put this in its own module to prevent guard creation. + use self::guard::disable; + mod guard { + // Note: The caller must NOT explicitly modify registers containing fields modified by disable/restore. + // (Fields modified as side effects of other operations are covered by the absence of preserves_flags, + // so they are fine -- see msp430.rs for more.) + #[inline(always)] + pub(super) fn disable() -> Guard { + Guard { + #[cfg(feature = "critical-section")] + // SAFETY: the state will be restored in the subsequent `release`. + state: unsafe { critical_section::acquire() }, + #[cfg(not(feature = "critical-section"))] + // Get current interrupt state and disable interrupts. + state: super::arch::disable(), + } + } + pub(super) struct Guard { + #[cfg(feature = "critical-section")] + state: critical_section::RestoreState, + #[cfg(not(feature = "critical-section"))] + state: super::arch::State, + } + impl Drop for Guard { + #[inline(always)] + fn drop(&mut self) { + #[cfg(feature = "critical-section")] + // SAFETY: the state was retrieved by the previous `acquire`. + unsafe { + critical_section::release(self.state); + } + #[cfg(not(feature = "critical-section"))] + // Restore interrupt state. + // SAFETY: the state was retrieved by the previous `disable`. + unsafe { + super::arch::restore(self.state); + } + } + } + } + + macro_rules! atomic_base { + (base, $([$($generics:tt)*])? $atomic_type:ident, $value_type:ty, $align:literal) => { + #[repr(C, align($align))] + pub(crate) struct $atomic_type $(<$($generics)*>)? { + v: UnsafeCell<$value_type>, + } + + // Send is implicitly implemented for atomic integers, but not for atomic pointers. + // SAFETY: any data races are prevented by disabling interrupts (or + // atomic intrinsics) or critical-section (see module-level comments). + unsafe impl $(<$($generics)*>)? Send for $atomic_type $(<$($generics)*>)? {} + // SAFETY: any data races are prevented by disabling interrupts (or + // atomic intrinsics) or critical-section (see module-level comments). + unsafe impl $(<$($generics)*>)? Sync for $atomic_type $(<$($generics)*>)? {} + + impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? { + #[inline] + pub(crate) const fn new(v: $value_type) -> Self { + Self { v: UnsafeCell::new(v) } + } + + #[inline] + pub(crate) fn is_lock_free() -> bool { + Self::IS_ALWAYS_LOCK_FREE + } + pub(crate) const IS_ALWAYS_LOCK_FREE: bool = IS_ALWAYS_LOCK_FREE; + + #[inline] + fn read(&self, _guard: &guard::Guard) -> $value_type { + // SAFETY: any data races are prevented by disabling interrupts or critical-section (see + // module-level comments) and the raw pointer is valid because we got it + // from a reference. + unsafe { self.v.get().read() } + } + #[inline] + fn write(&self, val: $value_type, _guard: &guard::Guard) { + // SAFETY: any data races are prevented by disabling interrupts or critical-section (see + // module-level comments) and the raw pointer is valid because we got it + // from a reference. + unsafe { self.v.get().write(val) } + } + + // As for CAS, there is no corresponding atomic operation on all architectures that use this code. + // (If the CAS instruction exists, all atomic operations can be implemented by it, so this code will not be used.) + #[inline] + #[cfg_attr( + all(debug_assertions, not(portable_atomic_no_track_caller)), + track_caller + )] + pub(crate) fn compare_exchange( + &self, + current: $value_type, + new: $value_type, + success: Ordering, + failure: Ordering, + ) -> Result<$value_type, $value_type> { + crate::utils::assert_compare_exchange_ordering(success, failure); + let guard = disable(); + let prev = self.read(&guard); + if prev == current { + self.write(new, &guard); + Ok(prev) + } else { + Err(prev) + } + } + #[inline] + #[cfg_attr( + all(debug_assertions, not(portable_atomic_no_track_caller)), + track_caller + )] + pub(crate) fn compare_exchange_weak( + &self, + current: $value_type, + new: $value_type, + success: Ordering, + failure: Ordering, + ) -> Result<$value_type, $value_type> { + self.compare_exchange(current, new, success, failure) + } + + #[inline] + pub(crate) const fn as_ptr(&self) -> *mut $value_type { + self.v.get() + } + } + }; + (native_load_store, $([$($generics:tt)*])? $atomic_type:ident, $value_type:ty) => { + impl $(<$($generics)*>)? core::ops::Deref for $atomic_type $(<$($generics)*>)? { + type Target = atomic::$atomic_type $(<$($generics)*>)?; + #[inline(always)] + fn deref(&self) -> &Self::Target { + // SAFETY: $atomic_type and atomic::$atomic_type have the same layout and + // guarantee atomicity in a compatible way. (see module-level comments) + unsafe { + &*(self as *const Self as *const atomic::$atomic_type $(<$($generics)*>)?) + } + } + } + }; + (emulate_load_store, $([$($generics:tt)*])? $atomic_type:ident, $value_type:ty) => { + impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? { + #[inline] + #[cfg_attr( + all(debug_assertions, not(portable_atomic_no_track_caller)), + track_caller + )] + pub(crate) fn load(&self, order: Ordering) -> $value_type { + crate::utils::assert_load_ordering(order); + let guard = disable(); + self.read(&guard) + } + #[inline] + #[cfg_attr( + all(debug_assertions, not(portable_atomic_no_track_caller)), + track_caller + )] + pub(crate) fn store(&self, val: $value_type, order: Ordering) { + crate::utils::assert_store_ordering(order); + let guard = disable(); + self.write(val, &guard); + } + } + }; + (emulate_swap, $([$($generics:tt)*])? $atomic_type:ident, $value_type:ty) => { + impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? { + #[inline] + pub(crate) fn swap(&self, val: $value_type, _order: Ordering) -> $value_type { + let guard = disable(); + let prev = self.read(&guard); + self.write(val, &guard); + prev + } + } + }; + } + + #[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any( + test, + target_arch = "avr", + target_arch = "msp430", + portable_atomic_no_atomic_cas + )) + )] + #[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any( + test, + target_arch = "avr", + target_arch = "msp430", + not(target_has_atomic = "ptr") + )) + )] + items!({ + #[cfg(target_pointer_width = "16")] + atomic_base!(base, [T] AtomicPtr, *mut T, 2); + #[cfg(target_pointer_width = "32")] + atomic_base!(base, [T] AtomicPtr, *mut T, 4); + #[cfg(target_pointer_width = "64")] + atomic_base!(base, [T] AtomicPtr, *mut T, 8); + #[cfg(target_pointer_width = "128")] + atomic_base!(base, [T] AtomicPtr, *mut T, 16); + + impl_default_bit_opts!(AtomicPtr, usize); + + cfg_sel!({ + #[cfg(any(target_arch = "avr", feature = "critical-section"))] + { + atomic_base!(emulate_load_store, [T] AtomicPtr, *mut T); + } + #[cfg(else)] + { + atomic_base!(native_load_store, [T] AtomicPtr, *mut T); + } + }); + + #[cfg(not(all( + any(target_arch = "riscv32", target_arch = "riscv64"), + not(feature = "critical-section"), + any( + portable_atomic_force_amo, + target_feature = "zaamo", + portable_atomic_target_feature = "zaamo", + ), + )))] + items!({ + atomic_base!(emulate_swap, [T] AtomicPtr, *mut T); + impl AtomicPtr { + #[inline] + pub(crate) fn fetch_byte_add(&self, val: usize, _order: Ordering) -> *mut T { + #[cfg(portable_atomic_no_strict_provenance)] + use crate::utils::ptr::PtrExt as _; + let guard = disable(); + let prev = self.read(&guard); + self.write(prev.with_addr(prev.addr().wrapping_add(val)), &guard); + prev + } + #[inline] + pub(crate) fn fetch_byte_sub(&self, val: usize, _order: Ordering) -> *mut T { + #[cfg(portable_atomic_no_strict_provenance)] + use crate::utils::ptr::PtrExt as _; + let guard = disable(); + let prev = self.read(&guard); + self.write(prev.with_addr(prev.addr().wrapping_sub(val)), &guard); + prev + } + #[inline] + pub(crate) fn fetch_and(&self, val: usize, _order: Ordering) -> *mut T { + #[cfg(portable_atomic_no_strict_provenance)] + use crate::utils::ptr::PtrExt as _; + let guard = disable(); + let prev = self.read(&guard); + self.write(prev.with_addr(prev.addr() & val), &guard); + prev + } + #[inline] + pub(crate) fn fetch_or(&self, val: usize, _order: Ordering) -> *mut T { + #[cfg(portable_atomic_no_strict_provenance)] + use crate::utils::ptr::PtrExt as _; + let guard = disable(); + let prev = self.read(&guard); + self.write(prev.with_addr(prev.addr() | val), &guard); + prev + } + #[inline] + pub(crate) fn fetch_xor(&self, val: usize, _order: Ordering) -> *mut T { + #[cfg(portable_atomic_no_strict_provenance)] + use crate::utils::ptr::PtrExt as _; + let guard = disable(); + let prev = self.read(&guard); + self.write(prev.with_addr(prev.addr() ^ val), &guard); + prev + } + } + }); + + impl AtomicPtr { + #[cfg(test)] + #[inline] + fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T { + self.fetch_byte_add(val.wrapping_mul(core::mem::size_of::()), order) + } + #[cfg(test)] + #[inline] + fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T { + self.fetch_byte_sub(val.wrapping_mul(core::mem::size_of::()), order) + } + } + }); + + macro_rules! atomic_int { + (base, $atomic_type:ident, $int_type:ty, $align:literal) => { + atomic_base!(base, $atomic_type, $int_type, $align); + // As for nand and neg, there is no corresponding atomic operation on all architectures that use this code. + impl $atomic_type { + #[inline] + pub(crate) fn fetch_nand(&self, val: $int_type, _order: Ordering) -> $int_type { + let guard = disable(); + let prev = self.read(&guard); + self.write(!(prev & val), &guard); + prev + } + #[inline] + pub(crate) fn fetch_neg(&self, _order: Ordering) -> $int_type { + let guard = disable(); + let prev = self.read(&guard); + self.write(prev.wrapping_neg(), &guard); + prev + } + #[inline] + pub(crate) fn neg(&self, order: Ordering) { + self.fetch_neg(order); + } + } + }; + (load_store_atomic $([$kind:ident])?, $atomic_type:ident, $int_type:ty, $align:literal) => { + cfg_sel!({ + #[cfg(feature = "critical-section")] + { + atomic_int!(all_critical_session, $atomic_type, $int_type, $align); + } + #[cfg(else)] + { + atomic_int!(base, $atomic_type, $int_type, $align); + impl_default_bit_opts!($atomic_type, $int_type); + // load/store + cfg_sel!({ + // AVR with very old rustc + #[cfg(all(target_arch = "avr", portable_atomic_no_asm))] + { + atomic_base!(emulate_load_store, $atomic_type, $int_type); + } + #[cfg(else)] + { + atomic_base!(native_load_store, $atomic_type, $int_type); + } + }); + // RMW + cfg_sel!({ + // AVR 8-bit RMW with RMW instructions + #[cfg(all( + target_arch = "avr", + not(portable_atomic_no_asm), + any(target_feature = "rmw", portable_atomic_target_feature = "rmw"), + ))] + { + atomic_int!(emulate_arithmetic, $atomic_type, $int_type); + } + // RISC-V RMW with Zaamo extension + #[cfg(all( + any(target_arch = "riscv32", target_arch = "riscv64"), + any( + portable_atomic_force_amo, + target_feature = "zaamo", + portable_atomic_target_feature = "zaamo", + ), + ))] + { + atomic_int!(cas $([$kind])?, $atomic_type, $int_type); + } + #[cfg(else)] + { + atomic_int!(cas[emulate], $atomic_type, $int_type); + } + }); + // RMW (no-fetch) + #[cfg(not(target_arch = "msp430"))] + items!({ + impl_default_no_fetch_ops!($atomic_type, $int_type); + impl $atomic_type { + #[inline] + pub(crate) fn not(&self, order: Ordering) { + self.fetch_not(order); + } + } + }); + } + }); + }; + (all_critical_session, $atomic_type:ident, $int_type:ty, $align:literal) => { + atomic_int!(base, $atomic_type, $int_type, $align); + atomic_base!(emulate_load_store, $atomic_type, $int_type); + atomic_int!(cas[emulate], $atomic_type, $int_type); + impl_default_no_fetch_ops!($atomic_type, $int_type); + impl_default_bit_opts!($atomic_type, $int_type); + impl $atomic_type { + #[inline] + pub(crate) fn not(&self, order: Ordering) { + self.fetch_not(order); + } + } + }; + (emulate_arithmetic, $atomic_type:ident, $int_type:ty) => { + impl $atomic_type { + #[inline] + pub(crate) fn fetch_add(&self, val: $int_type, _order: Ordering) -> $int_type { + let guard = disable(); + let prev = self.read(&guard); + self.write(prev.wrapping_add(val), &guard); + prev + } + #[inline] + pub(crate) fn fetch_sub(&self, val: $int_type, _order: Ordering) -> $int_type { + let guard = disable(); + let prev = self.read(&guard); + self.write(prev.wrapping_sub(val), &guard); + prev + } + #[inline] + pub(crate) fn fetch_max(&self, val: $int_type, _order: Ordering) -> $int_type { + let guard = disable(); + let prev = self.read(&guard); + self.write(core::cmp::max(prev, val), &guard); + prev + } + #[inline] + pub(crate) fn fetch_min(&self, val: $int_type, _order: Ordering) -> $int_type { + let guard = disable(); + let prev = self.read(&guard); + self.write(core::cmp::min(prev, val), &guard); + prev + } + } + }; + (emulate_bit, $atomic_type:ident, $int_type:ty) => { + impl $atomic_type { + #[inline] + pub(crate) fn fetch_and(&self, val: $int_type, _order: Ordering) -> $int_type { + let guard = disable(); + let prev = self.read(&guard); + self.write(prev & val, &guard); + prev + } + #[inline] + pub(crate) fn fetch_or(&self, val: $int_type, _order: Ordering) -> $int_type { + let guard = disable(); + let prev = self.read(&guard); + self.write(prev | val, &guard); + prev + } + #[inline] + pub(crate) fn fetch_xor(&self, val: $int_type, _order: Ordering) -> $int_type { + let guard = disable(); + let prev = self.read(&guard); + self.write(prev ^ val, &guard); + prev + } + #[inline] + pub(crate) fn fetch_not(&self, _order: Ordering) -> $int_type { + let guard = disable(); + let prev = self.read(&guard); + self.write(!prev, &guard); + prev + } + } + }; + (cas[emulate], $atomic_type:ident, $int_type:ty) => { + atomic_base!(emulate_swap, $atomic_type, $int_type); + atomic_int!(emulate_arithmetic, $atomic_type, $int_type); + atomic_int!(emulate_bit, $atomic_type, $int_type); + }; + // RISC-V 32-bit(RV32)/{32,64}-bit(RV64) RMW with Zaamo extension + // RISC-V 8-bit/16-bit RMW with Zabha extension + (cas, $atomic_type:ident, $int_type:ty) => {}; + // RISC-V 8-bit/16-bit RMW with Zaamo extension + (cas[sub_word], $atomic_type:ident, $int_type:ty) => { + // RISC-V 8-bit/16-bit RMW with Zaamo+Zabha extension + #[cfg(any(target_feature = "zabha", portable_atomic_target_feature = "zabha"))] + atomic_int!(cas, $atomic_type, $int_type); + + // RISC-V 8-bit/16-bit RMW with Zaamo extension + #[cfg(not(any(target_feature = "zabha", portable_atomic_target_feature = "zabha")))] + atomic_base!(emulate_swap, $atomic_type, $int_type); + #[cfg(not(any(target_feature = "zabha", portable_atomic_target_feature = "zabha")))] + atomic_int!(emulate_arithmetic, $atomic_type, $int_type); + }; + } + + #[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any( + test, + target_arch = "avr", + target_arch = "msp430", + portable_atomic_no_atomic_cas, + )) + )] + #[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any( + test, + target_arch = "avr", + target_arch = "msp430", + not(target_has_atomic = "ptr"), + )) + )] + items!({ + // On some platforms, atomic load/store can be implemented in a more efficient + // way than disabling interrupts. On MSP430, some RMWs that do not return the + // previous value can also be optimized. + // + // Note: On single-core systems, it is okay to use critical session-based + // CAS together with atomic load/store. The load/store will not be + // called while interrupts are disabled, and since the load/store is + // atomic, it is not affected by interrupts even if interrupts are enabled. + #[cfg(not(any( + all(target_arch = "avr", portable_atomic_no_asm), + feature = "critical-section", + )))] + use self::arch::atomic; + + #[cfg(target_pointer_width = "16")] + #[cfg(not(target_arch = "avr"))] + atomic_int!(load_store_atomic, AtomicIsize, isize, 2); + #[cfg(target_pointer_width = "16")] + #[cfg(not(target_arch = "avr"))] + atomic_int!(load_store_atomic, AtomicUsize, usize, 2); + #[cfg(target_arch = "avr")] + atomic_int!(all_critical_session, AtomicIsize, isize, 2); + #[cfg(target_arch = "avr")] + atomic_int!(all_critical_session, AtomicUsize, usize, 2); + #[cfg(target_pointer_width = "32")] + atomic_int!(load_store_atomic, AtomicIsize, isize, 4); + #[cfg(target_pointer_width = "32")] + atomic_int!(load_store_atomic, AtomicUsize, usize, 4); + #[cfg(target_pointer_width = "64")] + atomic_int!(load_store_atomic, AtomicIsize, isize, 8); + #[cfg(target_pointer_width = "64")] + atomic_int!(load_store_atomic, AtomicUsize, usize, 8); + #[cfg(target_pointer_width = "128")] + atomic_int!(load_store_atomic, AtomicIsize, isize, 16); + #[cfg(target_pointer_width = "128")] + atomic_int!(load_store_atomic, AtomicUsize, usize, 16); + + #[cfg(not(all(target_arch = "avr", portable_atomic_no_asm)))] + atomic_int!(load_store_atomic[sub_word], AtomicI8, i8, 1); + #[cfg(not(all(target_arch = "avr", portable_atomic_no_asm)))] + atomic_int!(load_store_atomic[sub_word], AtomicU8, u8, 1); + #[cfg(all(target_arch = "avr", portable_atomic_no_asm))] + atomic_int!(all_critical_session, AtomicI8, i8, 1); + #[cfg(all(target_arch = "avr", portable_atomic_no_asm))] + atomic_int!(all_critical_session, AtomicU8, u8, 1); + #[cfg(not(target_arch = "avr"))] + atomic_int!(load_store_atomic[sub_word], AtomicI16, i16, 2); + #[cfg(not(target_arch = "avr"))] + atomic_int!(load_store_atomic[sub_word], AtomicU16, u16, 2); + #[cfg(target_arch = "avr")] + atomic_int!(all_critical_session, AtomicI16, i16, 2); + #[cfg(target_arch = "avr")] + atomic_int!(all_critical_session, AtomicU16, u16, 2); + + #[cfg(not(target_pointer_width = "16"))] + atomic_int!(load_store_atomic, AtomicI32, i32, 4); + #[cfg(not(target_pointer_width = "16"))] + atomic_int!(load_store_atomic, AtomicU32, u32, 4); + + cfg_has_fast_atomic_64!({ + atomic_int!(load_store_atomic, AtomicI64, i64, 8); + atomic_int!(load_store_atomic, AtomicU64, u64, 8); + }); + }); + + // Double or more width atomics (require fallback feature for consistency with other situations). + #[cfg(target_pointer_width = "16")] + #[cfg(any(test, feature = "fallback"))] + items!({ + atomic_int!(all_critical_session, AtomicI32, i32, 4); + atomic_int!(all_critical_session, AtomicU32, u32, 4); + }); + #[cfg(any( + test, + all( + feature = "fallback", + not(all( + target_arch = "riscv32", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any( + target_feature = "zacas", + portable_atomic_target_feature = "zacas", + all( + feature = "fallback", + not(portable_atomic_no_outline_atomics), + any(target_os = "linux", target_os = "android"), + ), + ), + )), + ), + ))] + #[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any(test, portable_atomic_no_atomic_64)) + )] + #[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any(test, not(target_has_atomic = "64"))) + )] + cfg_no_fast_atomic_64!({ + atomic_int!(all_critical_session, AtomicI64, i64, 8); + atomic_int!(all_critical_session, AtomicU64, u64, 8); + }); + #[cfg(any( + test, + all( + feature = "fallback", + not(all( + target_arch = "riscv64", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any( + target_feature = "zacas", + portable_atomic_target_feature = "zacas", + all( + feature = "fallback", + not(portable_atomic_no_outline_atomics), + any(target_os = "linux", target_os = "android"), + ), + ), + )), + ), + ))] + items!({ + atomic_int!(all_critical_session, AtomicI128, i128, 16); + atomic_int!(all_critical_session, AtomicU128, u128, 16); + }); +}); + +#[cfg(test)] +mod tests { + use super::*; + + test_atomic_ptr_single_thread!(); + test_atomic_int_single_thread!(i8); + test_atomic_int_single_thread!(u8); + test_atomic_int_single_thread!(i16); + test_atomic_int_single_thread!(u16); + test_atomic_int_single_thread!(i32); + test_atomic_int_single_thread!(u32); + test_atomic_int_single_thread!(i64); + test_atomic_int_single_thread!(u64); + test_atomic_int_single_thread!(i128); + test_atomic_int_single_thread!(u128); + test_atomic_int_single_thread!(isize); + test_atomic_int_single_thread!(usize); +} diff --git a/vendor/portable-atomic/src/imp/interrupt/msp430.rs b/vendor/portable-atomic/src/imp/interrupt/msp430.rs new file mode 100644 index 0000000..d582fd3 --- /dev/null +++ b/vendor/portable-atomic/src/imp/interrupt/msp430.rs @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Adapted from https://github.com/rust-embedded/msp430. + +See also src/imp/msp430.rs. + +Refs: +- MSP430x5xx and MSP430x6xx Family User's Guide, Rev. Q + https://www.ti.com/lit/ug/slau208q/slau208q.pdf + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; + +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any(test, portable_atomic_no_atomic_cas)) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any(test, not(target_has_atomic = "ptr"))) +)] +pub(super) use super::super::msp430 as atomic; + +pub(crate) type State = u16; + +/// Disables interrupts and returns the previous interrupt state. +#[inline(always)] +pub(crate) fn disable() -> State { + let sr: State; + // SAFETY: reading the status register and disabling interrupts are safe. + // (see module-level comments of interrupt/mod.rs on the safety of using privileged instructions) + // + // See "NOTE: Enable and Disable Interrupt" of User's Guide for NOP: https://www.ti.com/lit/ug/slau208q/slau208q.pdf#page=60 + unsafe { + #[cfg(not(portable_atomic_no_asm))] + asm!( + "mov r2, {sr}", // sr = SR + "dint {{ nop", // SR.GIE = 0 + sr = out(reg) sr, + // Do not use `nomem` and `readonly` because prevent subsequent memory accesses from being reordered before interrupts are disabled. + // Do not use `preserves_flags` because DINT modifies the GIE (global interrupt enable) bit of the status register. + options(nostack), + ); + #[cfg(portable_atomic_no_asm)] + { + llvm_asm!("mov r2, $0" : "=r"(sr) ::: "volatile"); + llvm_asm!("dint { nop" ::: "memory" : "volatile"); + } + } + sr +} + +/// Restores the previous interrupt state. +/// +/// # Safety +/// +/// The state must be the one retrieved by the previous `disable`. +#[inline(always)] +pub(crate) unsafe fn restore(prev_sr: State) { + // SAFETY: the caller must guarantee that the state was retrieved by the previous `disable`, + // + // This clobbers the entire status register, but we never explicitly modify + // flags within a critical session, and the only flags that may be changed + // within a critical session are the arithmetic flags that are changed as + // a side effect of arithmetic operations, etc., which LLVM recognizes unless + // preserves_flags is set, so it is safe to clobber them here. + // See also the discussion at https://github.com/taiki-e/portable-atomic/pull/40. + // + // See "NOTE: Enable and Disable Interrupt" of User's Guide for NOP: https://www.ti.com/lit/ug/slau208q/slau208q.pdf#page=60 + unsafe { + #[cfg(not(portable_atomic_no_asm))] + asm!( + "nop {{ mov {prev_sr}, r2 {{ nop", // SR = prev_sr + prev_sr = in(reg) prev_sr, + // Do not use `nomem` and `readonly` because prevent preceding memory accesses from being reordered after interrupts are enabled. + // Do not use `preserves_flags` because MOV modifies the status register. + options(nostack), + ); + #[cfg(portable_atomic_no_asm)] + llvm_asm!("nop { mov $0, r2 { nop" :: "r"(prev_sr) : "memory" : "volatile"); + } +} diff --git a/vendor/portable-atomic/src/imp/interrupt/riscv.rs b/vendor/portable-atomic/src/imp/interrupt/riscv.rs new file mode 100644 index 0000000..6e580f6 --- /dev/null +++ b/vendor/portable-atomic/src/imp/interrupt/riscv.rs @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Refs: +- RISC-V Instruction Set Manual + Machine Status (mstatus and mstatush) Registers + https://docs.riscv.org/reference/isa/v20260120/priv/machine.html#3-1-1-6-machine-status-mstatus-and-mstatush-registers + Supervisor Status (sstatus) Register + https://docs.riscv.org/reference/isa/v20260120/priv/supervisor.html#sstatus + +See also src/imp/riscv.rs. + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; + +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any(test, portable_atomic_no_atomic_cas)) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any(test, not(target_has_atomic = "ptr"))) +)] +pub(super) use super::super::riscv as atomic; + +cfg_sel!({ + // Supervisor-mode (S-mode) + #[cfg(portable_atomic_s_mode)] + { + // Status register + macro_rules! status { + () => { + "sstatus" + }; + } + // SIE (Supervisor Interrupt Enable) bit (1 << 1) + #[cfg(portable_atomic_s_mode)] + macro_rules! mask { + () => { + "0x2" + }; + } + const MASK: State = 0x2; + } + // Machine-mode (M-mode) + #[cfg(else)] + { + // Status register + macro_rules! status { + () => { + "mstatus" + }; + } + // MIE (Machine Interrupt Enable) bit (1 << 3) + macro_rules! mask { + () => { + "0x8" + }; + } + const MASK: State = 0x8; + } +}); + +pub(crate) type State = crate::utils::RegSize; + +/// Disables interrupts and returns the previous interrupt state. +#[inline(always)] +pub(crate) fn disable() -> State { + let status: State; + // SAFETY: reading mstatus/sstatus and disabling interrupts is safe. + // (see module-level comments of interrupt/mod.rs on the safety of using privileged instructions) + unsafe { + asm!( + concat!("csrrci {status}, ", status!(), ", ", mask!()), // atomic { status = status!(); status!() &= !mask!() } + status = out(reg) status, + // Do not use `nomem` and `readonly` because prevent subsequent memory accesses from being reordered before interrupts are disabled. + options(nostack, preserves_flags), + ); + } + status +} + +/// Restores the previous interrupt state. +/// +/// # Safety +/// +/// The state must be the one retrieved by the previous `disable`. +#[inline(always)] +pub(crate) unsafe fn restore(prev_status: State) { + // SAFETY: the caller must guarantee that the state was retrieved by the previous `disable`, + // + // This avoids clobbering other fields in the mstatus/sstatus register. + unsafe { + asm!( + concat!("csrs ", status!(), ", {mask}"), // atomic { status!() |= mask } + mask = in(reg) prev_status & MASK, + // Do not use `nomem` and `readonly` because prevent preceding memory accesses from being reordered after interrupts are enabled. + options(nostack, preserves_flags), + ); + } +} diff --git a/vendor/portable-atomic/src/imp/interrupt/xtensa.rs b/vendor/portable-atomic/src/imp/interrupt/xtensa.rs new file mode 100644 index 0000000..adbceaa --- /dev/null +++ b/vendor/portable-atomic/src/imp/interrupt/xtensa.rs @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Refs: +- Xtensa Instruction Set Architecture (ISA) Summary for all Xtensa LX Processors + https://www.cadence.com/content/dam/cadence-www/global/en_US/documents/tools/silicon-solutions/compute-ip/isa-summary.pdf +- Linux kernel's Xtensa atomic implementation + https://github.com/torvalds/linux/blob/v6.19/arch/xtensa/include/asm/atomic.h + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +use core::arch::asm; +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any(test, portable_atomic_no_atomic_cas)) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any(test, not(target_has_atomic = "ptr"))) +)] +pub(super) use core::sync::atomic; + +pub(crate) type State = u32; + +/// Disables interrupts and returns the previous interrupt state. +#[inline(always)] +pub(crate) fn disable() -> State { + let ps: State; + // SAFETY: reading the PS special register and disabling all interrupts is safe. + // (see module-level comments of interrupt/mod.rs on the safety of using privileged instructions) + // + // Interrupt level 15 to disable all interrupts. + // SYNC after RSIL is not required. + // Use a14 per https://github.com/torvalds/linux/blob/v6.16/arch/xtensa/include/asm/atomic.h#L33-L37. + unsafe { + asm!( + "rsil a14, 15", // a14 = PS; PS.INTLEVEL = 15 + out("a14") ps, + // Do not use `nomem` and `readonly` because prevent subsequent memory accesses from being reordered before interrupts are disabled. + options(nostack), + ); + } + ps +} + +/// Restores the previous interrupt state. +/// +/// # Safety +/// +/// The state must be the one retrieved by the previous `disable`. +#[inline(always)] +pub(crate) unsafe fn restore(prev_ps: State) { + // SAFETY: the caller must guarantee that the state was retrieved by the previous `disable`, + // and we've checked that interrupts were enabled before disabling interrupts. + // + // SYNC after WSR is required to guarantee that subsequent RSIL read the written value. + // See also 3.8.10 Processor Control Instructions of Xtensa Instruction Set Architecture (ISA) Summary for all Xtensa LX Processors. + unsafe { + asm!( + "wsr.ps a14", // PS = a14 + "rsync", // wait + in("a14") prev_ps, + // Do not use `nomem` and `readonly` because prevent preceding memory accesses from being reordered after interrupts are enabled. + options(nostack), + ); + } +} diff --git a/vendor/portable-atomic/src/imp/mod.rs b/vendor/portable-atomic/src/imp/mod.rs new file mode 100644 index 0000000..53a0549 --- /dev/null +++ b/vendor/portable-atomic/src/imp/mod.rs @@ -0,0 +1,566 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +// ----------------------------------------------------------------------------- +// Lock-free implementations + +cfg_core_atomic!({ + mod core_atomic; +}); + +// AVR +#[cfg(target_arch = "avr")] +#[cfg(not(portable_atomic_no_asm))] +#[cfg(not(feature = "critical-section"))] +mod avr; + +// pre-v6 Arm Linux +#[cfg(all( + target_arch = "arm", + not(any(miri, portable_atomic_sanitize_thread)), + any(target_os = "linux", target_os = "android"), + not(any(target_feature = "v6", portable_atomic_target_feature = "v6")), +))] +pub(crate) mod arm_linux; + +// MSP430 +#[cfg(target_arch = "msp430")] +pub(crate) mod msp430; + +// RISC-V without A-extension +#[cfg(any(test, not(feature = "critical-section")))] +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any( + all(test, not(any(miri, portable_atomic_sanitize_thread))), + portable_atomic_no_atomic_cas, + )) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any( + all(test, not(any(miri, portable_atomic_sanitize_thread))), + not(target_has_atomic = "ptr"), + )) +)] +#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] +mod riscv; + +// x86-specific optimizations +// Miri and Sanitizer do not support inline assembly. +#[cfg(all( + any(target_arch = "x86", target_arch = "x86_64"), + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), +))] +pub(crate) mod x86; + +// 64-bit atomic implementations on 32-bit architectures +#[cfg(any(target_arch = "arm", target_arch = "riscv32"))] +mod atomic64; + +// 128-bit atomic implementations on 64-bit architectures +#[cfg(any( + target_arch = "aarch64", + target_arch = "arm64ec", + target_arch = "powerpc64", + target_arch = "riscv64", + target_arch = "s390x", + target_arch = "x86_64", +))] +mod atomic128; + +// ----------------------------------------------------------------------------- +// Lock-based fallback implementations + +#[cfg(feature = "fallback")] +#[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(not(portable_atomic_no_atomic_cas)))] +#[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg(target_has_atomic = "ptr"))] +#[cfg_attr( + not(test), + cfg(not(any( + // --------------- + // Use other ways. + target_arch = "avr", + target_arch = "msp430", + portable_atomic_unsafe_assume_single_core, + // -------------------- + // Has 128-bit atomics. + all( + target_arch = "aarch64", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + ), + all( + target_arch = "arm64ec", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + ), + all( + target_arch = "x86_64", + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + ), + all( + target_arch = "riscv64", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_feature = "zacas", portable_atomic_target_feature = "zacas"), + ), + all( + target_arch = "powerpc64", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + ), + ), + all( + target_arch = "s390x", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + ), + )) +))] +mod fallback; + +// ----------------------------------------------------------------------------- +// Fallback implementation based on disabling interrupts or critical-section + +// On AVR, we always use critical section based fallback implementation. +// AVR can be safely assumed to be single-core, so this is sound. +// MSP430 as well. +// See the module-level comments of interrupt module for more. +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any( + target_arch = "avr", + target_arch = "msp430", + all(feature = "critical-section", any(test, portable_atomic_no_atomic_cas)), + portable_atomic_unsafe_assume_single_core, + portable_atomic_unsafe_assume_privileged, + )) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any( + target_arch = "avr", + target_arch = "msp430", + all(feature = "critical-section", any(test, not(target_has_atomic = "ptr"))), + portable_atomic_unsafe_assume_single_core, + portable_atomic_unsafe_assume_privileged, + )) +)] +#[cfg(any( + target_arch = "arm", + target_arch = "avr", + target_arch = "msp430", + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "xtensa", + feature = "critical-section", +))] +mod interrupt; + +// ----------------------------------------------------------------------------- +// Atomic float implementations + +#[cfg(feature = "float")] +pub(crate) mod float; + +// ----------------------------------------------------------------------------- + +// {8,16,32}-bit & ptr-sized atomics +cfg_sel!({ + // has CAS | (has core atomic & !(avr | msp430 | critical section)) => core atomic + #[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(not(any( + target_arch = "avr", + target_arch = "msp430", + portable_atomic_no_atomic_load_store, + all( + any( + target_arch = "riscv32", + target_arch = "riscv64", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ), + portable_atomic_no_atomic_cas, + ), + ))) + )] + #[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(not(any( + target_arch = "avr", + target_arch = "msp430", + portable_atomic_no_atomic_load_store, + all( + any( + target_arch = "riscv32", + target_arch = "riscv64", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ), + not(target_has_atomic = "ptr"), + ), + ))) + )] + { + pub(crate) use self::core_atomic::{ + AtomicI8, AtomicI16, AtomicI32, AtomicIsize, AtomicPtr, AtomicU8, AtomicU16, AtomicU32, + AtomicUsize, + }; + } + // no native atomic CAS & (assume single core | critical section) => critical section based fallback + #[cfg(any( + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ))] + { + pub(crate) use self::interrupt::{ + AtomicI8, AtomicI16, AtomicIsize, AtomicPtr, AtomicU8, AtomicU16, AtomicUsize, + }; + #[cfg(any(not(target_pointer_width = "16"), feature = "fallback"))] + pub(crate) use self::interrupt::{AtomicI32, AtomicU32}; + } + // RISC-V without A-extension & !(assume single core | critical section) + #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + { + pub(crate) use self::riscv::{ + AtomicI8, AtomicI16, AtomicI32, AtomicIsize, AtomicPtr, AtomicU8, AtomicU16, AtomicU32, + AtomicUsize, + }; + } + // bpf & !(critical section) => core atomic + #[cfg(target_arch = "bpf")] + { + pub(crate) use self::core_atomic::{AtomicIsize, AtomicPtr, AtomicUsize}; + } + #[cfg(else)] + { + // no atomic + } +}); + +// 64-bit atomics +cfg_sel!({ + // has CAS | (has core atomic & !(avr | msp430 | critical section)) => core atomic + #[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(all( + not(any( + target_arch = "avr", + target_arch = "msp430", + portable_atomic_no_atomic_load_store, + all( + any( + target_arch = "riscv32", + target_arch = "riscv64", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ), + portable_atomic_no_atomic_cas, + ) + )), + any( + not(portable_atomic_no_atomic_64), + not(any(target_pointer_width = "16", target_pointer_width = "32")), + ), + )) + )] + #[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(all( + not(any( + target_arch = "avr", + target_arch = "msp430", + portable_atomic_no_atomic_load_store, + all( + any( + target_arch = "riscv32", + target_arch = "riscv64", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ), + not(target_has_atomic = "ptr"), + ) + )), + any( + target_has_atomic = "64", + not(any(target_pointer_width = "16", target_pointer_width = "32")), + ), + )) + )] + { + pub(crate) use self::core_atomic::{AtomicI64, AtomicU64}; + } + // pre-v6 Arm Linux + #[cfg(all( + feature = "fallback", + target_arch = "arm", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_os = "linux", target_os = "android"), + not(any(target_feature = "v6", portable_atomic_target_feature = "v6")), + not(portable_atomic_no_outline_atomics), + ))] + { + pub(crate) use self::atomic64::arm_linux::{AtomicI64, AtomicU64}; + } + // riscv32 & (zacas | outline-atomics) + #[cfg(all( + target_arch = "riscv32", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any( + target_feature = "zacas", + portable_atomic_target_feature = "zacas", + all( + feature = "fallback", + not(portable_atomic_no_outline_atomics), + any(target_os = "linux", target_os = "android"), + ), + ), + ))] + { + pub(crate) use self::atomic64::riscv32::{AtomicI64, AtomicU64}; + } + // no native atomic CAS & (assume single core | critical section) => critical section based fallback + #[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any( + target_arch = "avr", + target_arch = "msp430", + all(feature = "critical-section", portable_atomic_no_atomic_cas), + portable_atomic_unsafe_assume_single_core, + )) + )] + #[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any( + target_arch = "avr", + target_arch = "msp430", + all(feature = "critical-section", not(target_has_atomic = "ptr")), + portable_atomic_unsafe_assume_single_core, + )) + )] + { + #[cfg(any( + not(any(target_pointer_width = "16", target_pointer_width = "32")), + feature = "fallback", + ))] + pub(crate) use self::interrupt::{AtomicI64, AtomicU64}; + } + // no core 64-bit atomic & has CAS => use lock-base fallback + #[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(all(feature = "fallback", not(portable_atomic_no_atomic_cas))) + )] + #[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(all(feature = "fallback", target_has_atomic = "ptr")) + )] + { + pub(crate) use self::fallback::{AtomicI64, AtomicU64}; + } + // RISC-V without A-extension & !(assume single core | critical section) + #[cfg(target_arch = "riscv64")] + { + pub(crate) use self::riscv::{AtomicI64, AtomicU64}; + } + // bpf & !(critical section) => core atomic + #[cfg(target_arch = "bpf")] + { + pub(crate) use self::core_atomic::{AtomicI64, AtomicU64}; + } + #[cfg(else)] + { + // no atomic + } +}); + +// 128-bit atomics +cfg_sel!({ + // AArch64 + #[cfg(any( + all( + target_arch = "aarch64", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + ), + all( + target_arch = "arm64ec", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + ), + ))] + { + pub(crate) use self::atomic128::aarch64::{AtomicI128, AtomicU128}; + } + // x86_64 & (cmpxchg16b | outline-atomics) + #[cfg(all( + target_arch = "x86_64", + not(all( + any(miri, portable_atomic_sanitize_thread), + portable_atomic_no_cmpxchg16b_intrinsic, + )), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any( + target_feature = "cmpxchg16b", + portable_atomic_target_feature = "cmpxchg16b", + all( + feature = "fallback", + not(portable_atomic_no_outline_atomics), + not(any(target_env = "sgx", miri)), + ), + ), + ))] + { + pub(crate) use self::atomic128::x86_64::{AtomicI128, AtomicU128}; + } + // riscv64 & (zacas | outline-atomics) + #[cfg(all( + target_arch = "riscv64", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any( + target_feature = "zacas", + portable_atomic_target_feature = "zacas", + all( + feature = "fallback", + not(portable_atomic_no_outline_atomics), + any(target_os = "linux", target_os = "android"), + ), + ), + ))] + { + pub(crate) use self::atomic128::riscv64::{AtomicI128, AtomicU128}; + } + // powerpc64 & (pwr8 | outline-atomics) + #[cfg(all( + target_arch = "powerpc64", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + all( + feature = "fallback", + not(portable_atomic_no_outline_atomics), + any( + all( + target_os = "linux", + any( + all( + target_env = "gnu", + any(target_endian = "little", not(target_feature = "crt-static")), + ), + all( + target_env = "musl", + any(not(target_feature = "crt-static"), feature = "std"), + ), + target_env = "ohos", + all(target_env = "uclibc", not(target_feature = "crt-static")), + portable_atomic_outline_atomics, + ), + ), + target_os = "android", + all( + target_os = "freebsd", + any( + target_endian = "little", + not(target_feature = "crt-static"), + portable_atomic_outline_atomics, + ), + ), + target_os = "openbsd", + all( + target_os = "aix", + not(portable_atomic_pre_llvm_20), + portable_atomic_outline_atomics, + ), // TODO(aix): currently disabled by default + ), + not(any(miri, portable_atomic_sanitize_thread)), + ), + ), + ))] + { + pub(crate) use self::atomic128::powerpc64::{AtomicI128, AtomicU128}; + } + // s390x + #[cfg(all( + target_arch = "s390x", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + ))] + { + pub(crate) use self::atomic128::s390x::{AtomicI128, AtomicU128}; + } + // no native atomic CAS & (assume single core | critical section) => critical section based fallback + #[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(any( + target_arch = "avr", + target_arch = "msp430", + all(feature = "critical-section", portable_atomic_no_atomic_cas), + portable_atomic_unsafe_assume_single_core, + )) + )] + #[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(any( + target_arch = "avr", + target_arch = "msp430", + all(feature = "critical-section", not(target_has_atomic = "ptr")), + portable_atomic_unsafe_assume_single_core, + )) + )] + { + #[cfg(feature = "fallback")] + pub(crate) use self::interrupt::{AtomicI128, AtomicU128}; + } + // no core 128-bit atomic & has CAS => use lock-base fallback + #[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(all(feature = "fallback", not(portable_atomic_no_atomic_cas))) + )] + #[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(all(feature = "fallback", target_has_atomic = "ptr")) + )] + { + pub(crate) use self::fallback::{AtomicI128, AtomicU128}; + } + #[cfg(else)] + { + // no atomic + } +}); diff --git a/vendor/portable-atomic/src/imp/msp430.rs b/vendor/portable-atomic/src/imp/msp430.rs new file mode 100644 index 0000000..d654184 --- /dev/null +++ b/vendor/portable-atomic/src/imp/msp430.rs @@ -0,0 +1,283 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Atomic implementation on MSP430. + +Adapted from https://github.com/pftbest/msp430-atomic. + +Operations not supported here are provided by disabling interrupts. +See also src/imp/interrupt/msp430.rs. + +See "Atomic operation overview by architecture" in atomic-maybe-uninit for a more comprehensive and +detailed description of the atomic and synchronize instructions in this architecture: +https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#msp430 + +Note: Ordering is always SeqCst. + +Refs: +- MSP430x5xx and MSP430x6xx Family User's Guide, Rev. Q + https://www.ti.com/lit/ug/slau208q/slau208q.pdf +- atomic-maybe-uninit + https://github.com/taiki-e/atomic-maybe-uninit + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; +#[cfg(not(feature = "critical-section"))] +use core::cell::UnsafeCell; +use core::sync::atomic::Ordering; + +/// An atomic fence. +/// +/// # Panics +/// +/// Panics if `order` is [`Relaxed`](Ordering::Relaxed). +#[inline] +#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] +pub fn fence(order: Ordering) { + match order { + Ordering::Relaxed => panic!("there is no such thing as a relaxed fence"), + // MSP430 is single-core and a compiler fence works as an atomic fence. + _ => compiler_fence(order), + } +} + +/// A compiler memory fence. +/// +/// # Panics +/// +/// Panics if `order` is [`Relaxed`](Ordering::Relaxed). +#[inline] +#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] +pub fn compiler_fence(order: Ordering) { + match order { + Ordering::Relaxed => panic!("there is no such thing as a relaxed compiler fence"), + _ => {} + } + // SAFETY: using an empty asm is safe. + unsafe { + // Do not use `nomem` and `readonly` because prevent preceding and subsequent memory accesses from being reordered. + #[cfg(not(portable_atomic_no_asm))] + asm!("", options(nostack, preserves_flags)); + #[cfg(portable_atomic_no_asm)] + llvm_asm!("" ::: "memory" : "volatile"); + } +} + +#[cfg(not(feature = "critical-section"))] +items!({ + macro_rules! atomic { + (load_store, $([$($generics:tt)*])? $atomic_type:ident, $value_type:ty, $size:tt) => { + #[repr(transparent)] + pub(crate) struct $atomic_type $(<$($generics)*>)? { + v: UnsafeCell<$value_type>, + } + + // Send is implicitly implemented for atomic integers, but not for atomic pointers. + // SAFETY: any data races are prevented by atomic operations. + unsafe impl $(<$($generics)*>)? Send for $atomic_type $(<$($generics)*>)? {} + // SAFETY: any data races are prevented by atomic operations. + unsafe impl $(<$($generics)*>)? Sync for $atomic_type $(<$($generics)*>)? {} + + impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? { + #[inline] + #[cfg_attr( + all(debug_assertions, not(portable_atomic_no_track_caller)), + track_caller + )] + pub(crate) fn load(&self, order: Ordering) -> $value_type { + crate::utils::assert_load_ordering(order); + let src = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + let out; + #[cfg(not(portable_atomic_no_asm))] + asm!( + concat!("mov.", $size, " @{src}, {out}"), // atomic { out = *src } + src = in(reg) src, + out = lateout(reg) out, + options(nostack, preserves_flags), + ); + #[cfg(portable_atomic_no_asm)] + llvm_asm!( + concat!("mov.", $size, " $1, $0") + : "=r"(out) : "*m"(src) : "memory" : "volatile" + ); + out + } + } + + #[inline] + #[cfg_attr( + all(debug_assertions, not(portable_atomic_no_track_caller)), + track_caller + )] + pub(crate) fn store(&self, val: $value_type, order: Ordering) { + crate::utils::assert_store_ordering(order); + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + #[cfg(not(portable_atomic_no_asm))] + asm!( + concat!("mov.", $size, " {val}, 0({dst})"), // atomic { *dst = val } + dst = in(reg) dst, + val = in(reg) val, + options(nostack, preserves_flags), + ); + #[cfg(portable_atomic_no_asm)] + llvm_asm!( + concat!("mov.", $size, " $1, $0") + :: "*m"(dst), "ir"(val) : "memory" : "volatile" + ); + } + } + } + }; + ($([$($generics:tt)*])? $atomic_type:ident, $value_type:ty, $size:tt) => { + atomic!(load_store, $([$($generics)*])? $atomic_type, $value_type, $size); + impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? { + #[inline] + pub(crate) fn add(&self, val: $value_type, _order: Ordering) { + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + #[cfg(not(portable_atomic_no_asm))] + asm!( + concat!("add.", $size, " {val}, 0({dst})"), // atomic { *dst += val } + dst = in(reg) dst, + val = in(reg) val, + // Do not use `preserves_flags` because ADD modifies the V, N, Z, and C bits of the status register. + options(nostack), + ); + #[cfg(portable_atomic_no_asm)] + llvm_asm!( + concat!("add.", $size, " $1, $0") + :: "*m"(dst), "ir"(val) : "memory" : "volatile" + ); + } + } + + #[inline] + pub(crate) fn sub(&self, val: $value_type, _order: Ordering) { + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + #[cfg(not(portable_atomic_no_asm))] + asm!( + concat!("sub.", $size, " {val}, 0({dst})"), // atomic { *dst -= val } + dst = in(reg) dst, + val = in(reg) val, + // Do not use `preserves_flags` because SUB modifies the V, N, Z, and C bits of the status register. + options(nostack), + ); + #[cfg(portable_atomic_no_asm)] + llvm_asm!( + concat!("sub.", $size, " $1, $0") + :: "*m"(dst), "ir"(val) : "memory" : "volatile" + ); + } + } + + #[inline] + pub(crate) fn and(&self, val: $value_type, _order: Ordering) { + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + #[cfg(not(portable_atomic_no_asm))] + asm!( + concat!("and.", $size, " {val}, 0({dst})"), // atomic { *dst &= val } + dst = in(reg) dst, + val = in(reg) val, + // Do not use `preserves_flags` because AND modifies the V, N, Z, and C bits of the status register. + options(nostack), + ); + #[cfg(portable_atomic_no_asm)] + llvm_asm!( + concat!("and.", $size, " $1, $0") + :: "*m"(dst), "ir"(val) : "memory" : "volatile" + ); + } + } + + #[inline] + pub(crate) fn or(&self, val: $value_type, _order: Ordering) { + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + #[cfg(not(portable_atomic_no_asm))] + asm!( + concat!("bis.", $size, " {val}, 0({dst})"), // atomic { *dst |= val } + dst = in(reg) dst, + val = in(reg) val, + options(nostack, preserves_flags), + ); + #[cfg(portable_atomic_no_asm)] + llvm_asm!( + concat!("bis.", $size, " $1, $0") + :: "*m"(dst), "ir"(val) : "memory" : "volatile" + ); + } + } + + #[inline] + pub(crate) fn xor(&self, val: $value_type, _order: Ordering) { + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + #[cfg(not(portable_atomic_no_asm))] + asm!( + concat!("xor.", $size, " {val}, 0({dst})"), // atomic { *dst ^= val } + dst = in(reg) dst, + val = in(reg) val, + // Do not use `preserves_flags` because XOR modifies the V, N, Z, and C bits of the status register. + options(nostack), + ); + #[cfg(portable_atomic_no_asm)] + llvm_asm!( + concat!("xor.", $size, " $1, $0") + :: "*m"(dst), "ir"(val) : "memory" : "volatile" + ); + } + } + + #[inline] + pub(crate) fn not(&self, _order: Ordering) { + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + #[cfg(not(portable_atomic_no_asm))] + asm!( + concat!("inv.", $size, " 0({dst})"), // atomic { *dst = !*dst } + dst = in(reg) dst, + // Do not use `preserves_flags` because INV modifies the V, N, Z, and C bits of the status register. + options(nostack), + ); + #[cfg(portable_atomic_no_asm)] + llvm_asm!( + concat!("inv.", $size, " $0") + :: "*m"(dst) : "memory" : "volatile" + ); + } + } + } + }; + } + + atomic!(AtomicI8, i8, "b"); + atomic!(AtomicU8, u8, "b"); + atomic!(AtomicI16, i16, "w"); + atomic!(AtomicU16, u16, "w"); + atomic!(AtomicIsize, isize, "w"); + atomic!(AtomicUsize, usize, "w"); + atomic!(load_store, [T] AtomicPtr, *mut T, "w"); +}); diff --git a/vendor/portable-atomic/src/imp/riscv.rs b/vendor/portable-atomic/src/imp/riscv.rs new file mode 100644 index 0000000..5be5eae --- /dev/null +++ b/vendor/portable-atomic/src/imp/riscv.rs @@ -0,0 +1,947 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Atomic load/store implementation on RISC-V. + +This is for RISC-V targets without A extension. (pre-1.76 rustc doesn't provide atomics +at all on such targets. https://github.com/rust-lang/rust/pull/114499) + +Also, optionally provides RMW implementation when Zaamo extension or force-amo feature is enabled. + +If A extension is not available but Zalrsc or Zacas extension is available, LLVM can implement all +atomic operations using it (https://github.com/llvm/llvm-project/commit/70f70390bb83a383fcb88ea843adbc4edf6ee34b), +so this module contains no code for these extensions. + +See "Atomic operation overview by architecture" in atomic-maybe-uninit for a more comprehensive and +detailed description of the atomic and synchronize instructions in this architecture: +https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#risc-v + +Refs: +- RISC-V Instruction Set Manual + "Zaamo" Extension for Atomic Memory Operations + https://docs.riscv.org/reference/isa/v20260120/unpriv/a-st-ext.html#sec:amo + "Zabha" Extension for Byte and Halfword Atomic Memory Operations + https://docs.riscv.org/reference/isa/v20260120/unpriv/zabha.html +- RISC-V Atomics ABI Specification + https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/draft-20250812-301374e92976e298e676e7129a6212926b2299ce/riscv-atomic.adoc +- atomic-maybe-uninit + https://github.com/taiki-e/atomic-maybe-uninit + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; +use core::{cell::UnsafeCell, sync::atomic::Ordering}; + +#[cfg(any( + test, + portable_atomic_force_amo, + target_feature = "zaamo", + portable_atomic_target_feature = "zaamo", +))] +items!({ + macro_rules! atomic_rmw_amo_ext { + // Use +a also for zaamo because `option arch +zaamo` requires LLVM 19. + // https://github.com/llvm/llvm-project/commit/8be079cdddfd628d356d9ddb5ab397ea95fb1030 + ("w") => { + "+a" + }; + ("d") => { + "+a" + }; + ("b") => { + "+a,+zabha" + }; + ("h") => { + "+a,+zabha" + }; + } + macro_rules! atomic_rmw_amo { + ($op:ident, $dst:ident, $val:ident, $order:ident, $size:tt) => {{ + let out; + macro_rules! op { + ($asm_order:tt) => { + // SAFETY: The user guaranteed that the AMO instruction is available in this + // system by setting the portable_atomic_force_amo/target_feature and + // portable_atomic_unsafe_assume_single_core. + // The caller of this macro must guarantee the validity of the pointer. + asm!( + ".option push", + // https://github.com/riscv-non-isa/riscv-asm-manual/blob/v0.0.1/src/asm-manual.adoc#arch + // LLVM supports `.option arch` directive on LLVM 17+. + // https://github.com/llvm/llvm-project/commit/9e8ed3403c191ab9c4903e8eeb8f732ff8a43cb4 + // Note that `.insn ` directive requires LLVM 19. + // https://github.com/llvm/llvm-project/commit/2a086dce691e3cc34a2fc27f4fb255bb2cbbfac9 + concat!(".option arch, ", atomic_rmw_amo_ext!($size)), + concat!("amo", stringify!($op), ".", $size, $asm_order, " {out}, {val}, 0({dst})"), // atomic { _x = *dst; *dst = op(_x, val); out = _x } + ".option pop", + dst = in(reg) ptr_reg!($dst), + val = in(reg) $val, + out = lateout(reg) out, + options(nostack, preserves_flags), + ) + }; + } + match $order { + Ordering::Relaxed => op!(""), + Ordering::Acquire => op!(".aq"), + Ordering::Release => op!(".rl"), + // AcqRel and SeqCst RMWs are equivalent. + Ordering::AcqRel | Ordering::SeqCst => op!(".aqrl"), + _ => unreachable!(), + } + out + }}; + } + + #[cfg(not(any(target_feature = "zabha", portable_atomic_target_feature = "zabha")))] + items!({ + #[cfg(target_arch = "riscv32")] + macro_rules! w { + () => { + "" + }; + } + #[cfg(target_arch = "riscv64")] + macro_rules! w { + () => { + "w" + }; + } + + // 32-bit val.wrapping_shl(shift) but no extra `& (u32::BITS - 1)` + #[inline(always)] + fn sllw(val: u32, shift: u32) -> u32 { + // SAFETY: Calling sll{,w} is safe. + unsafe { + let out; + asm!( + concat!("sll", w!(), " {out}, {val}, {shift}"), // out = val << shift & 31 + out = lateout(reg) out, + val = in(reg) val, + shift = in(reg) shift, + options(pure, nomem, nostack, preserves_flags), + ); + out + } + } + // 32-bit val.wrapping_shr(shift) but no extra `& (u32::BITS - 1)` + macro_rules! srlw { + ($val:expr, $shift:expr) => { + // SAFETY: Calling srl{,w} is safe. + unsafe { + let val: u32 = $val; + let shift: u32 = $shift; + let out; + asm!( + concat!("srl", w!(), " {out}, {val}, {shift}"), // out = val >> shift & 31 + out = lateout(reg) out, + val = in(reg) val, + shift = in(reg) shift, + options(pure, nomem, nostack, preserves_flags), + ); + out + } + }; + } + + trait ZeroExtend: Copy { + /// Zero-extends `self` to `u32` if it is smaller than 32-bit. + fn zero_extend(self) -> u32; + } + macro_rules! zero_extend { + ($int:ident, $uint:ident) => { + impl ZeroExtend for $uint { + #[inline(always)] + fn zero_extend(self) -> u32 { + self as u32 + } + } + impl ZeroExtend for $int { + #[allow(clippy::cast_sign_loss)] + #[inline(always)] + fn zero_extend(self) -> u32 { + self as $uint as u32 + } + } + }; + } + zero_extend!(i8, u8); + zero_extend!(i16, u16); + }); +}); + +macro_rules! atomic_load_store { + ($([$($generics:tt)*])? $atomic_type:ident, $value_type:ty, $size:tt) => { + #[repr(transparent)] + pub(crate) struct $atomic_type $(<$($generics)*>)? { + v: UnsafeCell<$value_type>, + } + + // Send is implicitly implemented for atomic integers, but not for atomic pointers. + // SAFETY: any data races are prevented by atomic operations. + unsafe impl $(<$($generics)*>)? Send for $atomic_type $(<$($generics)*>)? {} + // SAFETY: any data races are prevented by atomic operations. + unsafe impl $(<$($generics)*>)? Sync for $atomic_type $(<$($generics)*>)? {} + + #[cfg(any(test, not(portable_atomic_unsafe_assume_single_core)))] + impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? { + #[inline] + pub(crate) const fn new(v: $value_type) -> Self { + Self { v: UnsafeCell::new(v) } + } + + #[inline] + pub(crate) fn is_lock_free() -> bool { + Self::IS_ALWAYS_LOCK_FREE + } + pub(crate) const IS_ALWAYS_LOCK_FREE: bool = true; + + #[inline] + pub(crate) const fn as_ptr(&self) -> *mut $value_type { + self.v.get() + } + } + impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? { + #[inline] + #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] + pub(crate) fn load(&self, order: Ordering) -> $value_type { + crate::utils::assert_load_ordering(order); + let src = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + let out; + macro_rules! atomic_load { + ($acquire:tt, $release:tt) => { + asm!( + $release, // fence + concat!("l", $size, " {out}, 0({src})"), // atomic { out = *src } + $acquire, // fence + src = in(reg) ptr_reg!(src), + out = lateout(reg) out, + options(nostack, preserves_flags), + ) + }; + } + match order { + Ordering::Relaxed => atomic_load!("", ""), + Ordering::Acquire => atomic_load!("fence r, rw", ""), + Ordering::SeqCst => atomic_load!("fence r, rw", "fence rw, rw"), + _ => unreachable!(), + } + out + } + } + + #[inline] + #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] + pub(crate) fn store(&self, val: $value_type, order: Ordering) { + crate::utils::assert_store_ordering(order); + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { + macro_rules! atomic_store { + ($acquire:tt, $release:tt) => { + asm!( + $release, // fence + concat!("s", $size, " {val}, 0({dst})"), // atomic { *dst = val } + $acquire, // fence + dst = in(reg) ptr_reg!(dst), + val = in(reg) val, + options(nostack, preserves_flags), + ) + }; + } + match order { + Ordering::Relaxed => atomic_store!("", ""), + Ordering::Release => atomic_store!("", "fence rw, w"), + // https://github.com/llvm/llvm-project/commit/3ea8f2526541884e03d5bd4f4e46f4eb190990b6 + Ordering::SeqCst => atomic_store!("fence rw, rw", "fence rw, w"), + _ => unreachable!(), + } + } + } + } + }; +} + +macro_rules! atomic_base { + ( + $([$($generics:tt)*])? $atomic_type:ident, $value_type:ty, $int_type:ty, $size:tt, + $fetch_add:ident, $fetch_sub:ident + ) => { + atomic_load_store!($([$($generics)*])? $atomic_type, $value_type, $size); + #[cfg(any( + test, + portable_atomic_force_amo, + target_feature = "zaamo", + portable_atomic_target_feature = "zaamo", + ))] + items!({ + // There is no amo{sub,nand,neg}. + impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? { + #[inline] + pub(crate) fn swap(&self, val: $value_type, order: Ordering) -> $value_type { + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { atomic_rmw_amo!(swap, dst, val, order, $size) } + } + #[inline] + pub(crate) fn $fetch_add(&self, val: $int_type, order: Ordering) -> $value_type { + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { atomic_rmw_amo!(add, dst, val, order, $size) } + } + #[inline] + pub(crate) fn $fetch_sub(&self, val: $int_type, order: Ordering) -> $value_type { + self.$fetch_add(val.wrapping_neg(), order) + } + #[inline] + pub(crate) fn fetch_and(&self, val: $int_type, order: Ordering) -> $value_type { + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { atomic_rmw_amo!(and, dst, val, order, $size) } + } + #[inline] + pub(crate) fn fetch_or(&self, val: $int_type, order: Ordering) -> $value_type { + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { atomic_rmw_amo!(or, dst, val, order, $size) } + } + #[inline] + pub(crate) fn fetch_xor(&self, val: $int_type, order: Ordering) -> $value_type { + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { atomic_rmw_amo!(xor, dst, val, order, $size) } + } + } + #[cfg(not(any(portable_atomic_unsafe_assume_single_core, feature = "critical-section")))] + impl_default_bit_opts!($atomic_type, $int_type); + }); + }; +} + +macro_rules! atomic_ptr { + ($size:tt) => { + atomic_base!([T] AtomicPtr, *mut T, usize, $size, fetch_byte_add, fetch_byte_sub); + }; +} + +macro_rules! atomic { + ($atomic_type:ident, $value_type:ty, $size:tt, $max:tt, $min:tt) => { + atomic_base!($atomic_type, $value_type, $value_type, $size, fetch_add, fetch_sub); + #[cfg(any( + test, + portable_atomic_force_amo, + target_feature = "zaamo", + portable_atomic_target_feature = "zaamo", + ))] + items!({ + // There is no amo{sub,nand,neg}. + impl $atomic_type { + #[inline] + pub(crate) fn fetch_not(&self, order: Ordering) -> $value_type { + let dst = self.v.get(); + let val: crate::utils::RegSize = !0; + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { atomic_rmw_amo!(xor, dst, val, order, $size) } + } + #[inline] + pub(crate) fn fetch_max(&self, val: $value_type, order: Ordering) -> $value_type { + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { atomic_rmw_amo!($max, dst, val, order, $size) } + } + #[inline] + pub(crate) fn fetch_min(&self, val: $value_type, order: Ordering) -> $value_type { + let dst = self.v.get(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + unsafe { atomic_rmw_amo!($min, dst, val, order, $size) } + } + } + #[cfg(not(any( + portable_atomic_unsafe_assume_single_core, + feature = "critical-section", + )))] + items!({ + impl_default_no_fetch_ops!($atomic_type, $value_type); + impl $atomic_type { + #[inline] + pub(crate) fn not(&self, order: Ordering) { + self.fetch_not(order); + } + } + }); + }); + }; +} + +macro_rules! atomic_sub_word { + ($atomic_type:ident, $value_type:ty, $size:tt, $max:tt, $min:tt) => { + cfg_sel!({ + #[cfg(any(target_feature = "zabha", portable_atomic_target_feature = "zabha"))] + { + atomic!($atomic_type, $value_type, $size, $max, $min); + } + #[cfg(else)] + { + atomic_load_store!($atomic_type, $value_type, $size); + #[cfg(any( + test, + portable_atomic_force_amo, + target_feature = "zaamo", + portable_atomic_target_feature = "zaamo", + ))] + items!({ + impl $atomic_type { + #[inline] + pub(crate) fn fetch_and( + &self, + val: $value_type, + order: Ordering, + ) -> $value_type { + let dst = self.v.get(); + let (dst, shift, mut mask) = + crate::utils::create_sub_word_mask_values(dst); + mask = !sllw(mask, shift); + let mut val = sllw(ZeroExtend::zero_extend(val), shift); + val |= mask; + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + let out: u32 = unsafe { atomic_rmw_amo!(and, dst, val, order, "w") }; + srlw!(out, shift) + } + #[inline] + pub(crate) fn fetch_or( + &self, + val: $value_type, + order: Ordering, + ) -> $value_type { + let dst = self.v.get(); + let (dst, shift, _mask) = + crate::utils::create_sub_word_mask_values(dst); + let val = sllw(ZeroExtend::zero_extend(val), shift); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + let out: u32 = unsafe { atomic_rmw_amo!(or, dst, val, order, "w") }; + srlw!(out, shift) + } + #[inline] + pub(crate) fn fetch_xor( + &self, + val: $value_type, + order: Ordering, + ) -> $value_type { + let dst = self.v.get(); + let (dst, shift, _mask) = + crate::utils::create_sub_word_mask_values(dst); + let val = sllw(ZeroExtend::zero_extend(val), shift); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + let out: u32 = unsafe { atomic_rmw_amo!(xor, dst, val, order, "w") }; + srlw!(out, shift) + } + #[inline] + pub(crate) fn fetch_not(&self, order: Ordering) -> $value_type { + self.fetch_xor(!0, order) + } + } + #[cfg(not(any( + portable_atomic_unsafe_assume_single_core, + feature = "critical-section", + )))] + items!({ + impl_default_bit_opts!($atomic_type, $value_type); + impl $atomic_type { + #[inline] + pub(crate) fn and(&self, val: $value_type, order: Ordering) { + self.fetch_and(val, order); + } + #[inline] + pub(crate) fn or(&self, val: $value_type, order: Ordering) { + self.fetch_or(val, order); + } + #[inline] + pub(crate) fn xor(&self, val: $value_type, order: Ordering) { + self.fetch_xor(val, order); + } + #[inline] + pub(crate) fn not(&self, order: Ordering) { + self.fetch_not(order); + } + } + }); + }); + } + }); + }; +} + +atomic_sub_word!(AtomicI8, i8, "b", max, min); +atomic_sub_word!(AtomicU8, u8, "b", maxu, minu); +atomic_sub_word!(AtomicI16, i16, "h", max, min); +atomic_sub_word!(AtomicU16, u16, "h", maxu, minu); +atomic!(AtomicI32, i32, "w", max, min); +atomic!(AtomicU32, u32, "w", maxu, minu); +#[cfg(target_arch = "riscv64")] +atomic!(AtomicI64, i64, "d", max, min); +#[cfg(target_arch = "riscv64")] +atomic!(AtomicU64, u64, "d", maxu, minu); +#[cfg(target_pointer_width = "32")] +atomic!(AtomicIsize, isize, "w", max, min); +#[cfg(target_pointer_width = "32")] +atomic!(AtomicUsize, usize, "w", maxu, minu); +#[cfg(target_pointer_width = "32")] +atomic_ptr!("w"); +#[cfg(target_pointer_width = "64")] +atomic!(AtomicIsize, isize, "d", max, min); +#[cfg(target_pointer_width = "64")] +atomic!(AtomicUsize, usize, "d", maxu, minu); +#[cfg(target_pointer_width = "64")] +atomic_ptr!("d"); + +#[cfg(test)] +mod tests { + use super::*; + + test_atomic_ptr_load_store!(); + test_atomic_int_load_store!(i8); + test_atomic_int_load_store!(u8); + test_atomic_int_load_store!(i16); + test_atomic_int_load_store!(u16); + test_atomic_int_load_store!(i32); + test_atomic_int_load_store!(u32); + #[cfg(target_arch = "riscv64")] + test_atomic_int_load_store!(i64); + #[cfg(target_arch = "riscv64")] + test_atomic_int_load_store!(u64); + test_atomic_int_load_store!(isize); + test_atomic_int_load_store!(usize); + + macro_rules! test_atomic_ptr_amo { + () => { + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + mod test_atomic_ptr_amo { + use super::*; + test_atomic_ptr_amo!(AtomicPtr); + } + }; + ($atomic_type:ty) => { + #[allow(unused_imports)] + use sptr::Strict as _; + + use crate::tests::helper; // for old rustc + + ::quickcheck::quickcheck! { + fn quickcheck_swap(x: usize, y: usize) -> bool { + let x = sptr::invalid_mut(x); + let y = sptr::invalid_mut(y); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.swap(y, order), x); + assert_eq!(a.swap(x, order), y); + } + true + } + fn quickcheck_fetch_byte_add(x: usize, y: usize) -> bool { + let x = sptr::invalid_mut(x); + let y = sptr::invalid_mut::(y); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_byte_add(y.addr(), order), x); + assert_eq!( + a.load(Ordering::Relaxed).addr(), x.addr().wrapping_add(y.addr()) + ); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_byte_add(x.addr(), order), y); + assert_eq!( + a.load(Ordering::Relaxed).addr(), y.addr().wrapping_add(x.addr()) + ); + } + true + } + fn quickcheck_fetch_byte_sub(x: usize, y: usize) -> bool { + let x = sptr::invalid_mut(x); + let y = sptr::invalid_mut::(y); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_byte_sub(y.addr(), order), x); + assert_eq!( + a.load(Ordering::Relaxed).addr(), x.addr().wrapping_sub(y.addr()) + ); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_byte_sub(x.addr(), order), y); + assert_eq!( + a.load(Ordering::Relaxed).addr(), y.addr().wrapping_sub(x.addr()) + ); + } + true + } + fn quickcheck_fetch_and(x: usize, y: usize) -> bool { + let x = sptr::invalid_mut(x); + let y = sptr::invalid_mut::(y); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_and(y.addr(), order), x); + assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() & y.addr()); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_and(x.addr(), order), y); + assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr() & x.addr()); + } + true + } + fn quickcheck_fetch_or(x: usize, y: usize) -> bool { + let x = sptr::invalid_mut(x); + let y = sptr::invalid_mut::(y); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_or(y.addr(), order), x); + assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() | y.addr()); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_or(x.addr(), order), y); + assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr() | x.addr()); + } + true + } + fn quickcheck_fetch_xor(x: usize, y: usize) -> bool { + let x = sptr::invalid_mut(x); + let y = sptr::invalid_mut::(y); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_xor(y.addr(), order), x); + assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() ^ y.addr()); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_xor(x.addr(), order), y); + assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr() ^ x.addr()); + } + true + } + } + }; + } + macro_rules! test_atomic_int_amo { + ($int_type:ident) => { + paste::paste! { + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + mod [] { + use super::*; + test_atomic_int_amo!([], $int_type); + } + } + }; + ($atomic_type:ty, $int_type:ident) => { + use crate::tests::helper; + ::quickcheck::quickcheck! { + fn quickcheck_swap(x: $int_type, y: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.swap(y, order), x); + assert_eq!(a.swap(x, order), y); + } + true + } + fn quickcheck_fetch_add(x: $int_type, y: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_add(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), x.wrapping_add(y)); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_add(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), y.wrapping_add(x)); + } + true + } + fn quickcheck_fetch_sub(x: $int_type, y: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_sub(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), x.wrapping_sub(y)); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_sub(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), y.wrapping_sub(x)); + } + true + } + fn quickcheck_fetch_and(x: $int_type, y: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_and(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), x & y); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_and(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), y & x); + } + true + } + fn quickcheck_fetch_or(x: $int_type, y: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_or(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), x | y); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_or(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), y | x); + } + true + } + fn quickcheck_fetch_xor(x: $int_type, y: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_xor(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), x ^ y); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_xor(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), y ^ x); + } + true + } + fn quickcheck_fetch_max(x: $int_type, y: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_max(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), core::cmp::max(x, y)); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_max(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), core::cmp::max(y, x)); + } + true + } + fn quickcheck_fetch_min(x: $int_type, y: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_min(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), core::cmp::min(x, y)); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_min(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), core::cmp::min(y, x)); + } + true + } + fn quickcheck_fetch_not(x: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_not(order), x); + assert_eq!(a.load(Ordering::Relaxed), !x); + assert_eq!(a.fetch_not(order), !x); + assert_eq!(a.load(Ordering::Relaxed), x); + } + true + } + } + }; + } + macro_rules! test_atomic_int_amo_sub_word { + ($int_type:ident) => { + paste::paste! { + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + mod [] { + use super::*; + #[cfg(any(target_feature = "zabha", portable_atomic_target_feature = "zabha"))] + test_atomic_int_amo!([], $int_type); + #[cfg(not(any(target_feature = "zabha", portable_atomic_target_feature = "zabha")))] + test_atomic_int_amo_sub_word!([], $int_type); + } + } + }; + ($atomic_type:ty, $int_type:ident) => { + use crate::tests::helper::{self, *}; + ::quickcheck::quickcheck! { + fn quickcheck_fetch_and(x: $int_type, y: $int_type) -> bool { + let mut rng = fastrand::Rng::new(); + for &order in &helper::SWAP_ORDERINGS { + for base in [0, !0] { + let mut arr = Align16([ + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + ]); + let a_idx = rng.usize(3..=6); + arr.0[a_idx] = <$atomic_type>::new(x); + let a = &arr.0[a_idx]; + assert_eq!(a.fetch_and(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), x & y); + for i in 0..a_idx { + assert_eq!(arr.0[i].load(Ordering::Relaxed), base, "invalid value written"); + } + for i in a_idx + 1..arr.0.len() { + assert_eq!(arr.0[i].load(Ordering::Relaxed), base, "invalid value written"); + } + arr.0[a_idx] = <$atomic_type>::new(y); + let a = &arr.0[a_idx]; + assert_eq!(a.fetch_and(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), y & x); + for i in 0..a_idx { + assert_eq!(arr.0[i].load(Ordering::Relaxed), base, "invalid value written"); + } + for i in a_idx + 1..arr.0.len() { + assert_eq!(arr.0[i].load(Ordering::Relaxed), base, "invalid value written"); + } + } + } + true + } + fn quickcheck_fetch_or(x: $int_type, y: $int_type) -> bool { + let mut rng = fastrand::Rng::new(); + for &order in &helper::SWAP_ORDERINGS { + for base in [0, !0] { + let mut arr = Align16([ + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + ]); + let a_idx = rng.usize(3..=6); + arr.0[a_idx] = <$atomic_type>::new(x); + let a = &arr.0[a_idx]; + assert_eq!(a.fetch_or(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), x | y); + for i in 0..a_idx { + assert_eq!(arr.0[i].load(Ordering::Relaxed), base, "invalid value written"); + } + for i in a_idx + 1..arr.0.len() { + assert_eq!(arr.0[i].load(Ordering::Relaxed), base, "invalid value written"); + } + arr.0[a_idx] = <$atomic_type>::new(y); + let a = &arr.0[a_idx]; + assert_eq!(a.fetch_or(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), y | x); + for i in 0..a_idx { + assert_eq!(arr.0[i].load(Ordering::Relaxed), base, "invalid value written"); + } + for i in a_idx + 1..arr.0.len() { + assert_eq!(arr.0[i].load(Ordering::Relaxed), base, "invalid value written"); + } + } + } + true + } + fn quickcheck_fetch_xor(x: $int_type, y: $int_type) -> bool { + let mut rng = fastrand::Rng::new(); + for &order in &helper::SWAP_ORDERINGS { + for base in [0, !0] { + let mut arr = Align16([ + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + ]); + let a_idx = rng.usize(3..=6); + arr.0[a_idx] = <$atomic_type>::new(x); + let a = &arr.0[a_idx]; + assert_eq!(a.fetch_xor(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), x ^ y); + for i in 0..a_idx { + assert_eq!(arr.0[i].load(Ordering::Relaxed), base, "invalid value written"); + } + for i in a_idx + 1..arr.0.len() { + assert_eq!(arr.0[i].load(Ordering::Relaxed), base, "invalid value written"); + } + arr.0[a_idx] = <$atomic_type>::new(y); + let a = &arr.0[a_idx]; + assert_eq!(a.fetch_xor(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), y ^ x); + for i in 0..a_idx { + assert_eq!(arr.0[i].load(Ordering::Relaxed), base, "invalid value written"); + } + for i in a_idx + 1..arr.0.len() { + assert_eq!(arr.0[i].load(Ordering::Relaxed), base, "invalid value written"); + } + } + } + true + } + fn quickcheck_fetch_not(x: $int_type) -> bool { + let mut rng = fastrand::Rng::new(); + for &order in &helper::SWAP_ORDERINGS { + for base in [0, !0] { + let mut arr = Align16([ + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + <$atomic_type>::new(base), + ]); + let a_idx = rng.usize(3..=6); + arr.0[a_idx] = <$atomic_type>::new(x); + let a = &arr.0[a_idx]; + assert_eq!(a.fetch_not(order), x); + assert_eq!(a.load(Ordering::Relaxed), !x); + assert_eq!(a.fetch_not(order), !x); + assert_eq!(a.load(Ordering::Relaxed), x); + for i in 0..a_idx { + assert_eq!(arr.0[i].load(Ordering::Relaxed), base, "invalid value written"); + } + for i in a_idx + 1..arr.0.len() { + assert_eq!(arr.0[i].load(Ordering::Relaxed), base, "invalid value written"); + } + } + } + true + } + } + }; + } + test_atomic_ptr_amo!(); + test_atomic_int_amo_sub_word!(i8); + test_atomic_int_amo_sub_word!(u8); + test_atomic_int_amo_sub_word!(i16); + test_atomic_int_amo_sub_word!(u16); + test_atomic_int_amo!(i32); + test_atomic_int_amo!(u32); + #[cfg(target_arch = "riscv64")] + test_atomic_int_amo!(i64); + #[cfg(target_arch = "riscv64")] + test_atomic_int_amo!(u64); + test_atomic_int_amo!(isize); + test_atomic_int_amo!(usize); +} diff --git a/vendor/portable-atomic/src/imp/x86.rs b/vendor/portable-atomic/src/imp/x86.rs new file mode 100644 index 0000000..dc0eaae --- /dev/null +++ b/vendor/portable-atomic/src/imp/x86.rs @@ -0,0 +1,283 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/* +Atomic operations implementation on x86/x86_64. + +This module provides atomic operations not supported by LLVM or optimizes +cases where LLVM code generation is not optimal. + +Note: On Miri and ThreadSanitizer which do not support inline assembly, we don't use +this module and use CAS loop instead. + +Refs: +- x86 and amd64 instruction reference https://www.felixcloutier.com/x86 + +See tests/asm-test/asm/portable-atomic for generated assembly. +*/ + +#[cfg(not(portable_atomic_no_asm))] +use core::arch::asm; +use core::sync::atomic::Ordering; + +#[cfg(target_pointer_width = "32")] +macro_rules! ptr_modifier { + () => { + ":e" + }; +} +#[cfg(target_pointer_width = "64")] +macro_rules! ptr_modifier { + () => { + "" + }; +} + +/// An atomic fence. +/// +/// # Panics +/// +/// Panics if `order` is [`Relaxed`](Ordering::Relaxed). +#[cfg_attr(doc, allow(dead_code))] +#[inline] +#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] +pub fn fence(order: Ordering) { + if order == Ordering::SeqCst { + let p = core::cell::UnsafeCell::new(core::mem::MaybeUninit::::uninit()); + // SAFETY: raw pointer passed in is valid because we got it from a reference. + unsafe { + // Equivalent to `mfence`, but is up to 3.1x faster on Coffee Lake and up to 2.4x faster on Raptor Lake-H at least in simple cases. + // - https://github.com/taiki-e/portable-atomic/pull/156 + // - LLVM uses `lock or` https://godbolt.org/z/vv6rjzfYd + // - Windows uses `xchg` for x86_32 for MemoryBarrier https://learn.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-memorybarrier + // - MSVC STL uses `lock inc` https://github.com/microsoft/STL/pull/740 + // - boost uses `lock or` https://github.com/boostorg/atomic/commit/559eba81af71386cedd99f170dc6101c6ad7bf22 + #[cfg(target_pointer_width = "64")] + asm!( + concat!("xchg qword ptr [{p", ptr_modifier!(), "}], {tmp}"), + p = in(reg) p.get(), + tmp = out(reg) _, + options(nostack, preserves_flags), + ); + #[cfg(target_pointer_width = "32")] + asm!( + concat!("xchg dword ptr [{p", ptr_modifier!(), "}], {tmp:e}"), + p = in(reg) p.get(), + tmp = out(reg) _, + options(nostack, preserves_flags), + ); + } + } else { + core::sync::atomic::fence(order); + } +} + +cfg_core_atomic!({ + use super::core_atomic::{ + AtomicI8, AtomicI16, AtomicI32, AtomicI64, AtomicIsize, AtomicPtr, AtomicU8, AtomicU16, + AtomicU32, AtomicU64, AtomicUsize, + }; + + macro_rules! atomic_int { + ($atomic_type:ident, $ptr_size:tt) => { + impl $atomic_type { + #[inline] + pub(crate) fn not(&self, _order: Ordering) { + let dst = self.as_ptr(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + // + // https://www.felixcloutier.com/x86/not + unsafe { + // atomic RMW is always SeqCst. + asm!( + concat!("lock not ", $ptr_size, " ptr [{dst", ptr_modifier!(), "}]"), + dst = in(reg) dst, + options(nostack, preserves_flags), + ); + } + } + #[inline] + pub(crate) fn neg(&self, _order: Ordering) { + let dst = self.as_ptr(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + // + // https://www.felixcloutier.com/x86/neg + unsafe { + // atomic RMW is always SeqCst. + asm!( + concat!("lock neg ", $ptr_size, " ptr [{dst", ptr_modifier!(), "}]"), + dst = in(reg) dst, + // Do not use `preserves_flags` because NEG modifies the CF, OF, SF, ZF, AF, and PF flag. + options(nostack), + ); + } + } + } + }; + } + + atomic_int!(AtomicI8, "byte"); + atomic_int!(AtomicU8, "byte"); + atomic_int!(AtomicI16, "word"); + atomic_int!(AtomicU16, "word"); + atomic_int!(AtomicI32, "dword"); + atomic_int!(AtomicU32, "dword"); + #[cfg(target_arch = "x86_64")] + atomic_int!(AtomicI64, "qword"); + #[cfg(target_arch = "x86_64")] + atomic_int!(AtomicU64, "qword"); + #[cfg(target_pointer_width = "32")] + atomic_int!(AtomicIsize, "dword"); + #[cfg(target_pointer_width = "32")] + atomic_int!(AtomicUsize, "dword"); + #[cfg(target_pointer_width = "64")] + atomic_int!(AtomicIsize, "qword"); + #[cfg(target_pointer_width = "64")] + atomic_int!(AtomicUsize, "qword"); + + #[cfg(target_arch = "x86")] + impl AtomicI64 { + #[inline] + pub(crate) fn not(&self, order: Ordering) { + self.fetch_not(order); + } + #[inline] + pub(crate) fn neg(&self, order: Ordering) { + self.fetch_neg(order); + } + } + #[cfg(target_arch = "x86")] + impl AtomicU64 { + #[inline] + pub(crate) fn not(&self, order: Ordering) { + self.fetch_not(order); + } + #[inline] + pub(crate) fn neg(&self, order: Ordering) { + self.fetch_neg(order); + } + } + + macro_rules! atomic_bit_opts { + ( + $([$($generics:tt)*])? $atomic_type:ident, $int_type:ident, $val_modifier:tt, + $ptr_size:tt + ) => { + // LLVM 14 and older don't support generating `lock bt{s,r,c}`. + // LLVM 15 only supports generating `lock bt{s,r,c}` for immediate bit offsets. + // LLVM 16+ can generate `lock bt{s,r,c}` for both immediate and register bit offsets. + // https://godbolt.org/z/TGhr5z4ds + // So, use fetch_* based implementations on LLVM 16+, otherwise use asm based implementations. + #[cfg(not(portable_atomic_pre_llvm_16))] + impl_default_bit_opts!($atomic_type, $int_type); + #[cfg(portable_atomic_pre_llvm_16)] + impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? { + // `::BITS` requires Rust 1.53 + const BITS: u32 = (core::mem::size_of::<$int_type>() * 8) as u32; + #[inline] + pub(crate) fn bit_set(&self, bit: u32, _order: Ordering) -> bool { + let dst = self.as_ptr(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + // the masking by the bit size of the type ensures that we do not shift + // out of bounds. + // + // https://www.felixcloutier.com/x86/bts + unsafe { + let r: u8; + // atomic RMW is always SeqCst. + asm!( + concat!("lock bts ", $ptr_size, " ptr [{dst", ptr_modifier!(), "}], {bit", $val_modifier, "}"), + "setb {r}", + dst = in(reg) dst, + bit = in(reg) (bit & (Self::BITS - 1)) as $int_type, + r = out(reg_byte) r, + // Do not use `preserves_flags` because BTS modifies the CF flag. + options(nostack), + ); + crate::utils::assert_unchecked(r == 0 || r == 1); // may help remove extra test + r != 0 + } + } + #[inline] + pub(crate) fn bit_clear(&self, bit: u32, _order: Ordering) -> bool { + let dst = self.as_ptr(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + // the masking by the bit size of the type ensures that we do not shift + // out of bounds. + // + // https://www.felixcloutier.com/x86/btr + unsafe { + let r: u8; + // atomic RMW is always SeqCst. + asm!( + concat!("lock btr ", $ptr_size, " ptr [{dst", ptr_modifier!(), "}], {bit", $val_modifier, "}"), + "setb {r}", + dst = in(reg) dst, + bit = in(reg) (bit & (Self::BITS - 1)) as $int_type, + r = out(reg_byte) r, + // Do not use `preserves_flags` because BTR modifies the CF flag. + options(nostack), + ); + crate::utils::assert_unchecked(r == 0 || r == 1); // may help remove extra test + r != 0 + } + } + #[inline] + pub(crate) fn bit_toggle(&self, bit: u32, _order: Ordering) -> bool { + let dst = self.as_ptr(); + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. + // the masking by the bit size of the type ensures that we do not shift + // out of bounds. + // + // https://www.felixcloutier.com/x86/btc + unsafe { + let r: u8; + // atomic RMW is always SeqCst. + asm!( + concat!("lock btc ", $ptr_size, " ptr [{dst", ptr_modifier!(), "}], {bit", $val_modifier, "}"), + "setb {r}", + dst = in(reg) dst, + bit = in(reg) (bit & (Self::BITS - 1)) as $int_type, + r = out(reg_byte) r, + // Do not use `preserves_flags` because BTC modifies the CF flag. + options(nostack), + ); + crate::utils::assert_unchecked(r == 0 || r == 1); // may help remove extra test + r != 0 + } + } + } + }; + } + + impl_default_bit_opts!(AtomicI8, i8); + impl_default_bit_opts!(AtomicU8, u8); + atomic_bit_opts!(AtomicI16, i16, ":x", "word"); + atomic_bit_opts!(AtomicU16, u16, ":x", "word"); + atomic_bit_opts!(AtomicI32, i32, ":e", "dword"); + atomic_bit_opts!(AtomicU32, u32, ":e", "dword"); + #[cfg(target_arch = "x86_64")] + atomic_bit_opts!(AtomicI64, i64, "", "qword"); + #[cfg(target_arch = "x86_64")] + atomic_bit_opts!(AtomicU64, u64, "", "qword"); + #[cfg(target_arch = "x86")] + impl_default_bit_opts!(AtomicI64, i64); + #[cfg(target_arch = "x86")] + impl_default_bit_opts!(AtomicU64, u64); + #[cfg(target_pointer_width = "32")] + atomic_bit_opts!(AtomicIsize, isize, ":e", "dword"); + #[cfg(target_pointer_width = "32")] + atomic_bit_opts!(AtomicUsize, usize, ":e", "dword"); + #[cfg(target_pointer_width = "32")] + atomic_bit_opts!([T] AtomicPtr, usize, ":e", "dword"); + #[cfg(target_pointer_width = "64")] + atomic_bit_opts!(AtomicIsize, isize, "", "qword"); + #[cfg(target_pointer_width = "64")] + atomic_bit_opts!(AtomicUsize, usize, "", "qword"); + #[cfg(target_pointer_width = "64")] + atomic_bit_opts!([T] AtomicPtr, usize, "", "qword"); +}); diff --git a/vendor/portable-atomic/src/lib.rs b/vendor/portable-atomic/src/lib.rs new file mode 100644 index 0000000..57e8bc3 --- /dev/null +++ b/vendor/portable-atomic/src/lib.rs @@ -0,0 +1,5224 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/*! + + + +Portable atomic types including support for 128-bit atomics, atomic float, etc. + +- Provide all atomic integer types (`Atomic{I,U}{8,16,32,64}`) for all targets that can use atomic CAS. (i.e., all targets that can use `std`, and most no-std targets) +- Provide `AtomicI128` and `AtomicU128`. +- Provide `AtomicF32` and `AtomicF64`. ([optional, requires the `float` feature](#optional-features-float)) +- Provide `AtomicF16` and `AtomicF128` for [unstable `f16` and `f128`](https://github.com/rust-lang/rust/issues/116909). ([optional, requires the `float` feature and unstable cfgs](#optional-features-float)) +- Provide atomic load/store for targets where atomic is not available at all in the standard library. (RISC-V without A-extension, MSP430, AVR) +- Provide atomic CAS for targets where atomic CAS is not available in the standard library. (thumbv6m, pre-v6 Arm, RISC-V without A-extension, MSP430, AVR, Xtensa, etc.) (always enabled for MSP430 and AVR, [optional](#optional-features-critical-section) otherwise) +- Make features that require newer compilers, such as [`fetch_{max,min}`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.fetch_max), [`fetch_update`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.fetch_update), [`as_ptr`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.as_ptr), [`from_ptr`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.from_ptr), [`AtomicBool::fetch_not`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicBool.html#method.fetch_not), [`AtomicPtr::fetch_*`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicPtr.html#method.fetch_and), and [stronger CAS failure ordering](https://github.com/rust-lang/rust/pull/98383) available on Rust 1.34+. +- Provide workaround for bugs in the standard library's atomic-related APIs, such as [rust-lang/compiler-builtins#1234], [rust-lang/rust#100650], `fence`/`compiler_fence` on MSP430 that cause LLVM error, etc. + + + +portable-atomic version of `std::sync::Arc` and `std::task::Wake` is provided by the [portable-atomic-util] crate. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +portable-atomic = "1" +``` + +The default features are mainly for users who use atomics larger than the pointer width. +If you don't need them, disabling the default features may reduce code size and compile time slightly. + +```toml +[dependencies] +portable-atomic = { version = "1", default-features = false } +``` + +If your crate supports no-std environment and requires atomic CAS, enabling the `require-cas` feature will allow the portable-atomic to display a [helpful error message](https://github.com/taiki-e/portable-atomic/pull/100) to users on targets requiring additional action on the user side to provide atomic CAS. + +```toml +[dependencies] +portable-atomic = { version = "1.3", default-features = false, features = ["require-cas"] } +``` + +(Since 1.8, portable-atomic can display a [helpful error message](https://github.com/taiki-e/portable-atomic/pull/181) even without the `require-cas` feature when the rustc version is 1.78+. However, the `require-cas` feature also allows rejecting builds at an earlier stage, we recommend enabling it unless enabling it causes [problems](https://github.com/matklad/once_cell/pull/267).) + +## 128-bit atomics support + +Native 128-bit atomic operations are available on x86_64 (Rust 1.59+), AArch64 (Rust 1.59+), riscv64 (Rust 1.59+), Arm64EC (Rust 1.84+), s390x (Rust 1.84+), and powerpc64 (Rust 1.95+), otherwise the fallback implementation is used. + +On x86_64, even if `cmpxchg16b` is not available at compile-time (Note: `cmpxchg16b` target feature is enabled by default only on Apple, Windows (except Windows 7), and Fuchsia targets), run-time detection checks whether `cmpxchg16b` is available. If `cmpxchg16b` is not available at either compile-time or run-time detection, the fallback implementation is used. See also [`portable_atomic_no_outline_atomics`](#optional-cfg-no-outline-atomics) cfg. + +They are usually implemented using inline assembly, and when using Miri or ThreadSanitizer that do not support inline assembly, core intrinsics are used instead of inline assembly if possible. + +See the [`atomic128` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/atomic128/README.md) for details. + +## Optional features/cfgs + +portable-atomic provides features and cfgs to allow enabling specific APIs and customizing its behavior. + +Some options have both a feature and a cfg. When both exist, it indicates that the feature does not follow Cargo's recommendation that [features should be additive](https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-unification). Therefore, the maintainer's recommendation is to use cfg instead of feature. However, in the embedded ecosystem, it is very common to use features in such places, so these options provide both so you can choose based on your preference. + +
+How to enable cfg (click to show) + +One of the ways to enable cfg is to set [rustflags in the cargo config](https://doc.rust-lang.org/cargo/reference/config.html#targettriplerustflags): + +```toml +# .cargo/config.toml +[target.] +rustflags = ["--cfg", "portable_atomic_unsafe_assume_single_core"] +``` + +Or set environment variable: + +```sh +RUSTFLAGS="--cfg portable_atomic_unsafe_assume_single_core" cargo ... +``` + +
+ +- **`fallback` feature** *(enabled by default)*
+ Enable fallback implementations. + + This enables atomic types with larger than the width supported by atomic instructions available on the current target. If the current target [supports 128-bit atomics](#128-bit-atomics-support), this is no-op. + + This uses fallback implementation that using global locks by default. The following features/cfgs change this behavior: + - [`unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg](#optional-features-unsafe-assume-single-core): Use fallback implementations that disabling interrupts instead of using global locks. + - If your target is single-core and calling interrupt disable instructions is safe, this is a safer and more efficient option. + - [`unsafe-assume-privileged` feature / `portable_atomic_unsafe_assume_privileged` cfg](#optional-features-unsafe-assume-privileged): Use fallback implementations that using global locks with disabling interrupts. + - If your target is multi-core and calling interrupt disable instructions is safe, this is a safer option. + +- **`float` feature**
+ Provide `AtomicF{32,64}`. + + If you want atomic types for unstable float types ([`f16` and `f128`](https://github.com/rust-lang/rust/issues/116909)), enable unstable cfg (`portable_atomic_unstable_f16` cfg for `AtomicF16`, `portable_atomic_unstable_f128` cfg for `AtomicF128`, [there is no possibility that both feature and cfg will be provided for unstable options.](https://github.com/taiki-e/portable-atomic/pull/200#issuecomment-2682252991)). + +
+ +> **ⓘ Note** +> +> - Atomic float's `fetch_{add,sub,min,max}` are usually implemented using CAS loops, which can be slower than equivalent operations of atomic integers. As an exception, AArch64 with FEAT_LSFE and GPU targets have atomic float instructions and we use them on AArch64 when `lsfe` target feature is available at compile-time. We [plan to use atomic float instructions for GPU targets as well in the future.](https://github.com/taiki-e/portable-atomic/issues/34) +> - Unstable cfgs are outside of the normal semver guarantees and minor or patch versions of portable-atomic may make breaking changes to them at any time. + +
+ +- **`std` feature**
+ Use `std`. + +- **`require-cas` feature**
+ Emit compile error if atomic CAS is not available. See [Usage](#usage) section for usage of this feature. + +- **`serde` feature**
+ Implement `serde::{Serialize,Deserialize}` for atomic types. + + Note: + - The MSRV when this feature is enabled depends on the MSRV of [serde]. + +- **`critical-section` feature**
+ Use [critical-section] to provide atomic CAS for targets where atomic CAS is not available in the standard library. + + `critical-section` support is useful to get atomic CAS when the [`unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)](#optional-features-unsafe-assume-single-core) can't be used, + such as multi-core targets, unprivileged code running under some RTOS, or environments where disabling interrupts + needs extra care due to e.g. real-time requirements. + +
+ +> **ⓘ Note** +> +> - When enabling this feature, you should provide a suitable critical section implementation for the current target, see the [critical-section] documentation for details on how to do so. +> - With this feature, critical sections are taken for all atomic operations, while with `unsafe-assume-single-core` feature [some operations](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/interrupt/README.md#no-disable-interrupts) don't require disabling interrupts. Therefore, for better performance, if all the `critical-section` implementation for your target does is disable interrupts, prefer using `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg) instead. +> - It is usually **discouraged** to always enable this feature in libraries that depend on `portable-atomic`. +> +> Enabling this feature will prevent the end user from having the chance to take advantage of other (potentially) efficient implementations (implementations provided by `unsafe-assume-single-core` feature mentioned above, implementation proposed in [#60], etc.). Also, targets that are currently unsupported may be supported in the future. +> +> The recommended approach for libraries is to leave it up to the end user whether or not to enable this feature. (However, it may make sense to enable this feature by default for libraries specific to a platform where other implementations are known not to work.) +> +> See also [this comment](https://github.com/matklad/once_cell/issues/264#issuecomment-2352654806). +> +> As an example, the end-user's `Cargo.toml` that uses a crate that provides a critical-section implementation and a crate that depends on portable-atomic as an option would be expected to look like this: +> +> ```toml +> [dependencies] +> portable-atomic = { version = "1", default-features = false, features = ["critical-section"] } +> crate-provides-critical-section-impl = "..." +> crate-uses-portable-atomic-as-feature = { version = "...", features = ["portable-atomic"] } +> ``` +> +> - Enabling both this feature and `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg) will result in a compile error. +> - Enabling both this feature and `unsafe-assume-privileged` feature (or `portable_atomic_unsafe_assume_privileged` cfg) will result in a compile error. +> - The MSRV when this feature is enabled depends on the MSRV of [critical-section]. + +
+ +- **`unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg**
+ Assume that the target is single-core and privileged instructions required to disable interrupts are available. + + - When this feature/cfg is enabled, this crate provides atomic CAS for targets where atomic CAS is not available in the standard library by disabling interrupts. + - When both this feature/cfg and enabled-by-default `fallback` feature is enabled, this crate provides atomic types with larger than the width supported by native instructions by disabling interrupts. + +
+ +> **⚠ Warning** +> +> This feature/cfg is `unsafe`, and note the following safety requirements: +> - Enabling this feature/cfg for multi-core systems is always **unsound**. +> +> - This uses privileged instructions to disable interrupts, so it usually doesn't work on unprivileged mode. +> +> Enabling this feature/cfg in an environment where privileged instructions are not available, or if the instructions used are not sufficient to disable interrupts in the system, it is also usually considered **unsound**, although the details are system-dependent. +> +> The following are known cases: +> - On Arm (except for M-Profile architectures), this disables only IRQs by default. For many systems (e.g., GBA) this is enough. If the system need to disable both IRQs and FIQs, you need to enable the `disable-fiq` feature (or `portable_atomic_disable_fiq` cfg) together. +> - On RISC-V, this generates code for machine-mode (M-mode) by default. If you enable the `s-mode` feature (or `portable_atomic_s_mode` cfg) together, this generates code for supervisor-mode (S-mode). In particular, `qemu-system-riscv*` uses [OpenSBI](https://github.com/riscv-software-src/opensbi) as the default firmware. + +
+ +Consider using the [`unsafe-assume-privileged` feature (or `portable_atomic_unsafe_assume_privileged` cfg)](#optional-features-unsafe-assume-privileged) for multi-core systems with atomic CAS. + +Consider using the [`critical-section` feature](#optional-features-critical-section) for systems that cannot use this feature/cfg. + +See also the [`interrupt` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/interrupt/README.md). + +
+ +> **ⓘ Note** +> +> - It is **very strongly discouraged** to enable this feature/cfg in libraries that depend on `portable-atomic`. +> +> The recommended approach for libraries is to leave it up to the end user whether or not to enable this feature/cfg. (However, it may make sense to enable this feature/cfg by default for libraries specific to a platform where it is guaranteed to always be sound, for example in a hardware abstraction layer targeting a single-core chip.) +> - Enabling this feature/cfg for unsupported architectures will result in a compile error. +> - Arm, RISC-V, and Xtensa are currently supported. (Since all MSP430 and AVR are single-core, we always provide atomic CAS for them without this feature/cfg.) +> - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target is not supported yet. +> - Enabling this feature/cfg for targets where privileged instructions are obviously unavailable (e.g., Linux) will result in a compile error. +> - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target supports privileged instructions but the build rejected. +> - Enabling both this feature/cfg and `critical-section` feature will result in a compile error. +> - When both this feature/cfg and `unsafe-assume-privileged` feature (or `portable_atomic_unsafe_assume_privileged` cfg) are enabled, this feature/cfg is preferred. + +
+ +- **`unsafe-assume-privileged` feature / `portable_atomic_unsafe_assume_privileged` cfg**
+ Similar to `unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg, but only assumes about availability of privileged instructions required to disable interrupts. + + - When both this feature/cfg and enabled-by-default `fallback` feature is enabled, this crate provides atomic types with larger than the width supported by native instructions by using global locks with disabling interrupts. + +
+ +> **⚠ Warning** +> +> This feature/cfg is `unsafe`, and except for being sound in multi-core systems, this has the same safety requirements as [`unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg](#optional-features-unsafe-assume-single-core). + +
+ +
+ +> **ⓘ Note** +> +> - It is **very strongly discouraged** to enable this feature/cfg in libraries that depend on `portable-atomic`. +> +> The recommended approach for libraries is to leave it up to the end user whether or not to enable this feature/cfg. (However, it may make sense to enable this feature/cfg by default for libraries specific to a platform where it is guaranteed to always be sound, for example in a hardware abstraction layer.) +> - Enabling this feature/cfg for unsupported targets will result in a compile error. +> - This requires atomic CAS (`cfg(target_has_atomic = "ptr")` or `cfg_no_atomic_cas!`). +> - Arm, RISC-V, and Xtensa are currently supported. +> - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target is not supported yet. +> - Enabling this feature/cfg for targets where privileged instructions are obviously unavailable (e.g., Linux) will result in a compile error. +> - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target supports privileged instructions but the build rejected. +> - Enabling both this feature/cfg and `critical-section` feature will result in a compile error. +> - When both this feature/cfg and `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg) are enabled, `unsafe-assume-single-core` is preferred. + +
+ +- **`portable_atomic_no_outline_atomics` cfg**
+ Disable dynamic dispatching by run-time CPU feature detection. + + Dynamic dispatching by run-time CPU feature detection allows maintaining support for older CPUs while using features that are not supported on older CPUs, such as CMPXCHG16B (x86_64) and FEAT_LSE/FEAT_LSE2 (AArch64). + + See also the [`atomic128` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/atomic128/README.md). + +
+ +> **ⓘ Note** +> +> - If the required target features are enabled at compile-time, dynamic dispatching is automatically disabled and the atomic operations are inlined. +> - This is compatible with no-std (as with all features except `std`). +> - On some targets, run-time detection is disabled by default mainly for compatibility with incomplete build environments or support for it is experimental, and can be enabled by `portable_atomic_outline_atomics` cfg. (When both cfg are enabled, `*_no_*` cfg is preferred.) +> - Some AArch64 targets enable LLVM's `outline-atomics` target feature by default, so if you set this cfg, you may want to disable that as well. (However, portable-atomic's outline-atomics does not depend on the compiler-rt symbols, so even if you need to disable LLVM's outline-atomics, you may not need to disable portable-atomic's outline-atomics.) +> - Dynamic detection is currently only supported in x86_64, AArch64, Arm, RISC-V, Arm64EC, and powerpc64. Enabling this cfg for unsupported architectures will be ignored. + +
+ +## Related Projects + +- [portable-atomic-util]: Synchronization primitives built with portable-atomic. This provides portable-atomic version of `std::sync::Arc` and `std::task::Wake`. +- [atomic-maybe-uninit]: Atomic operations on potentially uninitialized integers. +- [atomic-memcpy]: Byte-wise atomic memcpy. +- [asmtest]: A library for tracking generated assemblies. + +[#60]: https://github.com/taiki-e/portable-atomic/issues/60 +[asmtest]: https://github.com/taiki-e/asmtest +[atomic-maybe-uninit]: https://github.com/taiki-e/atomic-maybe-uninit +[atomic-memcpy]: https://github.com/taiki-e/atomic-memcpy +[critical-section]: https://github.com/rust-embedded/critical-section +[portable-atomic-util]: https://github.com/taiki-e/portable-atomic-util +[rust-lang/compiler-builtins#1234]: https://github.com/rust-lang/compiler-builtins/pull/1234 +[rust-lang/rust#100650]: https://github.com/rust-lang/rust/issues/100650 +[serde]: https://github.com/serde-rs/serde + + +*/ + +#![no_std] +#![doc(test( + no_crate_inject, + attr( + deny(warnings, rust_2018_idioms, single_use_lifetimes), + allow(dead_code, unused_variables) + ) +))] +#![cfg_attr(not(portable_atomic_no_unsafe_op_in_unsafe_fn), warn(unsafe_op_in_unsafe_fn))] // unsafe_op_in_unsafe_fn requires Rust 1.52 +#![cfg_attr(portable_atomic_no_unsafe_op_in_unsafe_fn, allow(unused_unsafe))] +#![warn( + // Lints that may help when writing public library. + missing_debug_implementations, + // missing_docs, + clippy::alloc_instead_of_core, + clippy::exhaustive_enums, + clippy::exhaustive_structs, + clippy::impl_trait_in_params, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::missing_inline_in_public_items, + // Code outside of cfg(feature = "float") shouldn't use float. + clippy::float_arithmetic, +)] +#![cfg_attr(not(portable_atomic_no_asm), warn(missing_docs))] // module-level #![allow(missing_docs)] doesn't work for macros on old rustc +#![cfg_attr(portable_atomic_no_strict_provenance, allow(unstable_name_collisions))] +#![allow( + clippy::inline_always, + clippy::manual_assert_eq, + clippy::unreadable_literal, + clippy::used_underscore_items +)] +// asm_experimental_arch +// AVR, MSP430, and Xtensa are tier 3 platforms and require nightly anyway. +// On tier 2 platforms (currently N/A), we use cfg set by build script to +// determine whether this feature is available or not. +#![cfg_attr( + all( + not(portable_atomic_no_asm), + any( + all(target_arch = "avr", not(feature = "critical-section")), + target_arch = "msp430", + all( + target_arch = "xtensa", + any( + portable_atomic_unsafe_assume_single_core, + portable_atomic_unsafe_assume_privileged, + ), + ), + ), + ), + feature(asm_experimental_arch) +)] +// f16/f128 +// cfg is unstable and explicitly enabled by the user +#![cfg_attr( + any(portable_atomic_unstable_f16, portable_atomic_unstable_f128), + allow(unused_features) +)] +#![cfg_attr(all(portable_atomic_unstable_f16, feature = "float"), feature(f16))] +#![cfg_attr(all(portable_atomic_unstable_f128, feature = "float"), feature(f128))] +// Old nightly only +// These features are already stabilized or have already been removed from compilers, +// and can safely be enabled for old nightly as long as version detection works. +// - cfg(target_has_atomic) +// - asm! on AArch64, Arm, RISC-V, x86, x86_64, Arm64EC, s390x, PowerPC64 +// - llvm_asm! on AVR (tier 3) and MSP430 (tier 3) +// - #[instruction_set] on non-Linux/Android pre-v6 Arm (tier 3) +// This also helps us test that our assembly code works with the minimum external +// LLVM version of the first rustc version that inline assembly stabilized. +#![cfg_attr(portable_atomic_unstable_cfg_target_has_atomic, feature(cfg_target_has_atomic))] +#![cfg_attr( + all( + portable_atomic_unstable_asm, + any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "x86", + target_arch = "x86_64", + ), + ), + feature(asm) +)] +#![cfg_attr( + all( + portable_atomic_unstable_asm_experimental_arch, + any(target_arch = "arm64ec", target_arch = "s390x", target_arch = "powerpc64"), + ), + feature(asm_experimental_arch) +)] +#![cfg_attr( + all(any(target_arch = "avr", target_arch = "msp430"), portable_atomic_no_asm), + feature(llvm_asm) +)] +#![cfg_attr( + all( + target_arch = "arm", + portable_atomic_unstable_isa_attribute, + any(portable_atomic_unsafe_assume_single_core, portable_atomic_unsafe_assume_privileged), + not(any(target_feature = "v7", portable_atomic_target_feature = "v7")), + not(any(target_feature = "mclass", portable_atomic_target_feature = "mclass")), + ), + feature(isa_attribute) +)] +// Miri and/or ThreadSanitizer only +// They do not support inline assembly, so we need to use unstable features instead. +// Since they require nightly compilers anyway, we can use the unstable features. +// This is not an ideal situation, but it is still better than always using lock-based +// fallback and causing memory ordering problems to be missed by these checkers. +#![cfg_attr( + all( + any( + target_arch = "aarch64", + target_arch = "arm64ec", + target_arch = "powerpc64", + target_arch = "s390x", + ), + any(miri, portable_atomic_sanitize_thread), + ), + allow(internal_features) +)] +#![cfg_attr( + all( + any( + target_arch = "aarch64", + target_arch = "arm64ec", + target_arch = "powerpc64", + target_arch = "s390x", + ), + portable_atomic_atomic_intrinsics, + any(miri, portable_atomic_sanitize_thread), + ), + feature(core_intrinsics) +)] +// docs.rs only (cfg is enabled by docs.rs, not build script) +#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, doc(auto_cfg = false))] +#![cfg_attr( + all( + portable_atomic_no_atomic_load_store, + not(any( + target_arch = "avr", + target_arch = "bpf", + target_arch = "msp430", + target_arch = "riscv32", + target_arch = "riscv64", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + )), + ), + allow(unused_imports, unused_macros, clippy::unused_trait_names) +)] + +#[cfg(any(test, feature = "std"))] +extern crate std; + +#[macro_use] +mod cfgs; +#[cfg(target_pointer_width = "16")] +pub use self::{cfg_has_atomic_16 as cfg_has_atomic_ptr, cfg_no_atomic_16 as cfg_no_atomic_ptr}; +#[cfg(target_pointer_width = "32")] +pub use self::{cfg_has_atomic_32 as cfg_has_atomic_ptr, cfg_no_atomic_32 as cfg_no_atomic_ptr}; +#[cfg(target_pointer_width = "64")] +pub use self::{cfg_has_atomic_64 as cfg_has_atomic_ptr, cfg_no_atomic_64 as cfg_no_atomic_ptr}; +#[cfg(target_pointer_width = "128")] +pub use self::{cfg_has_atomic_128 as cfg_has_atomic_ptr, cfg_no_atomic_128 as cfg_no_atomic_ptr}; + +// There are currently no 128-bit or higher builtin targets. +// (Although some of our generic code is written with the future +// addition of 128-bit targets in mind.) +// Note that Rust (and C99) pointers must be at least 16-bit (i.e., 8-bit targets are impossible): https://github.com/rust-lang/rust/pull/49305 +#[cfg(not(any( + target_pointer_width = "16", + target_pointer_width = "32", + target_pointer_width = "64", +)))] +compile_error!( + "portable-atomic currently only supports targets with {16,32,64}-bit pointer width; \ + if you need support for others, \ + please submit an issue at " +); + +// Reject unsupported architectures. +#[cfg(portable_atomic_unsafe_assume_single_core)] +#[cfg(not(any( + target_arch = "arm", + target_arch = "avr", + target_arch = "msp430", + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "xtensa", +)))] +compile_error!( + "`portable_atomic_unsafe_assume_single_core` cfg (`unsafe-assume-single-core` feature) \ + is not supported yet on this architecture;\n\ + if you need unsafe-assume-{single-core,privileged} support for this target,\n\ + please submit an issue at " +); +// unsafe-assume-single-core is accepted on AVR/MSP430, but +// unsafe-assume-privileged on them is really useless on them since they are +// always single-core, so rejected here. +#[cfg(portable_atomic_unsafe_assume_privileged)] +#[cfg(not(any( + target_arch = "arm", + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "xtensa", +)))] +compile_error!( + "`portable_atomic_unsafe_assume_privileged` cfg (`unsafe-assume-privileged` feature) \ + is not supported yet on this architecture;\n\ + if you need unsafe-assume-{single-core,privileged} support for this target,\n\ + please submit an issue at " +); +// unsafe-assume-privileged requires CAS. +#[cfg(portable_atomic_unsafe_assume_privileged)] +cfg_no_atomic_cas! { + compile_error!( + "`portable_atomic_unsafe_assume_privileged` cfg (`unsafe-assume-privileged` feature) \ + requires atomic CAS" + ); +} +// Reject targets where privileged instructions are obviously unavailable. +// TODO: Some embedded OSes should probably be accepted here. +#[cfg(any(portable_atomic_unsafe_assume_single_core, portable_atomic_unsafe_assume_privileged))] +#[cfg(any( + target_arch = "arm", + target_arch = "avr", + target_arch = "msp430", + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "xtensa", +))] +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(all(not(portable_atomic_no_atomic_cas), not(target_os = "none"))) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(all(target_has_atomic = "ptr", not(target_os = "none"))) +)] +compile_error!( + "`portable_atomic_unsafe_assume_{single_core,privileged}` cfg (`unsafe-assume-{single-core,privileged}` feature) \ + is not compatible with target where privileged instructions are obviously unavailable;\n\ + if you need unsafe-assume-{single-core,privileged} support for this target,\n\ + please submit an issue at \n\ + see also for troubleshooting" +); + +#[cfg(portable_atomic_outline_atomics)] +#[cfg(not(any( + target_arch = "aarch64", + target_arch = "powerpc64", + target_arch = "riscv32", + target_arch = "riscv64", +)))] +compile_error!("`portable_atomic_outline_atomics` cfg does not compatible with this target"); + +#[cfg(portable_atomic_disable_fiq)] +#[cfg(not(all( + target_arch = "arm", + not(any(target_feature = "mclass", portable_atomic_target_feature = "mclass")), +)))] +compile_error!( + "`portable_atomic_disable_fiq` cfg (`disable-fiq` feature) is only available on Arm (except for M-Profile architectures)" +); +#[cfg(portable_atomic_s_mode)] +#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] +compile_error!("`portable_atomic_s_mode` cfg (`s-mode` feature) is only available on RISC-V"); +#[cfg(portable_atomic_force_amo)] +#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] +compile_error!("`portable_atomic_force_amo` cfg (`force-amo` feature) is only available on RISC-V"); + +#[cfg(portable_atomic_disable_fiq)] +#[cfg(not(any( + portable_atomic_unsafe_assume_single_core, + portable_atomic_unsafe_assume_privileged, +)))] +compile_error!( + "`portable_atomic_disable_fiq` cfg (`disable-fiq` feature) may only be used together with `portable_atomic_unsafe_assume_{single_core,privileged}` cfg (`unsafe-assume-{single-core,privileged}` feature)" +); +#[cfg(portable_atomic_s_mode)] +#[cfg(not(any( + portable_atomic_unsafe_assume_single_core, + portable_atomic_unsafe_assume_privileged, +)))] +compile_error!( + "`portable_atomic_s_mode` cfg (`s-mode` feature) may only be used together with `portable_atomic_unsafe_assume_{single_core,privileged}` cfg (`unsafe-assume-{single-core,privileged}` feature)" +); +#[cfg(portable_atomic_force_amo)] +#[cfg(not(portable_atomic_unsafe_assume_single_core))] +compile_error!( + "`portable_atomic_force_amo` cfg (`force-amo` feature) may only be used together with `portable_atomic_unsafe_assume_single_core` cfg (`unsafe-assume-single-core` feature)" +); +#[cfg(portable_atomic_unsafe_assume_privileged)] +#[cfg(not(feature = "fallback"))] +compile_error!( + "`portable_atomic_unsafe_assume_privileged` cfg (`unsafe-assume-privileged` feature) may only be used together with `fallback` feature" +); + +#[cfg(all( + any(portable_atomic_unsafe_assume_single_core, portable_atomic_unsafe_assume_privileged), + feature = "critical-section" +))] +compile_error!( + "you may not enable `critical-section` feature and `portable_atomic_unsafe_assume_{single_core,privileged}` cfg (`unsafe-assume-{single-core,privileged}` feature) at the same time" +); + +#[cfg(feature = "require-cas")] +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(not(any( + not(portable_atomic_no_atomic_cas), + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ))) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(not(any( + target_has_atomic = "ptr", + target_arch = "avr", + target_arch = "msp430", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + ))) +)] +compile_error!( + "dependents require atomic CAS but not available on this target by default;\n\ + consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg).\n\ + see for more." +); + +#[macro_use] +mod utils; + +#[cfg(test)] +#[macro_use] +mod tests; + +#[doc(no_inline)] +pub use core::sync::atomic::Ordering; + +cfg_sel!({ + // LLVM doesn't support fence/compiler_fence for MSP430. + #[cfg(target_arch = "msp430")] + { + pub use self::imp::msp430::compiler_fence; + } + #[cfg(else)] + { + pub use core::sync::atomic::compiler_fence; + } +}); +cfg_sel!({ + // LLVM doesn't support fence/compiler_fence for MSP430. + #[cfg(target_arch = "msp430")] + { + pub use self::imp::msp430::fence; + } + // We have optimized fence for x86. + // Miri and Sanitizer do not support inline assembly. + #[cfg(all( + not(doc), + any(target_arch = "x86", target_arch = "x86_64"), + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + ))] + { + pub use self::imp::x86::fence; + } + // We have optimized fence for pre-v6 ARM Linux/Android. + // Miri and Sanitizer do not go through __sync_synchronize. + #[cfg(all( + not(doc), + target_arch = "arm", + not(any(miri, portable_atomic_sanitize_thread)), + any(target_os = "linux", target_os = "android"), + not(any(target_feature = "v6", portable_atomic_target_feature = "v6")), + ))] + { + pub use self::imp::arm_linux::fence; + } + #[cfg(else)] + { + pub use core::sync::atomic::fence; + } +}); + +mod imp; + +pub mod hint { + //! Re-export of the [`core::hint`] module. + //! + //! The only difference from the [`core::hint`] module is that [`spin_loop`] + //! is available in all rust versions that this crate supports. + //! + //! ``` + //! use portable_atomic::hint; + //! + //! hint::spin_loop(); + //! ``` + + #[doc(no_inline)] + pub use core::hint::*; + + /// Emits a machine instruction to signal the processor that it is running in + /// a busy-wait spin-loop ("spin lock"). + /// + /// Upon receiving the spin-loop signal the processor can optimize its behavior by, + /// for example, saving power or switching hyper-threads. + /// + /// This function is different from [`thread::yield_now`] which directly + /// yields to the system's scheduler, whereas `spin_loop` does not interact + /// with the operating system. + /// + /// A common use case for `spin_loop` is implementing bounded optimistic + /// spinning in a CAS loop in synchronization primitives. To avoid problems + /// like priority inversion, it is strongly recommended that the spin loop is + /// terminated after a finite amount of iterations and an appropriate blocking + /// syscall is made. + /// + /// **Note:** On platforms that do not support receiving spin-loop hints this + /// function does not do anything at all. + /// + /// [`thread::yield_now`]: https://doc.rust-lang.org/std/thread/fn.yield_now.html + #[inline] + pub fn spin_loop() { + #[allow(deprecated)] + core::sync::atomic::spin_loop_hint(); + } +} + +#[cfg(doc)] +use core::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release, SeqCst}; +use core::{fmt, ptr}; + +cfg_has_atomic_8! { +/// A boolean type which can be safely shared between threads. +/// +/// This type has the same in-memory representation as a [`bool`]. +/// +/// If the compiler and the platform support atomic loads and stores of `u8`, +/// this type is a wrapper for the standard library's +/// [`AtomicBool`](core::sync::atomic::AtomicBool). If the platform supports it +/// but the compiler does not, atomic operations are implemented using inline +/// assembly. +#[repr(C, align(1))] +pub struct AtomicBool { + v: core::cell::UnsafeCell, +} + +impl Default for AtomicBool { + /// Creates an `AtomicBool` initialized to `false`. + #[inline] + fn default() -> Self { + Self::new(false) + } +} + +impl From for AtomicBool { + /// Converts a `bool` into an `AtomicBool`. + #[inline] + fn from(b: bool) -> Self { + Self::new(b) + } +} + +// Send is implicitly implemented. +// SAFETY: any data races are prevented by disabling interrupts or +// atomic intrinsics (see module-level comments). +unsafe impl Sync for AtomicBool {} + +// UnwindSafe is implicitly implemented. +#[cfg(not(portable_atomic_no_core_unwind_safe))] +impl core::panic::RefUnwindSafe for AtomicBool {} +#[cfg(all(portable_atomic_no_core_unwind_safe, feature = "std"))] +impl std::panic::RefUnwindSafe for AtomicBool {} + +impl_debug_and_serde!(AtomicBool); + +impl AtomicBool { + /// Creates a new `AtomicBool`. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::AtomicBool; + /// + /// let atomic_true = AtomicBool::new(true); + /// let atomic_false = AtomicBool::new(false); + /// ``` + #[inline] + #[must_use] + pub const fn new(v: bool) -> Self { + static_assert_layout!(AtomicBool, bool); + Self { v: core::cell::UnsafeCell::new(v as u8) } + } + + // TODO: update docs based on https://github.com/rust-lang/rust/pull/116762 + const_fn! { + const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))]; + /// Creates a new `AtomicBool` from a pointer. + /// + /// This is `const fn` on Rust 1.58+. + /// + /// # Safety + /// + /// * `ptr` must be aligned to `align_of::()` (note that on some platforms this can + /// be bigger than `align_of::()`). + /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`. + /// * If this atomic type is [lock-free](Self::is_lock_free), non-atomic accesses to the value + /// behind `ptr` must have a happens-before relationship with atomic accesses via the returned + /// value (or vice-versa). + /// * In other words, time periods where the value is accessed atomically may not overlap + /// with periods where the value is accessed non-atomically. + /// * This requirement is trivially satisfied if `ptr` is never used non-atomically for the + /// duration of lifetime `'a`. Most use cases should be able to follow this guideline. + /// * This requirement is also trivially satisfied if all accesses (atomic or not) are done + /// from the same thread. + /// * If this atomic type is *not* lock-free: + /// * Any accesses to the value behind `ptr` must have a happens-before relationship + /// with accesses via the returned value (or vice-versa). + /// * Any concurrent accesses to the value behind `ptr` for the duration of lifetime `'a` must + /// be compatible with operations performed by this atomic type. + /// * This method must not be used to create overlapping or mixed-size atomic accesses, as + /// these are not supported by the memory model. + /// + /// [valid]: core::ptr#safety + #[inline] + #[must_use] + pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a Self { + #[allow(clippy::cast_ptr_alignment)] + // SAFETY: guaranteed by the caller + unsafe { &*(ptr as *mut Self as *const Self) } + } + } + + /// Returns `true` if operations on values of this type are lock-free. + /// + /// If the compiler or the platform doesn't support the necessary + /// atomic instructions, global locks for every potentially + /// concurrent atomic operation will be used. + /// + /// This function is guaranteed to always return the same result. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::AtomicBool; + /// + /// let is_lock_free = AtomicBool::is_lock_free(); + /// ``` + #[inline] + #[must_use] + pub fn is_lock_free() -> bool { + imp::AtomicU8::is_lock_free() + } + + /// Returns `true` if operations on values of this type are lock-free. + /// + /// If the compiler or the platform doesn't support the necessary + /// atomic instructions, global locks for every potentially + /// concurrent atomic operation will be used. + /// + /// **Note:** If the atomic operation relies on dynamic CPU feature detection, + /// this type may be lock-free even if the function returns false. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::AtomicBool; + /// + /// const IS_ALWAYS_LOCK_FREE: bool = AtomicBool::is_always_lock_free(); + /// ``` + #[inline] + #[must_use] + pub const fn is_always_lock_free() -> bool { + imp::AtomicU8::IS_ALWAYS_LOCK_FREE + } + #[cfg(test)] + const IS_ALWAYS_LOCK_FREE: bool = Self::is_always_lock_free(); + + const_fn! { + const_if: #[cfg(not(portable_atomic_no_const_mut_refs))]; + /// Returns a mutable reference to the underlying [`bool`]. + /// + /// This is safe because the mutable reference guarantees that no other threads are + /// concurrently accessing the atomic data. + /// + /// This is `const fn` on Rust 1.83+. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let mut some_bool = AtomicBool::new(true); + /// assert_eq!(*some_bool.get_mut(), true); + /// *some_bool.get_mut() = false; + /// assert_eq!(some_bool.load(Ordering::SeqCst), false); + /// ``` + #[inline] + pub const fn get_mut(&mut self) -> &mut bool { + // SAFETY: the mutable reference guarantees unique ownership. + unsafe { &mut *self.as_ptr() } + } + } + + // TODO: Add from_mut/get_mut_slice/from_mut_slice once it is stable on std atomic types. + // https://github.com/rust-lang/rust/issues/76314 + + const_fn! { + const_if: #[cfg(not(portable_atomic_no_const_transmute))]; + /// Consumes the atomic and returns the contained value. + /// + /// This is safe because passing `self` by value guarantees that no other threads are + /// concurrently accessing the atomic data. + /// + /// This is `const fn` on Rust 1.56+. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::AtomicBool; + /// + /// let some_bool = AtomicBool::new(true); + /// assert_eq!(some_bool.into_inner(), true); + /// ``` + #[inline] + pub const fn into_inner(self) -> bool { + // SAFETY: AtomicBool and u8 have the same size and in-memory representations, + // so they can be safely transmuted. + // (const UnsafeCell::into_inner is unstable) + unsafe { core::mem::transmute::(self) != 0 } + } + } + + /// Loads a value from the bool. + /// + /// `load` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `order` is [`Release`] or [`AcqRel`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let some_bool = AtomicBool::new(true); + /// + /// assert_eq!(some_bool.load(Ordering::Relaxed), true); + /// ``` + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn load(&self, order: Ordering) -> bool { + self.as_atomic_u8().load(order) != 0 + } + + /// Stores a value into the bool. + /// + /// `store` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `order` is [`Acquire`] or [`AcqRel`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let some_bool = AtomicBool::new(true); + /// + /// some_bool.store(false, Ordering::Relaxed); + /// assert_eq!(some_bool.load(Ordering::Relaxed), false); + /// ``` + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn store(&self, val: bool, order: Ordering) { + self.as_atomic_u8().store(val as u8, order); + } + + cfg_has_atomic_cas_or_amo32! { + /// Stores a value into the bool, returning the previous value. + /// + /// `swap` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let some_bool = AtomicBool::new(true); + /// + /// assert_eq!(some_bool.swap(false, Ordering::Relaxed), true); + /// assert_eq!(some_bool.load(Ordering::Relaxed), false); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn swap(&self, val: bool, order: Ordering) -> bool { + #[cfg(any( + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "loongarch32", + target_arch = "loongarch64", + ))] + { + // See https://github.com/rust-lang/rust/pull/114034 for details. + // https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L249 + // https://godbolt.org/z/ofbGGdx44 + if val { self.fetch_or(true, order) } else { self.fetch_and(false, order) } + } + #[cfg(not(any( + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "loongarch32", + target_arch = "loongarch64", + )))] + { + self.as_atomic_u8().swap(val as u8, order) != 0 + } + } + + /// Stores a value into the [`bool`] if the current value is the same as the `current` value. + /// + /// The return value is a result indicating whether the new value was written and containing + /// the previous value. On success this value is guaranteed to be equal to `current`. + /// + /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory + /// ordering of this operation. `success` describes the required ordering for the + /// read-modify-write operation that takes place if the comparison with `current` succeeds. + /// `failure` describes the required ordering for the load operation that takes place when + /// the comparison fails. Using [`Acquire`] as success ordering makes the store part + /// of this operation [`Relaxed`], and using [`Release`] makes the successful load + /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `failure` is [`Release`], [`AcqRel`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let some_bool = AtomicBool::new(true); + /// + /// assert_eq!( + /// some_bool.compare_exchange(true, false, Ordering::Acquire, Ordering::Relaxed), + /// Ok(true) + /// ); + /// assert_eq!(some_bool.load(Ordering::Relaxed), false); + /// + /// assert_eq!( + /// some_bool.compare_exchange(true, true, Ordering::SeqCst, Ordering::Acquire), + /// Err(false) + /// ); + /// assert_eq!(some_bool.load(Ordering::Relaxed), false); + /// ``` + #[cfg_attr(docsrs, doc(alias = "compare_and_swap"))] + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn compare_exchange( + &self, + current: bool, + new: bool, + success: Ordering, + failure: Ordering, + ) -> Result { + #[cfg(any( + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "loongarch32", + target_arch = "loongarch64", + ))] + { + // See https://github.com/rust-lang/rust/pull/114034 for details. + // https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L249 + // https://godbolt.org/z/ofbGGdx44 + crate::utils::assert_compare_exchange_ordering(success, failure); + let order = crate::utils::upgrade_success_ordering(success, failure); + let old = if current == new { + // This is a no-op, but we still need to perform the operation + // for memory ordering reasons. + self.fetch_or(false, order) + } else { + // This sets the value to the new one and returns the old one. + self.swap(new, order) + }; + if old == current { Ok(old) } else { Err(old) } + } + #[cfg(not(any( + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "loongarch32", + target_arch = "loongarch64", + )))] + { + match self.as_atomic_u8().compare_exchange(current as u8, new as u8, success, failure) { + Ok(x) => Ok(x != 0), + Err(x) => Err(x != 0), + } + } + } + + /// Stores a value into the [`bool`] if the current value is the same as the `current` value. + /// + /// Unlike [`AtomicBool::compare_exchange`], this function is allowed to spuriously fail even when the + /// comparison succeeds, which can result in more efficient code on some platforms. The + /// return value is a result indicating whether the new value was written and containing the + /// previous value. + /// + /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory + /// ordering of this operation. `success` describes the required ordering for the + /// read-modify-write operation that takes place if the comparison with `current` succeeds. + /// `failure` describes the required ordering for the load operation that takes place when + /// the comparison fails. Using [`Acquire`] as success ordering makes the store part + /// of this operation [`Relaxed`], and using [`Release`] makes the successful load + /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `failure` is [`Release`], [`AcqRel`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let val = AtomicBool::new(false); + /// + /// let new = true; + /// let mut old = val.load(Ordering::Relaxed); + /// loop { + /// match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { + /// Ok(_) => break, + /// Err(x) => old = x, + /// } + /// } + /// ``` + #[cfg_attr(docsrs, doc(alias = "compare_and_swap"))] + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn compare_exchange_weak( + &self, + current: bool, + new: bool, + success: Ordering, + failure: Ordering, + ) -> Result { + #[cfg(any( + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "loongarch32", + target_arch = "loongarch64", + ))] + { + // See https://github.com/rust-lang/rust/pull/114034 for details. + // https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L249 + // https://godbolt.org/z/ofbGGdx44 + self.compare_exchange(current, new, success, failure) + } + #[cfg(not(any( + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "loongarch32", + target_arch = "loongarch64", + )))] + { + match self + .as_atomic_u8() + .compare_exchange_weak(current as u8, new as u8, success, failure) + { + Ok(x) => Ok(x != 0), + Err(x) => Err(x != 0), + } + } + } + + /// Logical "and" with a boolean value. + /// + /// Performs a logical "and" operation on the current value and the argument `val`, and sets + /// the new value to the result. + /// + /// Returns the previous value. + /// + /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_and(true, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// + /// let foo = AtomicBool::new(false); + /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), false); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_and(&self, val: bool, order: Ordering) -> bool { + self.as_atomic_u8().fetch_and(val as u8, order) != 0 + } + + /// Logical "and" with a boolean value. + /// + /// Performs a logical "and" operation on the current value and the argument `val`, and sets + /// the new value to the result. + /// + /// Unlike `fetch_and`, this does not return the previous value. + /// + /// `and` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// This function may generate more efficient code than `fetch_and` on some platforms. + /// + /// - x86/x86_64: `lock and` instead of `cmpxchg` loop + /// - MSP430: `and` instead of disabling interrupts + /// + /// Note: On x86/x86_64, the use of either function should not usually + /// affect the generated code, because LLVM can properly optimize the case + /// where the result is unused. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let foo = AtomicBool::new(true); + /// foo.and(false, Ordering::SeqCst); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// + /// let foo = AtomicBool::new(true); + /// foo.and(true, Ordering::SeqCst); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// + /// let foo = AtomicBool::new(false); + /// foo.and(false, Ordering::SeqCst); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn and(&self, val: bool, order: Ordering) { + self.as_atomic_u8().and(val as u8, order); + } + + /// Logical "nand" with a boolean value. + /// + /// Performs a logical "nand" operation on the current value and the argument `val`, and sets + /// the new value to the result. + /// + /// Returns the previous value. + /// + /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_nand(true, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst) as usize, 0); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// + /// let foo = AtomicBool::new(false); + /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), false); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool { + // https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L973-L985 + if val { + // !(x & true) == !x + // We must invert the bool. + self.fetch_xor(true, order) + } else { + // !(x & false) == true + // We must set the bool to true. + self.swap(true, order) + } + } + + /// Logical "or" with a boolean value. + /// + /// Performs a logical "or" operation on the current value and the argument `val`, and sets the + /// new value to the result. + /// + /// Returns the previous value. + /// + /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_or(true, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// + /// let foo = AtomicBool::new(false); + /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), false); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_or(&self, val: bool, order: Ordering) -> bool { + self.as_atomic_u8().fetch_or(val as u8, order) != 0 + } + + /// Logical "or" with a boolean value. + /// + /// Performs a logical "or" operation on the current value and the argument `val`, and sets the + /// new value to the result. + /// + /// Unlike `fetch_or`, this does not return the previous value. + /// + /// `or` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// This function may generate more efficient code than `fetch_or` on some platforms. + /// + /// - x86/x86_64: `lock or` instead of `cmpxchg` loop + /// - MSP430: `bis` instead of disabling interrupts + /// + /// Note: On x86/x86_64, the use of either function should not usually + /// affect the generated code, because LLVM can properly optimize the case + /// where the result is unused. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let foo = AtomicBool::new(true); + /// foo.or(false, Ordering::SeqCst); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// + /// let foo = AtomicBool::new(true); + /// foo.or(true, Ordering::SeqCst); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// + /// let foo = AtomicBool::new(false); + /// foo.or(false, Ordering::SeqCst); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn or(&self, val: bool, order: Ordering) { + self.as_atomic_u8().or(val as u8, order); + } + + /// Logical "xor" with a boolean value. + /// + /// Performs a logical "xor" operation on the current value and the argument `val`, and sets + /// the new value to the result. + /// + /// Returns the previous value. + /// + /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_xor(true, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// + /// let foo = AtomicBool::new(false); + /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), false); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool { + self.as_atomic_u8().fetch_xor(val as u8, order) != 0 + } + + /// Logical "xor" with a boolean value. + /// + /// Performs a logical "xor" operation on the current value and the argument `val`, and sets + /// the new value to the result. + /// + /// Unlike `fetch_xor`, this does not return the previous value. + /// + /// `xor` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// This function may generate more efficient code than `fetch_xor` on some platforms. + /// + /// - x86/x86_64: `lock xor` instead of `cmpxchg` loop + /// - MSP430: `xor` instead of disabling interrupts + /// + /// Note: On x86/x86_64, the use of either function should not usually + /// affect the generated code, because LLVM can properly optimize the case + /// where the result is unused. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let foo = AtomicBool::new(true); + /// foo.xor(false, Ordering::SeqCst); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// + /// let foo = AtomicBool::new(true); + /// foo.xor(true, Ordering::SeqCst); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// + /// let foo = AtomicBool::new(false); + /// foo.xor(false, Ordering::SeqCst); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn xor(&self, val: bool, order: Ordering) { + self.as_atomic_u8().xor(val as u8, order); + } + + /// Logical "not" with a boolean value. + /// + /// Performs a logical "not" operation on the current value, and sets + /// the new value to the result. + /// + /// Returns the previous value. + /// + /// `fetch_not` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_not(Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// + /// let foo = AtomicBool::new(false); + /// assert_eq!(foo.fetch_not(Ordering::SeqCst), false); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_not(&self, order: Ordering) -> bool { + self.fetch_xor(true, order) + } + + /// Logical "not" with a boolean value. + /// + /// Performs a logical "not" operation on the current value, and sets + /// the new value to the result. + /// + /// Unlike `fetch_not`, this does not return the previous value. + /// + /// `not` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// This function may generate more efficient code than `fetch_not` on some platforms. + /// + /// - x86/x86_64: `lock xor` instead of `cmpxchg` loop + /// - MSP430: `xor` instead of disabling interrupts + /// + /// Note: On x86/x86_64, the use of either function should not usually + /// affect the generated code, because LLVM can properly optimize the case + /// where the result is unused. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let foo = AtomicBool::new(true); + /// foo.not(Ordering::SeqCst); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// + /// let foo = AtomicBool::new(false); + /// foo.not(Ordering::SeqCst); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn not(&self, order: Ordering) { + self.xor(true, order); + } + + /// Fetches the value, and applies a function to it that returns an optional + /// new value. Returns a `Result` of `Ok(previous_value)` if the function + /// returned `Some(_)`, else `Err(previous_value)`. + /// + /// Note: This may call the function multiple times if the value has been + /// changed from other threads in the meantime, as long as the function + /// returns `Some(_)`, but the function will have been applied only once to + /// the stored value. + /// + /// `fetch_update` takes two [`Ordering`] arguments to describe the memory + /// ordering of this operation. The first describes the required ordering for + /// when the operation finally succeeds while the second describes the + /// required ordering for loads. These correspond to the success and failure + /// orderings of [`compare_exchange`](Self::compare_exchange) respectively. + /// + /// Using [`Acquire`] as success ordering makes the store part of this + /// operation [`Relaxed`], and using [`Release`] makes the final successful + /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], + /// [`Acquire`] or [`Relaxed`]. + /// + /// # Considerations + /// + /// This method is not magic; it is not provided by the hardware. + /// It is implemented in terms of [`compare_exchange_weak`](Self::compare_exchange_weak), + /// and suffers from the same drawbacks. + /// In particular, this method will not circumvent the [ABA Problem]. + /// + /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem + /// + /// # Panics + /// + /// Panics if `fetch_order` is [`Release`], [`AcqRel`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicBool, Ordering}; + /// + /// let x = AtomicBool::new(false); + /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(false)); + /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(false)); + /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(true)); + /// assert_eq!(x.load(Ordering::SeqCst), false); + /// ``` + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn fetch_update( + &self, + set_order: Ordering, + fetch_order: Ordering, + mut f: F, + ) -> Result + where + F: FnMut(bool) -> Option, + { + let mut prev = self.load(fetch_order); + while let Some(next) = f(prev) { + match self.compare_exchange_weak(prev, next, set_order, fetch_order) { + x @ Ok(_) => return x, + Err(next_prev) => prev = next_prev, + } + } + Err(prev) + } + } // cfg_has_atomic_cas_or_amo32! + + const_fn! { + // This function is actually `const fn`-compatible on Rust 1.32+, + // but makes `const fn` only on Rust 1.58+ to match other atomic types. + const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))]; + /// Returns a mutable pointer to the underlying [`bool`]. + /// + /// Returning an `*mut` pointer from a shared reference to this atomic is + /// safe because the atomic types work with interior mutability. Any use of + /// the returned raw pointer requires an `unsafe` block and has to uphold + /// the safety requirements. If there is concurrent access, note the following + /// additional safety requirements: + /// + /// - If this atomic type is [lock-free](Self::is_lock_free), any concurrent + /// operations on it must be atomic. + /// - Otherwise, any concurrent operations on it must be compatible with + /// operations performed by this atomic type. + /// + /// This is `const fn` on Rust 1.58+. + #[inline] + pub const fn as_ptr(&self) -> *mut bool { + self.v.get() as *mut bool + } + } + + #[inline(always)] + fn as_atomic_u8(&self) -> &imp::AtomicU8 { + // SAFETY: AtomicBool and imp::AtomicU8 have the same layout, + // and both access data in the same way. + unsafe { &*(self as *const Self as *const imp::AtomicU8) } + } +} +// See https://github.com/taiki-e/portable-atomic/issues/180 +#[cfg(not(feature = "require-cas"))] +cfg_no_atomic_cas! { +#[doc(hidden)] +#[allow(unused_variables, clippy::unused_self, clippy::extra_unused_lifetimes)] +impl<'a> AtomicBool { + cfg_no_atomic_cas_or_amo32! { + #[inline] + pub fn swap(&self, val: bool, order: Ordering) -> bool + where + &'a Self: HasSwap, + { + unimplemented!() + } + #[inline] + pub fn compare_exchange( + &self, + current: bool, + new: bool, + success: Ordering, + failure: Ordering, + ) -> Result + where + &'a Self: HasCompareExchange, + { + unimplemented!() + } + #[inline] + pub fn compare_exchange_weak( + &self, + current: bool, + new: bool, + success: Ordering, + failure: Ordering, + ) -> Result + where + &'a Self: HasCompareExchangeWeak, + { + unimplemented!() + } + #[inline] + pub fn fetch_and(&self, val: bool, order: Ordering) -> bool + where + &'a Self: HasFetchAnd, + { + unimplemented!() + } + #[inline] + pub fn and(&self, val: bool, order: Ordering) + where + &'a Self: HasAnd, + { + unimplemented!() + } + #[inline] + pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool + where + &'a Self: HasFetchNand, + { + unimplemented!() + } + #[inline] + pub fn fetch_or(&self, val: bool, order: Ordering) -> bool + where + &'a Self: HasFetchOr, + { + unimplemented!() + } + #[inline] + pub fn or(&self, val: bool, order: Ordering) + where + &'a Self: HasOr, + { + unimplemented!() + } + #[inline] + pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool + where + &'a Self: HasFetchXor, + { + unimplemented!() + } + #[inline] + pub fn xor(&self, val: bool, order: Ordering) + where + &'a Self: HasXor, + { + unimplemented!() + } + #[inline] + pub fn fetch_not(&self, order: Ordering) -> bool + where + &'a Self: HasFetchNot, + { + unimplemented!() + } + #[inline] + pub fn not(&self, order: Ordering) + where + &'a Self: HasNot, + { + unimplemented!() + } + #[inline] + pub fn fetch_update( + &self, + set_order: Ordering, + fetch_order: Ordering, + f: F, + ) -> Result + where + F: FnMut(bool) -> Option, + &'a Self: HasFetchUpdate, + { + unimplemented!() + } + } // cfg_no_atomic_cas_or_amo32! +} +} // cfg_no_atomic_cas! +} // cfg_has_atomic_8! + +cfg_has_atomic_ptr! { +/// A raw pointer type which can be safely shared between threads. +/// +/// This type has the same in-memory representation as a `*mut T`. +/// +/// If the compiler and the platform support atomic loads and stores of pointers, +/// this type is a wrapper for the standard library's +/// [`AtomicPtr`](core::sync::atomic::AtomicPtr). If the platform supports it +/// but the compiler does not, atomic operations are implemented using inline +/// assembly. +// We can use #[repr(transparent)] here, but #[repr(C, align(N))] +// will show clearer docs. +#[cfg_attr(target_pointer_width = "16", repr(C, align(2)))] +#[cfg_attr(target_pointer_width = "32", repr(C, align(4)))] +#[cfg_attr(target_pointer_width = "64", repr(C, align(8)))] +#[cfg_attr(target_pointer_width = "128", repr(C, align(16)))] +pub struct AtomicPtr { + inner: imp::AtomicPtr, +} + +impl Default for AtomicPtr { + /// Creates a null `AtomicPtr`. + #[inline] + fn default() -> Self { + Self::new(ptr::null_mut()) + } +} + +impl From<*mut T> for AtomicPtr { + #[inline] + fn from(p: *mut T) -> Self { + Self::new(p) + } +} + +impl fmt::Debug for AtomicPtr { + #[inline] // fmt is not hot path, but #[inline] on fmt seems to still be useful: https://github.com/rust-lang/rust/pull/117727 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // std atomic types use Relaxed in Debug::fmt: https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L2188 + fmt::Debug::fmt(&self.load(Ordering::Relaxed), f) + } +} + +impl fmt::Pointer for AtomicPtr { + #[inline] // fmt is not hot path, but #[inline] on fmt seems to still be useful: https://github.com/rust-lang/rust/pull/117727 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // std atomic types use Relaxed in Debug::fmt: https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L2188 + fmt::Pointer::fmt(&self.load(Ordering::Relaxed), f) + } +} + +// UnwindSafe is implicitly implemented. +#[cfg(not(portable_atomic_no_core_unwind_safe))] +impl core::panic::RefUnwindSafe for AtomicPtr {} +#[cfg(all(portable_atomic_no_core_unwind_safe, feature = "std"))] +impl std::panic::RefUnwindSafe for AtomicPtr {} + +impl AtomicPtr { + /// Creates a new `AtomicPtr`. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::AtomicPtr; + /// + /// let ptr = &mut 5; + /// let atomic_ptr = AtomicPtr::new(ptr); + /// ``` + #[inline] + #[must_use] + pub const fn new(p: *mut T) -> Self { + static_assert_layout!(AtomicPtr<()>, *mut ()); + Self { inner: imp::AtomicPtr::new(p) } + } + + // TODO: update docs based on https://github.com/rust-lang/rust/pull/116762 + const_fn! { + const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))]; + /// Creates a new `AtomicPtr` from a pointer. + /// + /// This is `const fn` on Rust 1.58+. + /// + /// # Safety + /// + /// * `ptr` must be aligned to `align_of::>()` (note that on some platforms this + /// can be bigger than `align_of::<*mut T>()`). + /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`. + /// * If this atomic type is [lock-free](Self::is_lock_free), non-atomic accesses to the value + /// behind `ptr` must have a happens-before relationship with atomic accesses via the returned + /// value (or vice-versa). + /// * In other words, time periods where the value is accessed atomically may not overlap + /// with periods where the value is accessed non-atomically. + /// * This requirement is trivially satisfied if `ptr` is never used non-atomically for the + /// duration of lifetime `'a`. Most use cases should be able to follow this guideline. + /// * This requirement is also trivially satisfied if all accesses (atomic or not) are done + /// from the same thread. + /// * If this atomic type is *not* lock-free: + /// * Any accesses to the value behind `ptr` must have a happens-before relationship + /// with accesses via the returned value (or vice-versa). + /// * Any concurrent accesses to the value behind `ptr` for the duration of lifetime `'a` must + /// be compatible with operations performed by this atomic type. + /// * This method must not be used to create overlapping or mixed-size atomic accesses, as + /// these are not supported by the memory model. + /// + /// [valid]: core::ptr#safety + #[inline] + #[must_use] + pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a Self { + #[allow(clippy::cast_ptr_alignment)] + // SAFETY: guaranteed by the caller + unsafe { &*(ptr as *mut Self as *const Self) } + } + } + + /// Returns `true` if operations on values of this type are lock-free. + /// + /// If the compiler or the platform doesn't support the necessary + /// atomic instructions, global locks for every potentially + /// concurrent atomic operation will be used. + /// + /// This function is guaranteed to always return the same result. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::AtomicPtr; + /// + /// let is_lock_free = AtomicPtr::<()>::is_lock_free(); + /// ``` + #[inline] + #[must_use] + pub fn is_lock_free() -> bool { + >::is_lock_free() + } + + /// Returns `true` if operations on values of this type are lock-free. + /// + /// If the compiler or the platform doesn't support the necessary + /// atomic instructions, global locks for every potentially + /// concurrent atomic operation will be used. + /// + /// **Note:** If the atomic operation relies on dynamic CPU feature detection, + /// this type may be lock-free even if the function returns false. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::AtomicPtr; + /// + /// const IS_ALWAYS_LOCK_FREE: bool = AtomicPtr::<()>::is_always_lock_free(); + /// ``` + #[inline] + #[must_use] + pub const fn is_always_lock_free() -> bool { + >::IS_ALWAYS_LOCK_FREE + } + #[cfg(test)] + const IS_ALWAYS_LOCK_FREE: bool = Self::is_always_lock_free(); + + const_fn! { + const_if: #[cfg(not(portable_atomic_no_const_mut_refs))]; + /// Returns a mutable reference to the underlying pointer. + /// + /// This is safe because the mutable reference guarantees that no other threads are + /// concurrently accessing the atomic data. + /// + /// This is `const fn` on Rust 1.83+. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let mut data = 10; + /// let mut atomic_ptr = AtomicPtr::new(&mut data); + /// let mut other_data = 5; + /// *atomic_ptr.get_mut() = &mut other_data; + /// assert_eq!(unsafe { *atomic_ptr.load(Ordering::SeqCst) }, 5); + /// ``` + #[inline] + pub const fn get_mut(&mut self) -> &mut *mut T { + // SAFETY: the mutable reference guarantees unique ownership. + // (core::sync::atomic::Atomic*::get_mut is not const yet) + unsafe { &mut *self.as_ptr() } + } + } + + // TODO: Add from_mut/get_mut_slice/from_mut_slice once it is stable on std atomic types. + // https://github.com/rust-lang/rust/issues/76314 + + const_fn! { + const_if: #[cfg(not(portable_atomic_no_const_transmute))]; + /// Consumes the atomic and returns the contained value. + /// + /// This is safe because passing `self` by value guarantees that no other threads are + /// concurrently accessing the atomic data. + /// + /// This is `const fn` on Rust 1.56+. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::AtomicPtr; + /// + /// let mut data = 5; + /// let atomic_ptr = AtomicPtr::new(&mut data); + /// assert_eq!(unsafe { *atomic_ptr.into_inner() }, 5); + /// ``` + #[inline] + pub const fn into_inner(self) -> *mut T { + // SAFETY: AtomicPtr and *mut T have the same size and in-memory representations, + // so they can be safely transmuted. + // (const UnsafeCell::into_inner is unstable) + unsafe { core::mem::transmute(self) } + } + } + + /// Loads a value from the pointer. + /// + /// `load` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `order` is [`Release`] or [`AcqRel`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let ptr = &mut 5; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let value = some_ptr.load(Ordering::Relaxed); + /// ``` + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn load(&self, order: Ordering) -> *mut T { + self.inner.load(order) + } + + /// Stores a value into the pointer. + /// + /// `store` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `order` is [`Acquire`] or [`AcqRel`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let ptr = &mut 5; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let other_ptr = &mut 10; + /// + /// some_ptr.store(other_ptr, Ordering::Relaxed); + /// ``` + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn store(&self, ptr: *mut T, order: Ordering) { + self.inner.store(ptr, order); + } + + cfg_has_atomic_cas_or_amo32! { + /// Stores a value into the pointer, returning the previous value. + /// + /// `swap` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let ptr = &mut 5; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let other_ptr = &mut 10; + /// + /// let value = some_ptr.swap(other_ptr, Ordering::Relaxed); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T { + self.inner.swap(ptr, order) + } + + cfg_has_atomic_cas! { + /// Stores a value into the pointer if the current value is the same as the `current` value. + /// + /// The return value is a result indicating whether the new value was written and containing + /// the previous value. On success this value is guaranteed to be equal to `current`. + /// + /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory + /// ordering of this operation. `success` describes the required ordering for the + /// read-modify-write operation that takes place if the comparison with `current` succeeds. + /// `failure` describes the required ordering for the load operation that takes place when + /// the comparison fails. Using [`Acquire`] as success ordering makes the store part + /// of this operation [`Relaxed`], and using [`Release`] makes the successful load + /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `failure` is [`Release`], [`AcqRel`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let ptr = &mut 5; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let other_ptr = &mut 10; + /// + /// let value = some_ptr.compare_exchange(ptr, other_ptr, Ordering::SeqCst, Ordering::Relaxed); + /// ``` + #[cfg_attr(docsrs, doc(alias = "compare_and_swap"))] + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn compare_exchange( + &self, + current: *mut T, + new: *mut T, + success: Ordering, + failure: Ordering, + ) -> Result<*mut T, *mut T> { + self.inner.compare_exchange(current, new, success, failure) + } + + /// Stores a value into the pointer if the current value is the same as the `current` value. + /// + /// Unlike [`AtomicPtr::compare_exchange`], this function is allowed to spuriously fail even when the + /// comparison succeeds, which can result in more efficient code on some platforms. The + /// return value is a result indicating whether the new value was written and containing the + /// previous value. + /// + /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory + /// ordering of this operation. `success` describes the required ordering for the + /// read-modify-write operation that takes place if the comparison with `current` succeeds. + /// `failure` describes the required ordering for the load operation that takes place when + /// the comparison fails. Using [`Acquire`] as success ordering makes the store part + /// of this operation [`Relaxed`], and using [`Release`] makes the successful load + /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `failure` is [`Release`], [`AcqRel`]. + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let some_ptr = AtomicPtr::new(&mut 5); + /// + /// let new = &mut 10; + /// let mut old = some_ptr.load(Ordering::Relaxed); + /// loop { + /// match some_ptr.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { + /// Ok(_) => break, + /// Err(x) => old = x, + /// } + /// } + /// ``` + #[cfg_attr(docsrs, doc(alias = "compare_and_swap"))] + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn compare_exchange_weak( + &self, + current: *mut T, + new: *mut T, + success: Ordering, + failure: Ordering, + ) -> Result<*mut T, *mut T> { + self.inner.compare_exchange_weak(current, new, success, failure) + } + + /// Fetches the value, and applies a function to it that returns an optional + /// new value. Returns a `Result` of `Ok(previous_value)` if the function + /// returned `Some(_)`, else `Err(previous_value)`. + /// + /// Note: This may call the function multiple times if the value has been + /// changed from other threads in the meantime, as long as the function + /// returns `Some(_)`, but the function will have been applied only once to + /// the stored value. + /// + /// `fetch_update` takes two [`Ordering`] arguments to describe the memory + /// ordering of this operation. The first describes the required ordering for + /// when the operation finally succeeds while the second describes the + /// required ordering for loads. These correspond to the success and failure + /// orderings of [`compare_exchange`](Self::compare_exchange) respectively. + /// + /// Using [`Acquire`] as success ordering makes the store part of this + /// operation [`Relaxed`], and using [`Release`] makes the final successful + /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], + /// [`Acquire`] or [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `fetch_order` is [`Release`], [`AcqRel`]. + /// + /// # Considerations + /// + /// This method is not magic; it is not provided by the hardware. + /// It is implemented in terms of [`compare_exchange_weak`](Self::compare_exchange_weak), + /// and suffers from the same drawbacks. + /// In particular, this method will not circumvent the [ABA Problem]. + /// + /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let ptr: *mut _ = &mut 5; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let new: *mut _ = &mut 10; + /// assert_eq!(some_ptr.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(ptr)); + /// let result = some_ptr.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| { + /// if x == ptr { + /// Some(new) + /// } else { + /// None + /// } + /// }); + /// assert_eq!(result, Ok(ptr)); + /// assert_eq!(some_ptr.load(Ordering::SeqCst), new); + /// ``` + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn fetch_update( + &self, + set_order: Ordering, + fetch_order: Ordering, + mut f: F, + ) -> Result<*mut T, *mut T> + where + F: FnMut(*mut T) -> Option<*mut T>, + { + let mut prev = self.load(fetch_order); + while let Some(next) = f(prev) { + match self.compare_exchange_weak(prev, next, set_order, fetch_order) { + x @ Ok(_) => return x, + Err(next_prev) => prev = next_prev, + } + } + Err(prev) + } + } // cfg_has_atomic_cas! + + /// Offsets the pointer's address by adding `val` (in units of `T`), + /// returning the previous pointer. + /// + /// This is equivalent to using [`wrapping_add`] to atomically perform the + /// equivalent of `ptr = ptr.wrapping_add(val);`. + /// + /// This method operates in units of `T`, which means that it cannot be used + /// to offset the pointer by an amount which is not a multiple of + /// `size_of::()`. This can sometimes be inconvenient, as you may want to + /// work with a deliberately misaligned pointer. In such cases, you may use + /// the [`fetch_byte_add`](Self::fetch_byte_add) method instead. + /// + /// `fetch_ptr_add` takes an [`Ordering`] argument which describes the + /// memory ordering of this operation. All ordering modes are possible. Note + /// that using [`Acquire`] makes the store part of this operation + /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`]. + /// + /// [`wrapping_add`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_add + /// + /// # Examples + /// + /// ``` + /// # #![allow(unstable_name_collisions)] + /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let atom = AtomicPtr::::new(core::ptr::null_mut()); + /// assert_eq!(atom.fetch_ptr_add(1, Ordering::Relaxed).addr(), 0); + /// // Note: units of `size_of::()`. + /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 8); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T { + self.fetch_byte_add(val.wrapping_mul(core::mem::size_of::()), order) + } + + /// Offsets the pointer's address by subtracting `val` (in units of `T`), + /// returning the previous pointer. + /// + /// This is equivalent to using [`wrapping_sub`] to atomically perform the + /// equivalent of `ptr = ptr.wrapping_sub(val);`. + /// + /// This method operates in units of `T`, which means that it cannot be used + /// to offset the pointer by an amount which is not a multiple of + /// `size_of::()`. This can sometimes be inconvenient, as you may want to + /// work with a deliberately misaligned pointer. In such cases, you may use + /// the [`fetch_byte_sub`](Self::fetch_byte_sub) method instead. + /// + /// `fetch_ptr_sub` takes an [`Ordering`] argument which describes the memory + /// ordering of this operation. All ordering modes are possible. Note that + /// using [`Acquire`] makes the store part of this operation [`Relaxed`], + /// and using [`Release`] makes the load part [`Relaxed`]. + /// + /// [`wrapping_sub`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_sub + /// + /// # Examples + /// + /// ``` + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let array = [1i32, 2i32]; + /// let atom = AtomicPtr::new(array.as_ptr().wrapping_add(1) as *mut _); + /// + /// assert!(core::ptr::eq(atom.fetch_ptr_sub(1, Ordering::Relaxed), &array[1])); + /// assert!(core::ptr::eq(atom.load(Ordering::Relaxed), &array[0])); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T { + self.fetch_byte_sub(val.wrapping_mul(core::mem::size_of::()), order) + } + + /// Offsets the pointer's address by adding `val` *bytes*, returning the + /// previous pointer. + /// + /// This is equivalent to using [`wrapping_add`] and [`cast`] to atomically + /// perform `ptr = ptr.cast::().wrapping_add(val).cast::()`. + /// + /// `fetch_byte_add` takes an [`Ordering`] argument which describes the + /// memory ordering of this operation. All ordering modes are possible. Note + /// that using [`Acquire`] makes the store part of this operation + /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`]. + /// + /// [`wrapping_add`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_add + /// [`cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast + /// + /// # Examples + /// + /// ``` + /// # #![allow(unstable_name_collisions)] + /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let atom = AtomicPtr::::new(core::ptr::null_mut()); + /// assert_eq!(atom.fetch_byte_add(1, Ordering::Relaxed).addr(), 0); + /// // Note: in units of bytes, not `size_of::()`. + /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 1); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T { + self.inner.fetch_byte_add(val, order) + } + + /// Offsets the pointer's address by subtracting `val` *bytes*, returning the + /// previous pointer. + /// + /// This is equivalent to using [`wrapping_sub`] and [`cast`] to atomically + /// perform `ptr = ptr.cast::().wrapping_sub(val).cast::()`. + /// + /// `fetch_byte_sub` takes an [`Ordering`] argument which describes the + /// memory ordering of this operation. All ordering modes are possible. Note + /// that using [`Acquire`] makes the store part of this operation + /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`]. + /// + /// [`wrapping_sub`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_sub + /// [`cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast + /// + /// # Examples + /// + /// ``` + /// # #![allow(unstable_name_collisions)] + /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let atom = AtomicPtr::::new(sptr::invalid_mut(1)); + /// assert_eq!(atom.fetch_byte_sub(1, Ordering::Relaxed).addr(), 1); + /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 0); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T { + self.inner.fetch_byte_sub(val, order) + } + + /// Performs a bitwise "or" operation on the address of the current pointer, + /// and the argument `val`, and stores a pointer with provenance of the + /// current pointer and the resulting address. + /// + /// This is equivalent to using [`map_addr`] to atomically perform + /// `ptr = ptr.map_addr(|a| a | val)`. This can be used in tagged + /// pointer schemes to atomically set tag bits. + /// + /// **Caveat**: This operation returns the previous value. To compute the + /// stored value without losing provenance, you may use [`map_addr`]. For + /// example: `a.fetch_or(val).map_addr(|a| a | val)`. + /// + /// `fetch_or` takes an [`Ordering`] argument which describes the memory + /// ordering of this operation. All ordering modes are possible. Note that + /// using [`Acquire`] makes the store part of this operation [`Relaxed`], + /// and using [`Release`] makes the load part [`Relaxed`]. + /// + /// This API and its claimed semantics are part of the Strict Provenance + /// experiment, see the [module documentation for `ptr`][core::ptr] for + /// details. + /// + /// [`map_addr`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.map_addr + /// + /// # Examples + /// + /// ``` + /// # #![allow(unstable_name_collisions)] + /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let pointer = &mut 3i64 as *mut i64; + /// + /// let atom = AtomicPtr::::new(pointer); + /// // Tag the bottom bit of the pointer. + /// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 0); + /// // Extract and untag. + /// let tagged = atom.load(Ordering::Relaxed); + /// assert_eq!(tagged.addr() & 1, 1); + /// assert_eq!(tagged.map_addr(|p| p & !1), pointer); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T { + self.inner.fetch_or(val, order) + } + + /// Performs a bitwise "and" operation on the address of the current + /// pointer, and the argument `val`, and stores a pointer with provenance of + /// the current pointer and the resulting address. + /// + /// This is equivalent to using [`map_addr`] to atomically perform + /// `ptr = ptr.map_addr(|a| a & val)`. This can be used in tagged + /// pointer schemes to atomically unset tag bits. + /// + /// **Caveat**: This operation returns the previous value. To compute the + /// stored value without losing provenance, you may use [`map_addr`]. For + /// example: `a.fetch_and(val).map_addr(|a| a & val)`. + /// + /// `fetch_and` takes an [`Ordering`] argument which describes the memory + /// ordering of this operation. All ordering modes are possible. Note that + /// using [`Acquire`] makes the store part of this operation [`Relaxed`], + /// and using [`Release`] makes the load part [`Relaxed`]. + /// + /// This API and its claimed semantics are part of the Strict Provenance + /// experiment, see the [module documentation for `ptr`][core::ptr] for + /// details. + /// + /// [`map_addr`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.map_addr + /// + /// # Examples + /// + /// ``` + /// # #![allow(unstable_name_collisions)] + /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let pointer = &mut 3i64 as *mut i64; + /// // A tagged pointer + /// let atom = AtomicPtr::::new(pointer.map_addr(|a| a | 1)); + /// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 1); + /// // Untag, and extract the previously tagged pointer. + /// let untagged = atom.fetch_and(!1, Ordering::Relaxed).map_addr(|a| a & !1); + /// assert_eq!(untagged, pointer); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T { + self.inner.fetch_and(val, order) + } + + /// Performs a bitwise "xor" operation on the address of the current + /// pointer, and the argument `val`, and stores a pointer with provenance of + /// the current pointer and the resulting address. + /// + /// This is equivalent to using [`map_addr`] to atomically perform + /// `ptr = ptr.map_addr(|a| a ^ val)`. This can be used in tagged + /// pointer schemes to atomically toggle tag bits. + /// + /// **Caveat**: This operation returns the previous value. To compute the + /// stored value without losing provenance, you may use [`map_addr`]. For + /// example: `a.fetch_xor(val).map_addr(|a| a ^ val)`. + /// + /// `fetch_xor` takes an [`Ordering`] argument which describes the memory + /// ordering of this operation. All ordering modes are possible. Note that + /// using [`Acquire`] makes the store part of this operation [`Relaxed`], + /// and using [`Release`] makes the load part [`Relaxed`]. + /// + /// This API and its claimed semantics are part of the Strict Provenance + /// experiment, see the [module documentation for `ptr`][core::ptr] for + /// details. + /// + /// [`map_addr`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.map_addr + /// + /// # Examples + /// + /// ``` + /// # #![allow(unstable_name_collisions)] + /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let pointer = &mut 3i64 as *mut i64; + /// let atom = AtomicPtr::::new(pointer); + /// + /// // Toggle a tag bit on the pointer. + /// atom.fetch_xor(1, Ordering::Relaxed); + /// assert_eq!(atom.load(Ordering::Relaxed).addr() & 1, 1); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T { + self.inner.fetch_xor(val, order) + } + + /// Sets the bit at the specified bit-position to 1. + /// + /// Returns `true` if the specified bit was previously set to 1. + /// + /// `bit_set` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// This corresponds to x86's `lock bts`, and the implementation calls them on x86/x86_64. + /// + /// # Examples + /// + /// ``` + /// # #![allow(unstable_name_collisions)] + /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let pointer = &mut 3i64 as *mut i64; + /// + /// let atom = AtomicPtr::::new(pointer); + /// // Tag the bottom bit of the pointer. + /// assert!(!atom.bit_set(0, Ordering::Relaxed)); + /// // Extract and untag. + /// let tagged = atom.load(Ordering::Relaxed); + /// assert_eq!(tagged.addr() & 1, 1); + /// assert_eq!(tagged.map_addr(|p| p & !1), pointer); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn bit_set(&self, bit: u32, order: Ordering) -> bool { + self.inner.bit_set(bit, order) + } + + /// Clears the bit at the specified bit-position to 0. + /// + /// Returns `true` if the specified bit was previously set to 1. + /// + /// `bit_clear` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// This corresponds to x86's `lock btr`, and the implementation calls them on x86/x86_64. + /// + /// # Examples + /// + /// ``` + /// # #![allow(unstable_name_collisions)] + /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let pointer = &mut 3i64 as *mut i64; + /// // A tagged pointer + /// let atom = AtomicPtr::::new(pointer.map_addr(|a| a | 1)); + /// assert!(atom.bit_set(0, Ordering::Relaxed)); + /// // Untag + /// assert!(atom.bit_clear(0, Ordering::Relaxed)); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn bit_clear(&self, bit: u32, order: Ordering) -> bool { + self.inner.bit_clear(bit, order) + } + + /// Toggles the bit at the specified bit-position. + /// + /// Returns `true` if the specified bit was previously set to 1. + /// + /// `bit_toggle` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// This corresponds to x86's `lock btc`, and the implementation calls them on x86/x86_64. + /// + /// # Examples + /// + /// ``` + /// # #![allow(unstable_name_collisions)] + /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc + /// use portable_atomic::{AtomicPtr, Ordering}; + /// + /// let pointer = &mut 3i64 as *mut i64; + /// let atom = AtomicPtr::::new(pointer); + /// + /// // Toggle a tag bit on the pointer. + /// atom.bit_toggle(0, Ordering::Relaxed); + /// assert_eq!(atom.load(Ordering::Relaxed).addr() & 1, 1); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn bit_toggle(&self, bit: u32, order: Ordering) -> bool { + self.inner.bit_toggle(bit, order) + } + } // cfg_has_atomic_cas_or_amo32! + + const_fn! { + const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))]; + /// Returns a mutable pointer to the underlying pointer. + /// + /// Returning an `*mut` pointer from a shared reference to this atomic is + /// safe because the atomic types work with interior mutability. Any use of + /// the returned raw pointer requires an `unsafe` block and has to uphold + /// the safety requirements. If there is concurrent access, note the following + /// additional safety requirements: + /// + /// - If this atomic type is [lock-free](Self::is_lock_free), any concurrent + /// operations on it must be atomic. + /// - Otherwise, any concurrent operations on it must be compatible with + /// operations performed by this atomic type. + /// + /// This is `const fn` on Rust 1.58+. + #[inline] + pub const fn as_ptr(&self) -> *mut *mut T { + self.inner.as_ptr() + } + } +} +// See https://github.com/taiki-e/portable-atomic/issues/180 +#[cfg(not(feature = "require-cas"))] +cfg_no_atomic_cas! { +#[doc(hidden)] +#[allow(unused_variables, clippy::unused_self, clippy::extra_unused_lifetimes)] +impl<'a, T: 'a> AtomicPtr { + cfg_no_atomic_cas_or_amo32! { + #[inline] + pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T + where + &'a Self: HasSwap, + { + unimplemented!() + } + } // cfg_no_atomic_cas_or_amo32! + #[inline] + pub fn compare_exchange( + &self, + current: *mut T, + new: *mut T, + success: Ordering, + failure: Ordering, + ) -> Result<*mut T, *mut T> + where + &'a Self: HasCompareExchange, + { + unimplemented!() + } + #[inline] + pub fn compare_exchange_weak( + &self, + current: *mut T, + new: *mut T, + success: Ordering, + failure: Ordering, + ) -> Result<*mut T, *mut T> + where + &'a Self: HasCompareExchangeWeak, + { + unimplemented!() + } + #[inline] + pub fn fetch_update( + &self, + set_order: Ordering, + fetch_order: Ordering, + f: F, + ) -> Result<*mut T, *mut T> + where + F: FnMut(*mut T) -> Option<*mut T>, + &'a Self: HasFetchUpdate, + { + unimplemented!() + } + cfg_no_atomic_cas_or_amo32! { + #[inline] + pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T + where + &'a Self: HasFetchPtrAdd, + { + unimplemented!() + } + #[inline] + pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T + where + &'a Self: HasFetchPtrSub, + { + unimplemented!() + } + #[inline] + pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T + where + &'a Self: HasFetchByteAdd, + { + unimplemented!() + } + #[inline] + pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T + where + &'a Self: HasFetchByteSub, + { + unimplemented!() + } + #[inline] + pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T + where + &'a Self: HasFetchOr, + { + unimplemented!() + } + #[inline] + pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T + where + &'a Self: HasFetchAnd, + { + unimplemented!() + } + #[inline] + pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T + where + &'a Self: HasFetchXor, + { + unimplemented!() + } + #[inline] + pub fn bit_set(&self, bit: u32, order: Ordering) -> bool + where + &'a Self: HasBitSet, + { + unimplemented!() + } + #[inline] + pub fn bit_clear(&self, bit: u32, order: Ordering) -> bool + where + &'a Self: HasBitClear, + { + unimplemented!() + } + #[inline] + pub fn bit_toggle(&self, bit: u32, order: Ordering) -> bool + where + &'a Self: HasBitToggle, + { + unimplemented!() + } + } // cfg_no_atomic_cas_or_amo32! +} +} // cfg_no_atomic_cas! +} // cfg_has_atomic_ptr! + +macro_rules! atomic_int { + // Atomic{I,U}* impls + ($atomic_type:ident, $int_type:ident, $align:literal, + $cfg_has_atomic_cas_or_amo32_or_8:ident, $cfg_no_atomic_cas_or_amo32_or_8:ident + $(, #[$cfg_float:meta] $atomic_float_type:ident, $float_type:ident)? + ) => { + doc_comment! { + concat!("An integer type which can be safely shared between threads. + +This type has the same in-memory representation as the underlying integer type, +[`", stringify!($int_type), "`]. + +If the compiler and the platform support atomic loads and stores of [`", stringify!($int_type), +"`], this type is a wrapper for the standard library's `", stringify!($atomic_type), +"`. If the platform supports it but the compiler does not, atomic operations are implemented using +inline assembly. Otherwise synchronizes using global locks. +You can call [`", stringify!($atomic_type), "::is_lock_free()`] to check whether +atomic instructions or locks will be used. +" + ), + // We can use #[repr(transparent)] here, but #[repr(C, align(N))] + // will show clearer docs. + #[repr(C, align($align))] + pub struct $atomic_type { + inner: imp::$atomic_type, + } + } + + impl Default for $atomic_type { + #[inline] + fn default() -> Self { + Self::new($int_type::default()) + } + } + + impl From<$int_type> for $atomic_type { + #[inline] + fn from(v: $int_type) -> Self { + Self::new(v) + } + } + + // UnwindSafe is implicitly implemented. + #[cfg(not(portable_atomic_no_core_unwind_safe))] + impl core::panic::RefUnwindSafe for $atomic_type {} + #[cfg(all(portable_atomic_no_core_unwind_safe, feature = "std"))] + impl std::panic::RefUnwindSafe for $atomic_type {} + + impl_debug_and_serde!($atomic_type); + + impl $atomic_type { + doc_comment! { + concat!( + "Creates a new atomic integer. + +# Examples + +``` +use portable_atomic::", stringify!($atomic_type), "; + +let atomic_forty_two = ", stringify!($atomic_type), "::new(42); +```" + ), + #[inline] + #[must_use] + pub const fn new(v: $int_type) -> Self { + static_assert_layout!($atomic_type, $int_type); + Self { inner: imp::$atomic_type::new(v) } + } + } + + // TODO: update docs based on https://github.com/rust-lang/rust/pull/116762 + #[cfg(not(portable_atomic_no_const_raw_ptr_deref))] + doc_comment! { + concat!("Creates a new reference to an atomic integer from a pointer. + +This is `const fn` on Rust 1.58+. + +# Safety + +* `ptr` must be aligned to `align_of::<", stringify!($atomic_type), ">()` (note that on some platforms this + can be bigger than `align_of::<", stringify!($int_type), ">()`). +* `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`. +* If this atomic type is [lock-free](Self::is_lock_free), non-atomic accesses to the value + behind `ptr` must have a happens-before relationship with atomic accesses via + the returned value (or vice-versa). + * In other words, time periods where the value is accessed atomically may not + overlap with periods where the value is accessed non-atomically. + * This requirement is trivially satisfied if `ptr` is never used non-atomically + for the duration of lifetime `'a`. Most use cases should be able to follow + this guideline. + * This requirement is also trivially satisfied if all accesses (atomic or not) are + done from the same thread. +* If this atomic type is *not* lock-free: + * Any accesses to the value behind `ptr` must have a happens-before relationship + with accesses via the returned value (or vice-versa). + * Any concurrent accesses to the value behind `ptr` for the duration of lifetime `'a` must + be compatible with operations performed by this atomic type. +* This method must not be used to create overlapping or mixed-size atomic + accesses, as these are not supported by the memory model. + +[valid]: core::ptr#safety"), + #[inline] + #[must_use] + pub const unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a Self { + #[allow(clippy::cast_ptr_alignment)] + // SAFETY: guaranteed by the caller + unsafe { &*(ptr as *mut Self as *const Self) } + } + } + #[cfg(portable_atomic_no_const_raw_ptr_deref)] + doc_comment! { + concat!("Creates a new reference to an atomic integer from a pointer. + +This is `const fn` on Rust 1.58+. + +# Safety + +* `ptr` must be aligned to `align_of::<", stringify!($atomic_type), ">()` (note that on some platforms this + can be bigger than `align_of::<", stringify!($int_type), ">()`). +* `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`. +* If this atomic type is [lock-free](Self::is_lock_free), non-atomic accesses to the value + behind `ptr` must have a happens-before relationship with atomic accesses via + the returned value (or vice-versa). + * In other words, time periods where the value is accessed atomically may not + overlap with periods where the value is accessed non-atomically. + * This requirement is trivially satisfied if `ptr` is never used non-atomically + for the duration of lifetime `'a`. Most use cases should be able to follow + this guideline. + * This requirement is also trivially satisfied if all accesses (atomic or not) are + done from the same thread. +* If this atomic type is *not* lock-free: + * Any accesses to the value behind `ptr` must have a happens-before relationship + with accesses via the returned value (or vice-versa). + * Any concurrent accesses to the value behind `ptr` for the duration of lifetime `'a` must + be compatible with operations performed by this atomic type. +* This method must not be used to create overlapping or mixed-size atomic + accesses, as these are not supported by the memory model. + +[valid]: core::ptr#safety"), + #[inline] + #[must_use] + pub unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a Self { + #[allow(clippy::cast_ptr_alignment)] + // SAFETY: guaranteed by the caller + unsafe { &*(ptr as *mut Self as *const Self) } + } + } + + doc_comment! { + concat!("Returns `true` if operations on values of this type are lock-free. + +If the compiler or the platform doesn't support the necessary +atomic instructions, global locks for every potentially +concurrent atomic operation will be used. + +This function is guaranteed to always return the same result. + +# Examples + +``` +use portable_atomic::", stringify!($atomic_type), "; + +let is_lock_free = ", stringify!($atomic_type), "::is_lock_free(); +```"), + #[inline] + #[must_use] + pub fn is_lock_free() -> bool { + ::is_lock_free() + } + } + + doc_comment! { + concat!("Returns `true` if operations on values of this type are lock-free. + +If the compiler or the platform doesn't support the necessary +atomic instructions, global locks for every potentially +concurrent atomic operation will be used. + +**Note:** If the atomic operation relies on dynamic CPU feature detection, +this type may be lock-free even if the function returns false. + +# Examples + +``` +use portable_atomic::", stringify!($atomic_type), "; + +const IS_ALWAYS_LOCK_FREE: bool = ", stringify!($atomic_type), "::is_always_lock_free(); +```"), + #[inline] + #[must_use] + pub const fn is_always_lock_free() -> bool { + ::IS_ALWAYS_LOCK_FREE + } + } + #[cfg(test)] + #[cfg_attr(all(valgrind, target_arch = "powerpc64"), allow(dead_code))] // TODO(powerpc64): Hang (as of Valgrind 3.26) + const IS_ALWAYS_LOCK_FREE: bool = Self::is_always_lock_free(); + + #[cfg(not(portable_atomic_no_const_mut_refs))] + doc_comment! { + concat!("Returns a mutable reference to the underlying integer.\n +This is safe because the mutable reference guarantees that no other threads are +concurrently accessing the atomic data. + +This is `const fn` on Rust 1.83+. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let mut some_var = ", stringify!($atomic_type), "::new(10); +assert_eq!(*some_var.get_mut(), 10); +*some_var.get_mut() = 5; +assert_eq!(some_var.load(Ordering::SeqCst), 5); +```"), + #[inline] + pub const fn get_mut(&mut self) -> &mut $int_type { + // SAFETY: the mutable reference guarantees unique ownership. + // (core::sync::atomic::Atomic*::get_mut is not const yet) + unsafe { &mut *self.as_ptr() } + } + } + #[cfg(portable_atomic_no_const_mut_refs)] + doc_comment! { + concat!("Returns a mutable reference to the underlying integer.\n +This is safe because the mutable reference guarantees that no other threads are +concurrently accessing the atomic data. + +This is `const fn` on Rust 1.83+. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let mut some_var = ", stringify!($atomic_type), "::new(10); +assert_eq!(*some_var.get_mut(), 10); +*some_var.get_mut() = 5; +assert_eq!(some_var.load(Ordering::SeqCst), 5); +```"), + #[inline] + pub fn get_mut(&mut self) -> &mut $int_type { + // SAFETY: the mutable reference guarantees unique ownership. + unsafe { &mut *self.as_ptr() } + } + } + + // TODO: Add from_mut/get_mut_slice/from_mut_slice once it is stable on std atomic types. + // https://github.com/rust-lang/rust/issues/76314 + + #[cfg(not(portable_atomic_no_const_transmute))] + doc_comment! { + concat!("Consumes the atomic and returns the contained value. + +This is safe because passing `self` by value guarantees that no other threads are +concurrently accessing the atomic data. + +This is `const fn` on Rust 1.56+. + +# Examples + +``` +use portable_atomic::", stringify!($atomic_type), "; + +let some_var = ", stringify!($atomic_type), "::new(5); +assert_eq!(some_var.into_inner(), 5); +```"), + #[inline] + pub const fn into_inner(self) -> $int_type { + // SAFETY: $atomic_type and $int_type have the same size and in-memory representations, + // so they can be safely transmuted. + // (const UnsafeCell::into_inner is unstable) + unsafe { core::mem::transmute(self) } + } + } + #[cfg(portable_atomic_no_const_transmute)] + doc_comment! { + concat!("Consumes the atomic and returns the contained value. + +This is safe because passing `self` by value guarantees that no other threads are +concurrently accessing the atomic data. + +This is `const fn` on Rust 1.56+. + +# Examples + +``` +use portable_atomic::", stringify!($atomic_type), "; + +let some_var = ", stringify!($atomic_type), "::new(5); +assert_eq!(some_var.into_inner(), 5); +```"), + #[inline] + pub fn into_inner(self) -> $int_type { + // SAFETY: $atomic_type and $int_type have the same size and in-memory representations, + // so they can be safely transmuted. + // (const UnsafeCell::into_inner is unstable) + unsafe { core::mem::transmute(self) } + } + } + + doc_comment! { + concat!("Loads a value from the atomic integer. + +`load` takes an [`Ordering`] argument which describes the memory ordering of this operation. +Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`]. + +# Panics + +Panics if `order` is [`Release`] or [`AcqRel`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let some_var = ", stringify!($atomic_type), "::new(5); + +assert_eq!(some_var.load(Ordering::Relaxed), 5); +```"), + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn load(&self, order: Ordering) -> $int_type { + self.inner.load(order) + } + } + + doc_comment! { + concat!("Stores a value into the atomic integer. + +`store` takes an [`Ordering`] argument which describes the memory ordering of this operation. +Possible values are [`SeqCst`], [`Release`] and [`Relaxed`]. + +# Panics + +Panics if `order` is [`Acquire`] or [`AcqRel`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let some_var = ", stringify!($atomic_type), "::new(5); + +some_var.store(10, Ordering::Relaxed); +assert_eq!(some_var.load(Ordering::Relaxed), 10); +```"), + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn store(&self, val: $int_type, order: Ordering) { + self.inner.store(val, order) + } + } + + cfg_has_atomic_cas_or_amo32! { + $cfg_has_atomic_cas_or_amo32_or_8! { + doc_comment! { + concat!("Stores a value into the atomic integer, returning the previous value. + +`swap` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let some_var = ", stringify!($atomic_type), "::new(5); + +assert_eq!(some_var.swap(10, Ordering::Relaxed), 5); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { + self.inner.swap(val, order) + } + } + } // $cfg_has_atomic_cas_or_amo32_or_8! + + cfg_has_atomic_cas! { + doc_comment! { + concat!("Stores a value into the atomic integer if the current value is the same as +the `current` value. + +The return value is a result indicating whether the new value was written and +containing the previous value. On success this value is guaranteed to be equal to +`current`. + +`compare_exchange` takes two [`Ordering`] arguments to describe the memory +ordering of this operation. `success` describes the required ordering for the +read-modify-write operation that takes place if the comparison with `current` succeeds. +`failure` describes the required ordering for the load operation that takes place when +the comparison fails. Using [`Acquire`] as success ordering makes the store part +of this operation [`Relaxed`], and using [`Release`] makes the successful load +[`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]. + +# Panics + +Panics if `failure` is [`Release`], [`AcqRel`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let some_var = ", stringify!($atomic_type), "::new(5); + +assert_eq!( + some_var.compare_exchange(5, 10, Ordering::Acquire, Ordering::Relaxed), + Ok(5), +); +assert_eq!(some_var.load(Ordering::Relaxed), 10); + +assert_eq!( + some_var.compare_exchange(6, 12, Ordering::SeqCst, Ordering::Acquire), + Err(10), +); +assert_eq!(some_var.load(Ordering::Relaxed), 10); +```"), + #[cfg_attr(docsrs, doc(alias = "compare_and_swap"))] + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn compare_exchange( + &self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering, + ) -> Result<$int_type, $int_type> { + self.inner.compare_exchange(current, new, success, failure) + } + } + + doc_comment! { + concat!("Stores a value into the atomic integer if the current value is the same as +the `current` value. +Unlike [`compare_exchange`](Self::compare_exchange) +this function is allowed to spuriously fail even +when the comparison succeeds, which can result in more efficient code on some +platforms. The return value is a result indicating whether the new value was +written and containing the previous value. + +`compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory +ordering of this operation. `success` describes the required ordering for the +read-modify-write operation that takes place if the comparison with `current` succeeds. +`failure` describes the required ordering for the load operation that takes place when +the comparison fails. Using [`Acquire`] as success ordering makes the store part +of this operation [`Relaxed`], and using [`Release`] makes the successful load +[`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]. + +# Panics + +Panics if `failure` is [`Release`], [`AcqRel`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let val = ", stringify!($atomic_type), "::new(4); + +let mut old = val.load(Ordering::Relaxed); +loop { + let new = old * 2; + match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { + Ok(_) => break, + Err(x) => old = x, + } +} +```"), + #[cfg_attr(docsrs, doc(alias = "compare_and_swap"))] + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn compare_exchange_weak( + &self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering, + ) -> Result<$int_type, $int_type> { + self.inner.compare_exchange_weak(current, new, success, failure) + } + } + } // cfg_has_atomic_cas! + + $cfg_has_atomic_cas_or_amo32_or_8! { + doc_comment! { + concat!("Adds to the current value, returning the previous value. + +This operation wraps around on overflow. + +`fetch_add` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0); +assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0); +assert_eq!(foo.load(Ordering::SeqCst), 10); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { + self.inner.fetch_add(val, order) + } + } + + doc_comment! { + concat!("Adds to the current value. + +This operation wraps around on overflow. + +Unlike `fetch_add`, this does not return the previous value. + +`add` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +This function may generate more efficient code than `fetch_add` on some platforms. + +- MSP430: `add` instead of disabling interrupts ({8,16}-bit atomics) + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0); +foo.add(10, Ordering::SeqCst); +assert_eq!(foo.load(Ordering::SeqCst), 10); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn add(&self, val: $int_type, order: Ordering) { + self.inner.add(val, order); + } + } + + doc_comment! { + concat!("Subtracts from the current value, returning the previous value. + +This operation wraps around on overflow. + +`fetch_sub` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(20); +assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20); +assert_eq!(foo.load(Ordering::SeqCst), 10); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { + self.inner.fetch_sub(val, order) + } + } + + doc_comment! { + concat!("Subtracts from the current value. + +This operation wraps around on overflow. + +Unlike `fetch_sub`, this does not return the previous value. + +`sub` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +This function may generate more efficient code than `fetch_sub` on some platforms. + +- MSP430: `sub` instead of disabling interrupts ({8,16}-bit atomics) + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(20); +foo.sub(10, Ordering::SeqCst); +assert_eq!(foo.load(Ordering::SeqCst), 10); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn sub(&self, val: $int_type, order: Ordering) { + self.inner.sub(val, order); + } + } + } // $cfg_has_atomic_cas_or_amo32_or_8! + + doc_comment! { + concat!("Bitwise \"and\" with the current value. + +Performs a bitwise \"and\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +`fetch_and` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b101101); +assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101); +assert_eq!(foo.load(Ordering::SeqCst), 0b100001); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { + self.inner.fetch_and(val, order) + } + } + + doc_comment! { + concat!("Bitwise \"and\" with the current value. + +Performs a bitwise \"and\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Unlike `fetch_and`, this does not return the previous value. + +`and` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +This function may generate more efficient code than `fetch_and` on some platforms. + +- x86/x86_64: `lock and` instead of `cmpxchg` loop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64) +- MSP430: `and` instead of disabling interrupts ({8,16}-bit atomics) + +Note: On x86/x86_64, the use of either function should not usually +affect the generated code, because LLVM can properly optimize the case +where the result is unused. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b101101); +assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101); +assert_eq!(foo.load(Ordering::SeqCst), 0b100001); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn and(&self, val: $int_type, order: Ordering) { + self.inner.and(val, order); + } + } + + cfg_has_atomic_cas! { + doc_comment! { + concat!("Bitwise \"nand\" with the current value. + +Performs a bitwise \"nand\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +`fetch_nand` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0x13); +assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13); +assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31)); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { + self.inner.fetch_nand(val, order) + } + } + } // cfg_has_atomic_cas! + + doc_comment! { + concat!("Bitwise \"or\" with the current value. + +Performs a bitwise \"or\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +`fetch_or` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b101101); +assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101); +assert_eq!(foo.load(Ordering::SeqCst), 0b111111); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { + self.inner.fetch_or(val, order) + } + } + + doc_comment! { + concat!("Bitwise \"or\" with the current value. + +Performs a bitwise \"or\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Unlike `fetch_or`, this does not return the previous value. + +`or` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +This function may generate more efficient code than `fetch_or` on some platforms. + +- x86/x86_64: `lock or` instead of `cmpxchg` loop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64) +- MSP430: `or` instead of disabling interrupts ({8,16}-bit atomics) + +Note: On x86/x86_64, the use of either function should not usually +affect the generated code, because LLVM can properly optimize the case +where the result is unused. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b101101); +assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101); +assert_eq!(foo.load(Ordering::SeqCst), 0b111111); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn or(&self, val: $int_type, order: Ordering) { + self.inner.or(val, order); + } + } + + doc_comment! { + concat!("Bitwise \"xor\" with the current value. + +Performs a bitwise \"xor\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +`fetch_xor` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b101101); +assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101); +assert_eq!(foo.load(Ordering::SeqCst), 0b011110); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { + self.inner.fetch_xor(val, order) + } + } + + doc_comment! { + concat!("Bitwise \"xor\" with the current value. + +Performs a bitwise \"xor\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Unlike `fetch_xor`, this does not return the previous value. + +`xor` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +This function may generate more efficient code than `fetch_xor` on some platforms. + +- x86/x86_64: `lock xor` instead of `cmpxchg` loop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64) +- MSP430: `xor` instead of disabling interrupts ({8,16}-bit atomics) + +Note: On x86/x86_64, the use of either function should not usually +affect the generated code, because LLVM can properly optimize the case +where the result is unused. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b101101); +foo.xor(0b110011, Ordering::SeqCst); +assert_eq!(foo.load(Ordering::SeqCst), 0b011110); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn xor(&self, val: $int_type, order: Ordering) { + self.inner.xor(val, order); + } + } + + cfg_has_atomic_cas! { + doc_comment! { + concat!("Fetches the value, and applies a function to it that returns an optional +new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else +`Err(previous_value)`. + +Note: This may call the function multiple times if the value has been changed from other threads in +the meantime, as long as the function returns `Some(_)`, but the function will have been applied +only once to the stored value. + +`fetch_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation. +The first describes the required ordering for when the operation finally succeeds while the second +describes the required ordering for loads. These correspond to the success and failure orderings of +[`compare_exchange`](Self::compare_exchange) respectively. + +Using [`Acquire`] as success ordering makes the store part +of this operation [`Relaxed`], and using [`Release`] makes the final successful load +[`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]. + +# Panics + +Panics if `fetch_order` is [`Release`], [`AcqRel`]. + +# Considerations + +This method is not magic; it is not provided by the hardware. +It is implemented in terms of [`compare_exchange_weak`](Self::compare_exchange_weak), +and suffers from the same drawbacks. +In particular, this method will not circumvent the [ABA Problem]. + +[ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let x = ", stringify!($atomic_type), "::new(7); +assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7)); +assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7)); +assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8)); +assert_eq!(x.load(Ordering::SeqCst), 9); +```"), + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn fetch_update( + &self, + set_order: Ordering, + fetch_order: Ordering, + mut f: F, + ) -> Result<$int_type, $int_type> + where + F: FnMut($int_type) -> Option<$int_type>, + { + let mut prev = self.load(fetch_order); + while let Some(next) = f(prev) { + match self.compare_exchange_weak(prev, next, set_order, fetch_order) { + x @ Ok(_) => return x, + Err(next_prev) => prev = next_prev, + } + } + Err(prev) + } + } + } // cfg_has_atomic_cas! + + $cfg_has_atomic_cas_or_amo32_or_8! { + doc_comment! { + concat!("Maximum with the current value. + +Finds the maximum of the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +`fetch_max` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(23); +assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23); +assert_eq!(foo.load(Ordering::SeqCst), 42); +``` + +If you want to obtain the maximum value in one step, you can use the following: + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(23); +let bar = 42; +let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar); +assert!(max_foo == 42); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { + self.inner.fetch_max(val, order) + } + } + + doc_comment! { + concat!("Minimum with the current value. + +Finds the minimum of the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +`fetch_min` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(23); +assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23); +assert_eq!(foo.load(Ordering::Relaxed), 23); +assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23); +assert_eq!(foo.load(Ordering::Relaxed), 22); +``` + +If you want to obtain the minimum value in one step, you can use the following: + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(23); +let bar = 12; +let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar); +assert_eq!(min_foo, 12); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { + self.inner.fetch_min(val, order) + } + } + } // $cfg_has_atomic_cas_or_amo32_or_8! + + doc_comment! { + concat!("Sets the bit at the specified bit-position to 1. + +Returns `true` if the specified bit was previously set to 1. + +`bit_set` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +This corresponds to x86's `lock bts`, and the implementation calls them on x86/x86_64. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b0000); +assert!(!foo.bit_set(0, Ordering::Relaxed)); +assert_eq!(foo.load(Ordering::Relaxed), 0b0001); +assert!(foo.bit_set(0, Ordering::Relaxed)); +assert_eq!(foo.load(Ordering::Relaxed), 0b0001); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn bit_set(&self, bit: u32, order: Ordering) -> bool { + self.inner.bit_set(bit, order) + } + } + + doc_comment! { + concat!("Clears the bit at the specified bit-position to 0. + +Returns `true` if the specified bit was previously set to 1. + +`bit_clear` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +This corresponds to x86's `lock btr`, and the implementation calls them on x86/x86_64. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b0001); +assert!(foo.bit_clear(0, Ordering::Relaxed)); +assert_eq!(foo.load(Ordering::Relaxed), 0b0000); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn bit_clear(&self, bit: u32, order: Ordering) -> bool { + self.inner.bit_clear(bit, order) + } + } + + doc_comment! { + concat!("Toggles the bit at the specified bit-position. + +Returns `true` if the specified bit was previously set to 1. + +`bit_toggle` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +This corresponds to x86's `lock btc`, and the implementation calls them on x86/x86_64. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b0000); +assert!(!foo.bit_toggle(0, Ordering::Relaxed)); +assert_eq!(foo.load(Ordering::Relaxed), 0b0001); +assert!(foo.bit_toggle(0, Ordering::Relaxed)); +assert_eq!(foo.load(Ordering::Relaxed), 0b0000); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn bit_toggle(&self, bit: u32, order: Ordering) -> bool { + self.inner.bit_toggle(bit, order) + } + } + + doc_comment! { + concat!("Logical negates the current value, and sets the new value to the result. + +Returns the previous value. + +`fetch_not` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0); +assert_eq!(foo.fetch_not(Ordering::Relaxed), 0); +assert_eq!(foo.load(Ordering::Relaxed), !0); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_not(&self, order: Ordering) -> $int_type { + self.inner.fetch_not(order) + } + } + + doc_comment! { + concat!("Logical negates the current value, and sets the new value to the result. + +Unlike `fetch_not`, this does not return the previous value. + +`not` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +This function may generate more efficient code than `fetch_not` on some platforms. + +- x86/x86_64: `lock not` instead of `cmpxchg` loop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64) +- MSP430: `inv` instead of disabling interrupts ({8,16}-bit atomics) + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0); +foo.not(Ordering::Relaxed); +assert_eq!(foo.load(Ordering::Relaxed), !0); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn not(&self, order: Ordering) { + self.inner.not(order); + } + } + + cfg_has_atomic_cas! { + doc_comment! { + concat!("Negates the current value, and sets the new value to the result. + +Returns the previous value. + +`fetch_neg` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(5); +assert_eq!(foo.fetch_neg(Ordering::Relaxed), 5); +assert_eq!(foo.load(Ordering::Relaxed), 5_", stringify!($int_type), ".wrapping_neg()); +assert_eq!(foo.fetch_neg(Ordering::Relaxed), 5_", stringify!($int_type), ".wrapping_neg()); +assert_eq!(foo.load(Ordering::Relaxed), 5); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_neg(&self, order: Ordering) -> $int_type { + self.inner.fetch_neg(order) + } + } + + doc_comment! { + concat!("Negates the current value, and sets the new value to the result. + +Unlike `fetch_neg`, this does not return the previous value. + +`neg` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +This function may generate more efficient code than `fetch_neg` on some platforms. + +- x86/x86_64: `lock neg` instead of `cmpxchg` loop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64) + +# Examples + +``` +use portable_atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(5); +foo.neg(Ordering::Relaxed); +assert_eq!(foo.load(Ordering::Relaxed), 5_", stringify!($int_type), ".wrapping_neg()); +foo.neg(Ordering::Relaxed); +assert_eq!(foo.load(Ordering::Relaxed), 5); +```"), + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn neg(&self, order: Ordering) { + self.inner.neg(order); + } + } + } // cfg_has_atomic_cas! + } // cfg_has_atomic_cas_or_amo32! + + const_fn! { + const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))]; + /// Returns a mutable pointer to the underlying integer. + /// + /// Returning an `*mut` pointer from a shared reference to this atomic is + /// safe because the atomic types work with interior mutability. Any use of + /// the returned raw pointer requires an `unsafe` block and has to uphold + /// the safety requirements. If there is concurrent access, note the following + /// additional safety requirements: + /// + /// - If this atomic type is [lock-free](Self::is_lock_free), any concurrent + /// operations on it must be atomic. + /// - Otherwise, any concurrent operations on it must be compatible with + /// operations performed by this atomic type. + /// + /// This is `const fn` on Rust 1.58+. + #[inline] + pub const fn as_ptr(&self) -> *mut $int_type { + self.inner.as_ptr() + } + } + } + // See https://github.com/taiki-e/portable-atomic/issues/180 + #[cfg(not(feature = "require-cas"))] + cfg_no_atomic_cas! { + #[doc(hidden)] + #[allow(unused_variables, clippy::unused_self, clippy::extra_unused_lifetimes)] + impl<'a> $atomic_type { + $cfg_no_atomic_cas_or_amo32_or_8! { + #[inline] + pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type + where + &'a Self: HasSwap, + { + unimplemented!() + } + } // $cfg_no_atomic_cas_or_amo32_or_8! + #[inline] + pub fn compare_exchange( + &self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering, + ) -> Result<$int_type, $int_type> + where + &'a Self: HasCompareExchange, + { + unimplemented!() + } + #[inline] + pub fn compare_exchange_weak( + &self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering, + ) -> Result<$int_type, $int_type> + where + &'a Self: HasCompareExchangeWeak, + { + unimplemented!() + } + $cfg_no_atomic_cas_or_amo32_or_8! { + #[inline] + pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type + where + &'a Self: HasFetchAdd, + { + unimplemented!() + } + #[inline] + pub fn add(&self, val: $int_type, order: Ordering) + where + &'a Self: HasAdd, + { + unimplemented!() + } + #[inline] + pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type + where + &'a Self: HasFetchSub, + { + unimplemented!() + } + #[inline] + pub fn sub(&self, val: $int_type, order: Ordering) + where + &'a Self: HasSub, + { + unimplemented!() + } + } // $cfg_no_atomic_cas_or_amo32_or_8! + cfg_no_atomic_cas_or_amo32! { + #[inline] + pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type + where + &'a Self: HasFetchAnd, + { + unimplemented!() + } + #[inline] + pub fn and(&self, val: $int_type, order: Ordering) + where + &'a Self: HasAnd, + { + unimplemented!() + } + } // cfg_no_atomic_cas_or_amo32! + #[inline] + pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type + where + &'a Self: HasFetchNand, + { + unimplemented!() + } + cfg_no_atomic_cas_or_amo32! { + #[inline] + pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type + where + &'a Self: HasFetchOr, + { + unimplemented!() + } + #[inline] + pub fn or(&self, val: $int_type, order: Ordering) + where + &'a Self: HasOr, + { + unimplemented!() + } + #[inline] + pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type + where + &'a Self: HasFetchXor, + { + unimplemented!() + } + #[inline] + pub fn xor(&self, val: $int_type, order: Ordering) + where + &'a Self: HasXor, + { + unimplemented!() + } + } // cfg_no_atomic_cas_or_amo32! + #[inline] + pub fn fetch_update( + &self, + set_order: Ordering, + fetch_order: Ordering, + f: F, + ) -> Result<$int_type, $int_type> + where + F: FnMut($int_type) -> Option<$int_type>, + &'a Self: HasFetchUpdate, + { + unimplemented!() + } + $cfg_no_atomic_cas_or_amo32_or_8! { + #[inline] + pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type + where + &'a Self: HasFetchMax, + { + unimplemented!() + } + #[inline] + pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type + where + &'a Self: HasFetchMin, + { + unimplemented!() + } + } // $cfg_no_atomic_cas_or_amo32_or_8! + cfg_no_atomic_cas_or_amo32! { + #[inline] + pub fn bit_set(&self, bit: u32, order: Ordering) -> bool + where + &'a Self: HasBitSet, + { + unimplemented!() + } + #[inline] + pub fn bit_clear(&self, bit: u32, order: Ordering) -> bool + where + &'a Self: HasBitClear, + { + unimplemented!() + } + #[inline] + pub fn bit_toggle(&self, bit: u32, order: Ordering) -> bool + where + &'a Self: HasBitToggle, + { + unimplemented!() + } + #[inline] + pub fn fetch_not(&self, order: Ordering) -> $int_type + where + &'a Self: HasFetchNot, + { + unimplemented!() + } + #[inline] + pub fn not(&self, order: Ordering) + where + &'a Self: HasNot, + { + unimplemented!() + } + } // cfg_no_atomic_cas_or_amo32! + #[inline] + pub fn fetch_neg(&self, order: Ordering) -> $int_type + where + &'a Self: HasFetchNeg, + { + unimplemented!() + } + #[inline] + pub fn neg(&self, order: Ordering) + where + &'a Self: HasNeg, + { + unimplemented!() + } + } + } // cfg_no_atomic_cas! + $( + #[$cfg_float] + atomic_int!(float, + #[$cfg_float] $atomic_float_type, $float_type, $atomic_type, $int_type, $align + ); + )? + }; + + // AtomicF* impls + (float, + #[$cfg_float:meta] + $atomic_type:ident, + $float_type:ident, + $atomic_int_type:ident, + $int_type:ident, + $align:literal + ) => { + doc_comment! { + concat!("A floating point type which can be safely shared between threads. + +This type has the same in-memory representation as the underlying floating point type, +[`", stringify!($float_type), "`]. +" + ), + #[cfg_attr(docsrs, doc($cfg_float))] + // We can use #[repr(transparent)] here, but #[repr(C, align(N))] + // will show clearer docs. + #[repr(C, align($align))] + pub struct $atomic_type { + inner: imp::float::$atomic_type, + } + } + + impl Default for $atomic_type { + #[inline] + fn default() -> Self { + Self::new($float_type::default()) + } + } + + impl From<$float_type> for $atomic_type { + #[inline] + fn from(v: $float_type) -> Self { + Self::new(v) + } + } + + // UnwindSafe is implicitly implemented. + #[cfg(not(portable_atomic_no_core_unwind_safe))] + impl core::panic::RefUnwindSafe for $atomic_type {} + #[cfg(all(portable_atomic_no_core_unwind_safe, feature = "std"))] + impl std::panic::RefUnwindSafe for $atomic_type {} + + impl_debug_and_serde!($atomic_type); + + impl $atomic_type { + /// Creates a new atomic float. + #[inline] + #[must_use] + pub const fn new(v: $float_type) -> Self { + static_assert_layout!($atomic_type, $float_type); + Self { inner: imp::float::$atomic_type::new(v) } + } + + // TODO: update docs based on https://github.com/rust-lang/rust/pull/116762 + #[cfg(not(portable_atomic_no_const_raw_ptr_deref))] + doc_comment! { + concat!("Creates a new reference to an atomic float from a pointer. + +This is `const fn` on Rust 1.58+. + +# Safety + +* `ptr` must be aligned to `align_of::<", stringify!($atomic_type), ">()` (note that on some platforms this + can be bigger than `align_of::<", stringify!($float_type), ">()`). +* `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`. +* If this atomic type is [lock-free](Self::is_lock_free), non-atomic accesses to the value + behind `ptr` must have a happens-before relationship with atomic accesses via + the returned value (or vice-versa). + * In other words, time periods where the value is accessed atomically may not + overlap with periods where the value is accessed non-atomically. + * This requirement is trivially satisfied if `ptr` is never used non-atomically + for the duration of lifetime `'a`. Most use cases should be able to follow + this guideline. + * This requirement is also trivially satisfied if all accesses (atomic or not) are + done from the same thread. +* If this atomic type is *not* lock-free: + * Any accesses to the value behind `ptr` must have a happens-before relationship + with accesses via the returned value (or vice-versa). + * Any concurrent accesses to the value behind `ptr` for the duration of lifetime `'a` must + be compatible with operations performed by this atomic type. +* This method must not be used to create overlapping or mixed-size atomic + accesses, as these are not supported by the memory model. + +[valid]: core::ptr#safety"), + #[inline] + #[must_use] + pub const unsafe fn from_ptr<'a>(ptr: *mut $float_type) -> &'a Self { + #[allow(clippy::cast_ptr_alignment)] + // SAFETY: guaranteed by the caller + unsafe { &*(ptr as *mut Self as *const Self) } + } + } + #[cfg(portable_atomic_no_const_raw_ptr_deref)] + doc_comment! { + concat!("Creates a new reference to an atomic float from a pointer. + +This is `const fn` on Rust 1.58+. + +# Safety + +* `ptr` must be aligned to `align_of::<", stringify!($atomic_type), ">()` (note that on some platforms this + can be bigger than `align_of::<", stringify!($float_type), ">()`). +* `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`. +* If this atomic type is [lock-free](Self::is_lock_free), non-atomic accesses to the value + behind `ptr` must have a happens-before relationship with atomic accesses via + the returned value (or vice-versa). + * In other words, time periods where the value is accessed atomically may not + overlap with periods where the value is accessed non-atomically. + * This requirement is trivially satisfied if `ptr` is never used non-atomically + for the duration of lifetime `'a`. Most use cases should be able to follow + this guideline. + * This requirement is also trivially satisfied if all accesses (atomic or not) are + done from the same thread. +* If this atomic type is *not* lock-free: + * Any accesses to the value behind `ptr` must have a happens-before relationship + with accesses via the returned value (or vice-versa). + * Any concurrent accesses to the value behind `ptr` for the duration of lifetime `'a` must + be compatible with operations performed by this atomic type. +* This method must not be used to create overlapping or mixed-size atomic + accesses, as these are not supported by the memory model. + +[valid]: core::ptr#safety"), + #[inline] + #[must_use] + pub unsafe fn from_ptr<'a>(ptr: *mut $float_type) -> &'a Self { + #[allow(clippy::cast_ptr_alignment)] + // SAFETY: guaranteed by the caller + unsafe { &*(ptr as *mut Self as *const Self) } + } + } + + /// Returns `true` if operations on values of this type are lock-free. + /// + /// If the compiler or the platform doesn't support the necessary + /// atomic instructions, global locks for every potentially + /// concurrent atomic operation will be used. + /// + /// This function is guaranteed to always return the same result. + #[inline] + #[must_use] + pub fn is_lock_free() -> bool { + ::is_lock_free() + } + + /// Returns `true` if operations on values of this type are lock-free. + /// + /// If the compiler or the platform doesn't support the necessary + /// atomic instructions, global locks for every potentially + /// concurrent atomic operation will be used. + /// + /// **Note:** If the atomic operation relies on dynamic CPU feature detection, + /// this type may be lock-free even if the function returns false. + #[inline] + #[must_use] + pub const fn is_always_lock_free() -> bool { + ::IS_ALWAYS_LOCK_FREE + } + #[cfg(test)] + #[cfg_attr(all(not(debug_assertions), target_arch = "x86", not(target_feature = "sse2")), allow(dead_code))] + const IS_ALWAYS_LOCK_FREE: bool = Self::is_always_lock_free(); + + const_fn! { + const_if: #[cfg(not(portable_atomic_no_const_mut_refs))]; + /// Returns a mutable reference to the underlying float. + /// + /// This is safe because the mutable reference guarantees that no other threads are + /// concurrently accessing the atomic data. + /// + /// This is `const fn` on Rust 1.83+. + #[inline] + pub const fn get_mut(&mut self) -> &mut $float_type { + // SAFETY: the mutable reference guarantees unique ownership. + unsafe { &mut *self.as_ptr() } + } + } + + // TODO: Add from_mut/get_mut_slice/from_mut_slice once it is stable on std atomic types. + // https://github.com/rust-lang/rust/issues/76314 + + const_fn! { + const_if: #[cfg(not(portable_atomic_no_const_transmute))]; + /// Consumes the atomic and returns the contained value. + /// + /// This is safe because passing `self` by value guarantees that no other threads are + /// concurrently accessing the atomic data. + /// + /// This is `const fn` on Rust 1.56+. + #[inline] + pub const fn into_inner(self) -> $float_type { + // SAFETY: $atomic_type and $float_type have the same size and in-memory representations, + // so they can be safely transmuted. + // (const UnsafeCell::into_inner is unstable) + unsafe { core::mem::transmute(self) } + } + } + + /// Loads a value from the atomic float. + /// + /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation. + /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `order` is [`Release`] or [`AcqRel`]. + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn load(&self, order: Ordering) -> $float_type { + self.inner.load(order) + } + + /// Stores a value into the atomic float. + /// + /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation. + /// Possible values are [`SeqCst`], [`Release`] and [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `order` is [`Acquire`] or [`AcqRel`]. + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn store(&self, val: $float_type, order: Ordering) { + self.inner.store(val, order) + } + + cfg_has_atomic_cas_or_amo32! { + /// Stores a value into the atomic float, returning the previous value. + /// + /// `swap` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn swap(&self, val: $float_type, order: Ordering) -> $float_type { + self.inner.swap(val, order) + } + + cfg_has_atomic_cas! { + /// Stores a value into the atomic float if the current value is the same as + /// the `current` value. + /// + /// The return value is a result indicating whether the new value was written and + /// containing the previous value. On success this value is guaranteed to be equal to + /// `current`. + /// + /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory + /// ordering of this operation. `success` describes the required ordering for the + /// read-modify-write operation that takes place if the comparison with `current` succeeds. + /// `failure` describes the required ordering for the load operation that takes place when + /// the comparison fails. Using [`Acquire`] as success ordering makes the store part + /// of this operation [`Relaxed`], and using [`Release`] makes the successful load + /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `failure` is [`Release`], [`AcqRel`]. + #[cfg_attr(docsrs, doc(alias = "compare_and_swap"))] + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn compare_exchange( + &self, + current: $float_type, + new: $float_type, + success: Ordering, + failure: Ordering, + ) -> Result<$float_type, $float_type> { + self.inner.compare_exchange(current, new, success, failure) + } + + /// Stores a value into the atomic float if the current value is the same as + /// the `current` value. + /// Unlike [`compare_exchange`](Self::compare_exchange) + /// this function is allowed to spuriously fail even + /// when the comparison succeeds, which can result in more efficient code on some + /// platforms. The return value is a result indicating whether the new value was + /// written and containing the previous value. + /// + /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory + /// ordering of this operation. `success` describes the required ordering for the + /// read-modify-write operation that takes place if the comparison with `current` succeeds. + /// `failure` describes the required ordering for the load operation that takes place when + /// the comparison fails. Using [`Acquire`] as success ordering makes the store part + /// of this operation [`Relaxed`], and using [`Release`] makes the successful load + /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `failure` is [`Release`], [`AcqRel`]. + #[cfg_attr(docsrs, doc(alias = "compare_and_swap"))] + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn compare_exchange_weak( + &self, + current: $float_type, + new: $float_type, + success: Ordering, + failure: Ordering, + ) -> Result<$float_type, $float_type> { + self.inner.compare_exchange_weak(current, new, success, failure) + } + + /// Adds to the current value, returning the previous value. + /// + /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_add(&self, val: $float_type, order: Ordering) -> $float_type { + self.inner.fetch_add(val, order) + } + + /// Subtracts from the current value, returning the previous value. + /// + /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_sub(&self, val: $float_type, order: Ordering) -> $float_type { + self.inner.fetch_sub(val, order) + } + + /// Fetches the value, and applies a function to it that returns an optional + /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else + /// `Err(previous_value)`. + /// + /// Note: This may call the function multiple times if the value has been changed from other threads in + /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied + /// only once to the stored value. + /// + /// `fetch_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation. + /// The first describes the required ordering for when the operation finally succeeds while the second + /// describes the required ordering for loads. These correspond to the success and failure orderings of + /// [`compare_exchange`](Self::compare_exchange) respectively. + /// + /// Using [`Acquire`] as success ordering makes the store part + /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load + /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `fetch_order` is [`Release`], [`AcqRel`]. + /// + /// # Considerations + /// + /// This method is not magic; it is not provided by the hardware. + /// It is implemented in terms of [`compare_exchange_weak`](Self::compare_exchange_weak), + /// and suffers from the same drawbacks. + /// In particular, this method will not circumvent the [ABA Problem]. + /// + /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem + #[inline] + #[cfg_attr( + any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), + track_caller + )] + pub fn fetch_update( + &self, + set_order: Ordering, + fetch_order: Ordering, + mut f: F, + ) -> Result<$float_type, $float_type> + where + F: FnMut($float_type) -> Option<$float_type>, + { + let mut prev = self.load(fetch_order); + while let Some(next) = f(prev) { + match self.compare_exchange_weak(prev, next, set_order, fetch_order) { + x @ Ok(_) => return x, + Err(next_prev) => prev = next_prev, + } + } + Err(prev) + } + + /// Maximum with the current value. + /// + /// Finds the maximum of the current value and the argument `val`, and + /// sets the new value to the result. + /// + /// Returns the previous value. + /// + /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_max(&self, val: $float_type, order: Ordering) -> $float_type { + self.inner.fetch_max(val, order) + } + + /// Minimum with the current value. + /// + /// Finds the minimum of the current value and the argument `val`, and + /// sets the new value to the result. + /// + /// Returns the previous value. + /// + /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_min(&self, val: $float_type, order: Ordering) -> $float_type { + self.inner.fetch_min(val, order) + } + } // cfg_has_atomic_cas! + + /// Negates the current value, and sets the new value to the result. + /// + /// Returns the previous value. + /// + /// `fetch_neg` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_neg(&self, order: Ordering) -> $float_type { + self.inner.fetch_neg(order) + } + + /// Computes the absolute value of the current value, and sets the + /// new value to the result. + /// + /// Returns the previous value. + /// + /// `fetch_abs` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub fn fetch_abs(&self, order: Ordering) -> $float_type { + self.inner.fetch_abs(order) + } + } // cfg_has_atomic_cas_or_amo32! + + #[cfg(not(portable_atomic_no_const_raw_ptr_deref))] + doc_comment! { + concat!("Raw transmutation to `&", stringify!($atomic_int_type), "`. + +See [`", stringify!($float_type) ,"::from_bits`] for some discussion of the +portability of this operation (there are almost no issues). + +This is `const fn` on Rust 1.58+."), + #[inline] + pub const fn as_bits(&self) -> &$atomic_int_type { + self.inner.as_bits() + } + } + #[cfg(portable_atomic_no_const_raw_ptr_deref)] + doc_comment! { + concat!("Raw transmutation to `&", stringify!($atomic_int_type), "`. + +See [`", stringify!($float_type) ,"::from_bits`] for some discussion of the +portability of this operation (there are almost no issues). + +This is `const fn` on Rust 1.58+."), + #[inline] + pub fn as_bits(&self) -> &$atomic_int_type { + self.inner.as_bits() + } + } + + const_fn! { + const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))]; + /// Returns a mutable pointer to the underlying float. + /// + /// Returning an `*mut` pointer from a shared reference to this atomic is + /// safe because the atomic types work with interior mutability. Any use of + /// the returned raw pointer requires an `unsafe` block and has to uphold + /// the safety requirements. If there is concurrent access, note the following + /// additional safety requirements: + /// + /// - If this atomic type is [lock-free](Self::is_lock_free), any concurrent + /// operations on it must be atomic. + /// - Otherwise, any concurrent operations on it must be compatible with + /// operations performed by this atomic type. + /// + /// This is `const fn` on Rust 1.58+. + #[inline] + pub const fn as_ptr(&self) -> *mut $float_type { + self.inner.as_ptr() + } + } + } + // See https://github.com/taiki-e/portable-atomic/issues/180 + #[cfg(not(feature = "require-cas"))] + cfg_no_atomic_cas! { + #[doc(hidden)] + #[allow(unused_variables, clippy::unused_self, clippy::extra_unused_lifetimes)] + impl<'a> $atomic_type { + cfg_no_atomic_cas_or_amo32! { + #[inline] + pub fn swap(&self, val: $float_type, order: Ordering) -> $float_type + where + &'a Self: HasSwap, + { + unimplemented!() + } + } // cfg_no_atomic_cas_or_amo32! + #[inline] + pub fn compare_exchange( + &self, + current: $float_type, + new: $float_type, + success: Ordering, + failure: Ordering, + ) -> Result<$float_type, $float_type> + where + &'a Self: HasCompareExchange, + { + unimplemented!() + } + #[inline] + pub fn compare_exchange_weak( + &self, + current: $float_type, + new: $float_type, + success: Ordering, + failure: Ordering, + ) -> Result<$float_type, $float_type> + where + &'a Self: HasCompareExchangeWeak, + { + unimplemented!() + } + #[inline] + pub fn fetch_add(&self, val: $float_type, order: Ordering) -> $float_type + where + &'a Self: HasFetchAdd, + { + unimplemented!() + } + #[inline] + pub fn fetch_sub(&self, val: $float_type, order: Ordering) -> $float_type + where + &'a Self: HasFetchSub, + { + unimplemented!() + } + #[inline] + pub fn fetch_update( + &self, + set_order: Ordering, + fetch_order: Ordering, + f: F, + ) -> Result<$float_type, $float_type> + where + F: FnMut($float_type) -> Option<$float_type>, + &'a Self: HasFetchUpdate, + { + unimplemented!() + } + #[inline] + pub fn fetch_max(&self, val: $float_type, order: Ordering) -> $float_type + where + &'a Self: HasFetchMax, + { + unimplemented!() + } + #[inline] + pub fn fetch_min(&self, val: $float_type, order: Ordering) -> $float_type + where + &'a Self: HasFetchMin, + { + unimplemented!() + } + cfg_no_atomic_cas_or_amo32! { + #[inline] + pub fn fetch_neg(&self, order: Ordering) -> $float_type + where + &'a Self: HasFetchNeg, + { + unimplemented!() + } + #[inline] + pub fn fetch_abs(&self, order: Ordering) -> $float_type + where + &'a Self: HasFetchAbs, + { + unimplemented!() + } + } // cfg_no_atomic_cas_or_amo32! + } + } // cfg_no_atomic_cas! + }; +} + +cfg_has_atomic_ptr! { + #[cfg(target_pointer_width = "16")] + atomic_int!(AtomicIsize, isize, 2, cfg_has_atomic_cas_or_amo8, cfg_no_atomic_cas_or_amo8); + #[cfg(target_pointer_width = "16")] + atomic_int!(AtomicUsize, usize, 2, cfg_has_atomic_cas_or_amo8, cfg_no_atomic_cas_or_amo8); + #[cfg(target_pointer_width = "32")] + atomic_int!(AtomicIsize, isize, 4, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32); + #[cfg(target_pointer_width = "32")] + atomic_int!(AtomicUsize, usize, 4, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32); + #[cfg(target_pointer_width = "64")] + atomic_int!(AtomicIsize, isize, 8, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32); + #[cfg(target_pointer_width = "64")] + atomic_int!(AtomicUsize, usize, 8, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32); + #[cfg(target_pointer_width = "128")] + atomic_int!(AtomicIsize, isize, 16, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32); + #[cfg(target_pointer_width = "128")] + atomic_int!(AtomicUsize, usize, 16, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32); +} + +cfg_has_atomic_8! { + atomic_int!(AtomicI8, i8, 1, cfg_has_atomic_cas_or_amo8, cfg_no_atomic_cas_or_amo8); + atomic_int!(AtomicU8, u8, 1, cfg_has_atomic_cas_or_amo8, cfg_no_atomic_cas_or_amo8); +} +cfg_has_atomic_16! { + atomic_int!(AtomicI16, i16, 2, cfg_has_atomic_cas_or_amo8, cfg_no_atomic_cas_or_amo8); + atomic_int!(AtomicU16, u16, 2, cfg_has_atomic_cas_or_amo8, cfg_no_atomic_cas_or_amo8, + #[cfg(all(feature = "float", portable_atomic_unstable_f16))] AtomicF16, f16); +} +cfg_has_atomic_32! { + atomic_int!(AtomicI32, i32, 4, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32); + atomic_int!(AtomicU32, u32, 4, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32, + #[cfg(feature = "float")] AtomicF32, f32); +} +cfg_has_atomic_64! { + atomic_int!(AtomicI64, i64, 8, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32); + atomic_int!(AtomicU64, u64, 8, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32, + #[cfg(feature = "float")] AtomicF64, f64); +} +cfg_has_atomic_128! { + atomic_int!(AtomicI128, i128, 16, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32); + atomic_int!(AtomicU128, u128, 16, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32, + #[cfg(all(feature = "float", portable_atomic_unstable_f128))] AtomicF128, f128); +} + +// See https://github.com/taiki-e/portable-atomic/issues/180 +#[cfg(not(feature = "require-cas"))] +cfg_no_atomic_cas! { +cfg_no_atomic_cas_or_amo32! { +#[cfg(feature = "float")] +use self::diagnostic_helper::HasFetchAbs; +use self::diagnostic_helper::{ + HasAnd, HasBitClear, HasBitSet, HasBitToggle, HasFetchAnd, HasFetchByteAdd, HasFetchByteSub, + HasFetchNot, HasFetchOr, HasFetchPtrAdd, HasFetchPtrSub, HasFetchXor, HasNot, HasOr, HasXor, +}; +} // cfg_no_atomic_cas_or_amo32! +cfg_no_atomic_cas_or_amo8! { +use self::diagnostic_helper::{HasAdd, HasSub, HasSwap}; +} // cfg_no_atomic_cas_or_amo8! +#[cfg_attr(not(feature = "float"), allow(unused_imports))] +use self::diagnostic_helper::{ + HasCompareExchange, HasCompareExchangeWeak, HasFetchAdd, HasFetchMax, HasFetchMin, + HasFetchNand, HasFetchNeg, HasFetchSub, HasFetchUpdate, HasNeg, +}; +#[cfg_attr( + any( + all( + portable_atomic_no_atomic_load_store, + not(any( + target_arch = "avr", + target_arch = "bpf", + target_arch = "msp430", + target_arch = "riscv32", + target_arch = "riscv64", + feature = "critical-section", + portable_atomic_unsafe_assume_single_core, + )), + ), + not(feature = "float"), + ), + allow(dead_code, unreachable_pub) +)] +#[allow(unknown_lints, unnameable_types)] // Not public API. unnameable_types is available on Rust 1.79+ +mod diagnostic_helper { + cfg_no_atomic_cas_or_amo8! { + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`swap` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasSwap {} + } // cfg_no_atomic_cas_or_amo8! + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`compare_exchange` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasCompareExchange {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`compare_exchange_weak` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasCompareExchangeWeak {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_add` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchAdd {} + cfg_no_atomic_cas_or_amo8! { + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`add` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasAdd {} + } // cfg_no_atomic_cas_or_amo8! + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_sub` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchSub {} + cfg_no_atomic_cas_or_amo8! { + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`sub` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasSub {} + } // cfg_no_atomic_cas_or_amo8! + cfg_no_atomic_cas_or_amo32! { + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_ptr_add` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchPtrAdd {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_ptr_sub` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchPtrSub {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_byte_add` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchByteAdd {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_byte_sub` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchByteSub {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_and` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchAnd {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`and` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasAnd {} + } // cfg_no_atomic_cas_or_amo32! + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_nand` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchNand {} + cfg_no_atomic_cas_or_amo32! { + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_or` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchOr {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`or` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasOr {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_xor` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchXor {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`xor` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasXor {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_not` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchNot {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`not` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasNot {} + } // cfg_no_atomic_cas_or_amo32! + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_neg` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchNeg {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`neg` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasNeg {} + cfg_no_atomic_cas_or_amo32! { + #[cfg(feature = "float")] + #[cfg_attr(target_pointer_width = "16", allow(dead_code, unreachable_pub))] + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_abs` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchAbs {} + } // cfg_no_atomic_cas_or_amo32! + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_min` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchMin {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_max` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchMax {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`fetch_update` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasFetchUpdate {} + cfg_no_atomic_cas_or_amo32! { + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`bit_set` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasBitSet {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`bit_clear` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasBitClear {} + #[doc(hidden)] + #[cfg_attr( + not(portable_atomic_no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "`bit_toggle` requires atomic CAS but not available on this target by default", + label = "this associated function is not available on this target by default", + note = "consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)", + note = "see for more." + ) + )] + pub trait HasBitToggle {} + } // cfg_no_atomic_cas_or_amo32! +} +} // cfg_no_atomic_cas! diff --git a/vendor/portable-atomic/src/rustdoc.css b/vendor/portable-atomic/src/rustdoc.css new file mode 100644 index 0000000..e347195 --- /dev/null +++ b/vendor/portable-atomic/src/rustdoc.css @@ -0,0 +1,92 @@ +/* + * Adapted from https://github.com/TheBevyFlock/bevy_cli/blob/d3e79396595f675798af5be8be56efbfd2737ba0/bevy_lint/assets/rustdoc.css. + * Adjusted to work well with our GFM (GitHub Flavored Markdown) to CommonMark converter. + */ + +/* + * Extended theme configuration. + * + * These colors are based off Github's (blue for notes, green for tips, etc.), though the exact + * colors are taken from `rustdoc`'s themes. + */ +:root[data-theme="light"] { + --rustdoc-alert-note: #2196f3; + --rustdoc-alert-tip: #068000; + --rustdoc-alert-important: #6e4fc9; + --rustdoc-alert-warning: #ff8e00; + --rustdoc-alert-caution: #be2525; +} +:root[data-theme="dark"] { + --rustdoc-alert-note: #008dfd; + --rustdoc-alert-tip: #2bab63; + --rustdoc-alert-important: #b78cf2; + --rustdoc-alert-warning: #ff8e00; + --rustdoc-alert-caution: #d93d3d; +} +:root[data-theme="ayu"] { + --rustdoc-alert-note: #39afd7; + --rustdoc-alert-tip: #b8cc52; + --rustdoc-alert-important: #a37acc; + --rustdoc-alert-warning: #ff8e00; + --rustdoc-alert-caution: #df3600; +} + +/* + * Alerts are siblings to the `.warning` class, and as such use many of the same rules. + * + * The first `

` in a alert must be the title, as it will be colored and styled differently. + */ +.rustdoc-alert { + border-left: 2px solid; + margin: 0 0 0.75em 0; + position: relative; + overflow-x: visible !important; +} + +/* Remove the existing quote margin and setup some padding instead. */ +.rustdoc-alert blockquote { + margin: 0; + padding: 14px; +} + +/* Make the alert title the same sans-serif font and size as headings. */ +.rustdoc-alert blockquote > p:first-child { + font-family: "Fira Sans", Arial, sans-serif; + font-size: 1.125rem; +} + +/* Color styles for different kinds of alerts. */ +.rustdoc-alert.rustdoc-alert-note { + border-left-color: var(--rustdoc-alert-note); +} +.rustdoc-alert.rustdoc-alert-note blockquote > p:first-child { + color: var(--rustdoc-alert-note); +} + +.rustdoc-alert.rustdoc-alert-tip { + border-left-color: var(--rustdoc-alert-tip); +} +.rustdoc-alert.rustdoc-alert-tip blockquote > p:first-child { + color: var(--rustdoc-alert-tip); +} + +.rustdoc-alert.rustdoc-alert-important { + border-left-color: var(--rustdoc-alert-important); +} +.rustdoc-alert.rustdoc-alert-important blockquote > p:first-child { + color: var(--rustdoc-alert-important); +} + +.rustdoc-alert.rustdoc-alert-warning { + border-left-color: var(--rustdoc-alert-warning); +} +.rustdoc-alert.rustdoc-alert-warning blockquote > p:first-child { + color: var(--rustdoc-alert-warning); +} + +.rustdoc-alert.rustdoc-alert-caution { + border-left-color: var(--rustdoc-alert-caution); +} +.rustdoc-alert.rustdoc-alert-caution blockquote > p:first-child { + color: var(--rustdoc-alert-caution); +} diff --git a/vendor/portable-atomic/src/tests/helper.rs b/vendor/portable-atomic/src/tests/helper.rs new file mode 100644 index 0000000..eb40ef5 --- /dev/null +++ b/vendor/portable-atomic/src/tests/helper.rs @@ -0,0 +1,3294 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +#![allow(unused_macros, clippy::undocumented_unsafe_blocks)] + +use std::{ + eprintln, + sync::atomic::{AtomicIsize, AtomicUsize, Ordering}, +}; + +use crossbeam_utils::thread; + +macro_rules! __test_atomic_common { + ($atomic_type:ty, $value_type:ty) => { + use std::mem; + #[test] + fn assert_auto_traits() { + fn _assert() {} + _assert::<$atomic_type>(); + } + #[test] + fn alignment() { + // https://github.com/rust-lang/rust/blob/1.84.0/library/core/tests/atomic.rs#L252 + assert_eq!(mem::align_of::<$atomic_type>(), mem::size_of::<$atomic_type>()); + assert_eq!(mem::size_of::<$atomic_type>(), mem::size_of::<$value_type>()); + } + #[test] + fn is_lock_free() { + const IS_ALWAYS_LOCK_FREE: bool = <$atomic_type>::IS_ALWAYS_LOCK_FREE; + assert_eq!(IS_ALWAYS_LOCK_FREE, <$atomic_type>::IS_ALWAYS_LOCK_FREE); + let is_lock_free = <$atomic_type>::is_lock_free(); + if IS_ALWAYS_LOCK_FREE { + // If is_always_lock_free is true, then is_lock_free must always be true. + assert!(is_lock_free); + } + } + }; +} +macro_rules! __test_atomic_pub_common { + ($atomic_type:ty, $value_type:ty) => { + #[test] + fn is_always_lock_free() { + assert_eq!(<$atomic_type>::IS_ALWAYS_LOCK_FREE, <$atomic_type>::is_always_lock_free()); + } + #[test] + fn assert_ref_unwind_safe() { + #[cfg(not(all(portable_atomic_no_core_unwind_safe, not(feature = "std"))))] + static_assertions::assert_impl_all!($atomic_type: std::panic::RefUnwindSafe); + #[cfg(all(portable_atomic_no_core_unwind_safe, not(feature = "std")))] + static_assertions::assert_not_impl_all!($atomic_type: std::panic::RefUnwindSafe); + } + }; +} + +macro_rules! __test_atomic_int_load_store { + ($atomic_type:ty, $int_type:ident, single_thread) => { + __test_atomic_common!($atomic_type, $int_type); + use crate::tests::helper::{self, *}; + #[test] + fn accessor() { + let a = <$atomic_type>::new(10); + unsafe { + assert_eq!(*a.as_ptr(), 10); + *a.as_ptr() = 5; + assert_eq!(a.as_ptr() as *const (), &a as *const _ as *const ()); + assert_eq!(*a.as_ptr(), 5); + } + } + // https://bugs.llvm.org/show_bug.cgi?id=37061 + #[test] + fn static_load_only() { + static VAR: $atomic_type = <$atomic_type>::new(10); + for &order in &helper::LOAD_ORDERINGS { + assert_eq!(VAR.load(order), 10); + } + } + #[test] + fn load_store() { + static VAR: $atomic_type = <$atomic_type>::new(10); + test_load_ordering(&|order| { + VAR.load(order); + }); + test_store_ordering(&|order| VAR.store(10, order)); + for (&load_order, &store_order) in + helper::LOAD_ORDERINGS.iter().zip(&helper::STORE_ORDERINGS) + { + assert_eq!(VAR.load(load_order), 10); + VAR.store(5, store_order); + assert_eq!(VAR.load(load_order), 5); + VAR.store(10, store_order); + let a = <$atomic_type>::new(1); + assert_eq!(a.load(load_order), 1); + a.store($int_type::MIN, store_order); + assert_eq!(a.load(load_order), $int_type::MIN); + a.store($int_type::MAX, store_order); + assert_eq!(a.load(load_order), $int_type::MAX); + } + } + }; + ($atomic_type:ty, $int_type:ident) => { + __test_atomic_int_load_store!($atomic_type, $int_type, single_thread); + + use std::{collections::BTreeSet, eprintln, time::Instant, vec, vec::Vec}; + + use crossbeam_utils::thread; + + #[test] + fn stress_load_store() { + let mut rng = fastrand::Rng::new(); + let (iterations, threads) = stress_test_config(&mut rng); + let data1 = (0..iterations).map(|_| rng.$int_type(..)).collect::>(); + let set = data1.iter().copied().collect::>(); + let a = <$atomic_type>::new(data1[rng.usize(0..iterations)]); + let now = &Instant::now(); + thread::scope(|s| { + for _ in 0..threads { + s.spawn(|_| { + let mut rng = fastrand::Rng::new(); + let now = *now; + for i in 0..iterations { + a.store(data1[i], rand_store_ordering(&mut rng)); + } + eprintln!("store end={:?}", now.elapsed()); + }); + s.spawn(|_| { + let mut rng = fastrand::Rng::new(); + let now = *now; + let mut v = vec![0; iterations]; + for i in 0..iterations { + v[i] = a.load(rand_load_ordering(&mut rng)); + } + eprintln!("load end={:?}", now.elapsed()); + for v in v { + assert!(set.contains(&v), "load unexpected={}", v); + } + }); + } + }) + .unwrap(); + } + }; +} +macro_rules! __test_atomic_float_load_store { + ($atomic_type:ty, $float_type:ident, single_thread) => { + __test_atomic_common!($atomic_type, $float_type); + use crate::tests::helper::{self, *}; + #[test] + fn accessor() { + let a = <$atomic_type>::new(10.); + unsafe { + assert_eq!(*a.as_ptr(), 10.); + *a.as_ptr() = 5.; + assert_eq!(a.as_ptr() as *const (), &a as *const _ as *const ()); + assert_eq!(*a.as_ptr(), 5.); + } + } + // https://bugs.llvm.org/show_bug.cgi?id=37061 + #[test] + fn static_load_only() { + static VAR: $atomic_type = <$atomic_type>::new(10.); + for &order in &helper::LOAD_ORDERINGS { + assert_eq!(VAR.load(order), 10.); + } + } + #[test] + fn load_store() { + static VAR: $atomic_type = <$atomic_type>::new(10.); + test_load_ordering(&|order| { + VAR.load(order); + }); + test_store_ordering(&|order| VAR.store(10., order)); + for (&load_order, &store_order) in + helper::LOAD_ORDERINGS.iter().zip(&helper::STORE_ORDERINGS) + { + assert_eq!(VAR.load(load_order), 10.); + VAR.store(5., store_order); + assert_eq!(VAR.load(load_order), 5.); + VAR.store(10., store_order); + let a = <$atomic_type>::new(1.); + assert_eq!(a.load(load_order), 1.); + a.store(2., store_order); + assert_eq!(a.load(load_order), 2.); + } + } + }; + ($atomic_type:ty, $float_type:ident) => { + __test_atomic_float_load_store!($atomic_type, $float_type, single_thread); + // TODO: multi thread + }; +} +macro_rules! __test_atomic_bool_load_store { + ($atomic_type:ty, single_thread) => { + __test_atomic_common!($atomic_type, bool); + use crate::tests::helper::{self, *}; + #[test] + fn accessor() { + let a = <$atomic_type>::new(false); + unsafe { + assert_eq!(*a.as_ptr(), false); + *a.as_ptr() = true; + assert_eq!(a.as_ptr() as *const (), &a as *const _ as *const ()); + assert_eq!(*a.as_ptr(), true); + } + } + // https://bugs.llvm.org/show_bug.cgi?id=37061 + #[test] + fn static_load_only() { + static VAR: $atomic_type = <$atomic_type>::new(false); + for &order in &helper::LOAD_ORDERINGS { + assert_eq!(VAR.load(order), false); + } + } + #[test] + fn load_store() { + static VAR: $atomic_type = <$atomic_type>::new(false); + test_load_ordering(&|order| { + VAR.load(order); + }); + test_store_ordering(&|order| VAR.store(false, order)); + for (&load_order, &store_order) in + helper::LOAD_ORDERINGS.iter().zip(&helper::STORE_ORDERINGS) + { + assert_eq!(VAR.load(load_order), false); + VAR.store(true, store_order); + assert_eq!(VAR.load(load_order), true); + VAR.store(false, store_order); + let a = <$atomic_type>::new(true); + assert_eq!(a.load(load_order), true); + a.store(false, store_order); + assert_eq!(a.load(load_order), false); + } + } + }; + ($atomic_type:ty) => { + __test_atomic_bool_load_store!($atomic_type, single_thread); + // TODO: multi thread + }; +} +macro_rules! __test_atomic_ptr_load_store { + ($atomic_type:ty, single_thread) => { + __test_atomic_common!($atomic_type, *mut u8); + + use std::ptr; + + use crate::tests::helper::{self, *}; + + #[test] + fn accessor() { + let mut v = 1; + let a = <$atomic_type>::new(ptr::null_mut()); + unsafe { + assert!((*a.as_ptr()).is_null()); + *a.as_ptr() = &mut v; + assert_eq!(a.as_ptr() as *const (), &a as *const _ as *const ()); + assert!(!(*a.as_ptr()).is_null()); + } + } + // https://bugs.llvm.org/show_bug.cgi?id=37061 + #[test] + fn static_load_only() { + static VAR: $atomic_type = <$atomic_type>::new(ptr::null_mut()); + for &order in &helper::LOAD_ORDERINGS { + assert_eq!(VAR.load(order), ptr::null_mut()); + } + } + #[test] + fn load_store() { + static VAR: $atomic_type = <$atomic_type>::new(ptr::null_mut()); + test_load_ordering(&|order| { + VAR.load(order); + }); + test_store_ordering(&|order| VAR.store(ptr::null_mut(), order)); + let mut v = 1_u8; + let p = &mut v as *mut u8; + for (&load_order, &store_order) in + helper::LOAD_ORDERINGS.iter().zip(&helper::STORE_ORDERINGS) + { + assert_eq!(VAR.load(load_order), ptr::null_mut()); + VAR.store(p, store_order); + assert_eq!(VAR.load(load_order), p); + VAR.store(ptr::null_mut(), store_order); + let a = <$atomic_type>::new(p); + assert_eq!(a.load(load_order), p); + a.store(ptr::null_mut(), store_order); + assert_eq!(a.load(load_order), ptr::null_mut()); + } + } + }; + ($atomic_type:ty) => { + __test_atomic_ptr_load_store!($atomic_type, single_thread); + // TODO: multi thread + }; +} + +macro_rules! __test_atomic_int { + ($atomic_type:ty, $int_type:ident, single_thread) => { + #[test] + fn swap() { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return; + } + let a = <$atomic_type>::new(5); + test_swap_ordering(&|order| { + a.swap(5, order); + }); + for &order in &helper::SWAP_ORDERINGS { + assert_eq!(a.swap(10, order), 5); + assert_eq!(a.swap($int_type::MIN, order), 10); + assert_eq!(a.swap($int_type::MAX, order), $int_type::MIN); + assert_eq!(a.swap(5, order), $int_type::MAX); + } + } + #[test] + fn compare_exchange() { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return; + } + let a = <$atomic_type>::new(5); + test_compare_exchange_ordering(&|success, failure| { + let _ = a.compare_exchange(5, 5, success, failure); + }); + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(5); + assert_eq!(a.compare_exchange(5, 10, success, failure), Ok(5)); + assert_eq!(a.load(Ordering::Relaxed), 10); + assert_eq!(a.compare_exchange(6, 12, success, failure), Err(10)); + assert_eq!(a.load(Ordering::Relaxed), 10); + } + } + #[test] + fn compare_exchange_weak() { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return; + } + let a = <$atomic_type>::new(4); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + test_compare_exchange_ordering(&|success, failure| { + let _ = a.compare_exchange_weak(4, 4, success, failure); + }); + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(4); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.compare_exchange_weak(6, 8, success, failure), Err(4)); + let mut old = a.load(Ordering::Relaxed); + loop { + let new = old * 2; + match a.compare_exchange_weak(old, new, success, failure) { + Ok(_) => break, + Err(x) => old = x, + } + } + assert_eq!(a.load(Ordering::Relaxed), 8); + } + } + #[test] + fn fetch_add() { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return; + } + let a = <$atomic_type>::new(0); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + test_swap_ordering(&|order| { + a.fetch_add(0, order); + }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(0); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_add(10, order), 0); + assert_eq!(a.load(Ordering::Relaxed), 10); + let a = <$atomic_type>::new($int_type::MAX); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_add(1, order), $int_type::MAX); + assert_eq!(a.load(Ordering::Relaxed), $int_type::MAX.wrapping_add(1)); + } + } + #[test] + fn add() { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return; + } + let a = <$atomic_type>::new(0); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + test_swap_ordering(&|order| a.add(0, order)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(0); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + a.add(10, order); + assert_eq!(a.load(Ordering::Relaxed), 10); + let a = <$atomic_type>::new($int_type::MAX); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + a.add(1, order); + assert_eq!(a.load(Ordering::Relaxed), $int_type::MAX.wrapping_add(1)); + } + } + #[test] + fn fetch_sub() { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return; + } + let a = <$atomic_type>::new(20); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + test_swap_ordering(&|order| { + a.fetch_sub(0, order); + }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(20); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_sub(10, order), 20); + assert_eq!(a.load(Ordering::Relaxed), 10); + let a = <$atomic_type>::new($int_type::MIN); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_sub(1, order), $int_type::MIN); + assert_eq!(a.load(Ordering::Relaxed), $int_type::MIN.wrapping_sub(1)); + } + } + #[test] + fn sub() { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return; + } + let a = <$atomic_type>::new(20); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + test_swap_ordering(&|order| a.sub(0, order)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(20); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + a.sub(10, order); + assert_eq!(a.load(Ordering::Relaxed), 10); + let a = <$atomic_type>::new($int_type::MIN); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + a.sub(1, order); + assert_eq!(a.load(Ordering::Relaxed), $int_type::MIN.wrapping_sub(1)); + } + } + #[test] + fn fetch_and() { + let a = <$atomic_type>::new(0b101101); + test_swap_ordering(&|order| { + a.fetch_and(0b101101, order); + }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(0b101101); + assert_eq!(a.fetch_and(0b110011, order), 0b101101); + assert_eq!(a.load(Ordering::Relaxed), 0b100001); + } + } + #[test] + fn and() { + let a = <$atomic_type>::new(0b101101); + test_swap_ordering(&|order| a.and(0b101101, order)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(0b101101); + a.and(0b110011, order); + assert_eq!(a.load(Ordering::Relaxed), 0b100001); + } + } + #[test] + fn fetch_nand() { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") { + return; + } + let a = <$atomic_type>::new(0x13); + test_swap_ordering(&|order| { + a.fetch_nand(0x31, order); + }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(0x13); + assert_eq!(a.fetch_nand(0x31, order), 0x13); + assert_eq!(a.load(Ordering::Relaxed), !(0x13 & 0x31)); + } + } + #[test] + fn fetch_or() { + let a = <$atomic_type>::new(0b101101); + test_swap_ordering(&|order| { + a.fetch_or(0, order); + }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(0b101101); + assert_eq!(a.fetch_or(0b110011, order), 0b101101); + assert_eq!(a.load(Ordering::Relaxed), 0b111111); + } + } + #[test] + fn or() { + let a = <$atomic_type>::new(0b101101); + test_swap_ordering(&|order| a.or(0, order)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(0b101101); + a.or(0b110011, order); + assert_eq!(a.load(Ordering::Relaxed), 0b111111); + } + } + #[test] + fn fetch_xor() { + let a = <$atomic_type>::new(0b101101); + test_swap_ordering(&|order| { + a.fetch_xor(0, order); + }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(0b101101); + assert_eq!(a.fetch_xor(0b110011, order), 0b101101); + assert_eq!(a.load(Ordering::Relaxed), 0b011110); + } + } + #[test] + fn xor() { + let a = <$atomic_type>::new(0b101101); + test_swap_ordering(&|order| a.xor(0, order)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(0b101101); + a.xor(0b110011, order); + assert_eq!(a.load(Ordering::Relaxed), 0b011110); + } + } + #[test] + fn fetch_max() { + // TODO(gcc): failure: https://github.com/rust-lang/rustc_codegen_gcc/issues/821#issuecomment-3793567607 + if option_env!("RUSTC_CODEGEN_GCC").unwrap_or_default() == "1" + && $int_type::MIN == 0 + && mem::size_of::<$int_type>() <= 8 + { + return; + } + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return; + } + let a = <$atomic_type>::new(23); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + test_swap_ordering(&|order| { + a.fetch_max(23, order); + }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(23); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_max(22, order), 23); + assert_eq!(a.load(Ordering::Relaxed), 23); + assert_eq!(a.fetch_max(24, order), 23); + assert_eq!(a.load(Ordering::Relaxed), 24); + let a = <$atomic_type>::new(0); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_max(1, order), 0); + assert_eq!(a.load(Ordering::Relaxed), 1); + assert_eq!(a.fetch_max(0, order), 1); + assert_eq!(a.load(Ordering::Relaxed), 1); + let a = <$atomic_type>::new(!0); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_max(0, order), !0); + assert_eq!(a.load(Ordering::Relaxed), core::cmp::max(!0, 0)); + } + } + #[test] + fn fetch_min() { + // TODO(gcc): failure: https://github.com/rust-lang/rustc_codegen_gcc/issues/821#issuecomment-3793567607 + if option_env!("RUSTC_CODEGEN_GCC").unwrap_or_default() == "1" + && $int_type::MIN == 0 + && mem::size_of::<$int_type>() <= 8 + { + return; + } + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return; + } + let a = <$atomic_type>::new(23); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + test_swap_ordering(&|order| { + a.fetch_min(23, order); + }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(23); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_min(24, order), 23); + assert_eq!(a.load(Ordering::Relaxed), 23); + assert_eq!(a.fetch_min(22, order), 23); + assert_eq!(a.load(Ordering::Relaxed), 22); + let a = <$atomic_type>::new(1); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_min(0, order), 1); + assert_eq!(a.load(Ordering::Relaxed), 0); + assert_eq!(a.fetch_min(1, order), 0); + assert_eq!(a.load(Ordering::Relaxed), 0); + let a = <$atomic_type>::new(!0); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_min(0, order), !0); + assert_eq!(a.load(Ordering::Relaxed), core::cmp::min(!0, 0)); + } + } + #[test] + fn fetch_not() { + let a = <$atomic_type>::new(1); + test_swap_ordering(&|order| { + a.fetch_not(order); + }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(1); + assert_eq!(a.fetch_not(order), 1); + assert_eq!(a.load(Ordering::Relaxed), !1); + } + } + #[test] + fn not() { + let a = <$atomic_type>::new(1); + test_swap_ordering(&|order| a.not(order)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(1); + a.not(order); + assert_eq!(a.load(Ordering::Relaxed), !1); + } + } + #[test] + fn fetch_neg() { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return; + } + let a = <$atomic_type>::new(5); + test_swap_ordering(&|order| { + a.fetch_neg(order); + }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(5); + assert_eq!(a.fetch_neg(order), 5); + assert_eq!(a.load(Ordering::Relaxed), <$int_type>::wrapping_neg(5)); + assert_eq!(a.fetch_neg(order), <$int_type>::wrapping_neg(5)); + assert_eq!(a.load(Ordering::Relaxed), 5); + let a = <$atomic_type>::new(<$int_type>::MIN); + assert_eq!(a.fetch_neg(order), <$int_type>::MIN); + assert_eq!(a.load(Ordering::Relaxed), <$int_type>::MIN.wrapping_neg()); + assert_eq!(a.fetch_neg(order), <$int_type>::MIN.wrapping_neg()); + assert_eq!(a.load(Ordering::Relaxed), <$int_type>::MIN); + } + } + #[test] + fn neg() { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return; + } + let a = <$atomic_type>::new(5); + test_swap_ordering(&|order| a.neg(order)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(5); + a.neg(order); + assert_eq!(a.load(Ordering::Relaxed), <$int_type>::wrapping_neg(5)); + a.neg(order); + assert_eq!(a.load(Ordering::Relaxed), 5); + let a = <$atomic_type>::new(<$int_type>::MIN); + a.neg(order); + assert_eq!(a.load(Ordering::Relaxed), <$int_type>::MIN.wrapping_neg()); + a.neg(order); + assert_eq!(a.load(Ordering::Relaxed), <$int_type>::MIN); + } + } + #[test] + fn bit_set() { + let a = <$atomic_type>::new(0b0001); + test_swap_ordering(&|order| assert!(a.bit_set(0, order))); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(0b0000); + assert!(!a.bit_set(0, order)); + assert_eq!(a.load(Ordering::Relaxed), 0b0001); + assert!(a.bit_set(0, order)); + assert_eq!(a.load(Ordering::Relaxed), 0b0001); + } + } + #[test] + fn bit_clear() { + let a = <$atomic_type>::new(0b0000); + test_swap_ordering(&|order| assert!(!a.bit_clear(0, order))); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(0b0001); + assert!(a.bit_clear(0, order)); + assert_eq!(a.load(Ordering::Relaxed), 0b0000); + assert!(!a.bit_clear(0, order)); + assert_eq!(a.load(Ordering::Relaxed), 0b0000); + } + } + #[test] + fn bit_toggle() { + let a = <$atomic_type>::new(0b0000); + test_swap_ordering(&|order| { + a.bit_toggle(0, order); + }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(0b0000); + assert!(!a.bit_toggle(0, order)); + assert_eq!(a.load(Ordering::Relaxed), 0b0001); + assert!(a.bit_toggle(0, order)); + assert_eq!(a.load(Ordering::Relaxed), 0b0000); + } + } + ::quickcheck::quickcheck! { + fn quickcheck_swap(x: $int_type, y: $int_type) -> bool { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return true; + } + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.swap(y, order), x); + assert_eq!(a.swap(x, order), y); + } + true + } + fn quickcheck_compare_exchange(x: $int_type, y: $int_type) -> bool { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return true; + } + #[cfg(all( + target_arch = "arm", + not(any(target_feature = "v6", portable_atomic_target_feature = "v6")), + ))] + { + // TODO: LLVM bug: + // https://github.com/llvm/llvm-project/issues/61880 + // https://github.com/taiki-e/portable-atomic/issues/2 + if mem::size_of::<$int_type>() <= 2 { + return true; + } + } + let mut rng = fastrand::Rng::new(); + let z = loop { + let z = rng.$int_type(..); + if z != y { + break z; + } + }; + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.compare_exchange(x, y, success, failure).unwrap(), x); + assert_eq!(a.load(Ordering::Relaxed), y); + assert_eq!(a.compare_exchange(z, x, success, failure).unwrap_err(), y); + assert_eq!(a.load(Ordering::Relaxed), y); + } + true + } + fn quickcheck_fetch_add(x: $int_type, y: $int_type) -> bool { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return true; + } + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_add(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), x.wrapping_add(y)); + let a = <$atomic_type>::new(y); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_add(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), y.wrapping_add(x)); + } + true + } + fn quickcheck_add(x: $int_type, y: $int_type) -> bool { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return true; + } + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + a.add(y, order); + assert_eq!(a.load(Ordering::Relaxed), x.wrapping_add(y)); + let a = <$atomic_type>::new(y); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + a.add(x, order); + assert_eq!(a.load(Ordering::Relaxed), y.wrapping_add(x)); + } + true + } + fn quickcheck_fetch_sub(x: $int_type, y: $int_type) -> bool { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return true; + } + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_sub(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), x.wrapping_sub(y)); + let a = <$atomic_type>::new(y); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_sub(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), y.wrapping_sub(x)); + } + true + } + fn quickcheck_sub(x: $int_type, y: $int_type) -> bool { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return true; + } + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + a.sub(y, order); + assert_eq!(a.load(Ordering::Relaxed), x.wrapping_sub(y)); + let a = <$atomic_type>::new(y); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + a.sub(x, order); + assert_eq!(a.load(Ordering::Relaxed), y.wrapping_sub(x)); + } + true + } + fn quickcheck_fetch_and(x: $int_type, y: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_and(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), x & y); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_and(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), y & x); + } + true + } + fn quickcheck_and(x: $int_type, y: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + a.and(y, order); + assert_eq!(a.load(Ordering::Relaxed), x & y); + let a = <$atomic_type>::new(y); + a.and(x, order); + assert_eq!(a.load(Ordering::Relaxed), y & x); + } + true + } + fn quickcheck_fetch_nand(x: $int_type, y: $int_type) -> bool { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") { + return true; + } + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_nand(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), !(x & y)); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_nand(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), !(y & x)); + } + true + } + fn quickcheck_fetch_or(x: $int_type, y: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_or(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), x | y); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_or(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), y | x); + } + true + } + fn quickcheck_or(x: $int_type, y: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + a.or(y, order); + assert_eq!(a.load(Ordering::Relaxed), x | y); + let a = <$atomic_type>::new(y); + a.or(x, order); + assert_eq!(a.load(Ordering::Relaxed), y | x); + } + true + } + fn quickcheck_fetch_xor(x: $int_type, y: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_xor(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), x ^ y); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_xor(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), y ^ x); + } + true + } + fn quickcheck_xor(x: $int_type, y: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + a.xor(y, order); + assert_eq!(a.load(Ordering::Relaxed), x ^ y); + let a = <$atomic_type>::new(y); + a.xor(x, order); + assert_eq!(a.load(Ordering::Relaxed), y ^ x); + } + true + } + fn quickcheck_fetch_max(x: $int_type, y: $int_type) -> bool { + // TODO(gcc): failure: https://github.com/rust-lang/rustc_codegen_gcc/issues/821#issuecomment-3793567607 + if option_env!("RUSTC_CODEGEN_GCC").unwrap_or_default() == "1" + && $int_type::MIN == 0 + && mem::size_of::<$int_type>() <= 8 + { + return true; + } + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return true; + } + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_max(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), core::cmp::max(x, y)); + let a = <$atomic_type>::new(y); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_max(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), core::cmp::max(y, x)); + } + true + } + fn quickcheck_fetch_min(x: $int_type, y: $int_type) -> bool { + // TODO(gcc): failure: https://github.com/rust-lang/rustc_codegen_gcc/issues/821#issuecomment-3793567607 + if option_env!("RUSTC_CODEGEN_GCC").unwrap_or_default() == "1" + && $int_type::MIN == 0 + && mem::size_of::<$int_type>() <= 8 + { + return true; + } + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return true; + } + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_min(y, order), x); + assert_eq!(a.load(Ordering::Relaxed), core::cmp::min(x, y)); + let a = <$atomic_type>::new(y); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_min(x, order), y); + assert_eq!(a.load(Ordering::Relaxed), core::cmp::min(y, x)); + } + true + } + fn quickcheck_fetch_not(x: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_not(order), x); + assert_eq!(a.load(Ordering::Relaxed), !x); + assert_eq!(a.fetch_not(order), !x); + assert_eq!(a.load(Ordering::Relaxed), x); + } + true + } + fn quickcheck_not(x: $int_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + a.not(order); + assert_eq!(a.load(Ordering::Relaxed), !x); + a.not(order); + assert_eq!(a.load(Ordering::Relaxed), x); + } + true + } + fn quickcheck_fetch_neg(x: $int_type) -> bool { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return true; + } + #[cfg(all( + target_arch = "arm", + not(any(target_feature = "v6", portable_atomic_target_feature = "v6")), + ))] + { + // TODO: LLVM bug: + // https://github.com/llvm/llvm-project/issues/61880 + // https://github.com/taiki-e/portable-atomic/issues/2 + if mem::size_of::<$int_type>() <= 2 { + return true; + } + } + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_neg(order), x); + assert_eq!(a.load(Ordering::Relaxed), x.wrapping_neg()); + assert_eq!(a.fetch_neg(order), x.wrapping_neg()); + assert_eq!(a.load(Ordering::Relaxed), x); + } + true + } + fn quickcheck_neg(x: $int_type) -> bool { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return true; + } + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + a.neg(order); + assert_eq!(a.load(Ordering::Relaxed), x.wrapping_neg()); + a.neg(order); + assert_eq!(a.load(Ordering::Relaxed), x); + } + true + } + fn quickcheck_bit_set(x: $int_type, bit: u32) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + let b = a.bit_set(bit, order); + let mask = <$int_type>::wrapping_shl(1, bit); + assert_eq!(a.load(Ordering::Relaxed), x | mask); + assert_eq!(b, x & mask != 0); + } + true + } + fn quickcheck_bit_clear(x: $int_type, bit: u32) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + let b = a.bit_clear(bit, order); + let mask = <$int_type>::wrapping_shl(1, bit); + assert_eq!(a.load(Ordering::Relaxed), x & !mask); + assert_eq!(b, x & mask != 0); + } + true + } + fn quickcheck_bit_toggle(x: $int_type, bit: u32) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + let b = a.bit_toggle(bit, order); + let mask = <$int_type>::wrapping_shl(1, bit); + assert_eq!(a.load(Ordering::Relaxed), x ^ mask); + assert_eq!(b, x & mask != 0); + } + true + } + } + }; + ($atomic_type:ty, $int_type:ident) => { + __test_atomic_int!($atomic_type, $int_type, single_thread); + + #[test] + fn stress_swap() { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return; + } + let mut rng = fastrand::Rng::new(); + let (iterations, threads) = stress_test_config(&mut rng); + let data1 = &(0..threads) + .map(|_| (0..iterations).map(|_| rng.$int_type(..)).collect::>()) + .collect::>(); + let data2 = &(0..threads) + .map(|_| (0..iterations).map(|_| rng.$int_type(..)).collect::>()) + .collect::>(); + let set = &data1 + .iter() + .flat_map(|v| v.iter().copied()) + .chain(data2.iter().flat_map(|v| v.iter().copied())) + .collect::>(); + let a = &<$atomic_type>::new(data2[0][rng.usize(0..iterations)]); + let now = &Instant::now(); + thread::scope(|s| { + for thread in 0..threads { + if thread % 2 == 0 { + s.spawn(move |_| { + let mut rng = fastrand::Rng::new(); + let now = *now; + for i in 0..iterations { + a.store(data1[thread][i], rand_store_ordering(&mut rng)); + } + eprintln!("store end={:?}", now.elapsed()); + }); + } else { + s.spawn(|_| { + let mut rng = fastrand::Rng::new(); + let now = *now; + let mut v = vec![0; iterations]; + for i in 0..iterations { + v[i] = a.load(rand_load_ordering(&mut rng)); + } + eprintln!("load end={:?}", now.elapsed()); + for v in v { + assert!(set.contains(&v), "load unexpected={}", v); + } + }); + } + s.spawn(move |_| { + let mut rng = fastrand::Rng::new(); + let now = *now; + let mut v = vec![0; iterations]; + for i in 0..iterations { + v[i] = a.swap(data2[thread][i], rand_swap_ordering(&mut rng)); + } + eprintln!("swap end={:?}", now.elapsed()); + for v in v { + assert!(set.contains(&v), "swap unexpected={}", v); + } + }); + } + }) + .unwrap(); + } + #[test] + fn stress_compare_exchange() { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return; + } + let mut rng = fastrand::Rng::new(); + let (iterations, threads) = stress_test_config(&mut rng); + let data1 = &(0..threads) + .map(|_| (0..iterations).map(|_| rng.$int_type(..)).collect::>()) + .collect::>(); + let data2 = &(0..threads) + .map(|_| (0..iterations).map(|_| rng.$int_type(..)).collect::>()) + .collect::>(); + let set = &data1 + .iter() + .flat_map(|v| v.iter().copied()) + .chain(data2.iter().flat_map(|v| v.iter().copied())) + .collect::>(); + let a = &<$atomic_type>::new(data2[0][rng.usize(0..iterations)]); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(a); + } + let now = &Instant::now(); + thread::scope(|s| { + for thread in 0..threads { + s.spawn(move |_| { + let mut rng = fastrand::Rng::new(); + let now = *now; + for i in 0..iterations { + a.store(data1[thread][i], rand_store_ordering(&mut rng)); + } + eprintln!("store end={:?}", now.elapsed()); + }); + s.spawn(|_| { + let mut rng = fastrand::Rng::new(); + let now = *now; + let mut v = vec![data2[0][0]; iterations]; + for i in 0..iterations { + v[i] = a.load(rand_load_ordering(&mut rng)); + } + eprintln!("load end={:?}", now.elapsed()); + for v in v { + assert!(set.contains(&v), "load unexpected={}", v); + } + }); + s.spawn(move |_| { + let mut rng = fastrand::Rng::new(); + let now = *now; + let mut v = vec![data2[0][0]; iterations]; + for i in 0..iterations { + let old = if i % 2 == 0 { + rng.$int_type(..) + } else { + a.load(Ordering::Relaxed) + }; + let new = data2[thread][i]; + let o = rand_compare_exchange_ordering(&mut rng); + match a.compare_exchange(old, new, o.0, o.1) { + Ok(r) => assert_eq!(old, r), + Err(r) => v[i] = r, + } + } + eprintln!("compare_exchange end={:?}", now.elapsed()); + for v in v { + assert!(set.contains(&v), "cas unexpected={}", v); + } + }); + } + }) + .unwrap(); + } + }; +} +macro_rules! __test_atomic_float { + ($atomic_type:ty, $float_type:ident, single_thread) => { + #[test] + fn swap() { + let a = <$atomic_type>::new(5.); + test_swap_ordering(&|order| { a.swap(5., order); }); + for &order in &helper::SWAP_ORDERINGS { + assert_eq!(a.swap(10., order), 5.); + assert_eq!(a.swap(5., order), 10.); + } + } + #[test] + fn compare_exchange() { + let a = <$atomic_type>::new(5.); + test_compare_exchange_ordering(&|success, failure| { + let _ = a.compare_exchange(5., 5., success, failure); + }); + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(5.); + assert_eq!(a.compare_exchange(5., 10., success, failure), Ok(5.)); + assert_eq!(a.load(Ordering::Relaxed), 10.); + assert_eq!(a.compare_exchange(6., 12., success, failure), Err(10.)); + assert_eq!(a.load(Ordering::Relaxed), 10.); + } + } + #[test] + fn compare_exchange_weak() { + let a = <$atomic_type>::new(4.); + test_compare_exchange_ordering(&|success, failure| { + let _ = a.compare_exchange_weak(4., 4., success, failure); + }); + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(4.); + assert_eq!(a.compare_exchange_weak(6., 8., success, failure), Err(4.)); + let mut old = a.load(Ordering::Relaxed); + loop { + let new = old * 2.; + match a.compare_exchange_weak(old, new, success, failure) { + Ok(_) => break, + Err(x) => old = x, + } + } + assert_eq!(a.load(Ordering::Relaxed), 8.); + } + } + #[test] + fn fetch_add() { + let a = <$atomic_type>::new(0.); + test_swap_ordering(&|order| { a.fetch_add(0., order); }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(0.); + assert_eq!(a.fetch_add(10., order), 0.); + assert_eq!(a.load(Ordering::Relaxed), 10.); + let a = <$atomic_type>::new($float_type::MAX); + assert_eq!(a.fetch_add(1., order), $float_type::MAX); + assert_eq!(a.load(Ordering::Relaxed), $float_type::MAX + 1.); + } + } + #[test] + fn fetch_sub() { + let a = <$atomic_type>::new(20.); + test_swap_ordering(&|order| { a.fetch_sub(0., order); }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(20.); + assert_eq!(a.fetch_sub(10., order), 20.); + assert_eq!(a.load(Ordering::Relaxed), 10.); + let a = <$atomic_type>::new($float_type::MIN); + assert_eq!(a.fetch_sub(1., order), $float_type::MIN); + assert_eq!(a.load(Ordering::Relaxed), $float_type::MIN - 1.); + } + } + #[test] + fn fetch_max() { + if mem::size_of::<$float_type>() == 16 + && cfg!(any( + target_arch = "arm", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + target_vendor = "apple", + windows, + )) + { + // TODO(f128): + return; + } + let a = <$atomic_type>::new(23.); + test_swap_ordering(&|order| { a.fetch_max(23., order); }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(23.); + assert_eq!(a.fetch_max(22., order), 23.); + assert_eq!(a.load(Ordering::Relaxed), 23.); + assert_eq!(a.fetch_max(24., order), 23.); + assert_eq!(a.load(Ordering::Relaxed), 24.); + } + } + #[test] + fn fetch_min() { + if mem::size_of::<$float_type>() == 16 + && cfg!(any( + target_arch = "arm", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + target_vendor = "apple", + windows, + )) + { + // TODO(f128): + return; + } + let a = <$atomic_type>::new(23.); + test_swap_ordering(&|order| { a.fetch_min(23., order); }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(23.); + assert_eq!(a.fetch_min(24., order), 23.); + assert_eq!(a.load(Ordering::Relaxed), 23.); + assert_eq!(a.fetch_min(22., order), 23.); + assert_eq!(a.load(Ordering::Relaxed), 22.); + } + } + #[test] + fn fetch_neg() { + let a = <$atomic_type>::new(5.); + test_swap_ordering(&|order| { a.fetch_neg(order); }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(5.); + assert_eq!(a.fetch_neg(order), 5.); + assert_eq!(a.load(Ordering::Relaxed), -5.); + assert_eq!(a.fetch_neg(order), -5.); + assert_eq!(a.load(Ordering::Relaxed), 5.); + } + } + #[test] + fn fetch_abs() { + let a = <$atomic_type>::new(23.); + test_swap_ordering(&|order| { a.fetch_abs(order); }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(-23.); + assert_eq!(a.fetch_abs(order), -23.); + assert_eq!(a.load(Ordering::Relaxed), 23.); + assert_eq!(a.fetch_abs(order), 23.); + assert_eq!(a.load(Ordering::Relaxed), 23.); + } + } + ::quickcheck::quickcheck! { + fn quickcheck_swap(x: $float_type, y: $float_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_float_op_eq!(a.swap(y, order), x); + assert_float_op_eq!(a.swap(x, order), y); + } + true + } + fn quickcheck_compare_exchange(x: $float_type, y: $float_type) -> bool { + #[cfg(all( + target_arch = "arm", + not(any(target_feature = "v6", portable_atomic_target_feature = "v6")), + ))] + { + // TODO: LLVM bug: + // https://github.com/llvm/llvm-project/issues/61880 + // https://github.com/taiki-e/portable-atomic/issues/2 + if mem::size_of::<$float_type>() <= 2 { + return true; + } + } + let mut rng = fastrand::Rng::new(); + let z = loop { + let z = float_rand::$float_type(&mut rng); + if z != y { + break z; + } + }; + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_float_op_eq!(a.compare_exchange(x, y, success, failure).unwrap(), x); + assert_float_op_eq!(a.load(Ordering::Relaxed), y); + assert_float_op_eq!( + a.compare_exchange(z, x, success, failure).unwrap_err(), + y, + ); + assert_float_op_eq!(a.load(Ordering::Relaxed), y); + } + true + } + fn quickcheck_fetch_add(x: $float_type, y: $float_type) -> bool { + if cfg!(all(not(debug_assertions), target_arch = "x86", not(target_feature = "sse2"))) { + // TODO: rustc bug: https://github.com/rust-lang/rust/issues/114479 + return true; + } + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_float_op_eq!(a.fetch_add(y, order), x); + assert_float_op_eq!(a.load(Ordering::Relaxed), x + y); + let a = <$atomic_type>::new(y); + assert_float_op_eq!(a.fetch_add(x, order), y); + assert_float_op_eq!(a.load(Ordering::Relaxed), y + x); + } + true + } + fn quickcheck_fetch_sub(x: $float_type, y: $float_type) -> bool { + if cfg!(all(not(debug_assertions), target_arch = "x86", not(target_feature = "sse2"))) { + // TODO: rustc bug: https://github.com/rust-lang/rust/issues/114479 + return true; + } + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_float_op_eq!(a.fetch_sub(y, order), x); + assert_float_op_eq!(a.load(Ordering::Relaxed), x - y); + let a = <$atomic_type>::new(y); + assert_float_op_eq!(a.fetch_sub(x, order), y); + assert_float_op_eq!(a.load(Ordering::Relaxed), y - x); + } + true + } + fn quickcheck_fetch_max(x: $float_type, y: $float_type) -> bool { + if mem::size_of::<$float_type>() == 16 + && cfg!(any( + target_arch = "arm", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + target_vendor = "apple", + windows, + )) + { + // TODO(f128): + return true; + } + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_float_op_eq!(a.fetch_max(y, order), x); + assert_float_op_eq!(a.load(Ordering::Relaxed), x.max(y)); + let a = <$atomic_type>::new(y); + assert_float_op_eq!(a.fetch_max(x, order), y); + assert_float_op_eq!(a.load(Ordering::Relaxed), y.max(x)); + } + true + } + fn quickcheck_fetch_min(x: $float_type, y: $float_type) -> bool { + if mem::size_of::<$float_type>() == 16 + && cfg!(any( + target_arch = "arm", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + target_vendor = "apple", + windows, + )) + { + // TODO(f128): + return true; + } + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_float_op_eq!(a.fetch_min(y, order), x); + assert_float_op_eq!(a.load(Ordering::Relaxed), x.min(y)); + let a = <$atomic_type>::new(y); + assert_float_op_eq!(a.fetch_min(x, order), y); + assert_float_op_eq!(a.load(Ordering::Relaxed), y.min(x)); + } + true + } + fn quickcheck_fetch_neg(x: $float_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_float_op_eq!(a.fetch_neg(order), x); + assert_float_op_eq!(a.load(Ordering::Relaxed), -x); + assert_float_op_eq!(a.fetch_neg(order), -x); + assert_float_op_eq!(a.load(Ordering::Relaxed), x); + } + true + } + fn quickcheck_fetch_abs(x: $float_type) -> bool { + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_float_op_eq!(a.fetch_abs(order), x); + assert_float_op_eq!(a.fetch_abs(order), x.abs()); + assert_float_op_eq!(a.load(Ordering::Relaxed), x.abs()); + } + true + } + } + }; + ($atomic_type:ty, $float_type:ident) => { + __test_atomic_float!($atomic_type, $float_type, single_thread); + // TODO: multi thread + }; +} +macro_rules! __test_atomic_bool { + ($atomic_type:ty, single_thread) => { + #[test] + fn swap() { + let a = <$atomic_type>::new(true); + test_swap_ordering(&|order| { + a.swap(true, order); + }); + for &order in &helper::SWAP_ORDERINGS { + assert_eq!(a.swap(true, order), true); + assert_eq!(a.swap(false, order), true); + assert_eq!(a.swap(false, order), false); + assert_eq!(a.swap(true, order), false); + } + } + #[test] + fn compare_exchange() { + let a = <$atomic_type>::new(true); + test_compare_exchange_ordering(&|success, failure| { + let _ = a.compare_exchange(true, true, success, failure); + }); + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(true); + assert_eq!(a.compare_exchange(true, false, success, failure), Ok(true)); + assert_eq!(a.load(Ordering::Relaxed), false); + assert_eq!(a.compare_exchange(true, true, success, failure), Err(false)); + assert_eq!(a.load(Ordering::Relaxed), false); + } + } + #[test] + fn compare_exchange_weak() { + let a = <$atomic_type>::new(false); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS { + mark_aligned_defined(&a); + } + test_compare_exchange_ordering(&|success, failure| { + let _ = a.compare_exchange_weak(false, false, success, failure); + }); + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(false); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS { + mark_aligned_defined(&a); + } + assert_eq!(a.compare_exchange_weak(true, true, success, failure), Err(false)); + let mut old = a.load(Ordering::Relaxed); + let new = true; + loop { + match a.compare_exchange_weak(old, new, success, failure) { + Ok(_) => break, + Err(x) => old = x, + } + } + assert_eq!(a.load(Ordering::Relaxed), true); + } + } + #[test] + fn fetch_and() { + let a = <$atomic_type>::new(true); + test_swap_ordering(&|order| assert_eq!(a.fetch_and(true, order), true)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(true); + assert_eq!(a.fetch_and(false, order), true); + assert_eq!(a.load(Ordering::Relaxed), false); + let a = <$atomic_type>::new(true); + assert_eq!(a.fetch_and(true, order), true); + assert_eq!(a.load(Ordering::Relaxed), true); + let a = <$atomic_type>::new(false); + assert_eq!(a.fetch_and(false, order), false); + assert_eq!(a.load(Ordering::Relaxed), false); + let a = <$atomic_type>::new(false); + assert_eq!(a.fetch_and(true, order), false); + assert_eq!(a.load(Ordering::Relaxed), false); + } + } + #[test] + fn and() { + let a = <$atomic_type>::new(true); + test_swap_ordering(&|order| a.and(true, order)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(true); + a.and(false, order); + assert_eq!(a.load(Ordering::Relaxed), false); + let a = <$atomic_type>::new(true); + a.and(true, order); + assert_eq!(a.load(Ordering::Relaxed), true); + let a = <$atomic_type>::new(false); + a.and(false, order); + assert_eq!(a.load(Ordering::Relaxed), false); + let a = <$atomic_type>::new(false); + a.and(true, order); + assert_eq!(a.load(Ordering::Relaxed), false); + } + } + #[test] + fn fetch_or() { + let a = <$atomic_type>::new(true); + test_swap_ordering(&|order| assert_eq!(a.fetch_or(false, order), true)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(true); + assert_eq!(a.fetch_or(false, order), true); + assert_eq!(a.load(Ordering::Relaxed), true); + let a = <$atomic_type>::new(true); + assert_eq!(a.fetch_or(true, order), true); + assert_eq!(a.load(Ordering::Relaxed), true); + let a = <$atomic_type>::new(false); + assert_eq!(a.fetch_or(false, order), false); + assert_eq!(a.load(Ordering::Relaxed), false); + let a = <$atomic_type>::new(false); + assert_eq!(a.fetch_or(true, order), false); + assert_eq!(a.load(Ordering::Relaxed), true); + } + } + #[test] + fn or() { + let a = <$atomic_type>::new(true); + test_swap_ordering(&|order| a.or(false, order)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(true); + a.or(false, order); + assert_eq!(a.load(Ordering::Relaxed), true); + let a = <$atomic_type>::new(true); + a.or(true, order); + assert_eq!(a.load(Ordering::Relaxed), true); + let a = <$atomic_type>::new(false); + a.or(false, order); + assert_eq!(a.load(Ordering::Relaxed), false); + let a = <$atomic_type>::new(false); + a.or(true, order); + assert_eq!(a.load(Ordering::Relaxed), true); + } + } + #[test] + fn fetch_xor() { + let a = <$atomic_type>::new(true); + test_swap_ordering(&|order| assert_eq!(a.fetch_xor(false, order), true)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(true); + assert_eq!(a.fetch_xor(false, order), true); + assert_eq!(a.load(Ordering::Relaxed), true); + let a = <$atomic_type>::new(true); + assert_eq!(a.fetch_xor(true, order), true); + assert_eq!(a.load(Ordering::Relaxed), false); + let a = <$atomic_type>::new(false); + assert_eq!(a.fetch_xor(false, order), false); + assert_eq!(a.load(Ordering::Relaxed), false); + let a = <$atomic_type>::new(false); + assert_eq!(a.fetch_xor(true, order), false); + assert_eq!(a.load(Ordering::Relaxed), true); + } + } + #[test] + fn xor() { + let a = <$atomic_type>::new(true); + test_swap_ordering(&|order| a.xor(false, order)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(true); + a.xor(false, order); + assert_eq!(a.load(Ordering::Relaxed), true); + let a = <$atomic_type>::new(true); + a.xor(true, order); + assert_eq!(a.load(Ordering::Relaxed), false); + let a = <$atomic_type>::new(false); + a.xor(false, order); + assert_eq!(a.load(Ordering::Relaxed), false); + let a = <$atomic_type>::new(false); + a.xor(true, order); + assert_eq!(a.load(Ordering::Relaxed), true); + } + } + ::quickcheck::quickcheck! { + fn quickcheck_compare_exchange(x: bool, y: bool) -> bool { + let z = !y; + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(x); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS { + mark_aligned_defined(&a); + } + assert_eq!(a.compare_exchange(x, y, success, failure).unwrap(), x); + assert_eq!(a.load(Ordering::Relaxed), y); + assert_eq!(a.compare_exchange(z, x, success, failure).unwrap_err(), y); + assert_eq!(a.load(Ordering::Relaxed), y); + } + true + } + } + }; + ($atomic_type:ty) => { + __test_atomic_bool!($atomic_type, single_thread); + // TODO: multi thread + }; +} +macro_rules! __test_atomic_ptr { + ($atomic_type:ty, single_thread) => { + #[allow(unused_imports)] + use sptr::Strict as _; // for old rustc + #[test] + fn swap() { + let a = <$atomic_type>::new(ptr::null_mut()); + test_swap_ordering(&|order| { + a.swap(ptr::null_mut(), order); + }); + let x = &mut 1; + for &order in &helper::SWAP_ORDERINGS { + assert_eq!(a.swap(x, order), ptr::null_mut()); + assert_eq!(a.swap(ptr::null_mut(), order), x as *mut _); + } + } + #[test] + fn compare_exchange() { + let a = <$atomic_type>::new(ptr::null_mut()); + test_compare_exchange_ordering(&|success, failure| { + let _ = a.compare_exchange(ptr::null_mut(), ptr::null_mut(), success, failure); + }); + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(ptr::null_mut()); + let x = &mut 1; + assert_eq!( + a.compare_exchange(ptr::null_mut(), x, success, failure), + Ok(ptr::null_mut()), + ); + assert_eq!(a.load(Ordering::Relaxed), x as *mut _); + assert_eq!( + a.compare_exchange(ptr::null_mut(), ptr::null_mut(), success, failure), + Err(x as *mut _), + ); + assert_eq!(a.load(Ordering::Relaxed), x as *mut _); + } + } + #[test] + fn compare_exchange_weak() { + let a = <$atomic_type>::new(ptr::null_mut()); + test_compare_exchange_ordering(&|success, failure| { + let _ = a.compare_exchange_weak(ptr::null_mut(), ptr::null_mut(), success, failure); + }); + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(ptr::null_mut()); + let x = &mut 1; + assert_eq!(a.compare_exchange_weak(x, x, success, failure), Err(ptr::null_mut())); + let mut old = a.load(Ordering::Relaxed); + loop { + match a.compare_exchange_weak(old, x, success, failure) { + Ok(_) => break, + Err(x) => old = x, + } + } + assert_eq!(a.load(Ordering::Relaxed), x as *mut _); + } + } + // https://github.com/rust-lang/rust/blob/1.84.0/library/core/tests/atomic.rs#L130-L213 + #[test] + fn ptr_add_null() { + let atom = AtomicPtr::::new(core::ptr::null_mut()); + assert_eq!(atom.fetch_ptr_add(1, Ordering::SeqCst).addr(), 0); + assert_eq!(atom.load(Ordering::SeqCst).addr(), 8); + + assert_eq!(atom.fetch_byte_add(1, Ordering::SeqCst).addr(), 8); + assert_eq!(atom.load(Ordering::SeqCst).addr(), 9); + + assert_eq!(atom.fetch_ptr_sub(1, Ordering::SeqCst).addr(), 9); + assert_eq!(atom.load(Ordering::SeqCst).addr(), 1); + + assert_eq!(atom.fetch_byte_sub(1, Ordering::SeqCst).addr(), 1); + assert_eq!(atom.load(Ordering::SeqCst).addr(), 0); + } + #[test] + fn ptr_add_data() { + let num = 0i64; + let n = &num as *const i64 as *mut _; + let atom = AtomicPtr::::new(n); + assert_eq!(atom.fetch_ptr_add(1, Ordering::SeqCst), n); + assert_eq!(atom.load(Ordering::SeqCst), n.wrapping_add(1)); + + assert_eq!(atom.fetch_ptr_sub(1, Ordering::SeqCst), n.wrapping_add(1)); + assert_eq!(atom.load(Ordering::SeqCst), n); + #[allow(clippy::cast_ptr_alignment)] + let bytes_from_n = |b| n.cast::().wrapping_add(b).cast::(); + + assert_eq!(atom.fetch_byte_add(1, Ordering::SeqCst), n); + assert_eq!(atom.load(Ordering::SeqCst), bytes_from_n(1)); + + assert_eq!(atom.fetch_byte_add(5, Ordering::SeqCst), bytes_from_n(1)); + assert_eq!(atom.load(Ordering::SeqCst), bytes_from_n(6)); + + assert_eq!(atom.fetch_byte_sub(1, Ordering::SeqCst), bytes_from_n(6)); + assert_eq!(atom.load(Ordering::SeqCst), bytes_from_n(5)); + + assert_eq!(atom.fetch_byte_sub(5, Ordering::SeqCst), bytes_from_n(5)); + assert_eq!(atom.load(Ordering::SeqCst), n); + } + #[test] + fn ptr_bitops() { + let atom = AtomicPtr::::new(core::ptr::null_mut()); + assert_eq!(atom.fetch_or(0b0111, Ordering::SeqCst).addr(), 0); + assert_eq!(atom.load(Ordering::SeqCst).addr(), 0b0111); + + assert_eq!(atom.fetch_and(0b1101, Ordering::SeqCst).addr(), 0b0111); + assert_eq!(atom.load(Ordering::SeqCst).addr(), 0b0101); + + assert_eq!(atom.fetch_xor(0b1111, Ordering::SeqCst).addr(), 0b0101); + assert_eq!(atom.load(Ordering::SeqCst).addr(), 0b1010); + } + #[test] + fn ptr_bitops_tagging() { + const MASK_TAG: usize = 0b1111; + const MASK_PTR: usize = !MASK_TAG; + + #[repr(align(16))] + struct Tagme(#[allow(dead_code)] u128); + + let tagme = Tagme(1000); + let ptr = &tagme as *const Tagme as *mut Tagme; + let atom: AtomicPtr = AtomicPtr::new(ptr); + + assert_eq!(ptr.addr() & MASK_TAG, 0); + + assert_eq!(atom.fetch_or(0b0111, Ordering::SeqCst), ptr); + assert_eq!(atom.load(Ordering::SeqCst), ptr.map_addr(|a| a | 0b111)); + + assert_eq!( + atom.fetch_and(MASK_PTR | 0b0010, Ordering::SeqCst), + ptr.map_addr(|a| a | 0b111) + ); + assert_eq!(atom.load(Ordering::SeqCst), ptr.map_addr(|a| a | 0b0010)); + + assert_eq!(atom.fetch_xor(0b1011, Ordering::SeqCst), ptr.map_addr(|a| a | 0b0010)); + assert_eq!(atom.load(Ordering::SeqCst), ptr.map_addr(|a| a | 0b1001)); + + assert_eq!(atom.fetch_and(MASK_PTR, Ordering::SeqCst), ptr.map_addr(|a| a | 0b1001)); + assert_eq!(atom.load(Ordering::SeqCst), ptr); + } + #[test] + fn bit_set() { + let a = <$atomic_type>::new(ptr::null_mut::().cast::().map_addr(|a| a | 1)); + test_swap_ordering(&|order| assert!(a.bit_set(0, order))); + for &order in &helper::SWAP_ORDERINGS { + let pointer = &mut 1u64 as *mut u64 as *mut u8; + let atom = <$atomic_type>::new(pointer); + // Tag the bottom bit of the pointer. + assert!(!atom.bit_set(0, order)); + // Extract and untag. + let tagged = atom.load(Ordering::Relaxed); + assert_eq!(tagged.addr() & 1, 1); + assert_eq!(tagged.map_addr(|p| p & !1), pointer); + } + } + #[test] + fn bit_clear() { + let a = <$atomic_type>::new(ptr::null_mut::().cast::()); + test_swap_ordering(&|order| assert!(!a.bit_clear(0, order))); + for &order in &helper::SWAP_ORDERINGS { + let pointer = &mut 1u64 as *mut u64 as *mut u8; + // A tagged pointer + let atom = <$atomic_type>::new(pointer.map_addr(|a| a | 1)); + assert!(atom.bit_set(0, order)); + // Untag + assert!(atom.bit_clear(0, order)); + } + } + #[test] + fn bit_toggle() { + let a = <$atomic_type>::new(ptr::null_mut::().cast::()); + test_swap_ordering(&|order| { + a.bit_toggle(0, order); + }); + for &order in &helper::SWAP_ORDERINGS { + let pointer = &mut 1u64 as *mut u64 as *mut u8; + let atom = <$atomic_type>::new(pointer); + // Toggle a tag bit on the pointer. + atom.bit_toggle(0, order); + assert_eq!(atom.load(Ordering::Relaxed).addr() & 1, 1); + } + } + ::quickcheck::quickcheck! { + fn quickcheck_swap(x: usize, y: usize) -> bool { + let x = sptr::invalid_mut(x); + let y = sptr::invalid_mut(y); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.swap(y, order), x); + assert_eq!(a.swap(x, order), y); + } + true + } + fn quickcheck_compare_exchange(x: usize, y: usize) -> bool { + let mut rng = fastrand::Rng::new(); + let z = loop { + let z = rng.usize(..); + if z != y { + break z; + } + }; + let x = sptr::invalid_mut(x); + let y = sptr::invalid_mut(y); + let z = sptr::invalid_mut(z); + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.compare_exchange(x, y, success, failure).unwrap(), x); + assert_eq!(a.load(Ordering::Relaxed), y); + assert_eq!(a.compare_exchange(z, x, success, failure).unwrap_err(), y); + assert_eq!(a.load(Ordering::Relaxed), y); + } + true + } + fn quickcheck_fetch_byte_add(x: usize, y: usize) -> bool { + let x = sptr::invalid_mut(x); + let y = sptr::invalid_mut::(y); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_byte_add(y.addr(), order), x); + assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr().wrapping_add(y.addr())); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_byte_add(x.addr(), order), y); + assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr().wrapping_add(x.addr())); + } + true + } + fn quickcheck_fetch_byte_sub(x: usize, y: usize) -> bool { + let x = sptr::invalid_mut(x); + let y = sptr::invalid_mut::(y); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_byte_sub(y.addr(), order), x); + assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr().wrapping_sub(y.addr())); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_byte_sub(x.addr(), order), y); + assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr().wrapping_sub(x.addr())); + } + true + } + fn quickcheck_fetch_and(x: usize, y: usize) -> bool { + let x = sptr::invalid_mut(x); + let y = sptr::invalid_mut::(y); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_and(y.addr(), order), x); + assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() & y.addr()); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_and(x.addr(), order), y); + assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr() & x.addr()); + } + true + } + fn quickcheck_fetch_or(x: usize, y: usize) -> bool { + let x = sptr::invalid_mut(x); + let y = sptr::invalid_mut::(y); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_or(y.addr(), order), x); + assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() | y.addr()); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_or(x.addr(), order), y); + assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr() | x.addr()); + } + true + } + fn quickcheck_fetch_xor(x: usize, y: usize) -> bool { + let x = sptr::invalid_mut(x); + let y = sptr::invalid_mut::(y); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!(a.fetch_xor(y.addr(), order), x); + assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() ^ y.addr()); + let a = <$atomic_type>::new(y); + assert_eq!(a.fetch_xor(x.addr(), order), y); + assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr() ^ x.addr()); + } + true + } + fn quickcheck_bit_set(x: usize, bit: u32) -> bool { + let x = sptr::invalid_mut(x); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + let b = a.bit_set(bit, order); + let mask = ::wrapping_shl(1, bit); + assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() | mask); + assert_eq!(b, x.addr() & mask != 0); + } + true + } + fn quickcheck_bit_clear(x: usize, bit: u32) -> bool { + let x = sptr::invalid_mut(x); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + let b = a.bit_clear(bit, order); + let mask = ::wrapping_shl(1, bit); + assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() & !mask); + assert_eq!(b, x.addr() & mask != 0); + } + true + } + fn quickcheck_bit_toggle(x: usize, bit: u32) -> bool { + let x = sptr::invalid_mut(x); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(x); + let b = a.bit_toggle(bit, order); + let mask = ::wrapping_shl(1, bit); + assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() ^ mask); + assert_eq!(b, x.addr() & mask != 0); + } + true + } + } + }; + ($atomic_type:ty) => { + __test_atomic_ptr!($atomic_type, single_thread); + // TODO: multi thread + }; +} + +macro_rules! __test_atomic_int_pub { + ($atomic_type:ty, $int_type:ident) => { + __test_atomic_pub_common!($atomic_type, $int_type); + use std::boxed::Box; + + #[allow(unused_imports)] + use sptr::Strict as _; // for old rustc + #[test] + fn fetch_update() { + // TODO(gcc): failure + if option_env!("RUSTC_CODEGEN_GCC").unwrap_or_default() == "1" + && !cfg!(debug_assertions) + { + return; + } + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return; + } + let a = <$atomic_type>::new(7); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + test_compare_exchange_ordering(&|set, fetch| { + let _ = a.fetch_update(set, fetch, |x| Some(x)); + }); + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(7); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_update(success, failure, |_| None), Err(7)); + assert_eq!(a.fetch_update(success, failure, |x| Some(x + 1)), Ok(7)); + assert_eq!(a.fetch_update(success, failure, |x| Some(x + 1)), Ok(8)); + assert_eq!(a.load(Ordering::SeqCst), 9); + } + } + #[test] + fn impls() { + #[cfg(not(portable_atomic_no_const_transmute))] + const INTO_INNER: $int_type = { + let a = <$atomic_type>::new(10); + a.into_inner() + }; + #[cfg(not(portable_atomic_no_const_mut_refs))] + const GET_MUT: $atomic_type = { + let mut a = <$atomic_type>::new(10); + let _ = unsafe { <$atomic_type>::from_ptr(a.as_ptr()) }; + *a.get_mut() = 5; + a + }; + #[cfg(not(portable_atomic_no_const_transmute))] + { + assert_eq!(INTO_INNER, 10); + } + #[cfg(not(portable_atomic_no_const_mut_refs))] + { + assert_eq!(GET_MUT.into_inner(), 5); + } + let a = <$atomic_type>::default(); + let b = <$atomic_type>::from(0); + assert_eq!(a.load(Ordering::SeqCst), b.load(Ordering::SeqCst)); + assert_eq!(std::format!("{:?}", a), std::format!("{:?}", a.load(Ordering::SeqCst))); + assert_eq!(a.into_inner(), 0); + assert_eq!(b.into_inner(), 0); + + unsafe { + let ptr: *mut Align16<$int_type> = Box::into_raw(Box::new(Align16(0))); + assert!(ptr.addr() % mem::align_of::<$atomic_type>() == 0); + { + let a = <$atomic_type>::from_ptr(ptr.cast::<$int_type>()); + *a.as_ptr() = 1; + } + assert_eq!((*ptr).0, 1); + drop(Box::from_raw(ptr)); + } + } + ::quickcheck::quickcheck! { + fn quickcheck_fetch_update(x: $int_type, y: $int_type) -> bool { + // TODO(riscv): wrong result (as of Valgrind 3.26) + #[cfg(valgrind)] + if cfg!(target_arch = "riscv64") && mem::size_of::<$int_type>() <= 2 { + return true; + } + let mut rng = fastrand::Rng::new(); + let z = loop { + let z = rng.$int_type(..); + if z != y { + break z; + } + }; + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(x); + assert_eq!( + a.fetch_update(success, failure, |_| Some(y)) + .unwrap(), + x + ); + assert_eq!( + a.fetch_update(success, failure, |_| Some(z)) + .unwrap(), + y + ); + assert_eq!(a.load(Ordering::Relaxed), z); + assert_eq!( + a.fetch_update(success, failure, |z| if z == y { Some(z) } else { None }) + .unwrap_err(), + z + ); + assert_eq!(a.load(Ordering::Relaxed), z); + } + true + } + } + }; +} +macro_rules! __test_atomic_float_pub { + ($atomic_type:ty, $float_type:ident) => { + __test_atomic_pub_common!($atomic_type, $float_type); + use std::boxed::Box; + + #[allow(unused_imports)] + use sptr::Strict as _; // for old rustc + #[test] + fn fetch_update() { + let a = <$atomic_type>::new(7.); + test_compare_exchange_ordering(&|set, fetch| { + let _ = a.fetch_update(set, fetch, |x| Some(x)); + }); + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(7.); + assert_eq!(a.fetch_update(success, failure, |_| None), Err(7.)); + assert_eq!(a.fetch_update(success, failure, |x| Some(x + 1.)), Ok(7.)); + assert_eq!(a.fetch_update(success, failure, |x| Some(x + 1.)), Ok(8.)); + assert_eq!(a.load(Ordering::SeqCst), 9.); + } + } + #[test] + fn impls() { + #[cfg(not(portable_atomic_no_const_transmute))] + const INTO_INNER: $float_type = { + let a = <$atomic_type>::new(10.); + a.into_inner() + }; + #[cfg(not(portable_atomic_no_const_mut_refs))] + const GET_MUT: $atomic_type = { + let mut a = <$atomic_type>::new(10.); + let _ = unsafe { <$atomic_type>::from_ptr(a.as_ptr()) }; + *a.get_mut() = 5.; + a + }; + #[cfg(not(portable_atomic_no_const_transmute))] + { + assert_eq!(INTO_INNER, 10.); + } + #[cfg(not(portable_atomic_no_const_mut_refs))] + { + assert_eq!(GET_MUT.into_inner(), 5.); + } + let a = <$atomic_type>::default(); + let b = <$atomic_type>::from(0.); + assert_eq!(a.load(Ordering::SeqCst), b.load(Ordering::SeqCst)); + assert_eq!(std::format!("{:?}", a), std::format!("{:?}", a.load(Ordering::SeqCst))); + assert_eq!(a.into_inner(), 0.); + assert_eq!(b.into_inner(), 0.); + + unsafe { + let ptr: *mut Align16<$float_type> = Box::into_raw(Box::new(Align16(0.))); + assert!(ptr.addr() % mem::align_of::<$atomic_type>() == 0); + { + let a = <$atomic_type>::from_ptr(ptr.cast::<$float_type>()); + *a.as_ptr() = 1.; + } + assert_eq!((*ptr).0, 1.); + drop(Box::from_raw(ptr)); + } + } + }; +} +macro_rules! __test_atomic_bool_pub { + ($atomic_type:ty) => { + __test_atomic_pub_common!($atomic_type, bool); + use std::boxed::Box; + + #[allow(unused_imports)] + use sptr::Strict as _; // for old rustc + #[test] + fn fetch_nand() { + let a = <$atomic_type>::new(true); + test_swap_ordering(&|order| assert_eq!(a.fetch_nand(false, order), true)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(true); + assert_eq!(a.fetch_nand(false, order), true); + assert_eq!(a.load(Ordering::Relaxed), true); + let a = <$atomic_type>::new(true); + assert_eq!(a.fetch_nand(true, order), true); + assert_eq!(a.load(Ordering::Relaxed) as usize, 0); + assert_eq!(a.load(Ordering::Relaxed), false); + let a = <$atomic_type>::new(false); + assert_eq!(a.fetch_nand(false, order), false); + assert_eq!(a.load(Ordering::Relaxed), true); + let a = <$atomic_type>::new(false); + assert_eq!(a.fetch_nand(true, order), false); + assert_eq!(a.load(Ordering::Relaxed), true); + } + } + #[test] + fn fetch_not() { + let a = <$atomic_type>::new(true); + test_swap_ordering(&|order| { + a.fetch_not(order); + }); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(true); + assert_eq!(a.fetch_not(order), true); + assert_eq!(a.load(Ordering::Relaxed), false); + let a = <$atomic_type>::new(false); + assert_eq!(a.fetch_not(order), false); + assert_eq!(a.load(Ordering::Relaxed), true); + } + } + #[test] + fn not() { + let a = <$atomic_type>::new(true); + test_swap_ordering(&|order| a.not(order)); + for &order in &helper::SWAP_ORDERINGS { + let a = <$atomic_type>::new(true); + a.not(order); + assert_eq!(a.load(Ordering::Relaxed), false); + let a = <$atomic_type>::new(false); + a.not(order); + assert_eq!(a.load(Ordering::Relaxed), true); + } + } + #[test] + fn fetch_update() { + // TODO(gcc): failure + if option_env!("RUSTC_CODEGEN_GCC").unwrap_or_default() == "1" + && !cfg!(debug_assertions) + { + return; + } + let a = <$atomic_type>::new(false); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS { + mark_aligned_defined(&a); + } + test_compare_exchange_ordering(&|set, fetch| { + let _ = a.fetch_update(set, fetch, |x| Some(x)); + }); + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(false); + #[cfg(valgrind)] + if IMP_EMU_SUB_WORD_CAS { + mark_aligned_defined(&a); + } + assert_eq!(a.fetch_update(success, failure, |_| None), Err(false)); + assert_eq!(a.fetch_update(success, failure, |x| Some(!x)), Ok(false)); + assert_eq!(a.fetch_update(success, failure, |x| Some(!x)), Ok(true)); + assert_eq!(a.load(Ordering::SeqCst), false); + } + } + #[test] + fn impls() { + #[cfg(not(portable_atomic_no_const_transmute))] + const INTO_INNER: bool = { + let a = <$atomic_type>::new(true); + a.into_inner() + }; + #[cfg(not(portable_atomic_no_const_mut_refs))] + const GET_MUT: $atomic_type = { + let mut a = <$atomic_type>::new(true); + let _ = unsafe { <$atomic_type>::from_ptr(a.as_ptr()) }; + *a.get_mut() = false; + a + }; + #[cfg(not(portable_atomic_no_const_transmute))] + { + assert_eq!(INTO_INNER, true); + } + #[cfg(not(portable_atomic_no_const_mut_refs))] + { + assert_eq!(GET_MUT.into_inner(), false); + } + let a = <$atomic_type>::default(); + let b = <$atomic_type>::from(false); + assert_eq!(a.load(Ordering::SeqCst), b.load(Ordering::SeqCst)); + assert_eq!(std::format!("{:?}", a), std::format!("{:?}", a.load(Ordering::SeqCst))); + assert_eq!(a.into_inner(), false); + assert_eq!(b.into_inner(), false); + + unsafe { + let ptr: *mut bool = Box::into_raw(Box::new(false)); + assert!(ptr.addr() % mem::align_of::<$atomic_type>() == 0); + { + let a = <$atomic_type>::from_ptr(ptr); + *a.as_ptr() = true; + } + assert_eq!((*ptr), true); + drop(Box::from_raw(ptr)); + } + } + }; +} +macro_rules! __test_atomic_ptr_pub { + ($atomic_type:ty) => { + __test_atomic_pub_common!($atomic_type, *mut u8); + use std::boxed::Box; + #[test] + fn fetch_update() { + // TODO(gcc): failure + if option_env!("RUSTC_CODEGEN_GCC").unwrap_or_default() == "1" + && !cfg!(debug_assertions) + { + return; + } + let a = <$atomic_type>::new(ptr::null_mut()); + test_compare_exchange_ordering(&|set, fetch| { + let _ = a.fetch_update(set, fetch, |x| Some(x)); + }); + for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS { + let a = <$atomic_type>::new(ptr::null_mut()); + assert_eq!(a.fetch_update(success, failure, |_| None), Err(ptr::null_mut())); + assert_eq!( + a.fetch_update(success, failure, |_| Some(&a as *const _ as *mut _)), + Ok(ptr::null_mut()) + ); + assert_eq!(a.load(Ordering::SeqCst), &a as *const _ as *mut _); + } + } + #[test] + fn impls() { + #[cfg(not(portable_atomic_no_const_transmute))] + const INTO_INNER: *mut u8 = { + let a = <$atomic_type>::new(ptr::null_mut()); + a.into_inner() + }; + #[cfg(not(portable_atomic_no_const_mut_refs))] + const GET_MUT: $atomic_type = { + let mut a = <$atomic_type>::new(ptr::null_mut()); + let _ = unsafe { <$atomic_type>::from_ptr(a.as_ptr()) }; + *a.get_mut() = ptr::null_mut::().wrapping_add(1); + a + }; + #[cfg(not(portable_atomic_no_const_transmute))] + { + assert!(INTO_INNER.is_null()); + } + #[cfg(not(portable_atomic_no_const_mut_refs))] + { + assert_eq!(GET_MUT.into_inner(), ptr::null_mut::().wrapping_add(1)); + } + let a = <$atomic_type>::default(); + let b = <$atomic_type>::from(ptr::null_mut()); + assert_eq!(a.load(Ordering::SeqCst), b.load(Ordering::SeqCst)); + assert_eq!(std::format!("{:?}", a), std::format!("{:?}", a.load(Ordering::SeqCst))); + assert_eq!(std::format!("{:p}", a), std::format!("{:p}", a.load(Ordering::SeqCst))); + assert_eq!(a.into_inner(), ptr::null_mut()); + assert_eq!(b.into_inner(), ptr::null_mut()); + + unsafe { + let ptr: *mut Align16<*mut u8> = Box::into_raw(Box::new(Align16(ptr::null_mut()))); + assert!(ptr.addr() % mem::align_of::<$atomic_type>() == 0); + { + let a = <$atomic_type>::from_ptr(ptr.cast::<*mut u8>()); + *a.as_ptr() = ptr::null_mut::().wrapping_add(1); + } + assert_eq!((*ptr).0, ptr::null_mut::().wrapping_add(1)); + drop(Box::from_raw(ptr)); + } + } + }; +} + +macro_rules! test_atomic_int_load_store { + ($int_type:ident) => { + paste::paste! { + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + mod [] { + use super::*; + __test_atomic_int_load_store!([], $int_type); + } + } + }; +} +macro_rules! test_atomic_ptr_load_store { + () => { + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + mod test_atomic_ptr { + use super::*; + __test_atomic_ptr_load_store!(AtomicPtr); + } + }; +} + +macro_rules! test_atomic_int_single_thread { + ($int_type:ident) => { + paste::paste! { + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + mod [] { + use super::*; + __test_atomic_int_load_store!([], $int_type, single_thread); + __test_atomic_int!([], $int_type, single_thread); + } + } + }; +} +macro_rules! test_atomic_ptr_single_thread { + () => { + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + mod test_atomic_ptr { + use super::*; + __test_atomic_ptr_load_store!(AtomicPtr, single_thread); + __test_atomic_ptr!(AtomicPtr, single_thread); + } + }; +} + +macro_rules! test_atomic_int { + ($int_type:ident) => { + paste::paste! { + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + mod [] { + use super::*; + __test_atomic_int_load_store!([], $int_type); + __test_atomic_int!([], $int_type); + } + } + }; +} +macro_rules! test_atomic_ptr { + () => { + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + #[allow(unstable_name_collisions)] // for sptr crate + mod test_atomic_ptr { + use super::*; + __test_atomic_ptr_load_store!(AtomicPtr); + __test_atomic_ptr!(AtomicPtr); + } + }; +} + +macro_rules! test_atomic_int_pub { + ($int_type:ident) => { + paste::paste! { + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + mod [] { + use super::*; + __test_atomic_int_load_store!([], $int_type); + __test_atomic_int!([], $int_type); + __test_atomic_int_pub!([], $int_type); + } + } + }; +} +#[cfg(feature = "float")] +macro_rules! test_atomic_float_pub { + ($float_type:ident) => { + paste::paste! { + #[allow( + clippy::alloc_instead_of_core, + clippy::float_arithmetic, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + mod [] { + use super::*; + __test_atomic_float_load_store!([], $float_type); + __test_atomic_float!([], $float_type); + __test_atomic_float_pub!([], $float_type); + } + } + }; +} +macro_rules! test_atomic_bool_pub { + () => { + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + mod test_atomic_bool { + use super::*; + __test_atomic_bool_load_store!(AtomicBool); + __test_atomic_bool!(AtomicBool); + __test_atomic_bool_pub!(AtomicBool); + } + }; +} +macro_rules! test_atomic_ptr_pub { + () => { + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + #[allow(unstable_name_collisions)] // for sptr crate + mod test_atomic_ptr { + use super::*; + __test_atomic_ptr_load_store!(AtomicPtr); + __test_atomic_ptr!(AtomicPtr); + __test_atomic_ptr_pub!(AtomicPtr); + } + }; +} + +// Asserts that `$a` and `$b` have performed equivalent operations. +#[cfg(feature = "float")] +macro_rules! assert_float_op_eq { + ($a:expr, $b:expr $(,)?) => {{ + // See also: + // - https://github.com/rust-lang/unsafe-code-guidelines/issues/237. + // - https://github.com/rust-lang/portable-simd/issues/39. + let a = $a; + let b = $b; + if a.is_nan() && b.is_nan() // don't check sign of NaN: https://github.com/rust-lang/rust/issues/55131 + || a.is_infinite() + && b.is_infinite() + && a.is_sign_positive() == b.is_sign_positive() + && a.is_sign_negative() == b.is_sign_negative() + { + // ok + } else { + assert_eq!(a, b); + } + }}; +} + +#[allow(unused_unsafe)] // for old rustc +fn assert_panic(f: &dyn Fn()) -> std::string::String { + let backtrace = std::env::var_os("RUST_BACKTRACE"); + let hook = std::panic::take_hook(); + // set_var/remove_var is fine as we run tests with RUST_TEST_THREADS=1 + // std::panic::set_backtrace_style is better way here, but is unstable. + unsafe { std::env::set_var("RUST_BACKTRACE", "0") } // Suppress backtrace + std::panic::set_hook(std::boxed::Box::new(|_| {})); // Suppress panic msg + let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)); + std::panic::set_hook(hook); + match backtrace { + Some(v) => unsafe { std::env::set_var("RUST_BACKTRACE", v) }, + None => unsafe { std::env::remove_var("RUST_BACKTRACE") }, + } + let msg = res.unwrap_err(); + msg.downcast_ref::() + .cloned() + .unwrap_or_else(|| msg.downcast_ref::<&'static str>().copied().unwrap().into()) +} +pub(crate) const LOAD_ORDERINGS: [Ordering; 3] = + [Ordering::Relaxed, Ordering::Acquire, Ordering::SeqCst]; +pub(crate) fn rand_load_ordering(rng: &mut fastrand::Rng) -> Ordering { + LOAD_ORDERINGS[rng.usize(0..LOAD_ORDERINGS.len())] +} +pub(crate) fn test_load_ordering(f: &dyn Fn(Ordering)) { + for &order in &LOAD_ORDERINGS { + f(order); + } + if !skip_should_panic_test() { + assert_eq!( + assert_panic(&|| f(Ordering::Release)), + "there is no such thing as a release load" + ); + assert_eq!( + assert_panic(&|| f(Ordering::AcqRel)), + "there is no such thing as an acquire-release load" + ); + } +} +pub(crate) const STORE_ORDERINGS: [Ordering; 3] = + [Ordering::Relaxed, Ordering::Release, Ordering::SeqCst]; +pub(crate) fn rand_store_ordering(rng: &mut fastrand::Rng) -> Ordering { + STORE_ORDERINGS[rng.usize(0..STORE_ORDERINGS.len())] +} +pub(crate) fn test_store_ordering(f: &dyn Fn(Ordering)) { + for &order in &STORE_ORDERINGS { + f(order); + } + if !skip_should_panic_test() { + assert_eq!( + assert_panic(&|| f(Ordering::Acquire)), + "there is no such thing as an acquire store" + ); + assert_eq!( + assert_panic(&|| f(Ordering::AcqRel)), + "there is no such thing as an acquire-release store" + ); + } +} +pub(crate) const SWAP_ORDERINGS: [Ordering; 5] = + [Ordering::Relaxed, Ordering::Release, Ordering::Acquire, Ordering::AcqRel, Ordering::SeqCst]; +pub(crate) fn rand_swap_ordering(rng: &mut fastrand::Rng) -> Ordering { + SWAP_ORDERINGS[rng.usize(0..SWAP_ORDERINGS.len())] +} +pub(crate) fn test_swap_ordering(f: &dyn Fn(Ordering)) { + for &order in &SWAP_ORDERINGS { + f(order); + } +} +pub(crate) const COMPARE_EXCHANGE_ORDERINGS: [(Ordering, Ordering); 15] = [ + (Ordering::Relaxed, Ordering::Relaxed), + (Ordering::Relaxed, Ordering::Acquire), + (Ordering::Relaxed, Ordering::SeqCst), + (Ordering::Acquire, Ordering::Relaxed), + (Ordering::Acquire, Ordering::Acquire), + (Ordering::Acquire, Ordering::SeqCst), + (Ordering::Release, Ordering::Relaxed), + (Ordering::Release, Ordering::Acquire), + (Ordering::Release, Ordering::SeqCst), + (Ordering::AcqRel, Ordering::Relaxed), + (Ordering::AcqRel, Ordering::Acquire), + (Ordering::AcqRel, Ordering::SeqCst), + (Ordering::SeqCst, Ordering::Relaxed), + (Ordering::SeqCst, Ordering::Acquire), + (Ordering::SeqCst, Ordering::SeqCst), +]; +pub(crate) fn rand_compare_exchange_ordering(rng: &mut fastrand::Rng) -> (Ordering, Ordering) { + COMPARE_EXCHANGE_ORDERINGS[rng.usize(0..COMPARE_EXCHANGE_ORDERINGS.len())] +} +pub(crate) fn test_compare_exchange_ordering(f: &dyn Fn(Ordering, Ordering)) { + for &(success, failure) in &COMPARE_EXCHANGE_ORDERINGS { + f(success, failure); + } + if !skip_should_panic_test() { + for &order in &SWAP_ORDERINGS { + let msg = assert_panic(&|| f(order, Ordering::AcqRel)); + assert!( + msg == "there is no such thing as an acquire-release failure ordering" + || msg == "there is no such thing as an acquire-release load", + "{}", + msg + ); + let msg = assert_panic(&|| f(order, Ordering::Release)); + assert!( + msg == "there is no such thing as a release failure ordering" + || msg == "there is no such thing as a release load", + "{}", + msg + ); + } + } +} + +// Used in stress tests to find atomicity bug generated by __test_atomic_* macro. +pub(crate) fn stress_test_config(rng: &mut fastrand::Rng) -> (usize, usize) { + let iterations = if cfg!(miri) { + 50 + } else if cfg!(any(debug_assertions, qemu, valgrind)) { + 5_000 + } else { + 25_000 + }; + let threads = if cfg!(any(debug_assertions, valgrind)) { 2 } else { rng.usize(2..=8) }; + eprintln!("threads={}", threads); + (iterations, threads) +} + +// true if the current implementation implements sub-word atomics using word-size CAS. +#[cfg(valgrind)] +pub(crate) const IMP_EMU_SUB_WORD_CAS: bool = cfg!(target_arch = "s390x"); + +#[cfg(valgrind)] +#[inline(always)] +pub(crate) fn mark_aligned_defined(a: &T) { + test_helper::valgrind::make_aligned_mem_defined::(a); +} + +fn skip_should_panic_test() -> bool { + // Miri's panic handling is slow + // MSAN false positive: https://gist.github.com/taiki-e/dd6269a8ffec46284fdc764a4849f884 + // Valgrind false positive on s390x + is_panic_abort() + || cfg!(miri) + || option_env!("CARGO_PROFILE_RELEASE_LTO").map_or(false, |v| v == "fat") + && build_context::SANITIZE.contains("memory") + || cfg!(all(valgrind, target_arch = "s390x")) +} + +// For -C panic=abort -Z panic_abort_tests: https://github.com/rust-lang/rust/issues/67650 +fn is_panic_abort() -> bool { + !matches!(build_context::PANIC, "unwind" | "") // cfg(panic) requires Rust 1.60 +} + +#[repr(C, align(16))] +pub(crate) struct Align16(pub(crate) T); + +// Stress tests to find memory ordering bug. +// Note that this is not exhaustive and only tests a few cases. +macro_rules! __stress_acquire_release { + (should_pass, + $int_type:ident, $read:ident, $write:ident, $load_order:ident, $store_order:ident + ) => { + paste::paste! { + #[test] + #[cfg_attr(all(any(debug_assertions, valgrind_cross), not(miri)), ignore = "slow in some environments")] // debug mode is slow. + #[allow( + clippy::cast_possible_wrap, + clippy::cast_sign_loss, + clippy::cast_possible_truncation, + )] + fn []() { + __call_stress_test_fn!(acquire_release1, [], + $int_type, $read, $write, $load_order, $store_order); + } + } + }; + (can_panic, + $int_type:ident, $read:ident, $write:ident, $load_order:ident, $store_order:ident + ) => { + paste::paste! { + // Currently, to make this test work well enough outside of Miri, tens of thousands + // of iterations are needed, but this test is slow in some environments. + // So, ignore on non-Miri environments by default. See also catch_unwind_on_weak_memory_arch. + #[test] + #[cfg_attr(not(miri), ignore = "slow in some environments")] + #[allow( + clippy::cast_possible_wrap, + clippy::cast_sign_loss, + clippy::cast_possible_truncation, + )] + fn []() { + use crate::tests::helper::catch_unwind_on_weak_memory_arch as can_panic; + can_panic("a=", test_helper::function_name!(), || { + __call_stress_test_fn!(acquire_release1, [], + $int_type, $read, $write, $load_order, $store_order); + }); + } + } + }; +} +macro_rules! __stress_seqcst { + (should_pass, + $int_type:ident, $read:ident, $write:ident, $load_order:ident, $store_order:ident + ) => { + paste::paste! { + // Currently, to make this test work well enough outside of Miri, tens of thousands + // of iterations are needed, but this test is slow in some environments. + // So, ignore on QEMU by default. + #[test] + #[cfg_attr(any(all(any(debug_assertions, valgrind_cross), not(miri)), qemu), ignore = "slow in some environments")] // debug mode is slow. + #[allow( + clippy::cast_possible_wrap, + clippy::cast_sign_loss, + clippy::cast_possible_truncation, + )] + fn []() { + __call_stress_test_fn!(seqcst1, [], + $int_type, $read, $write, $load_order, $store_order); + } + } + }; + (can_panic, + $int_type:ident, $read:ident, $write:ident, $load_order:ident, $store_order:ident + ) => { + paste::paste! { + // Currently, to make this test work well enough outside of Miri, tens of thousands + // of iterations are needed, but this test is slow in some environments. + // So, ignore on non-Miri environments by default. See also catch_unwind_on_non_seqcst_arch. + #[test] + #[cfg_attr(not(miri), ignore = "slow in some environments")] + #[allow( + clippy::cast_possible_wrap, + clippy::cast_sign_loss, + clippy::cast_possible_truncation, + )] + fn []() { + use crate::tests::helper::catch_unwind_on_non_seqcst_arch as can_panic; + can_panic("c=2", test_helper::function_name!(), || { + __call_stress_test_fn!(seqcst1, [], + $int_type, $read, $write, $load_order, $store_order); + }); + } + } + }; +} +// To test this working correctly: +// - Uncomment can_panic case in __stress_seqcst, +// and run test with `--release -- acquire_release1 --ignored`. +// At least on AArch64 machine, some "panicked as expected" will be shown. +pub(crate) fn acquire_release1( + min: isize, + max: isize, + new: impl Fn(isize) -> T, + load: impl Fn(&T) -> isize + Send + Sync, + store: impl Fn(&T, isize) + Send + Sync, +) { + let n: usize = if cfg!(miri) { + 10 + } else if cfg!(any(qemu, valgrind)) { + 5_000 + } else { + 50_000 + }; + + let mut start: isize = 0; + #[allow(clippy::cast_possible_wrap)] + let mut end: isize = n as isize; + // This test is relatively fast because it spawns only one thread, but + // the iterations are limited to a maximum value of integers. + if max < end { + start = min; + end = max; + } + assert!((start..end).len() <= n, "{}", (start..end).len()); + let a = &new(start); + let b = &AtomicIsize::new(start); + let a_ready = &AtomicUsize::new(0); + let b_ready = &AtomicUsize::new(0); + thread::scope(|s| { + s.spawn(|_| { + while a_ready.load(Ordering::Relaxed) == 0 {} + b_ready.store(1, Ordering::Relaxed); + for i in start..end { + b.store(i, Ordering::Relaxed); + store(a, i); + } + }); + let end = end - 1; + a_ready.store(1, Ordering::Relaxed); + while b_ready.load(Ordering::Relaxed) == 0 {} + loop { + let a = load(a); + let b = b.load(Ordering::Relaxed); + assert!(a <= b, "a={},b={}", a, b); + if a == end && b == end { + break; + } + } + }) + .unwrap(); +} +// To test this working correctly: +// - Uncomment can_panic case in __stress_seqcst, +// and run test with `--release -- seqcst1 --ignored`. +// At least on AArch64 machine, some "panicked as expected" will be shown. +// - Change aarch64.rs's 128-bit seqcst load from `ldar; ldp; dmb ishld` to `ldp; dmb ish` +// and run test with `--release -- seqcst1` on AArch64 macOS or other AArch64 which supports FEAT_LSE2 +// with `RUSTFLAGS=-C target-feature=+lse2`. +// tests::stress_swap_u128::seqcst1_load_seqcst_swap_seqcst should fail within a few repetitions. +pub(crate) fn seqcst1( + _min: isize, + #[allow(unused_variables)] max: isize, + new: impl Fn(isize) -> T, + load: impl Fn(&T) -> isize + Send + Sync, + store: impl Fn(&T, isize) + Send + Sync, +) { + let n: usize = if cfg!(miri) { + 8 + } else if cfg!(valgrind) + || build_context::SANITIZE.contains("address") + || build_context::SANITIZE.contains("memory") + { + 50 + } else if cfg!(qemu) + || option_env!("GITHUB_ACTIONS").is_some() && cfg!(not(target_os = "linux")) + { + // GitHub Actions' macOS and Windows runners are slow. + 5_000 + } else { + 50_000 + }; + + let a = &new(0); + let b = &new(0); + let c = &AtomicUsize::new(0); + let a_done = &AtomicUsize::new(0); + let a_ready = &AtomicUsize::new(0); + let b_ready = &AtomicUsize::new(0); + let panicked = &AtomicUsize::new(0); + thread::scope(|s| { + s.spawn(|_| { + for n in 1..n { + // Acquire to make initialization of a/b/c visible. + while a_ready.load(Ordering::Acquire) != n { + if panicked.load(Ordering::Relaxed) != 0 { + return; + } + } + b_ready.store(n, Ordering::Relaxed); + store(a, 1); + if load(b) == 0 { + c.fetch_add(1, Ordering::Relaxed); + } + // Release to make update of c visible. + a_done.store(n, Ordering::Release); + } + }); + for n in 1..n { + store(a, 0); + store(b, 0); + c.store(0, Ordering::Relaxed); + // Release to make initialization of a/b/c visible. + a_ready.store(n, Ordering::Release); + while b_ready.load(Ordering::Relaxed) != n {} + store(b, 1); + if load(a) == 0 { + c.fetch_add(1, Ordering::Relaxed); + } + // Acquire to make update of c visible. + while a_done.load(Ordering::Acquire) != n {} + let c = c.load(Ordering::Relaxed); + let ok = matches!(c, 0 | 1); + if !ok { + panicked.store(1, Ordering::Relaxed); + panic!("c={},n={}", c, n); + } + } + }) + .unwrap(); +} +// Catches unwinding panic on architectures with weak memory models. +#[allow(dead_code)] +pub(crate) fn catch_unwind_on_weak_memory_arch(pat: &str, function_name: &str, f: impl Fn()) { + // With x86 TSO, RISC-V TSO (optional), SPARC TSO (optional, default?), + // and IBM-370 memory models should never be a panic here. + // Miri emulates weak memory models regardless of target architectures. + if cfg!(all( + any( + target_arch = "x86", + target_arch = "x86_64", + target_arch = "s390x", + target_arch = "sparc", + target_arch = "sparc64", + all(any(target_arch = "riscv32", target_arch = "riscv64"), target_feature = "ztso"), + ), + not(any(miri)), + )) { + f(); + } else if !is_panic_abort() { + // This could be Err on architectures with weak memory models. + // However, this does not necessarily mean that it will always be panic, + // and implementing it with stronger orderings is also okay. + match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) { + Ok(()) => { + // panic!(); + } + Err(msg) => { + let msg = msg + .downcast_ref::() + .cloned() + .unwrap_or_else(|| msg.downcast_ref::<&'static str>().copied().unwrap().into()); + assert!(msg.contains(pat), "{}", msg); + test_helper::eprintln_nocapture!(" {} panicked as expected", function_name); + } + } + } +} +// Catches unwinding panic on architectures with non-sequentially consistent memory models. +#[allow(dead_code)] +pub(crate) fn catch_unwind_on_non_seqcst_arch(pat: &str, function_name: &str, f: impl Fn()) { + if !is_panic_abort() { + // This could be Err on architectures with non-sequentially consistent memory models. + // However, this does not necessarily mean that it will always be panic, + // and implementing it with stronger orderings is also okay. + match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) { + Ok(()) => { + // panic!(); + } + Err(msg) => { + let msg = msg + .downcast_ref::() + .cloned() + .unwrap_or_else(|| msg.downcast_ref::<&'static str>().copied().unwrap().into()); + assert!(msg.contains(pat), "{}", msg); + test_helper::eprintln_nocapture!(" {} panicked as expected", function_name); + } + } + } +} +macro_rules! __call_stress_test_fn { + ($name:ident, $atomic_type:ident, + $int_type:ident, load, cas, $load_order:ident, $store_order:ident + ) => { + $name( + $int_type::MIN.try_into().unwrap_or(isize::MIN), + $int_type::MAX.try_into().unwrap_or(isize::MAX), + |v| <$atomic_type>::new(v as $int_type), + |a| a.load(Ordering::$load_order) as isize, + |a, v| { + a.fetch_update(Ordering::$store_order, Ordering::Relaxed, |_| Some(v as $int_type)) + .unwrap(); + }, + ) + }; + ($name:ident, $atomic_type:ident, + $int_type:ident, load, $write:ident, $load_order:ident, $store_order:ident + ) => { + $name( + $int_type::MIN.try_into().unwrap_or(isize::MIN), + $int_type::MAX.try_into().unwrap_or(isize::MAX), + |v| <$atomic_type>::new(v as $int_type), + |a| a.load(Ordering::$load_order) as isize, + |a, v| { + a.$write(v as $int_type, Ordering::$store_order); + }, + ) + }; + ($name:ident, $atomic_type:ident, + $int_type:ident, cas, $write:ident, $load_order:ident, $store_order:ident + ) => { + $name( + $int_type::MIN.try_into().unwrap_or(isize::MIN), + $int_type::MAX.try_into().unwrap_or(isize::MAX), + |v| <$atomic_type>::new(v as $int_type), + |a| { + a.compare_exchange(0, 0, Ordering::$load_order, match Ordering::$load_order { + Ordering::Release => Ordering::Relaxed, + Ordering::AcqRel => Ordering::Acquire, + _ => Ordering::$load_order, + }) + .unwrap_or_else(|x| x) as isize + }, + |a, v| { + a.$write(v as $int_type, Ordering::$store_order); + }, + ) + }; + ($name:ident, $atomic_type:ident, + $int_type:ident, cas_weak, $write:ident, $load_order:ident, $store_order:ident + ) => { + $name( + $int_type::MIN.try_into().unwrap_or(isize::MIN), + $int_type::MAX.try_into().unwrap_or(isize::MAX), + |v| <$atomic_type>::new(v as $int_type), + |a| { + a.compare_exchange_weak(0, 0, Ordering::$load_order, match Ordering::$load_order { + Ordering::Release => Ordering::Relaxed, + Ordering::AcqRel => Ordering::Acquire, + _ => Ordering::$load_order, + }) + .unwrap_or_else(|x| x) as isize + }, + |a, v| { + a.$write(v as $int_type, Ordering::$store_order); + }, + ) + }; +} +macro_rules! stress_test_load_store { + ($int_type:ident) => { + paste::paste! { + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + mod [] { + use std::{convert::TryInto as _, sync::atomic::Ordering}; + + use crate::tests::helper::*; + use super::*; + + __stress_acquire_release!(can_panic, $int_type, load, store, Relaxed, Relaxed); + __stress_acquire_release!(can_panic, $int_type, load, store, Relaxed, Release); + __stress_acquire_release!(can_panic, $int_type, load, store, Relaxed, SeqCst); + __stress_acquire_release!(can_panic, $int_type, load, store, Acquire, Relaxed); + __stress_acquire_release!(should_pass, $int_type, load, store, Acquire, Release); + __stress_acquire_release!(should_pass, $int_type, load, store, Acquire, SeqCst); + __stress_acquire_release!(can_panic, $int_type, load, store, SeqCst, Relaxed); + __stress_acquire_release!(should_pass, $int_type, load, store, SeqCst, Release); + __stress_acquire_release!(should_pass, $int_type, load, store, SeqCst, SeqCst); + + __stress_seqcst!(can_panic, $int_type, load, store, Relaxed, Relaxed); + __stress_seqcst!(can_panic, $int_type, load, store, Relaxed, Release); + __stress_seqcst!(can_panic, $int_type, load, store, Relaxed, SeqCst); + __stress_seqcst!(can_panic, $int_type, load, store, Acquire, Relaxed); + __stress_seqcst!(can_panic, $int_type, load, store, Acquire, Release); + __stress_seqcst!(can_panic, $int_type, load, store, Acquire, SeqCst); + __stress_seqcst!(can_panic, $int_type, load, store, SeqCst, Relaxed); + __stress_seqcst!(can_panic, $int_type, load, store, SeqCst, Release); + __stress_seqcst!(should_pass, $int_type, load, store, SeqCst, SeqCst); + } + } + }; +} +macro_rules! stress_test { + ($int_type:ident) => { + stress_test_load_store!($int_type); + paste::paste! { + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks + )] + mod [] { + use std::{convert::TryInto as _, sync::atomic::Ordering}; + + use crate::tests::helper::*; + use super::*; + + __stress_acquire_release!(can_panic, $int_type, load, swap, Relaxed, Relaxed); + __stress_acquire_release!(can_panic, $int_type, load, swap, Relaxed, Acquire); + __stress_acquire_release!(can_panic, $int_type, load, swap, Relaxed, Release); + __stress_acquire_release!(can_panic, $int_type, load, swap, Relaxed, AcqRel); + __stress_acquire_release!(can_panic, $int_type, load, swap, Relaxed, SeqCst); + __stress_acquire_release!(can_panic, $int_type, load, swap, Acquire, Relaxed); + __stress_acquire_release!(can_panic, $int_type, load, swap, Acquire, Acquire); + __stress_acquire_release!(should_pass, $int_type, load, swap, Acquire, Release); + __stress_acquire_release!(should_pass, $int_type, load, swap, Acquire, AcqRel); + __stress_acquire_release!(should_pass, $int_type, load, swap, Acquire, SeqCst); + __stress_acquire_release!(can_panic, $int_type, load, swap, SeqCst, Relaxed); + __stress_acquire_release!(can_panic, $int_type, load, swap, SeqCst, Acquire); + __stress_acquire_release!(should_pass, $int_type, load, swap, SeqCst, Release); + __stress_acquire_release!(should_pass, $int_type, load, swap, SeqCst, AcqRel); + __stress_acquire_release!(should_pass, $int_type, load, swap, SeqCst, SeqCst); + + __stress_seqcst!(can_panic, $int_type, load, swap, Relaxed, Relaxed); + __stress_seqcst!(can_panic, $int_type, load, swap, Relaxed, Acquire); + __stress_seqcst!(can_panic, $int_type, load, swap, Relaxed, Release); + __stress_seqcst!(can_panic, $int_type, load, swap, Relaxed, AcqRel); + __stress_seqcst!(can_panic, $int_type, load, swap, Relaxed, SeqCst); + __stress_seqcst!(can_panic, $int_type, load, swap, Acquire, Relaxed); + __stress_seqcst!(can_panic, $int_type, load, swap, Acquire, Acquire); + __stress_seqcst!(can_panic, $int_type, load, swap, Acquire, Release); + __stress_seqcst!(can_panic, $int_type, load, swap, Acquire, AcqRel); + __stress_seqcst!(can_panic, $int_type, load, swap, Acquire, SeqCst); + __stress_seqcst!(can_panic, $int_type, load, swap, SeqCst, Relaxed); + __stress_seqcst!(can_panic, $int_type, load, swap, SeqCst, Acquire); + __stress_seqcst!(can_panic, $int_type, load, swap, SeqCst, Release); + __stress_seqcst!(can_panic, $int_type, load, swap, SeqCst, AcqRel); + __stress_seqcst!(should_pass, $int_type, load, swap, SeqCst, SeqCst); + } + } + // TODO: cas + }; +} + +#[cfg(feature = "float")] +pub(crate) mod float_rand { + #[cfg(portable_atomic_unstable_f16)] + pub(crate) fn f16(rng: &mut fastrand::Rng) -> f16 { + f16::from_bits(rng.u16(..)) + } + pub(crate) fn f32(rng: &mut fastrand::Rng) -> f32 { + f32::from_bits(rng.u32(..)) + } + #[cfg(not(all(not(debug_assertions), target_arch = "x86", not(target_feature = "sse2"))))] + pub(crate) fn f64(rng: &mut fastrand::Rng) -> f64 { + f64::from_bits(rng.u64(..)) + } + #[cfg(portable_atomic_unstable_f128)] + pub(crate) fn f128(rng: &mut fastrand::Rng) -> f128 { + f128::from_bits(rng.u128(..)) + } +} diff --git a/vendor/portable-atomic/src/tests/mod.rs b/vendor/portable-atomic/src/tests/mod.rs new file mode 100644 index 0000000..51050af --- /dev/null +++ b/vendor/portable-atomic/src/tests/mod.rs @@ -0,0 +1,499 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +#![allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks, + clippy::wildcard_imports +)] + +#[macro_use] +pub(crate) mod helper; + +#[allow(dead_code)] +#[path = "../../version.rs"] +mod version; + +use test_helper as _; // For critical-section test + +use super::*; + +test_atomic_bool_pub!(); +test_atomic_ptr_pub!(); + +test_atomic_int_pub!(isize); +test_atomic_int_pub!(usize); +test_atomic_int_pub!(i8); +test_atomic_int_pub!(u8); +test_atomic_int_pub!(i16); +test_atomic_int_pub!(u16); +test_atomic_int_pub!(i32); +test_atomic_int_pub!(u32); +test_atomic_int_pub!(i64); +test_atomic_int_pub!(u64); +#[cfg(not(all(valgrind, target_arch = "powerpc64")))] // TODO(powerpc64): Hang (as of Valgrind 3.26) +test_atomic_int_pub!(i128); +#[cfg(not(all(valgrind, target_arch = "powerpc64")))] // TODO(powerpc64): Hang (as of Valgrind 3.26) +test_atomic_int_pub!(u128); + +#[cfg(all(feature = "float", portable_atomic_unstable_f16))] +test_atomic_float_pub!(f16); +#[cfg(feature = "float")] +test_atomic_float_pub!(f32); +#[cfg(feature = "float")] +// TODO: rustc bug: https://github.com/rust-lang/rust/issues/114479 +#[cfg(not(all(not(debug_assertions), target_arch = "x86", not(target_feature = "sse2"))))] +test_atomic_float_pub!(f64); +#[cfg(all(feature = "float", portable_atomic_unstable_f128))] +test_atomic_float_pub!(f128); + +#[deny(improper_ctypes)] +extern "C" { + fn _atomic_bool_ffi_safety(_: AtomicBool); + fn _atomic_ptr_ffi_safety(_: AtomicPtr); + fn _atomic_isize_ffi_safety(_: AtomicIsize); + fn _atomic_usize_ffi_safety(_: AtomicUsize); + fn _atomic_i8_ffi_safety(_: AtomicI8); + fn _atomic_u8_ffi_safety(_: AtomicU8); + fn _atomic_i16_ffi_safety(_: AtomicI16); + fn _atomic_u16_ffi_safety(_: AtomicU16); + fn _atomic_i32_ffi_safety(_: AtomicI32); + fn _atomic_u32_ffi_safety(_: AtomicU32); + fn _atomic_i64_ffi_safety(_: AtomicI64); + fn _atomic_u64_ffi_safety(_: AtomicU64); + #[rustversion::since(1.89)] // https://github.com/rust-lang/rust/pull/137306 + fn _atomic_i128_ffi_safety(_: AtomicI128); + #[rustversion::since(1.89)] // https://github.com/rust-lang/rust/pull/137306 + fn _atomic_u128_ffi_safety(_: AtomicU128); + #[cfg(all(feature = "float", portable_atomic_unstable_f16))] + fn _atomic_f16_ffi_safety(_: AtomicF16); + #[cfg(feature = "float")] + fn _atomic_f32_ffi_safety(_: AtomicF32); + #[cfg(feature = "float")] + fn _atomic_f64_ffi_safety(_: AtomicF64); + #[cfg(all(feature = "float", portable_atomic_unstable_f128))] + fn _atomic_f128_ffi_safety(_: AtomicF128); +} + +#[test] +fn test_is_lock_free() { + assert!(AtomicI8::is_always_lock_free()); + assert!(AtomicI8::is_lock_free()); + assert!(AtomicU8::is_always_lock_free()); + assert!(AtomicU8::is_lock_free()); + assert!(AtomicI16::is_always_lock_free()); + assert!(AtomicI16::is_lock_free()); + assert!(AtomicU16::is_always_lock_free()); + assert!(AtomicU16::is_lock_free()); + #[cfg(all(feature = "float", portable_atomic_unstable_f16))] + assert!(AtomicF16::is_always_lock_free()); + #[cfg(all(feature = "float", portable_atomic_unstable_f16))] + assert!(AtomicF16::is_lock_free()); + assert!(AtomicI32::is_always_lock_free()); + assert!(AtomicI32::is_lock_free()); + assert!(AtomicU32::is_always_lock_free()); + assert!(AtomicU32::is_lock_free()); + #[cfg(feature = "float")] + assert!(AtomicF32::is_always_lock_free()); + #[cfg(feature = "float")] + assert!(AtomicF32::is_lock_free()); + #[cfg(not(portable_atomic_no_cfg_target_has_atomic))] + { + if cfg!(any( + target_has_atomic = "64", + all( + target_arch = "riscv32", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_feature = "zacas", portable_atomic_target_feature = "zacas"), + ), + )) { + assert!(AtomicI64::is_always_lock_free()); + assert!(AtomicI64::is_lock_free()); + assert!(AtomicU64::is_always_lock_free()); + assert!(AtomicU64::is_lock_free()); + #[cfg(feature = "float")] + assert!(AtomicF64::is_always_lock_free()); + #[cfg(feature = "float")] + assert!(AtomicF64::is_lock_free()); + } else if cfg!(all( + feature = "fallback", + target_arch = "arm", + not(any(miri, portable_atomic_sanitize_thread)), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + any(target_os = "linux", target_os = "android"), + not(any(target_feature = "v6", portable_atomic_target_feature = "v6")), + not(portable_atomic_no_outline_atomics), + not(target_has_atomic = "64"), + not(portable_atomic_test_detect_false), + )) { + assert!(!AtomicI64::is_always_lock_free()); + assert!(!AtomicU64::is_always_lock_free()); + #[cfg(feature = "float")] + assert!(!AtomicF64::is_always_lock_free()); + assert!(AtomicI64::is_lock_free()); + assert!(AtomicU64::is_lock_free()); + #[cfg(feature = "float")] + assert!(AtomicF64::is_lock_free()); + } else { + assert!(!AtomicI64::is_always_lock_free()); + assert!(!AtomicU64::is_always_lock_free()); + #[cfg(feature = "float")] + assert!(!AtomicF64::is_always_lock_free()); + #[cfg(not(target_arch = "riscv32"))] + { + assert!(!AtomicI64::is_lock_free()); + assert!(!AtomicU64::is_lock_free()); + #[cfg(feature = "float")] + assert!(!AtomicF64::is_lock_free()); + } + #[cfg(target_arch = "riscv32")] + { + // TODO(riscv): check detect.has_zacas + } + } + } + if cfg!(portable_atomic_no_asm) && cfg!(not(portable_atomic_unstable_asm)) { + assert!(!AtomicI128::is_always_lock_free()); + assert!(!AtomicI128::is_lock_free()); + assert!(!AtomicU128::is_always_lock_free()); + assert!(!AtomicU128::is_lock_free()); + #[cfg(all(feature = "float", portable_atomic_unstable_f128))] + assert!(!AtomicF128::is_always_lock_free()); + #[cfg(all(feature = "float", portable_atomic_unstable_f128))] + assert!(!AtomicF128::is_lock_free()); + } else if cfg!(any( + all( + target_arch = "aarch64", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + any(not(portable_atomic_no_asm), portable_atomic_unstable_asm), + ), + all( + target_arch = "arm64ec", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + ), + all( + target_arch = "x86_64", + any(target_feature = "cmpxchg16b", portable_atomic_target_feature = "cmpxchg16b"), + ), + all( + target_arch = "riscv64", + any(target_feature = "zacas", portable_atomic_target_feature = "zacas"), + ), + all( + target_arch = "powerpc64", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + any( + target_feature = "quadword-atomics", + portable_atomic_target_feature = "quadword-atomics", + ), + ), + all( + target_arch = "s390x", + not(all( + any(miri, portable_atomic_sanitize_thread), + not(portable_atomic_atomic_intrinsics), + )), + not(portable_atomic_no_asm), + ), + )) { + assert!(AtomicI128::is_always_lock_free()); + assert!(AtomicI128::is_lock_free()); + assert!(AtomicU128::is_always_lock_free()); + assert!(AtomicU128::is_lock_free()); + #[cfg(all(feature = "float", portable_atomic_unstable_f128))] + assert!(AtomicF128::is_always_lock_free()); + #[cfg(all(feature = "float", portable_atomic_unstable_f128))] + assert!(AtomicF128::is_lock_free()); + } else { + assert!(!AtomicI128::is_always_lock_free()); + assert!(!AtomicU128::is_always_lock_free()); + #[cfg(all(feature = "float", portable_atomic_unstable_f128))] + assert!(!AtomicF128::is_always_lock_free()); + #[cfg(not(any( + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "riscv64", + )))] + { + assert!(!AtomicI128::is_lock_free()); + assert!(!AtomicU128::is_lock_free()); + #[cfg(all(feature = "float", portable_atomic_unstable_f128))] + assert!(!AtomicF128::is_lock_free()); + } + #[cfg(target_arch = "x86_64")] + { + let has_cmpxchg16b = cfg!(all( + feature = "fallback", + not(portable_atomic_no_outline_atomics), + not(any(target_env = "sgx", miri)), + not(portable_atomic_test_detect_false), + )) && std::is_x86_feature_detected!("cmpxchg16b"); + assert_eq!(AtomicI128::is_lock_free(), has_cmpxchg16b); + assert_eq!(AtomicU128::is_lock_free(), has_cmpxchg16b); + #[cfg(all(feature = "float", portable_atomic_unstable_f128))] + assert_eq!(AtomicF128::is_lock_free(), has_cmpxchg16b); + } + #[cfg(target_arch = "powerpc64")] + { + // TODO(powerpc64): is_powerpc_feature_detected is unstable + } + #[cfg(target_arch = "riscv64")] + { + // TODO(riscv): check detect.has_zacas + } + } +} + +// test version parsing code used in the build script. +#[test] +fn test_rustc_version() { + use self::version::Version; + + // rustc 1.34 (rustup) + let v = Version::parse( + "rustc 1.34.2 (6c2484dc3 2019-05-13) +binary: rustc +commit-hash: 6c2484dc3c532c052f159264e970278d8b77cdc9 +commit-date: 2019-05-13 +host: x86_64-apple-darwin +release: 1.34.2 +LLVM version: 8.0", + ) + .unwrap(); + assert_eq!(v, Version::stable(34, 8)); + + // rustc 1.50 (rustup) + let v = Version::parse( + "rustc 1.50.0 (cb75ad5db 2021-02-10) +binary: rustc +commit-hash: cb75ad5db02783e8b0222fee363c5f63f7e2cf5b +commit-date: 2021-02-10 +host: aarch64-unknown-linux-gnu +release: 1.50.0", + ) + .unwrap(); + assert_eq!(v, Version::stable(50, 0)); + + // rustc 1.67 (rustup) + let v = Version::parse( + "rustc 1.67.0 (fc594f156 2023-01-24) +binary: rustc +commit-hash: fc594f15669680fa70d255faec3ca3fb507c3405 +commit-date: 2023-01-24 +host: aarch64-apple-darwin +release: 1.67.0 +LLVM version: 15.0.6", + ) + .unwrap(); + assert_eq!(v, Version::stable(67, 15)); + + // rustc 1.68-beta (rustup) + let v = Version::parse( + "rustc 1.68.0-beta.2 (10b73bf73 2023-02-01) +binary: rustc +commit-hash: 10b73bf73a6b770cd92ad8ff538173bc3298411c +commit-date: 2023-02-01 +host: aarch64-apple-darwin +release: 1.68.0-beta.2 +LLVM version: 15.0.6", + ) + .unwrap(); + // We do not distinguish between stable and beta because we are only + // interested in whether unstable features are potentially available. + assert_eq!(v, Version::stable(68, 15)); + + // rustc nightly-2019-01-27 (rustup) + let v = Version::parse( + "rustc 1.33.0-nightly (20c2cba61 2019-01-26) +binary: rustc +commit-hash: 20c2cba61dc83e612d25ed496025171caa3db30f +commit-date: 2019-01-26 +host: x86_64-apple-darwin +release: 1.33.0-nightly +LLVM version: 8.0", + ) + .unwrap(); + assert_eq!(v.minor, 33); + assert!(v.nightly); + assert_eq!(v.llvm, 8); + assert_eq!(v.commit_date().year, 2019); + assert_eq!(v.commit_date().month, 1); + assert_eq!(v.commit_date().day, 26); + + // rustc 1.69-nightly (rustup) + let v = Version::parse( + "rustc 1.69.0-nightly (bd39bbb4b 2023-02-07) +binary: rustc +commit-hash: bd39bbb4bb92df439bf6d85470e296cc6a47ffbd +commit-date: 2023-02-07 +host: aarch64-apple-darwin +release: 1.69.0-nightly +LLVM version: 15.0.7", + ) + .unwrap(); + assert_eq!(v.minor, 69); + assert!(v.nightly); + assert_eq!(v.llvm, 15); + assert_eq!(v.commit_date().year, 2023); + assert_eq!(v.commit_date().month, 2); + assert_eq!(v.commit_date().day, 7); + + // clippy-driver 1.69-nightly (rustup) + let v = Version::parse( + "rustc 1.69.0-nightly (bd39bbb4b 2023-02-07) +binary: rustc +commit-hash: bd39bbb4bb92df439bf6d85470e296cc6a47ffbd +commit-date: 2023-02-07 +host: aarch64-apple-darwin +release: 1.69.0-nightly +LLVM version: 15.0.7", + ) + .unwrap(); + assert_eq!(v.minor, 69); + assert!(v.nightly); + assert_eq!(v.llvm, 15); + assert_eq!(v.commit_date().year, 2023); + assert_eq!(v.commit_date().month, 2); + assert_eq!(v.commit_date().day, 7); + + // rustc 1.69-dev (from source: ./x.py build) + let v = Version::parse( + "rustc 1.69.0-dev +binary: rustc +commit-hash: unknown +commit-date: unknown +host: aarch64-unknown-linux-gnu +release: 1.69.0-dev +LLVM version: 16.0.0", + ) + .unwrap(); + assert_eq!(v.minor, 69); + assert!(v.nightly); + assert_eq!(v.llvm, 16); + assert_eq!(v.commit_date().year, 0); + assert_eq!(v.commit_date().month, 0); + assert_eq!(v.commit_date().day, 0); + + // rustc 1.48 (debian 11: apt-get install cargo) + let v = Version::parse( + "rustc 1.48.0 +binary: rustc +commit-hash: unknown +commit-date: unknown +host: aarch64-unknown-linux-gnu +release: 1.48.0 +LLVM version: 11.0", + ) + .unwrap(); + assert_eq!(v, Version::stable(48, 11)); + + // rustc 1.67 (fedora: dnf install cargo) + let v = Version::parse( + "rustc 1.67.0 (fc594f156 2023-01-24) (Fedora 1.67.0-2.fc37) +binary: rustc +commit-hash: fc594f15669680fa70d255faec3ca3fb507c3405 +commit-date: 2023-01-24 +host: aarch64-unknown-linux-gnu +release: 1.67.0 +LLVM version: 15.0.7", + ) + .unwrap(); + assert_eq!(v, Version::stable(67, 15)); + + // rustc 1.64 (alpine: apk add cargo) + let v = Version::parse( + "rustc 1.64.0 +binary: rustc +commit-hash: unknown +commit-date: unknown +host: aarch64-alpine-linux-musl +release: 1.64.0 +LLVM version: 15.0.3", + ) + .unwrap(); + assert_eq!(v, Version::stable(64, 15)); +} + +#[cfg(feature = "serde")] +#[test] +fn test_serde() { + use std::{eprint, eprintln, fmt}; + + use serde::{ + de::{Deserialize, Deserializer}, + ser::{Serialize, Serializer}, + }; + use serde_test::{Token, assert_tokens}; + + #[derive(Debug)] + struct DebugPartialEq(T); + impl PartialEq for DebugPartialEq { + fn eq(&self, other: &Self) -> bool { + std::format!("{:?}", self) == std::format!("{:?}", other) + } + } + impl Serialize for DebugPartialEq { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } + } + impl<'de, T: Deserialize<'de>> Deserialize<'de> for DebugPartialEq { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + T::deserialize(deserializer).map(Self) + } + } + + macro_rules! t { + ($atomic_type:ty, $value_type:ident $(as $token_value_type:ident)?, $token_type:ident) => { + eprint!("test_serde {} ... ", stringify!($value_type)); + assert_tokens(&DebugPartialEq(<$atomic_type>::new($value_type::MAX)), &[ + Token::$token_type($value_type::MAX $(as $token_value_type)?), + ]); + assert_tokens(&DebugPartialEq(<$atomic_type>::new($value_type::MIN)), &[ + Token::$token_type($value_type::MIN $(as $token_value_type)?), + ]); + eprintln!("ok"); + }; + } + + assert_tokens(&DebugPartialEq(AtomicBool::new(true)), &[Token::Bool(true)]); + assert_tokens(&DebugPartialEq(AtomicBool::new(false)), &[Token::Bool(false)]); + t!(AtomicIsize, isize as i64, I64); + t!(AtomicUsize, usize as u64, U64); + t!(AtomicI8, i8, I8); + t!(AtomicU8, u8, U8); + t!(AtomicI16, i16, I16); + t!(AtomicU16, u16, U16); + t!(AtomicI32, i32, I32); + t!(AtomicU32, u32, U32); + t!(AtomicI64, i64, I64); + t!(AtomicU64, u64, U64); + #[cfg(not(all(valgrind, target_arch = "powerpc64")))] // TODO(powerpc64): Hang (as of Valgrind 3.26) + t!(AtomicI128, i128, I128); + #[cfg(not(all(valgrind, target_arch = "powerpc64")))] // TODO(powerpc64): Hang (as of Valgrind 3.26) + t!(AtomicU128, u128, U128); + // TODO(f16_and_f128): Test f16 & f128 once stabilized. + #[cfg(feature = "float")] + t!(AtomicF32, f32, F32); + #[cfg(feature = "float")] + t!(AtomicF64, f64, F64); +} diff --git a/vendor/portable-atomic/src/utils.rs b/vendor/portable-atomic/src/utils.rs new file mode 100644 index 0000000..20a1a69 --- /dev/null +++ b/vendor/portable-atomic/src/utils.rs @@ -0,0 +1,1289 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +#![cfg_attr(not(all(test, feature = "float")), allow(dead_code, unused_macros))] + +#[allow(unused_imports)] +pub(crate) use self::generated::{RegISize, RegSize}; +#[macro_use] +#[path = "gen/utils.rs"] +mod generated; + +use core::sync::atomic::Ordering; + +macro_rules! static_assert { + ($cond:expr $(,)?) => {{ + let [()] = [(); (true /* type check */ & $cond) as usize]; + }}; +} + +macro_rules! static_assert_layout { + ($atomic_type:ty, $value_type:ty) => { + static_assert!( + core::mem::align_of::<$atomic_type>() == core::mem::size_of::<$atomic_type>() + ); + static_assert!(core::mem::size_of::<$atomic_type>() == core::mem::size_of::<$value_type>()); + }; +} + +// #[doc = concat!(...)] requires Rust 1.54 +macro_rules! doc_comment { + ($doc:expr, $($tt:tt)*) => { + #[doc = $doc] + $($tt)* + }; +} + +// Adapted from https://github.com/BurntSushi/memchr/blob/2.4.1/src/memchr/x86/mod.rs#L9-L71. +/// # Safety +/// +/// - the caller must uphold the safety contract for the function returned by $detect_body. +/// - the memory pointed by the function pointer returned by $detect_body must be visible from any threads. +/// +/// The second requirement is always met if the function pointer is to the function definition. +/// (Currently, all uses of this macro in our code are in this case.) +#[allow(unused_macros)] +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "arm64ec", + target_arch = "powerpc64", + target_arch = "riscv32", + target_arch = "riscv64", + all(target_arch = "x86_64", not(any(target_env = "sgx", miri))), +))] +macro_rules! ifunc { + (unsafe fn($($arg_pat:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)? { $($init_body:tt)* }) => {{ + type FnTy = unsafe fn($($arg_ty),*) $(-> $ret_ty)?; + static FUNC: core::sync::atomic::AtomicPtr<()> + = core::sync::atomic::AtomicPtr::new(init as *mut ()); + #[cold] + unsafe fn init($($arg_pat: $arg_ty),*) $(-> $ret_ty)? { + let func: FnTy = { $($init_body)* }; + FUNC.store(func as *mut (), core::sync::atomic::Ordering::Relaxed); + // SAFETY: the caller must uphold the safety contract for the function returned by $init_body. + unsafe { func($($arg_pat),*) } + } + // SAFETY: `FnTy` is a function pointer, which is always safe to transmute with a `*mut ()`. + // (To force the caller to use unsafe block for this macro, do not use + // unsafe block here.) + let func = { + core::mem::transmute::<*mut (), FnTy>(FUNC.load(core::sync::atomic::Ordering::Relaxed)) + }; + // SAFETY: the caller must uphold the safety contract for the function returned by $init_body. + // (To force the caller to use unsafe block for this macro, do not use + // unsafe block here.) + func($($arg_pat),*) + }}; +} + +#[cfg(not(portable_atomic_no_asm))] +#[allow(unused_macros)] +macro_rules! __asm { + ($($tt:tt)*) => { + core::arch::asm!($($tt)*) + }; +} +#[cfg(portable_atomic_no_asm)] +#[allow(unused_macros)] +macro_rules! __asm { + ($($tt:tt)*) => { + asm!($($tt)*) + }; +} + +#[allow(unused_macros)] +#[cfg(not(portable_atomic_no_outline_atomics))] +#[cfg(any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "arm64ec", + target_arch = "powerpc64", + target_arch = "riscv32", + target_arch = "riscv64", + all(target_arch = "x86_64", not(any(target_env = "sgx", miri))), +))] +macro_rules! fn_alias { + ( + $(#[$($fn_attr:tt)*])* + $vis:vis unsafe fn($($arg_pat:ident: $arg_ty:ty),*) $(-> $ret_ty:ty)?; + $(#[$($alias_attr:tt)*])* + $new:ident = $from:ident($($last_args:tt)*); + $($rest:tt)* + ) => { + $(#[$($fn_attr)*])* + $(#[$($alias_attr)*])* + $vis unsafe fn $new($($arg_pat: $arg_ty),*) $(-> $ret_ty)? { + // SAFETY: the caller must uphold the safety contract. + unsafe { $from($($arg_pat,)* $($last_args)*) } + } + fn_alias! { + $(#[$($fn_attr)*])* + $vis unsafe fn($($arg_pat: $arg_ty),*) $(-> $ret_ty)?; + $($rest)* + } + }; + ( + $(#[$($attr:tt)*])* + $vis:vis unsafe fn($($arg_pat:ident: $arg_ty:ty),*) $(-> $ret_ty:ty)?; + ) => {} +} + +/// Make the given function const if the given condition is true. +macro_rules! const_fn { + ( + const_if: #[cfg($($cfg:tt)+)]; + $(#[$($attr:tt)*])* + $vis:vis const $($rest:tt)* + ) => { + #[cfg($($cfg)+)] + $(#[$($attr)*])* + $vis const $($rest)* + #[cfg(not($($cfg)+))] + $(#[$($attr)*])* + $vis $($rest)* + }; +} + +/// Implements `core::fmt::Debug` and `serde::{Serialize, Deserialize}` (when serde +/// feature is enabled) for atomic bool, integer, or float. +macro_rules! impl_debug_and_serde { + // TODO(f16_and_f128): Implement serde traits for f16 & f128 once stabilized. + (AtomicF16) => { + impl_debug!(AtomicF16); + }; + (AtomicF128) => { + impl_debug!(AtomicF128); + }; + ($atomic_type:ident) => { + impl_debug!($atomic_type); + #[cfg(feature = "serde")] + #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] + impl serde::ser::Serialize for $atomic_type { + #[allow(clippy::missing_inline_in_public_items)] // serde doesn't use inline on std atomic's Serialize/Deserialize impl + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + // https://github.com/serde-rs/serde/blob/v1.0.152/serde/src/ser/impls.rs#L958-L959 + self.load(Ordering::Relaxed).serialize(serializer) + } + } + #[cfg(feature = "serde")] + #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] + impl<'de> serde::de::Deserialize<'de> for $atomic_type { + #[allow(clippy::missing_inline_in_public_items)] // serde doesn't use inline on std atomic's Serialize/Deserialize impl + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + serde::de::Deserialize::deserialize(deserializer).map(Self::new) + } + } + }; +} +macro_rules! impl_debug { + ($atomic_type:ident) => { + impl fmt::Debug for $atomic_type { + #[inline] // fmt is not hot path, but #[inline] on fmt seems to still be useful: https://github.com/rust-lang/rust/pull/117727 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // std atomic types use Relaxed in Debug::fmt: https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L2188 + fmt::Debug::fmt(&self.load(Ordering::Relaxed), f) + } + } + }; +} + +// We do not provide `nand` because it cannot be optimized on neither x86 nor MSP430. +// https://godbolt.org/z/ahWejchbT +macro_rules! impl_default_no_fetch_ops { + ($atomic_type:ident, bool) => { + impl $atomic_type { + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn and(&self, val: bool, order: Ordering) { + self.fetch_and(val, order); + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn or(&self, val: bool, order: Ordering) { + self.fetch_or(val, order); + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn xor(&self, val: bool, order: Ordering) { + self.fetch_xor(val, order); + } + } + }; + ($atomic_type:ident, $int_type:ty) => { + impl $atomic_type { + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn add(&self, val: $int_type, order: Ordering) { + self.fetch_add(val, order); + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn sub(&self, val: $int_type, order: Ordering) { + self.fetch_sub(val, order); + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn and(&self, val: $int_type, order: Ordering) { + self.fetch_and(val, order); + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn or(&self, val: $int_type, order: Ordering) { + self.fetch_or(val, order); + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn xor(&self, val: $int_type, order: Ordering) { + self.fetch_xor(val, order); + } + } + }; +} +macro_rules! impl_default_bit_opts { + (AtomicPtr, $int_type:ty) => { + impl AtomicPtr { + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn bit_set(&self, bit: u32, order: Ordering) -> bool { + #[cfg(portable_atomic_no_strict_provenance)] + use crate::utils::ptr::PtrExt as _; + let mask = <$int_type>::wrapping_shl(1, bit); + self.fetch_or(mask, order).addr() & mask != 0 + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn bit_clear(&self, bit: u32, order: Ordering) -> bool { + #[cfg(portable_atomic_no_strict_provenance)] + use crate::utils::ptr::PtrExt as _; + let mask = <$int_type>::wrapping_shl(1, bit); + self.fetch_and(!mask, order).addr() & mask != 0 + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn bit_toggle(&self, bit: u32, order: Ordering) -> bool { + #[cfg(portable_atomic_no_strict_provenance)] + use crate::utils::ptr::PtrExt as _; + let mask = <$int_type>::wrapping_shl(1, bit); + self.fetch_xor(mask, order).addr() & mask != 0 + } + } + }; + ($atomic_type:ident, $int_type:ty) => { + impl $atomic_type { + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn bit_set(&self, bit: u32, order: Ordering) -> bool { + let mask = <$int_type>::wrapping_shl(1, bit); + self.fetch_or(mask, order) & mask != 0 + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn bit_clear(&self, bit: u32, order: Ordering) -> bool { + let mask = <$int_type>::wrapping_shl(1, bit); + self.fetch_and(!mask, order) & mask != 0 + } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn bit_toggle(&self, bit: u32, order: Ordering) -> bool { + let mask = <$int_type>::wrapping_shl(1, bit); + self.fetch_xor(mask, order) & mask != 0 + } + } + }; +} + +// This just outputs the input as is, but can be used like an item-level block by using it with cfg. +// Note: This macro is items!({ }), not items! { }. +// An extra brace is used in input to make contents rustfmt-able. +macro_rules! items { + ({$($tt:tt)*}) => { + $($tt)* + }; +} + +// rustfmt-compatible cfg_select/cfg_if alternative +// Note: This macro is cfg_sel!({ }), not cfg_sel! { }. +// An extra brace is used in input to make contents rustfmt-able. +macro_rules! cfg_sel { + ({#[cfg(else)] { $($output:tt)* }}) => { + $($output)* + }; + ({ + #[cfg($cfg:meta)] + { $($output:tt)* } + $($( $rest:tt )+)? + }) => { + #[cfg($cfg)] + cfg_sel! {{#[cfg(else)] { $($output)* }}} + $( + #[cfg(not($cfg))] + cfg_sel! {{ $($rest)+ }} + )? + }; + ({ + #[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg($cfg1:meta))] + #[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg($cfg2:meta))] + { $($output:tt)* } + $($( $rest:tt )+)? + }) => { + #[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg($cfg1))] + #[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg($cfg2))] + cfg_sel! {{#[cfg(else)] { $($output)* }}} + $( + #[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(not($cfg1)))] + #[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg(not($cfg2)))] + cfg_sel! {{ $($rest)+ }} + )? + }; +} + +// Equivalent to core::hint::cold_path, but compatible with pre-1.95 rustc. +#[allow(dead_code)] +#[inline(always)] +#[cold] +fn cold_path() {} +// Stable equivalent of core::hint::{likely, unlikely}. +#[allow(dead_code)] +#[inline(always)] +pub(crate) fn likely(b: bool) -> bool { + if b { + true + } else { + cold_path(); + false + } +} +#[allow(dead_code)] +#[inline(always)] +pub(crate) fn unlikely(b: bool) -> bool { + if b { + cold_path(); + true + } else { + false + } +} + +// Equivalent to core::hint::assert_unchecked, but compatible with pre-1.81 rustc. +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[allow(dead_code)] +#[inline(always)] +#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] +pub(crate) unsafe fn assert_unchecked(cond: bool) { + if !cond { + #[cfg(debug_assertions)] + unreachable!(); + #[cfg(not(debug_assertions))] + // SAFETY: the caller promised `cond` is true. + unsafe { + core::hint::unreachable_unchecked() + } + } +} + +// https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L3338 +#[inline] +#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] +pub(crate) fn assert_load_ordering(order: Ordering) { + match order { + Ordering::Acquire | Ordering::Relaxed | Ordering::SeqCst => {} + Ordering::Release => panic!("there is no such thing as a release load"), + Ordering::AcqRel => panic!("there is no such thing as an acquire-release load"), + _ => unreachable!(), + } +} +// https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L3323 +#[inline] +#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] +pub(crate) fn assert_store_ordering(order: Ordering) { + match order { + Ordering::Release | Ordering::Relaxed | Ordering::SeqCst => {} + Ordering::Acquire => panic!("there is no such thing as an acquire store"), + Ordering::AcqRel => panic!("there is no such thing as an acquire-release store"), + _ => unreachable!(), + } +} +// https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L3404 +#[inline] +#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)] +pub(crate) fn assert_compare_exchange_ordering(success: Ordering, failure: Ordering) { + match success { + Ordering::AcqRel + | Ordering::Acquire + | Ordering::Relaxed + | Ordering::Release + | Ordering::SeqCst => {} + _ => unreachable!(), + } + match failure { + Ordering::Acquire | Ordering::Relaxed | Ordering::SeqCst => {} + Ordering::Release => panic!("there is no such thing as a release failure ordering"), + Ordering::AcqRel => panic!("there is no such thing as an acquire-release failure ordering"), + _ => unreachable!(), + } +} + +// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0418r2.html +// https://github.com/rust-lang/rust/pull/98383 +#[allow(dead_code)] +#[inline] +pub(crate) fn upgrade_success_ordering(success: Ordering, failure: Ordering) -> Ordering { + match (success, failure) { + (Ordering::Relaxed, Ordering::Acquire) => Ordering::Acquire, + (Ordering::Release, Ordering::Acquire) => Ordering::AcqRel, + (_, Ordering::SeqCst) => Ordering::SeqCst, + _ => success, + } +} + +#[cfg(not(portable_atomic_no_asm_maybe_uninit))] +#[cfg(target_pointer_width = "32")] +// SAFETY: MaybeUninit returned by zero_extend64_ptr is always initialized. +const _: () = assert!(unsafe { + zero_extend64_ptr(ptr::without_provenance_mut(!0)).assume_init() == !0_u32 as u64 +}); +/// Zero-extends the given 32-bit pointer to `MaybeUninit`. +/// This is used for 64-bit architecture's 32-bit ABI (e.g., AArch64 ILP32 ABI). +/// See ptr_reg! macro in src/gen/utils.rs for details. +#[cfg(not(portable_atomic_no_asm_maybe_uninit))] +#[cfg(target_pointer_width = "32")] +#[allow(dead_code)] +#[inline] +pub(crate) const fn zero_extend64_ptr(v: *mut ()) -> core::mem::MaybeUninit { + #[repr(C)] + struct ZeroExtended { + #[cfg(target_endian = "big")] + pad: *mut (), + v: *mut (), + #[cfg(target_endian = "little")] + pad: *mut (), + } + // SAFETY: we can safely transmute any 64-bit value to MaybeUninit. + unsafe { core::mem::transmute(ZeroExtended { v, pad: core::ptr::null_mut() }) } +} + +#[allow(dead_code)] +#[cfg(any( + target_arch = "aarch64", + target_arch = "arm64ec", + target_arch = "powerpc64", + target_arch = "riscv64", + target_arch = "s390x", + target_arch = "x86_64", +))] +/// A 128-bit value represented as a pair of 64-bit values. +/// +/// This type is `#[repr(C)]`, both fields have the same in-memory representation +/// and are plain old data types, so access to the fields is always safe. +#[derive(Clone, Copy)] +#[repr(C)] +pub(crate) union U128 { + pub(crate) whole: u128, + pub(crate) pair: Pair, +} +#[allow(dead_code)] +#[cfg(any(target_arch = "arm", target_arch = "riscv32"))] +/// A 64-bit value represented as a pair of 32-bit values. +/// +/// This type is `#[repr(C)]`, both fields have the same in-memory representation +/// and are plain old data types, so access to the fields is always safe. +#[derive(Clone, Copy)] +#[repr(C)] +pub(crate) union U64 { + pub(crate) whole: u64, + pub(crate) pair: Pair, +} +#[allow(dead_code)] +#[derive(Clone, Copy)] +#[repr(C)] +pub(crate) struct Pair { + // little endian order + #[cfg(any( + target_endian = "little", + target_arch = "aarch64", + target_arch = "arm", + target_arch = "arm64ec", + ))] + pub(crate) lo: T, + pub(crate) hi: T, + // big endian order + #[cfg(not(any( + target_endian = "little", + target_arch = "aarch64", + target_arch = "arm", + target_arch = "arm64ec", + )))] + pub(crate) lo: T, +} + +#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] +type MinWord = u32; +#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] +type RetInt = u32; +// Adapted from https://github.com/taiki-e/atomic-maybe-uninit/blob/v0.3.6/src/utils.rs#L255. +// Helper for implementing sub-word atomic operations using word-sized LL/SC loop or CAS loop. +// +// Refs: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/CodeGen/AtomicExpandPass.cpp#L811 +// (aligned_ptr, shift, mask) +#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] +#[allow(dead_code)] +#[inline] +pub(crate) fn create_sub_word_mask_values(ptr: *mut T) -> (*mut MinWord, RetInt, RetInt) { + use core::mem; + + #[cfg(portable_atomic_no_strict_provenance)] + use self::ptr::PtrExt as _; + + // RISC-V, MIPS, SPARC, LoongArch, Xtensa, BPF: shift amount of 32-bit shift instructions is 5 bits unsigned (0-31). + // PowerPC, C-SKY: shift amount of 32-bit shift instructions is 6 bits unsigned (0-63) and shift amount 32-63 means "clear". + // Arm: shift amount of 32-bit shift instructions is 8 bits unsigned (0-255). + // Hexagon: shift amount of 32-bit shift instructions is 7 bits signed (-64-63) and negative shift amount means "reverse the direction of the shift". + // (On s390x, we don't use the mask returned from this function.) + // (See also https://devblogs.microsoft.com/oldnewthing/20230904-00/?p=108704 for others) + const SHIFT_MASK: bool = !cfg!(any( + target_arch = "bpf", + target_arch = "loongarch32", + target_arch = "loongarch64", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "s390x", + target_arch = "sparc", + target_arch = "sparc64", + target_arch = "xtensa", + )); + let ptr_mask = mem::size_of::() - 1; + let aligned_ptr = ptr.with_addr(ptr.addr() & !ptr_mask) as *mut MinWord; + let ptr_lsb = if SHIFT_MASK { + ptr.addr() & ptr_mask + } else { + // We use 32-bit wrapping shift instructions in asm on these platforms. + ptr.addr() + }; + let shift = if cfg!(any(target_endian = "little", target_arch = "s390x")) { + ptr_lsb.wrapping_mul(8) + } else { + (ptr_lsb ^ (mem::size_of::() - mem::size_of::())).wrapping_mul(8) + }; + let mut mask: RetInt = (1 << (mem::size_of::() * 8)) - 1; // !(0 as T) as RetInt + if SHIFT_MASK { + mask <<= shift; + } + #[allow(clippy::cast_possible_truncation)] + { + (aligned_ptr, shift as RetInt, mask) + } +} + +// This module provides core::ptr strict_provenance/exposed_provenance polyfill for pre-1.84 rustc. +#[allow(dead_code)] +pub(crate) mod ptr { + cfg_sel!({ + #[cfg(not(portable_atomic_no_strict_provenance))] + { + #[allow(unused_imports)] + pub(crate) use core::ptr::{ + with_exposed_provenance, with_exposed_provenance_mut, without_provenance_mut, + }; + } + #[cfg(else)] + { + #[inline(always)] + #[must_use] + pub(crate) const fn without_provenance_mut(addr: usize) -> *mut T { + // An int-to-pointer transmute currently has exactly the intended semantics: it creates a + // pointer without provenance. Note that this is *not* a stable guarantee about transmute + // semantics, it relies on sysroot crates having special status. + // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that + // pointer). + #[cfg(miri)] + unsafe { + core::mem::transmute(addr) + } + // const transmute requires Rust 1.56. + // Using transmute doesn't work with CHERI: https://github.com/kent-weak-memory/rust/blob/0c0ca909de877f889629057e1ddf139527446d75/library/core/src/ptr/mod.rs#L607 + #[cfg(not(miri))] + { + addr as *mut T + } + } + #[inline(always)] + #[must_use] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn with_exposed_provenance(addr: usize) -> *const T { + addr as *const T + } + #[inline(always)] + #[must_use] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub(crate) fn with_exposed_provenance_mut(addr: usize) -> *mut T { + addr as *mut T + } + + pub(crate) trait PtrExt: Copy { + #[must_use] + fn addr(self) -> usize; + #[must_use] + fn with_addr(self, addr: usize) -> Self + where + T: Sized; + } + impl PtrExt for *mut T { + #[inline(always)] + #[must_use] + fn addr(self) -> usize { + // A pointer-to-integer transmute currently has exactly the right semantics: it returns the + // address without exposing the provenance. Note that this is *not* a stable guarantee about + // transmute semantics, it relies on sysroot crates having special status. + // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the + // provenance). + #[cfg(miri)] + unsafe { + core::mem::transmute(self as *mut ()) + } + // Using transmute doesn't work with CHERI: https://github.com/kent-weak-memory/rust/blob/0c0ca909de877f889629057e1ddf139527446d75/library/core/src/ptr/mut_ptr.rs#L210 + #[cfg(not(miri))] + { + self as *mut () as usize + } + } + #[inline] + #[must_use] + fn with_addr(self, addr: usize) -> Self + where + T: Sized, + { + // This should probably be an intrinsic to avoid doing any sort of arithmetic, but + // meanwhile, we can implement it with `wrapping_offset`, which preserves the pointer's + // provenance. + let self_addr = self.addr() as isize; + let dest_addr = addr as isize; + let offset = dest_addr.wrapping_sub(self_addr); + (self as *mut u8).wrapping_offset(offset) as *mut T + } + } + } + }); +} + +// This module provides: +// - core::ffi polyfill (c_* type aliases and CStr) for pre-1.64 rustc compatibility. +// (core::ffi::* (except c_void) requires Rust 1.64) +// - Safe abstraction (c! macro) for creating static C strings without runtime checks. +// (c"..." requires Rust 1.77) +// - Helper macros for defining FFI bindings with static signature/type/value assertions. +// - Helper macros for defining asm-based syscalls on Linux. +#[cfg(any( + test, + portable_atomic_test_no_std_static_assert_ffi, + not(any(target_arch = "x86", target_arch = "x86_64")) +))] +#[cfg(any(not(portable_atomic_no_asm), portable_atomic_unstable_asm))] +#[allow(dead_code, non_camel_case_types, unused_macros)] +#[macro_use] +pub(crate) mod ffi { + // ------------------------------------------------------------------------- + // core::ffi polyfill and c"..." equivalent + + pub(crate) type c_void = core::ffi::c_void; + // c_{,u}int is {i,u}16 on 16-bit targets, otherwise {i,u}32. + // https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/ffi/mod.rs#L156 + cfg_sel!({ + #[cfg(target_pointer_width = "16")] + { + pub(crate) type c_int = i16; + pub(crate) type c_uint = u16; + } + #[cfg(else)] + { + pub(crate) type c_int = i32; + pub(crate) type c_uint = u32; + } + }); + // c_{,u}long is {i,u}64 on non-Windows 64-bit targets, otherwise {i,u}32. + // https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/ffi/mod.rs#L168 + cfg_sel!({ + #[cfg(all(target_pointer_width = "64", not(windows)))] + { + pub(crate) type c_long = i64; + pub(crate) type c_ulong = u64; + } + #[cfg(else)] + { + pub(crate) type c_long = i32; + pub(crate) type c_ulong = u32; + } + }); + // c_size_t is currently always usize. + // https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/ffi/mod.rs#L76 + pub(crate) type c_size_t = usize; + // c_char is u8 by default on non-Apple/non-Windows/non-Vita Arm/C-SKY/Hexagon/MSP430/PowerPC/RISC-V/s390x/Xtensa targets, otherwise i8 by default. + // See references in https://github.com/rust-lang/rust/issues/129945 for details. + cfg_sel!({ + #[cfg(all( + not(any(target_vendor = "apple", windows, target_os = "vita")), + any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "csky", + target_arch = "hexagon", + target_arch = "msp430", + target_arch = "powerpc", + target_arch = "powerpc64", + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "s390x", + target_arch = "xtensa", + ), + ))] + { + pub(crate) type c_char = u8; + } + #[cfg(else)] + { + pub(crate) type c_char = i8; + } + }); + + // Static assertions for C type definitions. + #[cfg(test)] + const _: fn() = || { + let _: c_int = 0 as std::os::raw::c_int; + let _: c_uint = 0 as std::os::raw::c_uint; + let _: c_long = 0 as std::os::raw::c_long; + let _: c_ulong = 0 as std::os::raw::c_ulong; + #[cfg(unix)] + let _: c_size_t = 0 as libc::size_t; // std::os::raw::c_size_t is unstable + let _: c_char = 0 as std::os::raw::c_char; + }; + + #[repr(transparent)] + pub(crate) struct CStr([c_char]); + impl CStr { + #[inline] + #[must_use] + pub(crate) const fn as_ptr(&self) -> *const c_char { + self.0.as_ptr() + } + /// # Safety + /// + /// The provided slice **must** be nul-terminated and not contain any interior + /// nul bytes. + #[inline] + #[must_use] + pub(crate) unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr { + // SAFETY: Casting to CStr is safe because *our* CStr is #[repr(transparent)] + // and its internal representation is a [u8] too. (Note that std's CStr + // is not #[repr(transparent)].) + // Dereferencing the obtained pointer is safe because it comes from a + // reference. Making a reference is then safe because its lifetime + // is bound by the lifetime of the given `bytes`. + unsafe { &*(bytes as *const [u8] as *const CStr) } + } + #[cfg(test)] + #[inline] + #[must_use] + pub(crate) fn to_bytes_with_nul(&self) -> &[u8] { + #[allow(clippy::unnecessary_cast)] // triggered for targets that c_char is u8 + // SAFETY: Transmuting a slice of `c_char`s to a slice of `u8`s + // is safe on all supported targets. + unsafe { + &*(&self.0 as *const [c_char] as *const [u8]) + } + } + } + + macro_rules! c { + ($s:expr) => {{ + const BYTES: &[u8] = concat!($s, "\0").as_bytes(); + const _: () = static_assert!(crate::utils::ffi::_const_is_c_str(BYTES)); + #[allow(unused_unsafe)] + // SAFETY: we've checked `BYTES` is a valid C string + unsafe { + crate::utils::ffi::CStr::from_bytes_with_nul_unchecked(BYTES) + } + }}; + } + + #[must_use] + pub(crate) const fn _const_is_c_str(bytes: &[u8]) -> bool { + #[cfg(portable_atomic_no_track_caller)] + { + // const_if_match/const_loop was stabilized (nightly-2020-06-30) 2 days before + // track_caller was stabilized (nightly-2020-07-02), so we reuse the cfg for + // track_caller here instead of emitting a cfg for const_if_match/const_loop. + // https://github.com/rust-lang/rust/pull/72437 + // track_caller was stabilized 11 days after the oldest nightly version + // that uses this module, and is included in the same 1.46 stable release. + // The check here is insufficient in this case, but this is fine because this function + // is internal code that is not used to process input from the user and our CI checks + // all builtin targets and some custom targets with some versions of newer compilers. + !bytes.is_empty() + } + #[cfg(not(portable_atomic_no_track_caller))] + { + // Based on https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/ffi/c_str.rs#L417 + // - bytes must be nul-terminated. + // - bytes must not contain any interior nul bytes. + if bytes.is_empty() { + return false; + } + let mut i = bytes.len() - 1; + if bytes[i] != 0 { + return false; + } + // Ending null byte exists, skip to the rest. + while i != 0 { + i -= 1; + if bytes[i] == 0 { + return false; + } + } + true + } + } + + // ------------------------------------------------------------------------- + // Helper macros for defining FFI bindings with static signature/type/value assertions. + + /// Defines types with #[cfg(test)] static assertions which checks + /// types are the same as the platform's latest header files' ones. + // Note: This macro is sys_ty!({ }), not sys_ty! { }. + // An extra brace is used in input to make contents rustfmt-able. + macro_rules! sys_type { + ({$( + $(#[$attr:meta])* + $vis:vis type $([$($windows_path:ident)::+])? $name:ident = $ty:ty; + )*}) => { + $( + $(#[$attr])* + $vis type $name = $ty; + )* + #[cfg(any(test, portable_atomic_test_no_std_static_assert_ffi))] + test_helper::static_assert_sys_type!($( + $(#[$attr])* + type $([$($windows_path)::+])? $name; + )*); + }; + } + /// Defines #[repr(C)] structs with #[cfg(test)] static assertions which checks + /// fields are the same as the platform's latest header files' ones. + // Note: This macro is sys_struct!({ }), not sys_struct! { }. + // An extra brace is used in input to make contents rustfmt-able. + macro_rules! sys_struct { + ({$( + $(#[$attr:meta])* + $vis:vis struct $([$($windows_path:ident)::+])? $name:ident {$( + $(#[$field_attr:meta])* + $field_vis:vis $field_name:ident: $field_ty:ty, + )*} + )*}) => { + $( + $(#[$attr])* + #[derive(Clone, Copy)] + #[cfg_attr( + any(test, portable_atomic_test_no_std_static_assert_ffi), + derive(Debug, PartialEq) + )] + #[repr(C)] + $vis struct $name {$( + $(#[$field_attr])* + $field_vis $field_name: $field_ty, + )*} + )* + #[cfg(any(test, portable_atomic_test_no_std_static_assert_ffi))] + test_helper::static_assert_sys_struct!($( + $(#[$attr])* + struct $([$($windows_path)::+])? $name {$( + $(#[$field_attr])* + $field_name: $field_ty, + )*} + )*); + }; + } + /// Defines constants with #[cfg(test)] static assertions which checks + /// values are the same as the platform's latest header files' ones. + // Note: This macro is sys_const!({ }), not sys_const! { }. + // An extra brace is used in input to make contents rustfmt-able. + macro_rules! sys_const { + ({$( + $(#[$attr:meta])* + $vis:vis const $([$($windows_path:ident)::+])? $name:ident: $ty:ty = $val:expr; + )*}) => { + $( + $(#[$attr])* + $vis const $name: $ty = $val; + )* + #[cfg(any(test, portable_atomic_test_no_std_static_assert_ffi))] + test_helper::static_assert_sys_const!($( + $(#[$attr])* + const $([$($windows_path)::+])? $name: $ty; + )*); + }; + } + /// Defines functions with #[cfg(test)] static assertions which checks + /// signatures are the same as the platform's latest header files' ones. + // Note: This macro is sys_fn!({ }), not sys_fn! { }. + // An extra brace is used in input to make contents rustfmt-able. + macro_rules! sys_fn { + ({ + $(#[$extern_attr:meta])* + extern $abi:tt {$( + $(#[$fn_attr:meta])* + $vis:vis fn $([$($windows_path:ident)::+])? $name:ident( + $($args:tt)* + ) $(-> $ret_ty:ty)?; + )*} + }) => { + $(#[$extern_attr])* + extern $abi {$( + $(#[$fn_attr])* + $vis fn $name($($args)*) $(-> $ret_ty)?; + )*} + #[cfg(any(test, portable_atomic_test_no_std_static_assert_ffi))] + test_helper::static_assert_sys_fn!( + $(#[$extern_attr])* + extern $abi {$( + $(#[$fn_attr])* + fn $([$($windows_path)::+])? $name($($args)*) $(-> $ret_ty)?; + )*} + ); + }; + } + + // ----------------------------------------------------------------------------- + // Helper macros for defining asm-based syscalls on Linux. + // + // Use asm-based syscall on Linux for compatibility with non-libc targets if possible. + // + // In non-Linux environments (including Android), syscalls should be called via libc, + // mainly for the following reasons. + // - asm-based syscalls are not permitted in the first place. e.g., + // - OpenBSD https://github.com/golang/go/issues/36435 + // - CheriBSD https://www.cheribsd.org/release-notes/25.03/index.html + // - Stability of asm-based syscalls is not guaranteed. e.g., + // - macOS https://go-review.googlesource.com/c/go/+/25495 + // - Syscalls via libc (or also libsys on FreeBSD) provide additional protections. e.g., + // - OpenBSD https://lwn.net/Articles/806863/ + // - CheriBSD https://www.cheribsd.org/release-notes/25.03/index.html + // - FreeBSD https://www.freebsd.org/status/report-2024-01-2024-03/libsys/ + // - Android https://android.googlesource.com/platform/bionic/+/HEAD/docs/fdtrack.md + // + // Miri and Sanitizer do not support inline assembly. + #[cfg(all( + target_os = "linux", + not(any(miri, portable_atomic_sanitize_thread)), + not(portable_atomic_no_asm_syscall), + ))] + #[macro_use] + mod syscall_helper { + // Note: + // - The syscall number and arguments must be extended to the register size by the caller of macros. + // The kernel extends the low bits on some architectures, but it does not on many architectures. e.g., + // x86_64 (pre-5.14): https://github.com/torvalds/linux/commit/0595494891723a1dcca5eaa8eeca8ab54ad953b9 + // powerpc64: https://github.com/torvalds/linux/blob/v7.1/arch/powerpc/kernel/syscall.c#L16 + // riscv64: https://github.com/torvalds/linux/blob/v7.1/arch/riscv/kernel/traps.c#L328 + // loongarch64: https://github.com/torvalds/linux/blob/v7.1/arch/loongarch/kernel/syscall.c#L61 + // + // Refs: + // - https://man7.org/linux/man-pages/man2/syscall.2.html + // - aarch64 (test-only) + // https://git.musl-libc.org/cgit/musl/tree/arch/aarch64/syscall_arch.h?h=v1.2.6 + // - arm (test-only) + // https://git.musl-libc.org/cgit/musl/tree/arch/arm/syscall_arch.h?h=v1.2.6 + // - powerpc64 (test-only) + // https://github.com/torvalds/linux/blob/v7.1/Documentation/arch/powerpc/syscall64-abi.rst + // https://git.musl-libc.org/cgit/musl/tree/arch/powerpc64/syscall_arch.h?h=v1.2.6 + // - riscv32/riscv64 + // https://git.musl-libc.org/cgit/musl/tree/arch/riscv32/syscall_arch.h?h=v1.2.6 + // https://git.musl-libc.org/cgit/musl/tree/arch/riscv64/syscall_arch.h?h=v1.2.6 + + #[cfg(test)] // test-only + #[cfg(all(target_arch = "aarch64", target_pointer_width = "64"))] + macro_rules! asm_syscall { + ( + $number:ident, $r:ident, + $($arg1:ident $(, $arg2:ident $(, $arg3:ident + $(, $arg4:ident $(, $arg5:ident $(, $arg6:ident )?)?)? + )?)?)? + ) => { + __asm!( + "svc 0", + in("x8") $number, + lateout("x0") $r, + $(in("x0") $arg1, + $(in("x1") $arg2, + $(in("x2") $arg3, + $(in("x3") $arg4, + $(in("x4") $arg5, + $(in("x5") $arg6, )? + )? + )? + )? + )? + )? + // Clobber SVE registers and do not use `preserves_flags` because + // AArch64 Linux syscalls clears non-v[0-31] bits of z[0-31], and all of p[0-15] and ffr, + // and calls SMSTOP SM which clears z[0-31], p[0-15], ffr, and modifies FPSR + // when CPU is in streaming SVE mode. + // https://github.com/torvalds/linux/blob/v7.1/Documentation/arch/arm64/sve.rst#3--system-call-behaviour + // https://github.com/torvalds/linux/blob/v7.1/Documentation/arch/arm64/sme.rst#3--system-call-behaviour + // https://developer.arm.com/documentation/109246/0101/SME-Overview/Streaming-SVE-mode + out("z0") _, + out("z1") _, + out("z2") _, + out("z3") _, + out("z4") _, + out("z5") _, + out("z6") _, + out("z7") _, + out("z8") _, + out("z9") _, + out("z10") _, + out("z11") _, + out("z12") _, + out("z13") _, + out("z14") _, + out("z15") _, + out("z16") _, + out("z17") _, + out("z18") _, + out("z19") _, + out("z20") _, + out("z21") _, + out("z22") _, + out("z23") _, + out("z24") _, + out("z25") _, + out("z26") _, + out("z27") _, + out("z28") _, + out("z29") _, + out("z30") _, + out("z31") _, + out("p0") _, + out("p1") _, + out("p2") _, + out("p3") _, + out("p4") _, + out("p5") _, + out("p6") _, + out("p7") _, + out("p8") _, + out("p9") _, + out("p10") _, + out("p11") _, + out("p12") _, + out("p13") _, + out("p14") _, + out("p15") _, + out("ffr") _, + options(nostack), + ) + }; + } + #[cfg(test)] // test-only + #[cfg(target_arch = "arm")] + macro_rules! asm_syscall { + ( + $number_const:path, $number:literal, $r:ident, + $($arg1:ident $(, $arg2:ident $(, $arg3:ident + $(, $arg4:ident $(, $arg5:ident $(, $arg6:ident )?)?)? + )?)?)? + ) => {{ + static_assert!($number_const == $number && 0 <= $number && $number <= 255); + __asm!( + // r7 is reserved on thumb and MOV requires Thumb-2 or Arm mode. + // cfg(target_feature = "thumb-mode")/cfg(target_feature = "thumb2") + // doesn't work on stable and register swapping is much cheaper than syscall, + // so we always swap register and use MOVS instead of MOV. + // Note: r6 is reserved by LLVM, so this assembly may not work for syscall6 + // with Thumb-1 (pre-v7 Arm in Thumb mode) because the allocation of + // `tmp` may fail. + // (syscall6 is needless in the current our use cases.) + "movs {tmp}, r7", + concat!("movs r7, ", $number), + "svc 0", + "movs r7, {tmp}", + tmp = out(reg) _, + lateout("r0") $r, + $(in("r0") $arg1, + $(in("r1") $arg2, + $(in("r2") $arg3, + $(in("r3") $arg4, + $(in("r4") $arg5, + $(in("r5") $arg6, )? + )? + )? + )? + )? + )? + // Do not use `preserves_flags` because MOVS modifies the flags. + // Do not use `nostack` because SVC pushes to stack on M-profile architectures. + // https://github.com/torvalds/linux/blob/v7.1/arch/arm/kernel/entry-header.S#L61 + ) + }}; + } + // POWER9+ has fast syscall using SCV, but it is needless in the current our use cases. + #[cfg(test)] // test-only + #[cfg(all(target_arch = "powerpc64", target_pointer_width = "64"))] + macro_rules! asm_syscall { + ( + $number:ident, $r:ident, + $($arg1:ident $(, $arg2:ident $(, $arg3:ident + $(, $arg4:ident $(, $arg5:ident $(, $arg6:ident )?)?)? + )?)?)? + ) => { + __asm!( + "sc", + "bns+ 2f", + "neg %r3, %r3", + "2:", + inout("r0") $number => _, + lateout("r3") $r, + $(in("r3") $arg1, + $(in("r4") $arg2, + $(in("r5") $arg3, + $(in("r6") $arg4, + $(in("r7") $arg5, + $(in("r8") $arg6, )? + )? + )? + )? + )? + )? + lateout("r4") _, + lateout("r5") _, + lateout("r6") _, + lateout("r7") _, + lateout("r8") _, + out("r9") _, + out("r10") _, + out("r11") _, + out("r12") _, + out("cr0") _, + out("ctr") _, + out("xer") _, + options(nostack, preserves_flags), + ) + }; + } + #[cfg(any( + target_arch = "riscv32", + all(target_arch = "riscv64", target_pointer_width = "64"), + ))] + macro_rules! asm_syscall { + ( + $number:ident, $r:ident, + $($arg1:ident $(, $arg2:ident $(, $arg3:ident + $(, $arg4:ident $(, $arg5:ident $(, $arg6:ident )?)?)? + )?)?)? + ) => { + __asm!( + "ecall", + in("a7") $number, + lateout("a0") $r, + $(in("a0") $arg1, + $(in("a1") $arg2, + $(in("a2") $arg3, + $(in("a3") $arg4, + $(in("a4") $arg5, + $(in("a5") $arg6, )? + )? + )? + )? + )? + )? + // Clobber vector registers and do not use `preserves_flags` because RISC-V Linux syscalls don't preserve them. + // https://github.com/torvalds/linux/blob/v7.1/Documentation/arch/riscv/vector.rst#3--vector-register-state-across-system-calls + out("v0") _, + out("v1") _, + out("v2") _, + out("v3") _, + out("v4") _, + out("v5") _, + out("v6") _, + out("v7") _, + out("v8") _, + out("v9") _, + out("v10") _, + out("v11") _, + out("v12") _, + out("v13") _, + out("v14") _, + out("v15") _, + out("v16") _, + out("v17") _, + out("v18") _, + out("v19") _, + out("v20") _, + out("v21") _, + out("v22") _, + out("v23") _, + out("v24") _, + out("v25") _, + out("v26") _, + out("v27") _, + out("v28") _, + out("v29") _, + out("v30") _, + out("v31") _, + options(nostack), + ) + }; + } + } + + #[allow( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks, + clippy::wildcard_imports + )] + #[cfg(test)] + mod tests { + #[test] + fn test_c_macro() { + #[track_caller] + fn t(s: &crate::utils::ffi::CStr, raw: &[u8]) { + assert_eq!(s.to_bytes_with_nul(), raw); + } + t(c!(""), b"\0"); + t(c!("a"), b"a\0"); + t(c!("abc"), b"abc\0"); + t(c!(concat!("abc", "d")), b"abcd\0"); + } + + #[test] + fn test_is_c_str() { + #[track_caller] + fn t(bytes: &[u8]) { + assert_eq!( + super::_const_is_c_str(bytes), + std::ffi::CStr::from_bytes_with_nul(bytes).is_ok() + ); + } + t(b"\0"); + t(b"a\0"); + t(b"abc\0"); + t(b""); + t(b"a"); + t(b"abc"); + t(b"\0a"); + t(b"\0a\0"); + t(b"ab\0c\0"); + t(b"\0\0"); + } + } +} diff --git a/vendor/portable-atomic/tests/.gitignore b/vendor/portable-atomic/tests/.gitignore new file mode 100644 index 0000000..2ef89d0 --- /dev/null +++ b/vendor/portable-atomic/tests/.gitignore @@ -0,0 +1 @@ +!rust-toolchain.toml diff --git a/vendor/portable-atomic/version.rs b/vendor/portable-atomic/version.rs new file mode 100644 index 0000000..87b4aa9 --- /dev/null +++ b/vendor/portable-atomic/version.rs @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +use std::{env, iter, process::Command, str}; + +pub(crate) fn rustc_version() -> Option { + let rustc = env::var_os("RUSTC")?; + let rustc_wrapper = if env::var_os("CARGO_ENCODED_RUSTFLAGS").is_some() { + env::var_os("RUSTC_WRAPPER").filter(|v| !v.is_empty()) + } else { + // Cargo sets environment variables for wrappers correctly only since https://github.com/rust-lang/cargo/pull/9601. + None + }; + // Do not apply RUSTC_WORKSPACE_WRAPPER: https://github.com/cuviper/autocfg/issues/58#issuecomment-2067625980 + let mut rustc = rustc_wrapper.into_iter().chain(iter::once(rustc)); + let mut cmd = Command::new(rustc.next().unwrap()); + cmd.args(rustc); + // Use verbose version output because the packagers add extra strings to the normal version output. + // Do not use long flags (--version --verbose) because clippy-deriver doesn't handle them properly. + // -vV is also matched with that cargo internally uses: https://github.com/rust-lang/cargo/blob/0.80.0/src/cargo/util/rustc.rs#L65 + let output = cmd.arg("-vV").output().ok()?; + let verbose_version = str::from_utf8(&output.stdout).ok()?; + Version::parse(verbose_version) +} + +#[cfg_attr(test, derive(Debug, PartialEq))] +pub(crate) struct Version { + pub(crate) minor: u32, + pub(crate) nightly: bool, + commit_date: Date, + pub(crate) llvm: u32, +} + +impl Version { + // The known latest stable version. If we unable to determine + // the rustc version, we assume this is the current version. + // It is no problem if this is older than the actual latest stable. + // LLVM version is assumed to be the minimum external LLVM version: + // https://github.com/rust-lang/rust/blob/1.97.0/src/bootstrap/src/core/build_steps/llvm.rs#L638 + pub(crate) const LATEST: Self = Self::stable(97, 21); + + pub(crate) const fn stable(rustc_minor: u32, llvm_major: u32) -> Self { + Self { minor: rustc_minor, nightly: false, commit_date: Date::UNKNOWN, llvm: llvm_major } + } + + pub(crate) fn probe(&self, minor: u32, year: u16, month: u8, day: u8) -> bool { + if self.nightly { + self.minor > minor + || self.minor == minor && self.commit_date >= Date::new(year, month, day) + } else { + self.minor >= minor + } + } + + #[cfg(test)] + pub(crate) fn commit_date(&self) -> &Date { + &self.commit_date + } + + pub(crate) fn parse(verbose_version: &str) -> Option { + let mut release = verbose_version + .lines() + .find(|line| line.starts_with("release: ")) + .map(|line| &line["release: ".len()..])? + .splitn(2, '-'); + let version = release.next().unwrap(); + let channel = release.next().unwrap_or_default(); + let mut digits = version.splitn(3, '.'); + let major = digits.next()?; + if major != "1" { + return None; + } + let minor = digits.next()?.parse::().ok()?; + let _patch = digits.next().unwrap_or("0").parse::().ok()?; + let nightly = match env::var_os("RUSTC_BOOTSTRAP") { + // When -1 is passed rustc works like stable, e.g., cfg(target_feature = "unstable_target_feature") will never be set. https://github.com/rust-lang/rust/pull/132993 + Some(ref v) if v == "-1" => false, + // When 1 is passed stable rustc works like nightly, but we ignore it for now. + _ => channel == "nightly" || channel == "dev", + }; + + // Note that rustc 1.49-1.50 (and 1.13 or older) don't print LLVM version. + let llvm_major = (|| { + let version = verbose_version + .lines() + .find(|line| line.starts_with("LLVM version: ")) + .map(|line| &line["LLVM version: ".len()..])?; + let mut digits = version.splitn(3, '.'); + let major = digits.next()?.parse::().ok()?; + let _minor = digits.next()?.parse::().ok()?; + let _patch = digits.next().unwrap_or("0").parse::().ok()?; + Some(major) + })() + .unwrap_or(0); + + // we don't refer commit date on stable/beta. + if nightly { + let commit_date = (|| { + let mut commit_date = verbose_version + .lines() + .find(|line| line.starts_with("commit-date: ")) + .map(|line| &line["commit-date: ".len()..])? + .splitn(3, '-'); + let year = commit_date.next()?.parse::().ok()?; + let month = commit_date.next()?.parse::().ok()?; + let day = commit_date.next()?.parse::().ok()?; + if month > 12 || day > 31 { + return None; + } + Some(Date::new(year, month, day)) + })(); + Some(Self { + minor, + nightly, + commit_date: commit_date.unwrap_or(Date::UNKNOWN), + llvm: llvm_major, + }) + } else { + Some(Self::stable(minor, llvm_major)) + } + } +} + +#[derive(PartialEq, PartialOrd)] +#[cfg_attr(test, derive(Debug))] +pub(crate) struct Date { + pub(crate) year: u16, + pub(crate) month: u8, + pub(crate) day: u8, +} + +impl Date { + const UNKNOWN: Self = Self::new(0, 0, 0); + + const fn new(year: u16, month: u8, day: u8) -> Self { + Self { year, month, day } + } +} diff --git a/vendor/proc-macro2/.cargo-checksum.json b/vendor/proc-macro2/.cargo-checksum.json new file mode 100644 index 0000000..9e59cae --- /dev/null +++ b/vendor/proc-macro2/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo_vcs_info.json":"0a870b23ea0c10231ed5a850b8fe8f23dd74926e90594e49a35a7e1b5e8a92f5",".github/FUNDING.yml":"b017158736b3c9751a2d21edfce7fe61c8954e2fced8da8dd3013c2f3e295bd9",".github/workflows/ci.yml":"f0003fd6c9bd0f9208f552a57dd5dd76fee714a7d0be286cecc98f06add580ff","Cargo.lock":"30daf1b1e7557b089dfe7783a6cdd8bd7b4f82b31eaaa554c1afbca448f3a936","Cargo.toml":"6bdbe54a7f052e552dcfca90351764476e2767237ec3f954df8bd9f602861056","Cargo.toml.orig":"e04a009c48ea3e9b017807ea9183e330cc909a9cc0e754c5c6b3f7c0b29fb9de","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"8eebdcf2f9a5034693589a9982adf06c2aac5c9f078c07a44400d293ed5b4a8e","build.rs":"baeb20b52f6b536be8657a566591a507bb2e34a45cf8baa42b135510a0c3c729","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/detection.rs":"ed9a5f9a979ab01247d7a68eeb1afa3c13209334c5bfff0f9289cb07e5bb4e8b","src/extra.rs":"29f094473279a29b71c3cc9f5fa27c2e2c30c670390cf7e4b7cf451486cc857e","src/fallback.rs":"416a3d24349c163d47f62ac8ae61c28ba6dc4990f04f3d5dacde030b86582d06","src/lib.rs":"ed6bf5e3c3b4fc952d4bdf9b48b149087bceaebf5392befce0bc6cae590a008d","src/location.rs":"9225c5a55f03b56cce42bc55ceb509e8216a5e0b24c94aa1cd071b04e3d6c15f","src/marker.rs":"c11c5a1be8bdf18be3fcd224393f350a9aae7ce282e19ce583c84910c6903a8f","src/num.rs":"82d625cbcd255965e46231ac3af1b74ab8bff9787c799e8ed1f978de146cb0b5","src/parse.rs":"1257d423e9311dda9db0239ff244dfe7b028c1048ab8a83d76daec6068b05114","src/probe.rs":"2b57e8ebf46a7c60ee2762f23f16d24ee9ddb8f1acd0a7faf7a99cf2e4187151","src/probe/proc_macro_span.rs":"53853f0c70170c9695294b8867821664d9b8f1c901957b003003a3c26987abbe","src/probe/proc_macro_span_file.rs":"e7fb4cf8852d9d589bfa3321d8d5cdc8cccb45606ec816a6b8a08f73e416b9ce","src/probe/proc_macro_span_location.rs":"e022386204b6e042b3c55a6c809923849a2f915199bcbf3be72d0b7c8ffa7f83","src/rcvec.rs":"d6e4c1ea42f75e63465fce50ca83f9257536ccdc0345fe78b0037aa2c08c5e37","src/rustc_literal_escaper.rs":"fb3f2f93a09b84f539e6ef514d4b403ee16f2112ff04642099170a60828318ee","src/wrapper.rs":"21a563ef1eec685e3d60ee0479812f212c578dc6d405053b7827c46f6801fdc6","tests/comments.rs":"11520f6baee23b9258db904f4c256fd3877493f754e2b99041f73a330e74a911","tests/features.rs":"7e52c0c801019b271bf11a994c2e1799a1429b0c1a3a34e551a23971797fe412","tests/marker.rs":"f16299460587d6c65603ed809f1a3b81853e4b99d6cb44d0b68bb07259d7e9f8","tests/test.rs":"7d58c3a754241ffdec84e4e9ac799852071db71d77359de164ca7ba6217020e9","tests/test_fmt.rs":"1fa3a817bf934c3bb38942e56eecb70ef525710c6bcfec0356adec654b053c0b","tests/test_size.rs":"7ed5f07c3ccc74c4d09f3c1c43542fbbe23417146761558a0fd4659e19ae1afc"},"package":"985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"} \ No newline at end of file diff --git a/vendor/proc-macro2/.cargo_vcs_info.json b/vendor/proc-macro2/.cargo_vcs_info.json new file mode 100644 index 0000000..61f4171 --- /dev/null +++ b/vendor/proc-macro2/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "ed8a5497669cd63db33bf24646f261b012bbbc4a" + }, + "path_in_vcs": "" +} \ No newline at end of file diff --git a/vendor/proc-macro2/.github/FUNDING.yml b/vendor/proc-macro2/.github/FUNDING.yml new file mode 100644 index 0000000..7507077 --- /dev/null +++ b/vendor/proc-macro2/.github/FUNDING.yml @@ -0,0 +1 @@ +github: dtolnay diff --git a/vendor/proc-macro2/.github/workflows/ci.yml b/vendor/proc-macro2/.github/workflows/ci.yml new file mode 100644 index 0000000..a14d4ab --- /dev/null +++ b/vendor/proc-macro2/.github/workflows/ci.yml @@ -0,0 +1,232 @@ +name: CI + +on: + push: + pull_request: + workflow_dispatch: + schedule: [cron: "40 1 * * *"] + +permissions: + contents: read + +env: + RUSTFLAGS: -Dwarnings + +jobs: + pre_ci: + uses: dtolnay/.github/.github/workflows/pre_ci.yml@master + + test: + name: Rust ${{matrix.rust}} + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rust: [1.80.0, stable, beta] + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{matrix.rust}} + components: rust-src + - run: cargo test + - run: cargo test --no-default-features + - run: cargo test --features span-locations + - name: RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo test + run: cargo test + env: + RUSTFLAGS: --cfg procmacro2_semver_exempt ${{env.RUSTFLAGS}} + - name: RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo test --no-default-features + run: cargo test --no-default-features + env: + RUSTFLAGS: --cfg procmacro2_semver_exempt ${{env.RUSTFLAGS}} + + nightly: + name: Rust nightly + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@nightly + with: + components: rust-src + - name: Enable type layout randomization + run: echo RUSTFLAGS=${RUSTFLAGS}\ -Zrandomize-layout\ --cfg=randomize_layout >> $GITHUB_ENV + - run: cargo check + env: + RUSTFLAGS: --cfg procmacro2_nightly_testing ${{env.RUSTFLAGS}} + - run: cargo test + - run: cargo test --no-default-features + - run: cargo test --no-default-features --test features -- --ignored make_sure_no_proc_macro # run the ignored test to make sure the `proc-macro` feature is disabled + - run: cargo test --features span-locations + - run: cargo test --manifest-path tests/ui/Cargo.toml + - name: RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo test + run: cargo test + env: + RUSTFLAGS: --cfg procmacro2_semver_exempt ${{env.RUSTFLAGS}} + - name: RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo test --no-default-features + run: cargo test --no-default-features + env: + RUSTFLAGS: --cfg procmacro2_semver_exempt ${{env.RUSTFLAGS}} + - name: RUSTFLAGS='-Z allow-features=' cargo test + run: cargo test + env: + RUSTFLAGS: -Z allow-features= --cfg procmacro2_backtrace ${{env.RUSTFLAGS}} + - uses: actions/upload-artifact@v7 + if: always() + with: + name: Cargo.lock + path: Cargo.lock + continue-on-error: true + + layout: + name: Layout + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@nightly + with: + components: rust-src + - run: cargo test --test test_size + - run: cargo test --test test_size --features span-locations + - run: cargo test --test test_size --no-default-features + - run: cargo test --test test_size --no-default-features --features span-locations + + msrv: + name: Rust 1.71.0 + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@1.71.0 + with: + components: rust-src + - run: cargo check + - run: cargo check --no-default-features + - run: cargo check --features span-locations + - name: RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo check + run: cargo check + env: + RUSTFLAGS: --cfg procmacro2_semver_exempt ${{env.RUSTFLAGS}} + - name: RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo check --no-default-features + run: cargo check --no-default-features + env: + RUSTFLAGS: --cfg procmacro2_semver_exempt ${{env.RUSTFLAGS}} + + minimal: + name: Minimal versions + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@nightly + - run: cargo generate-lockfile -Z minimal-versions + - run: cargo check --locked + + webassembly: + name: WebAssembly + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@nightly + with: + target: wasm32-unknown-unknown + components: rust-src + - name: Ignore WebAssembly linker warning + run: echo RUSTFLAGS=${RUSTFLAGS}\ -Alinker_messages >> $GITHUB_ENV + - run: cargo test --target wasm32-unknown-unknown --no-run + + fuzz: + name: Fuzz + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@nightly + with: + components: rust-src + - uses: dtolnay/install@cargo-fuzz + - run: cargo fuzz check + - run: cargo check --no-default-features --features afl + working-directory: fuzz + - uses: dtolnay/install@honggfuzz + - name: Run apt install binutils-dev libunwind-dev + run: | + sudo sed -i 's/^update_initramfs=yes$/update_initramfs=no/' /etc/initramfs-tools/update-initramfs.conf + sudo rm -f /var/lib/man-db/auto-update + sudo apt-get update + sudo apt-get install binutils-dev libunwind-dev + - run: cargo hfuzz build --no-default-features --features honggfuzz + working-directory: fuzz + + doc: + name: Documentation + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + env: + RUSTDOCFLAGS: -Dwarnings + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@nightly + with: + components: rust-src + - uses: dtolnay/install@cargo-docs-rs + - run: cargo docs-rs + + clippy: + name: Clippy + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@nightly + with: + components: clippy, rust-src + - run: cargo clippy --tests -- -Dclippy::all -Dclippy::pedantic + - run: cargo clippy --tests --all-features -- -Dclippy::all -Dclippy::pedantic + + miri: + name: Miri + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@miri + - run: cargo miri setup + - run: cargo miri test + env: + MIRIFLAGS: -Zmiri-strict-provenance + + outdated: + name: Outdated + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/install@cargo-outdated + - run: cargo outdated --workspace --exit-code 1 + - run: cargo outdated --manifest-path fuzz/Cargo.toml --exit-code 1 diff --git a/vendor/proc-macro2/Cargo.lock b/vendor/proc-macro2/Cargo.lock new file mode 100644 index 0000000..5545076 --- /dev/null +++ b/vendor/proc-macro2/Cargo.lock @@ -0,0 +1,230 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "bitflags" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "filetime" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" +dependencies = [ + "cfg-if", + "libc", +] + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +dependencies = [ + "flate2", + "quote", + "rayon", + "rustversion", + "tar", + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2 1.0.106", +] + +[[package]] +name = "rayon" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + +[[package]] +name = "tar" +version = "0.4.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "xattr" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" +dependencies = [ + "libc", + "rustix", +] diff --git a/vendor/proc-macro2/Cargo.toml b/vendor/proc-macro2/Cargo.toml new file mode 100644 index 0000000..4bfeee3 --- /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.71" +name = "proc-macro2" +version = "1.0.107" +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"] +targets = ["x86_64-unknown-linux-gnu"] +rustdoc-args = [ + "--cfg=procmacro2_semver_exempt", + "--generate-link-to-definition", + "--generate-macro-expansion", + "--extern-html-root-url=core=https://doc.rust-lang.org", + "--extern-html-root-url=alloc=https://doc.rust-lang.org", + "--extern-html-root-url=std=https://doc.rust-lang.org", + "--extern-html-root-url=proc_macro=https://doc.rust-lang.org", +] + +[package.metadata.playground] +features = ["span-locations"] + +[features] +default = ["proc-macro"] +nightly = [] +proc-macro = [] +span-locations = [] + +[lib] +name = "proc_macro2" +path = "src/lib.rs" + +[[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" diff --git a/vendor/proc-macro2/Cargo.toml.orig b/vendor/proc-macro2/Cargo.toml.orig new file mode 100644 index 0000000..0edc0fd --- /dev/null +++ b/vendor/proc-macro2/Cargo.toml.orig @@ -0,0 +1,67 @@ +[package] +name = "proc-macro2" +version = "1.0.107" +authors = ["David Tolnay ", "Alex Crichton "] +autobenches = false +categories = ["development-tools::procedural-macro-helpers"] +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" +edition = "2021" +keywords = ["macros", "syn"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/proc-macro2" +rust-version = "1.71" + +[package.metadata.docs.rs] +rustc-args = ["--cfg=procmacro2_semver_exempt"] +targets = ["x86_64-unknown-linux-gnu"] +rustdoc-args = [ + "--cfg=procmacro2_semver_exempt", + "--generate-link-to-definition", + "--generate-macro-expansion", + "--extern-html-root-url=core=https://doc.rust-lang.org", + "--extern-html-root-url=alloc=https://doc.rust-lang.org", + "--extern-html-root-url=std=https://doc.rust-lang.org", + "--extern-html-root-url=proc_macro=https://doc.rust-lang.org", +] + +[package.metadata.playground] +features = ["span-locations"] + +[dependencies] +unicode-ident = "1.0" + +[dev-dependencies] +flate2 = "1.0" +quote = { version = "1.0", default-features = false } +rayon = "1.0" +rustversion = "1" +tar = "0.4" + +[features] +proc-macro = [] +default = ["proc-macro"] + +# Expose methods Span::start and Span::end which give the line/column location +# of a token. +span-locations = [] + +# This feature no longer means anything. +nightly = [] + +[workspace] +members = ["benches/bench-libproc-macro", "tests/ui"] + +[patch.crates-io] +# Our doc tests depend on quote which depends on proc-macro2. Without this line, +# the proc-macro2 dependency of quote would be the released version of +# proc-macro2. Quote would implement its traits for types from that proc-macro2, +# meaning impls would be missing when tested against types from the local +# proc-macro2. +# +# GitHub Actions builds that are in progress at the time that you publish may +# spuriously fail. This is because they'll be building a local proc-macro2 which +# carries the second-most-recent version number, pulling in quote which resolves +# to a dependency on the just-published most recent version number. Thus the +# patch will fail to apply because the version numbers are different. +proc-macro2 = { path = "." } 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..ab8ca4e --- /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/3/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.71.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..26c3ed1 --- /dev/null +++ b/vendor/proc-macro2/build.rs @@ -0,0 +1,267 @@ +#![allow(unknown_lints)] +#![allow(unexpected_cfgs)] +#![allow(clippy::uninlined_format_args)] + +use std::env; +use std::ffi::OsString; +use std::fs; +use std::io::ErrorKind; +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(proc_macro_span_file)"); + println!("cargo:rustc-check-cfg=cfg(proc_macro_span_location)"); + println!("cargo:rustc-check-cfg=cfg(procmacro2_backtrace)"); + println!("cargo:rustc-check-cfg=cfg(procmacro2_build_probe)"); + 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 semver_exempt = cfg!(procmacro2_semver_exempt); + 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; + } + + let proc_macro_span; + let consider_rustc_bootstrap; + if compile_probe_unstable("proc_macro_span", 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_unstable("proc_macro_span", 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::byte_range and Span::join 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 proc_macro_span || (rustc >= 88 && compile_probe_stable("proc_macro_span_location")) { + // Enable non-dummy behavior of Span::start and Span::end methods on + // Rust 1.88+. + println!("cargo:rustc-cfg=proc_macro_span_location"); + } + + if proc_macro_span || (rustc >= 88 && compile_probe_stable("proc_macro_span_file")) { + // Enable non-dummy behavior of Span::file and Span::local_file methods + // on Rust 1.88+. + println!("cargo:rustc-cfg=proc_macro_span_file"); + } + + 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_unstable(feature: &str, rustc_bootstrap: bool) -> bool { + // RUSTC_STAGE indicates that this crate is being compiled as a dependency + // of a multistage rustc bootstrap. This environment uses Cargo in a highly + // non-standard way with issues such as: + // + // https://github.com/rust-lang/cargo/issues/11138 + // https://github.com/rust-lang/rust/issues/114839 + // + env::var_os("RUSTC_STAGE").is_none() && do_compile_probe(feature, rustc_bootstrap) +} + +fn compile_probe_stable(feature: &str) -> bool { + env::var_os("RUSTC_STAGE").is_some() || do_compile_probe(feature, true) +} + +fn do_compile_probe(feature: &str, rustc_bootstrap: bool) -> bool { + println!("cargo:rerun-if-changed=src/probe/{}.rs", feature); + + let rustc = cargo_env_var("RUSTC"); + let out_dir = cargo_env_var("OUT_DIR"); + let out_subdir = Path::new(&out_dir).join("probe"); + let probefile = Path::new("src") + .join("probe") + .join(feature) + .with_extension("rs"); + + if let Err(err) = fs::create_dir(&out_subdir) { + if err.kind() != ErrorKind::AlreadyExists { + eprintln!("Failed to create {}: {}", out_subdir.display(), err); + process::exit(1); + } + } + + 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("--cfg=procmacro2_build_probe") + .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_subdir) + .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); + } + } + } + + let success = match cmd.status() { + Ok(status) => status.success(), + Err(_) => false, + }; + + // Clean up to avoid leaving nondeterministic absolute paths in the dep-info + // file in OUT_DIR, which causes nonreproducible builds in build systems + // that treat the entire OUT_DIR as an artifact. + if let Err(err) = fs::remove_dir_all(&out_subdir) { + // libc::ENOTEMPTY + // Some filesystems (NFSv3) have timing issues under load where '.nfs*' + // dummy files can continue to get created for a short period after the + // probe command completes, breaking remove_dir_all. + // To be replaced with ErrorKind::DirectoryNotEmpty (Rust 1.83+). + const ENOTEMPTY: i32 = 39; + + if !(err.kind() == ErrorKind::NotFound + || (cfg!(target_os = "linux") && err.raw_os_error() == Some(ENOTEMPTY))) + { + eprintln!("Failed to clean up {}: {}", out_subdir.display(), err); + process::exit(1); + } + } + + success +} + +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/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..61dc21d --- /dev/null +++ b/vendor/proc-macro2/src/fallback.rs @@ -0,0 +1,1279 @@ +#[cfg(wrap_proc_macro)] +use crate::imp; +#[cfg(span_locations)] +use crate::location::LineColumn; +use crate::parse::{self, Cursor}; +use crate::rcvec::{RcVec, RcVecBuilder, RcVecIntoIter, RcVecMut}; +use crate::{Delimiter, Spacing, TokenTree}; +use alloc::borrow::ToOwned as _; +use alloc::boxed::Box; +#[cfg(all(span_locations, not(fuzzing)))] +use alloc::collections::BTreeMap; +use alloc::format; +use alloc::string::{String, ToString as _}; +#[cfg(all(span_locations, not(fuzzing)))] +use alloc::vec; +use alloc::vec::Vec; +#[cfg(all(span_locations, not(fuzzing)))] +use core::cell::RefCell; +#[cfg(span_locations)] +use core::cmp; +#[cfg(all(span_locations, not(fuzzing)))] +use core::cmp::Ordering; +use core::ffi::CStr; +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; +#[cfg(feature = "proc-macro")] +use core::str::FromStr; +#[cfg(wrap_proc_macro)] +use std::panic; +#[cfg(span_locations)] +use std::path::PathBuf; +#[cfg(all(span_locations, not(fuzzing)))] +use std::thread_local; + +/// 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(crate) fn new() -> Self { + TokenStream { + inner: RcVecBuilder::new().build(), + } + } + + pub(crate) fn from_str_checked(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) + } + + #[cfg(feature = "proc-macro")] + pub(crate) fn from_str_unchecked(src: &str) -> Self { + Self::from_str_checked(src).unwrap() + } + + pub(crate) 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 stack = Vec::new(); + let mut current = match self.inner.get_mut() { + Some(inner) => inner.take().into_iter(), + None => return, + }; + loop { + while let Some(token) = current.next() { + 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, + }; + let mut group = group; + if let Some(inner) = group.stream.inner.get_mut() { + stack.push(current); + current = inner.take().into_iter(); + } + } + match stack.pop() { + Some(next) => current = next, + None => return, + } + } + } +} + +pub(crate) struct TokenStreamBuilder { + inner: RcVecBuilder, +} + +impl TokenStreamBuilder { + pub(crate) fn new() -> Self { + TokenStreamBuilder { + inner: RcVecBuilder::new(), + } + } + + pub(crate) fn with_capacity(cap: usize) -> Self { + TokenStreamBuilder { + inner: RcVecBuilder::with_capacity(cap), + } + } + + pub(crate) fn push_token_from_parser(&mut self, tt: TokenTree) { + self.inner.push(tt); + } + + pub(crate) 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 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) => write!(f, "{}", tt), + TokenTree::Ident(tt) => write!(f, "{}", tt), + TokenTree::Punct(tt) => { + joint = tt.spacing() == Spacing::Joint; + write!(f, "{}", tt) + } + TokenTree::Literal(tt) => write!(f, "{}", tt), + }?; + } + + 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 { + TokenStream::from_str_unchecked(&inner.to_string()) + } +} + +#[cfg(feature = "proc-macro")] +impl From for proc_macro::TokenStream { + fn from(inner: TokenStream) -> Self { + proc_macro::TokenStream::from_str_unchecked(&inner.to_string()) + } +} + +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(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 { + self.byte(span.lo)..self.byte(span.hi) + } + + fn byte(&mut self, ch: u32) -> usize { + let char_index = (ch - 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. + let (&previous_char_index, &previous_byte_offset) = self + .char_index_to_byte_offset + .range(..=char_index) + .next_back() + .unwrap_or((&0, &0)); + + if previous_char_index == char_index { + return previous_byte_offset; + } + + // Look up next char index that is greater than the requested one. We + // resume counting chars from whichever point is closer. + let byte_offset = match self.char_index_to_byte_offset.range(char_index..).next() { + Some((&next_char_index, &next_byte_offset)) + if next_char_index - char_index < char_index - previous_char_index => + { + self.source_text[..next_byte_offset] + .char_indices() + .nth_back(next_char_index - char_index - 1) + .unwrap() + .0 + } + _ => { + match self.source_text[previous_byte_offset..] + .char_indices() + .nth(char_index - previous_char_index) + { + Some((byte_offset_from_previous, _ch)) => { + previous_byte_offset + byte_offset_from_previous + } + None => self.source_text.len(), + } + } + }; + + self.char_index_to_byte_offset + .insert(char_index, byte_offset); + byte_offset + } + + 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 + } + + fn find(&self, span: Span) -> usize { + match self.files.binary_search_by(|file| { + if file.span.hi < span.lo { + Ordering::Less + } else if file.span.lo > span.hi { + Ordering::Greater + } else { + assert!(file.span_within(span)); + Ordering::Equal + } + }) { + Ok(i) => i, + Err(_) => unreachable!("Invalid span with no related FileInfo!"), + } + } + + fn filepath(&self, span: Span) -> String { + let i = self.find(span); + if i == 0 { + "".to_owned() + } else { + format!("", i) + } + } + + fn fileinfo(&self, span: Span) -> &FileInfo { + let i = self.find(span); + &self.files[i] + } + + fn fileinfo_mut(&mut self, span: Span) -> &mut FileInfo { + let i = self.find(span); + &mut self.files[i] + } +} + +#[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(crate) fn call_site() -> Self { + Span {} + } + + #[cfg(span_locations)] + pub(crate) fn call_site() -> Self { + Span { lo: 0, hi: 0 } + } + + pub(crate) fn mixed_site() -> Self { + Span::call_site() + } + + #[cfg(procmacro2_semver_exempt)] + pub(crate) fn def_site() -> Self { + Span::call_site() + } + + pub(crate) 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(crate) fn located_at(&self, other: Span) -> Span { + other + } + + #[cfg(span_locations)] + pub(crate) 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(crate) 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(crate) 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(span_locations)] + pub(crate) fn file(&self) -> String { + #[cfg(fuzzing)] + return "".to_owned(); + + #[cfg(not(fuzzing))] + SOURCE_MAP.with(|sm| { + let sm = sm.borrow(); + sm.filepath(*self) + }) + } + + #[cfg(span_locations)] + pub(crate) fn local_file(&self) -> Option { + None + } + + #[cfg(not(span_locations))] + pub(crate) fn join(&self, _other: Span) -> Option { + Some(Span {}) + } + + #[cfg(span_locations)] + pub(crate) 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(crate) fn source_text(&self) -> Option { + None + } + + #[cfg(span_locations)] + pub(crate) 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(crate) fn new(delimiter: Delimiter, stream: TokenStream) -> Self { + Group { + delimiter, + stream, + span: Span::call_site(), + } + } + + pub(crate) fn delimiter(&self) -> Delimiter { + self.delimiter + } + + pub(crate) fn stream(&self) -> TokenStream { + self.stream.clone() + } + + pub(crate) fn span(&self) -> Span { + self.span + } + + pub(crate) fn span_open(&self) -> Span { + self.span.first_byte() + } + + pub(crate) fn span_close(&self) -> Span { + self.span.last_byte() + } + + pub(crate) 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(crate) fn new_checked(string: &str, span: Span) -> Self { + validate_ident(string); + Ident::new_unchecked(string, span) + } + + pub(crate) fn new_unchecked(string: &str, span: Span) -> Self { + Ident { + sym: Box::from(string), + span, + raw: false, + } + } + + #[track_caller] + pub(crate) fn new_raw_checked(string: &str, span: Span) -> Self { + validate_ident_raw(string); + Ident::new_raw_unchecked(string, span) + } + + pub(crate) fn new_raw_unchecked(string: &str, span: Span) -> Self { + Ident { + sym: Box::from(string), + span, + raw: true, + } + } + + pub(crate) fn span(&self) -> Span { + self.span + } + + pub(crate) 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#")?; + } + f.write_str(&self.sym) + } +} + +#[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(crate) fn $name(n: $kind) -> Literal { + Literal::_new(format!(concat!("{}", stringify!($kind)), n)) + } + )*) +} + +macro_rules! unsuffixed_numbers { + ($($name:ident => $kind:ident,)*) => ($( + pub(crate) 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) fn from_str_checked(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()) + } + + 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(crate) fn f32_unsuffixed(f: f32) -> Literal { + let mut s = f.to_string(); + if !s.contains('.') { + s.push_str(".0"); + } + Literal::_new(s) + } + + pub(crate) fn f64_unsuffixed(f: f64) -> Literal { + let mut s = f.to_string(); + if !s.contains('.') { + s.push_str(".0"); + } + Literal::_new(s) + } + + pub(crate) 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(crate) 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(crate) 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(crate) 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(crate) 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(crate) fn span(&self) -> Span { + self.span + } + + pub(crate) fn set_span(&mut self, span: Span) { + self.span = span; + } + + pub(crate) 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 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()); + } + } +} + +#[cfg(feature = "proc-macro")] +pub(crate) trait FromStr2: FromStr { + #[cfg(wrap_proc_macro)] + fn valid(src: &str) -> bool; + + #[cfg(wrap_proc_macro)] + fn from_str_checked(src: &str) -> Result { + // Validate using fallback parser, because rustc is incapable of + // returning a recoverable Err for certain invalid token streams, and + // will instead permanently poison the compilation. + if !Self::valid(src) { + return Err(imp::LexError::CompilerPanic); + } + + // Catch panic to work around https://github.com/rust-lang/rust/issues/58736. + match panic::catch_unwind(|| Self::from_str(src)) { + Ok(Ok(ok)) => Ok(ok), + Ok(Err(lex)) => Err(imp::LexError::Compiler(lex)), + Err(_panic) => Err(imp::LexError::CompilerPanic), + } + } + + fn from_str_unchecked(src: &str) -> Self { + Self::from_str(src).unwrap() + } +} + +#[cfg(feature = "proc-macro")] +impl FromStr2 for proc_macro::TokenStream { + #[cfg(wrap_proc_macro)] + fn valid(src: &str) -> bool { + TokenStream::from_str_checked(src).is_ok() + } +} + +#[cfg(feature = "proc-macro")] +impl FromStr2 for proc_macro::Literal { + #[cfg(wrap_proc_macro)] + fn valid(src: &str) -> bool { + Literal::from_str_checked(src).is_ok() + } +} diff --git a/vendor/proc-macro2/src/lib.rs b/vendor/proc-macro2/src/lib.rs new file mode 100644 index 0000000..f590f9b --- /dev/null +++ b/vendor/proc-macro2/src/lib.rs @@ -0,0 +1,1527 @@ +//! [![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: +//! +//! - **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/3/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.71.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. + +#![no_std] +#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.107")] +#![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::elidable_lifetime_names, + 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::uninlined_format_args, + clippy::unnecessary_wraps, + clippy::unused_self, + clippy::used_underscore_binding, + clippy::vec_init_then_push +)] +#![allow(unknown_lints, mismatched_lifetime_syntaxes)] + +#[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; +extern crate std; + +#[cfg(feature = "proc-macro")] +extern crate proc_macro; + +mod marker; +mod parse; +mod probe; +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; + +#[cfg(procmacro2_semver_exempt)] +mod num; +#[cfg(procmacro2_semver_exempt)] +#[allow(dead_code)] +mod rustc_literal_escaper; + +use crate::extra::DelimSpan; +use crate::marker::{ProcMacroAutoTraits, MARKER}; +#[cfg(procmacro2_semver_exempt)] +use crate::rustc_literal_escaper::MixedUnit; +#[cfg(procmacro2_semver_exempt)] +use alloc::borrow::ToOwned as _; +use alloc::string::{String, ToString as _}; +#[cfg(procmacro2_semver_exempt)] +use alloc::vec::Vec; +use core::cmp::Ordering; +use core::ffi::CStr; +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; +#[cfg(span_locations)] +use std::path::PathBuf; + +#[cfg(span_locations)] +#[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] +pub use crate::location::LineColumn; + +#[cfg(procmacro2_semver_exempt)] +#[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))] +pub use crate::rustc_literal_escaper::EscapeError; + +/// 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: imp::TokenStream::from(inner), + _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 { + match imp::TokenStream::from_str_checked(src) { + Ok(tokens) => Ok(TokenStream::_new(tokens)), + Err(lex) => Err(LexError { + inner: lex, + _marker: MARKER, + }), + } + } +} + +#[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(imp::TokenStream::from(inner)) + } +} + +#[cfg(feature = "proc-macro")] +#[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))] +impl From for proc_macro::TokenStream { + fn from(inner: TokenStream) -> Self { + proc_macro::TokenStream::from(inner.inner) + } +} + +impl From for TokenStream { + fn from(token: TokenTree) -> Self { + TokenStream::_new(imp::TokenStream::from(token)) + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, tokens: I) { + self.inner.extend(tokens); + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, streams: I) { + self.inner + .extend(streams.into_iter().map(|stream| stream.inner)); + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, tokens: I) { + self.inner.extend(tokens.into_iter().map(TokenTree::Group)); + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, tokens: I) { + self.inner.extend(tokens.into_iter().map(TokenTree::Ident)); + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, tokens: I) { + self.inner.extend(tokens.into_iter().map(TokenTree::Punct)); + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, tokens: I) { + self.inner + .extend(tokens.into_iter().map(TokenTree::Literal)); + } +} + +/// Collects a number of token trees into a single stream. +impl FromIterator for TokenStream { + fn from_iter>(tokens: I) -> Self { + TokenStream::_new(tokens.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 {} + +/// 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: imp::Span::from(inner), + _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() + } + + /// 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() + } + + /// The path to the source file in which this span occurs, for display + /// purposes. + /// + /// This might not correspond to a valid file system path. It might be + /// remapped, or might be an artificial path such as `""`. + #[cfg(span_locations)] + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] + pub fn file(&self) -> String { + self.inner.file() + } + + /// The path to the source file in which this span occurs on disk. + /// + /// This is the actual path on disk. It is unaffected by path remapping. + /// + /// This path should not be embedded in the output of the macro; prefer + /// `file()` instead. + #[cfg(span_locations)] + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] + pub fn local_file(&self) -> Option { + self.inner.local_file() + } + + /// 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`. + 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: imp::Group::from(inner), + } + } + + /// 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/3/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, + } + } + + fn _new_fallback(inner: fallback::Ident) -> Self { + Ident { + inner: imp::Ident::from(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: imp::Literal::from(inner), + _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`. + pub fn subspan>(&self, range: R) -> Option { + self.inner.subspan(range).map(Span::_new) + } + + /// Returns the unescaped string value if this is a string literal. + #[cfg(procmacro2_semver_exempt)] + pub fn str_value(&self) -> Result { + let repr = self.to_string(); + + if repr.starts_with('"') && repr[1..].ends_with('"') { + let quoted = &repr[1..repr.len() - 1]; + let mut value = String::with_capacity(quoted.len()); + let mut error = None; + rustc_literal_escaper::unescape_str(quoted, |_range, res| match res { + Ok(ch) => value.push(ch), + Err(err) => { + if err.is_fatal() { + error = Some(ConversionErrorKind::FailedToUnescape(err)); + } + } + }); + return match error { + Some(error) => Err(error), + None => Ok(value), + }; + } + + if repr.starts_with('r') { + if let Some(raw) = get_raw(&repr[1..]) { + return Ok(raw.to_owned()); + } + } + + Err(ConversionErrorKind::InvalidLiteralKind) + } + + /// Returns the unescaped string value (including nul terminator) if this is + /// a c-string literal. + #[cfg(procmacro2_semver_exempt)] + pub fn cstr_value(&self) -> Result, ConversionErrorKind> { + let repr = self.to_string(); + + if repr.starts_with("c\"") && repr[2..].ends_with('"') { + let quoted = &repr[2..repr.len() - 1]; + let mut value = Vec::with_capacity(quoted.len()); + let mut error = None; + rustc_literal_escaper::unescape_c_str(quoted, |_range, res| match res { + Ok(MixedUnit::Char(ch)) => { + value.extend_from_slice(ch.get().encode_utf8(&mut [0; 4]).as_bytes()); + } + Ok(MixedUnit::HighByte(byte)) => value.push(byte.get()), + Err(err) => { + if err.is_fatal() { + error = Some(ConversionErrorKind::FailedToUnescape(err)); + } + } + }); + return match error { + Some(error) => Err(error), + None => { + value.push(b'\0'); + Ok(value) + } + }; + } + + if repr.starts_with("cr") { + if let Some(raw) = get_raw(&repr[2..]) { + let mut value = Vec::with_capacity(raw.len() + 1); + value.extend_from_slice(raw.as_bytes()); + value.push(b'\0'); + return Ok(value); + } + } + + Err(ConversionErrorKind::InvalidLiteralKind) + } + + /// Returns the unescaped string value if this is a byte string literal. + #[cfg(procmacro2_semver_exempt)] + pub fn byte_str_value(&self) -> Result, ConversionErrorKind> { + let repr = self.to_string(); + + if repr.starts_with("b\"") && repr[2..].ends_with('"') { + let quoted = &repr[2..repr.len() - 1]; + let mut value = Vec::with_capacity(quoted.len()); + let mut error = None; + rustc_literal_escaper::unescape_byte_str(quoted, |_range, res| match res { + Ok(byte) => value.push(byte), + Err(err) => { + if err.is_fatal() { + error = Some(ConversionErrorKind::FailedToUnescape(err)); + } + } + }); + return match error { + Some(error) => Err(error), + None => Ok(value), + }; + } + + if repr.starts_with("br") { + if let Some(raw) = get_raw(&repr[2..]) { + return Ok(raw.as_bytes().to_owned()); + } + } + + Err(ConversionErrorKind::InvalidLiteralKind) + } + + // 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 { + match imp::Literal::from_str_checked(repr) { + Ok(lit) => Ok(Literal::_new(lit)), + Err(lex) => Err(LexError { + inner: lex, + _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) + } +} + +/// Error when retrieving a string literal's unescaped value. +#[cfg(procmacro2_semver_exempt)] +#[derive(Debug, PartialEq, Eq)] +pub enum ConversionErrorKind { + /// The literal is of the right string kind, but its contents are malformed + /// in a way that cannot be unescaped to a value. + FailedToUnescape(EscapeError), + /// The literal is not of the string kind whose value was requested, for + /// example byte string vs UTF-8 string. + InvalidLiteralKind, +} + +// ###"..."### -> ... +#[cfg(procmacro2_semver_exempt)] +fn get_raw(repr: &str) -> Option<&str> { + let pounds = repr.len() - repr.trim_start_matches('#').len(); + if repr.len() >= pounds + 1 + 1 + pounds + && repr[pounds..].starts_with('"') + && repr.trim_end_matches('#').len() + pounds == repr.len() + && repr[..repr.len() - pounds].ends_with('"') + { + Some(&repr[pounds + 1..repr.len() - pounds - 1]) + } else { + None + } +} + +/// 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/num.rs b/vendor/proc-macro2/src/num.rs new file mode 100644 index 0000000..3ac82c8 --- /dev/null +++ b/vendor/proc-macro2/src/num.rs @@ -0,0 +1,17 @@ +// TODO: use NonZero in Rust 1.89+ +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct NonZeroChar(char); + +impl NonZeroChar { + pub fn new(ch: char) -> Option { + if ch == '\0' { + None + } else { + Some(NonZeroChar(ch)) + } + } + + pub fn get(self) -> char { + self.0 + } +} diff --git a/vendor/proc-macro2/src/parse.rs b/vendor/proc-macro2/src/parse.rs new file mode 100644 index 0000000..7de0a5c --- /dev/null +++ b/vendor/proc-macro2/src/parse.rs @@ -0,0 +1,991 @@ +use crate::fallback::{ + self, is_ident_continue, is_ident_start, Group, Ident, LexError, Literal, Span, TokenStream, + TokenStreamBuilder, +}; +use crate::{Delimiter, Punct, Spacing, TokenTree}; +use alloc::borrow::ToOwned as _; +use alloc::string::ToString as _; +use alloc::vec::Vec; +use core::char; +use core::str::{Bytes, CharIndices, Chars}; + +#[derive(Copy, Clone, Eq, PartialEq)] +pub(crate) struct Cursor<'a> { + pub(crate) rest: &'a str, + #[cfg(span_locations)] + pub(crate) off: u32, +} + +impl<'a> Cursor<'a> { + pub(crate) 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(crate) fn starts_with(&self, s: &str) -> bool { + self.rest.starts_with(s) + } + + pub(crate) fn starts_with_char(&self, ch: char) -> bool { + self.rest.starts_with(ch) + } + + pub(crate) fn starts_with_fn(&self, f: Pattern) -> bool + where + Pattern: FnMut(char) -> bool, + { + self.rest.starts_with(f) + } + + pub(crate) 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 tokens = TokenStreamBuilder::new(); + let mut stack = Vec::new(); + + loop { + input = skip_whitespace(input); + + if let Ok((rest, ())) = doc_comment(input, &mut tokens) { + input = rest; + continue; + } + + #[cfg(span_locations)] + let lo = input.off; + + let Some(first) = input.bytes().next() else { + return match stack.last() { + None => Ok(tokens.build()), + #[cfg(span_locations)] + Some((lo, _frame)) => Err(LexError { + span: Span { lo: *lo, hi: *lo }, + }), + #[cfg(not(span_locations))] + Some(_frame) => 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, tokens); + #[cfg(span_locations)] + let frame = (lo, frame); + stack.push(frame); + tokens = TokenStreamBuilder::new(); + } else if let Some(close_delimiter) = match first { + b')' => Some(Delimiter::Parenthesis), + b']' => Some(Delimiter::Bracket), + b'}' => Some(Delimiter::Brace), + _ => None, + } { + let Some(frame) = stack.pop() else { + 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, tokens.build()); + g.set_span(Span { + #[cfg(span_locations)] + lo, + #[cfg(span_locations)] + hi: input.off, + }); + tokens = outer; + tokens.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, + })); + tokens.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_fallback(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_fallback(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() + .is_some_and(|&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 == '\'' { + let (after_lifetime, _ident) = ident_any(rest)?; + if after_lifetime.starts_with_char('\'') + || (after_lifetime.starts_with_char('#') && !rest.starts_with("r#")) + { + 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 Some(first) = chars.next() else { + 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>, tokens: &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); + tokens.push_token_from_parser(TokenTree::Punct(pound)); + + if inner { + let mut bang = Punct::new('!', Spacing::Alone); + bang.set_span(span); + tokens.push_token_from_parser(TokenTree::Punct(bang)); + } + + let doc_ident = crate::Ident::_new_fallback(Ident::new_unchecked("doc", fallback_span)); + let mut equal = Punct::new('=', Spacing::Alone); + equal.set_span(span); + let mut literal = crate::Literal::_new_fallback(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); + tokens.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/probe.rs b/vendor/proc-macro2/src/probe.rs new file mode 100644 index 0000000..b67f520 --- /dev/null +++ b/vendor/proc-macro2/src/probe.rs @@ -0,0 +1,10 @@ +#![allow(dead_code)] + +#[cfg(proc_macro_span)] +pub(crate) mod proc_macro_span; + +#[cfg(proc_macro_span_file)] +pub(crate) mod proc_macro_span_file; + +#[cfg(proc_macro_span_location)] +pub(crate) mod proc_macro_span_location; diff --git a/vendor/proc-macro2/src/probe/proc_macro_span.rs b/vendor/proc-macro2/src/probe/proc_macro_span.rs new file mode 100644 index 0000000..0a8137b --- /dev/null +++ b/vendor/proc-macro2/src/probe/proc_macro_span.rs @@ -0,0 +1,55 @@ +// 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. + +#![cfg_attr(procmacro2_build_probe, no_std)] +#![cfg_attr(procmacro2_build_probe, feature(proc_macro_span))] + +extern crate alloc; +extern crate proc_macro; +extern crate std; + +use alloc::string::String; +use core::ops::{Range, RangeBounds}; +use proc_macro::{Literal, Span}; +use std::path::PathBuf; + +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 file(this: &Span) -> String { + this.file() +} + +pub fn local_file(this: &Span) -> Option { + this.local_file() +} + +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. +#[cfg(procmacro2_build_probe)] +const _: Option<&str> = option_env!("RUSTC_BOOTSTRAP"); diff --git a/vendor/proc-macro2/src/probe/proc_macro_span_file.rs b/vendor/proc-macro2/src/probe/proc_macro_span_file.rs new file mode 100644 index 0000000..56ba9d5 --- /dev/null +++ b/vendor/proc-macro2/src/probe/proc_macro_span_file.rs @@ -0,0 +1,19 @@ +// The subset of Span's API stabilized in Rust 1.88. + +#![cfg_attr(procmacro2_build_probe, no_std)] + +extern crate alloc; +extern crate proc_macro; +extern crate std; + +use alloc::string::String; +use proc_macro::Span; +use std::path::PathBuf; + +pub fn file(this: &Span) -> String { + this.file() +} + +pub fn local_file(this: &Span) -> Option { + this.local_file() +} diff --git a/vendor/proc-macro2/src/probe/proc_macro_span_location.rs b/vendor/proc-macro2/src/probe/proc_macro_span_location.rs new file mode 100644 index 0000000..18ab278 --- /dev/null +++ b/vendor/proc-macro2/src/probe/proc_macro_span_location.rs @@ -0,0 +1,25 @@ +// The subset of Span's API stabilized in Rust 1.88. + +#![cfg_attr(procmacro2_build_probe, no_std)] + +extern crate alloc; +extern crate proc_macro; +extern crate std; + +use proc_macro::Span; + +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() +} diff --git a/vendor/proc-macro2/src/rcvec.rs b/vendor/proc-macro2/src/rcvec.rs new file mode 100644 index 0000000..8d49526 --- /dev/null +++ b/vendor/proc-macro2/src/rcvec.rs @@ -0,0 +1,146 @@ +use alloc::rc::Rc; +use alloc::vec::{self, 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(crate) fn is_empty(&self) -> bool { + self.inner.is_empty() + } + + pub(crate) fn len(&self) -> usize { + self.inner.len() + } + + pub(crate) fn iter(&self) -> slice::Iter { + self.inner.iter() + } + + pub(crate) fn make_mut(&mut self) -> RcVecMut + where + T: Clone, + { + RcVecMut { + inner: Rc::make_mut(&mut self.inner), + } + } + + pub(crate) fn get_mut(&mut self) -> Option> { + let inner = Rc::get_mut(&mut self.inner)?; + Some(RcVecMut { inner }) + } + + pub(crate) 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(crate) fn new() -> Self { + RcVecBuilder { inner: Vec::new() } + } + + pub(crate) fn with_capacity(cap: usize) -> Self { + RcVecBuilder { + inner: Vec::with_capacity(cap), + } + } + + pub(crate) fn push(&mut self, element: T) { + self.inner.push(element); + } + + pub(crate) fn extend(&mut self, iter: impl IntoIterator) { + self.inner.extend(iter); + } + + pub(crate) fn as_mut(&mut self) -> RcVecMut { + RcVecMut { + inner: &mut self.inner, + } + } + + pub(crate) fn build(self) -> RcVec { + RcVec { + inner: Rc::new(self.inner), + } + } +} + +impl<'a, T> RcVecMut<'a, T> { + pub(crate) fn push(&mut self, element: T) { + self.inner.push(element); + } + + pub(crate) fn extend(&mut self, iter: impl IntoIterator) { + self.inner.extend(iter); + } + + pub(crate) fn as_mut(&mut self) -> RcVecMut { + RcVecMut { inner: self.inner } + } + + pub(crate) fn take(self) -> RcVecBuilder { + let vec = mem::take(self.inner); + RcVecBuilder { inner: vec } + } +} + +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/rustc_literal_escaper.rs b/vendor/proc-macro2/src/rustc_literal_escaper.rs new file mode 100644 index 0000000..66b4c3b --- /dev/null +++ b/vendor/proc-macro2/src/rustc_literal_escaper.rs @@ -0,0 +1,701 @@ +// Vendored from rustc-literal-escaper v0.0.5 +// https://github.com/rust-lang/literal-escaper/tree/v0.0.5 + +//! Utilities for validating (raw) string, char, and byte literals and +//! turning escape sequences into the values they represent. + +use crate::num::NonZeroChar; +use core::ffi::CStr; +use core::num::NonZeroU8; +use core::ops::Range; +use core::str::Chars; + +/// Errors and warnings that can occur during string, char, and byte unescaping. +/// +/// Mostly relating to malformed escape sequences, but also a few other problems. +#[derive(Debug, PartialEq, Eq)] +pub enum EscapeError { + /// Expected 1 char, but 0 were found. + ZeroChars, + /// Expected 1 char, but more than 1 were found. + MoreThanOneChar, + + /// Escaped '\' character without continuation. + LoneSlash, + /// Invalid escape character (e.g. '\z'). + InvalidEscape, + /// Raw '\r' encountered. + BareCarriageReturn, + /// Raw '\r' encountered in raw string. + BareCarriageReturnInRawString, + /// Unescaped character that was expected to be escaped (e.g. raw '\t'). + EscapeOnlyChar, + + /// Numeric character escape is too short (e.g. '\x1'). + TooShortHexEscape, + /// Invalid character in numeric escape (e.g. '\xz') + InvalidCharInHexEscape, + /// Character code in numeric escape is non-ascii (e.g. '\xFF'). + OutOfRangeHexEscape, + + /// '\u' not followed by '{'. + NoBraceInUnicodeEscape, + /// Non-hexadecimal value in '\u{..}'. + InvalidCharInUnicodeEscape, + /// '\u{}' + EmptyUnicodeEscape, + /// No closing brace in '\u{..}', e.g. '\u{12'. + UnclosedUnicodeEscape, + /// '\u{_12}' + LeadingUnderscoreUnicodeEscape, + /// More than 6 characters in '\u{..}', e.g. '\u{10FFFF_FF}' + OverlongUnicodeEscape, + /// Invalid in-bound unicode character code, e.g. '\u{DFFF}'. + LoneSurrogateUnicodeEscape, + /// Out of bounds unicode character code, e.g. '\u{FFFFFF}'. + OutOfRangeUnicodeEscape, + + /// Unicode escape code in byte literal. + UnicodeEscapeInByte, + /// Non-ascii character in byte literal, byte string literal, or raw byte string literal. + NonAsciiCharInByte, + + /// `\0` in a C string literal. + NulInCStr, + + /// After a line ending with '\', the next line contains whitespace + /// characters that are not skipped. + UnskippedWhitespaceWarning, + + /// After a line ending with '\', multiple lines are skipped. + MultipleSkippedLinesWarning, +} + +impl EscapeError { + /// Returns true for actual errors, as opposed to warnings. + pub fn is_fatal(&self) -> bool { + !matches!( + self, + EscapeError::UnskippedWhitespaceWarning | EscapeError::MultipleSkippedLinesWarning + ) + } +} + +/// Check a raw string literal for validity +/// +/// Takes the contents of a raw string literal (without quotes) +/// and produces a sequence of characters or errors, +/// which are returned by invoking `callback`. +/// NOTE: Does no escaping, but produces errors for bare carriage return ('\r'). +pub fn check_raw_str(src: &str, callback: impl FnMut(Range, Result)) { + str::check_raw(src, callback); +} + +/// Check a raw byte string literal for validity +/// +/// Takes the contents of a raw byte string literal (without quotes) +/// and produces a sequence of bytes or errors, +/// which are returned by invoking `callback`. +/// NOTE: Does no escaping, but produces errors for bare carriage return ('\r'). +pub fn check_raw_byte_str(src: &str, callback: impl FnMut(Range, Result)) { + <[u8]>::check_raw(src, callback); +} + +/// Check a raw C string literal for validity +/// +/// Takes the contents of a raw C string literal (without quotes) +/// and produces a sequence of characters or errors, +/// which are returned by invoking `callback`. +/// NOTE: Does no escaping, but produces errors for bare carriage return ('\r'). +pub fn check_raw_c_str( + src: &str, + callback: impl FnMut(Range, Result), +) { + CStr::check_raw(src, callback); +} + +/// Trait for checking raw string literals for validity +trait CheckRaw { + /// Unit type of the implementing string type (`char` for string, `u8` for byte string) + type RawUnit; + + /// Converts chars to the unit type of the literal type + fn char2raw_unit(c: char) -> Result; + + /// Takes the contents of a raw literal (without quotes) + /// and produces a sequence of `Result` + /// which are returned via `callback`. + /// + /// NOTE: Does no escaping, but produces errors for bare carriage return ('\r'). + fn check_raw( + src: &str, + mut callback: impl FnMut(Range, Result), + ) { + let mut chars = src.chars(); + while let Some(c) = chars.next() { + let start = src.len() - chars.as_str().len() - c.len_utf8(); + let res = match c { + '\r' => Err(EscapeError::BareCarriageReturnInRawString), + _ => Self::char2raw_unit(c), + }; + let end = src.len() - chars.as_str().len(); + callback(start..end, res); + } + + // Unfortunately, it is a bit unclear whether the following equivalent code is slower or faster: bug 141855 + // src.char_indices().for_each(|(pos, c)| { + // callback( + // pos..pos + c.len_utf8(), + // if c == '\r' { + // Err(EscapeError::BareCarriageReturnInRawString) + // } else { + // Self::char2raw_unit(c) + // }, + // ); + // }); + } +} + +impl CheckRaw for str { + type RawUnit = char; + + #[inline] + fn char2raw_unit(c: char) -> Result { + Ok(c) + } +} + +impl CheckRaw for [u8] { + type RawUnit = u8; + + #[inline] + fn char2raw_unit(c: char) -> Result { + char2byte(c) + } +} + +/// Turn an ascii char into a byte +#[inline] +fn char2byte(c: char) -> Result { + // do NOT do: c.try_into().ok_or(EscapeError::NonAsciiCharInByte) + if c.is_ascii() { + Ok(c as u8) + } else { + Err(EscapeError::NonAsciiCharInByte) + } +} + +impl CheckRaw for CStr { + type RawUnit = NonZeroChar; + + #[inline] + fn char2raw_unit(c: char) -> Result { + NonZeroChar::new(c).ok_or(EscapeError::NulInCStr) + } +} + +/// Unescape a char literal +/// +/// Takes the contents of a char literal (without quotes), +/// and returns an unescaped char or an error. +#[inline] +pub fn unescape_char(src: &str) -> Result { + str::unescape_single(&mut src.chars()) +} + +/// Unescape a byte literal +/// +/// Takes the contents of a byte literal (without quotes), +/// and returns an unescaped byte or an error. +#[inline] +pub fn unescape_byte(src: &str) -> Result { + <[u8]>::unescape_single(&mut src.chars()) +} + +/// Unescape a string literal +/// +/// Takes the contents of a string literal (without quotes) +/// and produces a sequence of escaped characters or errors, +/// which are returned by invoking `callback`. +pub fn unescape_str(src: &str, callback: impl FnMut(Range, Result)) { + str::unescape(src, callback) +} + +/// Unescape a byte string literal +/// +/// Takes the contents of a byte string literal (without quotes) +/// and produces a sequence of escaped bytes or errors, +/// which are returned by invoking `callback`. +pub fn unescape_byte_str(src: &str, callback: impl FnMut(Range, Result)) { + <[u8]>::unescape(src, callback) +} + +/// Unescape a C string literal +/// +/// Takes the contents of a C string literal (without quotes) +/// and produces a sequence of escaped MixedUnits or errors, +/// which are returned by invoking `callback`. +pub fn unescape_c_str( + src: &str, + callback: impl FnMut(Range, Result), +) { + CStr::unescape(src, callback) +} + +/// Enum representing either a char or a byte +/// +/// Used for mixed utf8 string literals, i.e. those that allow both unicode +/// chars and high bytes. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum MixedUnit { + /// Used for ASCII chars (written directly or via `\x00`..`\x7f` escapes) + /// and Unicode chars (written directly or via `\u` escapes). + /// + /// For example, if '¥' appears in a string it is represented here as + /// `MixedUnit::Char('¥')`, and it will be appended to the relevant byte + /// string as the two-byte UTF-8 sequence `[0xc2, 0xa5]` + Char(NonZeroChar), + + /// Used for high bytes (`\x80`..`\xff`). + /// + /// For example, if `\xa5` appears in a string it is represented here as + /// `MixedUnit::HighByte(0xa5)`, and it will be appended to the relevant + /// byte string as the single byte `0xa5`. + HighByte(NonZeroU8), +} + +impl From for MixedUnit { + #[inline] + fn from(c: NonZeroChar) -> Self { + MixedUnit::Char(c) + } +} + +impl From for MixedUnit { + #[inline] + fn from(byte: NonZeroU8) -> Self { + if byte.get().is_ascii() { + MixedUnit::Char(NonZeroChar::new(byte.get() as char).unwrap()) + } else { + MixedUnit::HighByte(byte) + } + } +} + +impl TryFrom for MixedUnit { + type Error = EscapeError; + + #[inline] + fn try_from(c: char) -> Result { + NonZeroChar::new(c) + .map(MixedUnit::Char) + .ok_or(EscapeError::NulInCStr) + } +} + +impl TryFrom for MixedUnit { + type Error = EscapeError; + + #[inline] + fn try_from(byte: u8) -> Result { + NonZeroU8::new(byte) + .map(From::from) + .ok_or(EscapeError::NulInCStr) + } +} + +/// Trait for unescaping escape sequences in strings +trait Unescape { + /// Unit type of the implementing string type (`char` for string, `u8` for byte string) + type Unit; + + /// Result of unescaping the zero char ('\0') + const ZERO_RESULT: Result; + + /// Converts non-zero bytes to the unit type + fn nonzero_byte2unit(b: NonZeroU8) -> Self::Unit; + + /// Converts chars to the unit type + fn char2unit(c: char) -> Result; + + /// Converts the byte of a hex escape to the unit type + fn hex2unit(b: u8) -> Result; + + /// Converts the result of a unicode escape to the unit type + fn unicode2unit(r: Result) -> Result; + + /// Unescape a single unit (single quote syntax) + fn unescape_single(chars: &mut Chars<'_>) -> Result { + let res = match chars.next().ok_or(EscapeError::ZeroChars)? { + '\\' => Self::unescape_1(chars), + '\n' | '\t' | '\'' => Err(EscapeError::EscapeOnlyChar), + '\r' => Err(EscapeError::BareCarriageReturn), + c => Self::char2unit(c), + }?; + if chars.next().is_some() { + return Err(EscapeError::MoreThanOneChar); + } + Ok(res) + } + + /// Unescape the first unit of a string (double quoted syntax) + fn unescape_1(chars: &mut Chars<'_>) -> Result { + // Previous character was '\\', unescape what follows. + let c = chars.next().ok_or(EscapeError::LoneSlash)?; + if c == '0' { + Self::ZERO_RESULT + } else { + simple_escape(c) + .map(|b| Self::nonzero_byte2unit(b)) + .or_else(|c| match c { + 'x' => Self::hex2unit(hex_escape(chars)?), + 'u' => Self::unicode2unit({ + let value = unicode_escape(chars)?; + if value > char::MAX as u32 { + Err(EscapeError::OutOfRangeUnicodeEscape) + } else { + char::from_u32(value).ok_or(EscapeError::LoneSurrogateUnicodeEscape) + } + }), + _ => Err(EscapeError::InvalidEscape), + }) + } + } + + /// Unescape a string literal + /// + /// Takes the contents of a raw string literal (without quotes) + /// and produces a sequence of `Result` + /// which are returned via `callback`. + fn unescape( + src: &str, + mut callback: impl FnMut(Range, Result), + ) { + let mut chars = src.chars(); + while let Some(c) = chars.next() { + let start = src.len() - chars.as_str().len() - c.len_utf8(); + let res = match c { + '\\' => { + if let Some(b'\n') = chars.as_str().as_bytes().first() { + let _ = chars.next(); + // skip whitespace for backslash newline, see [Rust language reference] + // (https://doc.rust-lang.org/reference/tokens.html#string-literals). + let callback_err = |range, err| callback(range, Err(err)); + skip_ascii_whitespace(&mut chars, start, callback_err); + continue; + } else { + Self::unescape_1(&mut chars) + } + } + '"' => Err(EscapeError::EscapeOnlyChar), + '\r' => Err(EscapeError::BareCarriageReturn), + c => Self::char2unit(c), + }; + let end = src.len() - chars.as_str().len(); + callback(start..end, res); + } + } +} + +/// Interpret a non-nul ASCII escape +/// +/// Parses the character of an ASCII escape (except nul) without the leading backslash. +#[inline] // single use in Unescape::unescape_1 +fn simple_escape(c: char) -> Result { + // Previous character was '\\', unescape what follows. + Ok(NonZeroU8::new(match c { + '"' => b'"', + 'n' => b'\n', + 'r' => b'\r', + 't' => b'\t', + '\\' => b'\\', + '\'' => b'\'', + _ => Err(c)?, + }) + .unwrap()) +} + +/// Interpret a hexadecimal escape +/// +/// Parses the two hexadecimal characters of a hexadecimal escape without the leading r"\x". +#[inline] // single use in Unescape::unescape_1 +fn hex_escape(chars: &mut impl Iterator) -> Result { + let hi = chars.next().ok_or(EscapeError::TooShortHexEscape)?; + let hi = hi.to_digit(16).ok_or(EscapeError::InvalidCharInHexEscape)?; + + let lo = chars.next().ok_or(EscapeError::TooShortHexEscape)?; + let lo = lo.to_digit(16).ok_or(EscapeError::InvalidCharInHexEscape)?; + + Ok((hi * 16 + lo) as u8) +} + +/// Interpret a unicode escape +/// +/// Parse the braces with hexadecimal characters (and underscores) part of a unicode escape. +/// This r"{...}" normally comes after r"\u" and cannot start with an underscore. +#[inline] // single use in Unescape::unescape_1 +fn unicode_escape(chars: &mut impl Iterator) -> Result { + if chars.next() != Some('{') { + return Err(EscapeError::NoBraceInUnicodeEscape); + } + + // First character must be a hexadecimal digit. + let mut value: u32 = match chars.next().ok_or(EscapeError::UnclosedUnicodeEscape)? { + '_' => return Err(EscapeError::LeadingUnderscoreUnicodeEscape), + '}' => return Err(EscapeError::EmptyUnicodeEscape), + c => c + .to_digit(16) + .ok_or(EscapeError::InvalidCharInUnicodeEscape)?, + }; + + // First character is valid, now parse the rest of the number + // and closing brace. + let mut n_digits = 1; + loop { + match chars.next() { + None => return Err(EscapeError::UnclosedUnicodeEscape), + Some('_') => continue, + Some('}') => { + // Incorrect syntax has higher priority for error reporting + // than unallowed value for a literal. + return if n_digits > 6 { + Err(EscapeError::OverlongUnicodeEscape) + } else { + Ok(value) + }; + } + Some(c) => { + let digit: u32 = c + .to_digit(16) + .ok_or(EscapeError::InvalidCharInUnicodeEscape)?; + n_digits += 1; + if n_digits > 6 { + // Stop updating value since we're sure that it's incorrect already. + continue; + } + value = value * 16 + digit; + } + }; + } +} + +/// Interpret a string continuation escape (https://doc.rust-lang.org/reference/expressions/literal-expr.html#string-continuation-escapes) +/// +/// Skip ASCII whitespace, except for the formfeed character +/// (see [this issue](https://github.com/rust-lang/rust/issues/136600)). +/// Warns on unescaped newline and following non-ASCII whitespace. +#[inline] // single use in Unescape::unescape +fn skip_ascii_whitespace( + chars: &mut Chars<'_>, + start: usize, + mut callback: impl FnMut(Range, EscapeError), +) { + let rest = chars.as_str(); + let first_non_space = rest + .bytes() + .position(|b| b != b' ' && b != b'\t' && b != b'\n' && b != b'\r') + .unwrap_or(rest.len()); + let (space, rest) = rest.split_at(first_non_space); + // backslash newline adds 2 bytes + let end = start + 2 + first_non_space; + if space.contains('\n') { + callback(start..end, EscapeError::MultipleSkippedLinesWarning); + } + *chars = rest.chars(); + if let Some(c) = chars.clone().next() { + if c.is_whitespace() { + // for error reporting, include the character that was not skipped in the span + callback( + start..end + c.len_utf8(), + EscapeError::UnskippedWhitespaceWarning, + ); + } + } +} + +impl Unescape for str { + type Unit = char; + + const ZERO_RESULT: Result = Ok('\0'); + + #[inline] + fn nonzero_byte2unit(b: NonZeroU8) -> Self::Unit { + b.get().into() + } + + #[inline] + fn char2unit(c: char) -> Result { + Ok(c) + } + + #[inline] + fn hex2unit(b: u8) -> Result { + if b.is_ascii() { + Ok(b as char) + } else { + Err(EscapeError::OutOfRangeHexEscape) + } + } + + #[inline] + fn unicode2unit(r: Result) -> Result { + r + } +} + +impl Unescape for [u8] { + type Unit = u8; + + const ZERO_RESULT: Result = Ok(b'\0'); + + #[inline] + fn nonzero_byte2unit(b: NonZeroU8) -> Self::Unit { + b.get() + } + + #[inline] + fn char2unit(c: char) -> Result { + char2byte(c) + } + + #[inline] + fn hex2unit(b: u8) -> Result { + Ok(b) + } + + #[inline] + fn unicode2unit(_r: Result) -> Result { + Err(EscapeError::UnicodeEscapeInByte) + } +} + +impl Unescape for CStr { + type Unit = MixedUnit; + + const ZERO_RESULT: Result = Err(EscapeError::NulInCStr); + + #[inline] + fn nonzero_byte2unit(b: NonZeroU8) -> Self::Unit { + b.into() + } + + #[inline] + fn char2unit(c: char) -> Result { + c.try_into() + } + + #[inline] + fn hex2unit(byte: u8) -> Result { + byte.try_into() + } + + #[inline] + fn unicode2unit(r: Result) -> Result { + Self::char2unit(r?) + } +} + +/// Enum of the different kinds of literal +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Mode { + /// `'a'` + Char, + + /// `b'a'` + Byte, + + /// `"hello"` + Str, + /// `r"hello"` + RawStr, + + /// `b"hello"` + ByteStr, + /// `br"hello"` + RawByteStr, + + /// `c"hello"` + CStr, + /// `cr"hello"` + RawCStr, +} + +impl Mode { + pub fn in_double_quotes(self) -> bool { + match self { + Mode::Str + | Mode::RawStr + | Mode::ByteStr + | Mode::RawByteStr + | Mode::CStr + | Mode::RawCStr => true, + Mode::Char | Mode::Byte => false, + } + } + + pub fn prefix_noraw(self) -> &'static str { + match self { + Mode::Char | Mode::Str | Mode::RawStr => "", + Mode::Byte | Mode::ByteStr | Mode::RawByteStr => "b", + Mode::CStr | Mode::RawCStr => "c", + } + } +} + +/// Check a literal only for errors +/// +/// Takes the contents of a literal (without quotes) +/// and produces a sequence of only errors, +/// which are returned by invoking `error_callback`. +/// +/// NB Does not produce any output other than errors +pub fn check_for_errors( + src: &str, + mode: Mode, + mut error_callback: impl FnMut(Range, EscapeError), +) { + match mode { + Mode::Char => { + let mut chars = src.chars(); + if let Err(e) = str::unescape_single(&mut chars) { + error_callback(0..(src.len() - chars.as_str().len()), e); + } + } + Mode::Byte => { + let mut chars = src.chars(); + if let Err(e) = <[u8]>::unescape_single(&mut chars) { + error_callback(0..(src.len() - chars.as_str().len()), e); + } + } + Mode::Str => unescape_str(src, |range, res| { + if let Err(e) = res { + error_callback(range, e); + } + }), + Mode::ByteStr => unescape_byte_str(src, |range, res| { + if let Err(e) = res { + error_callback(range, e); + } + }), + Mode::CStr => unescape_c_str(src, |range, res| { + if let Err(e) = res { + error_callback(range, e); + } + }), + Mode::RawStr => check_raw_str(src, |range, res| { + if let Err(e) = res { + error_callback(range, e); + } + }), + Mode::RawByteStr => check_raw_byte_str(src, |range, res| { + if let Err(e) = res { + error_callback(range, e); + } + }), + Mode::RawCStr => check_raw_c_str(src, |range, res| { + if let Err(e) = res { + error_callback(range, e); + } + }), + } +} diff --git a/vendor/proc-macro2/src/wrapper.rs b/vendor/proc-macro2/src/wrapper.rs new file mode 100644 index 0000000..6043c16 --- /dev/null +++ b/vendor/proc-macro2/src/wrapper.rs @@ -0,0 +1,987 @@ +use crate::detection::inside_proc_macro; +use crate::fallback::{self, FromStr2 as _}; +#[cfg(span_locations)] +use crate::location::LineColumn; +#[cfg(proc_macro_span)] +use crate::probe::proc_macro_span; +#[cfg(all(span_locations, proc_macro_span_file))] +use crate::probe::proc_macro_span_file; +#[cfg(all(span_locations, proc_macro_span_location))] +use crate::probe::proc_macro_span_location; +use crate::{Delimiter, Punct, Spacing, TokenTree}; +#[cfg(all(span_locations, not(proc_macro_span_file)))] +use alloc::borrow::ToOwned as _; +use alloc::string::{String, ToString as _}; +use alloc::vec::Vec; +use core::ffi::CStr; +use core::fmt::{self, Debug, Display}; +#[cfg(span_locations)] +use core::ops::Range; +use core::ops::RangeBounds; +#[cfg(span_locations)] +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 L{}\n\n{}", line, backtrace) + } + #[cfg(not(procmacro2_backtrace))] + { + panic!("compiler/fallback mismatch L{}", 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(crate) fn new() -> Self { + if inside_proc_macro() { + TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::new())) + } else { + TokenStream::Fallback(fallback::TokenStream::new()) + } + } + + pub(crate) fn from_str_checked(src: &str) -> Result { + if inside_proc_macro() { + Ok(TokenStream::Compiler(DeferredTokenStream::new( + proc_macro::TokenStream::from_str_checked(src)?, + ))) + } else { + Ok(TokenStream::Fallback( + fallback::TokenStream::from_str_checked(src)?, + )) + } + } + + pub(crate) 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 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) => { + proc_macro::TokenStream::from_str_unchecked(&inner.to_string()) + } + } + } +} + +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) => proc_macro::TokenTree::Group(tt.inner.unwrap_nightly()), + 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()); + proc_macro::TokenTree::Punct(punct) + } + TokenTree::Ident(tt) => proc_macro::TokenTree::Ident(tt.inner.unwrap_nightly()), + TokenTree::Literal(tt) => proc_macro::TokenTree::Literal(tt.inner.unwrap_nightly()), + } +} + +impl From for TokenStream { + fn from(token: TokenTree) -> Self { + if inside_proc_macro() { + TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::from( + into_compiler_token(token), + ))) + } else { + TokenStream::Fallback(fallback::TokenStream::from(token)) + } + } +} + +impl FromIterator for TokenStream { + fn from_iter>(tokens: I) -> Self { + if inside_proc_macro() { + TokenStream::Compiler(DeferredTokenStream::new( + tokens.into_iter().map(into_compiler_token).collect(), + )) + } else { + TokenStream::Fallback(tokens.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, tokens: I) { + match self { + TokenStream::Compiler(tts) => { + // Here is the reason for DeferredTokenStream. + for token in tokens { + tts.extra.push(into_compiler_token(token)); + } + } + TokenStream::Fallback(tts) => tts.extend(tokens), + } + } +} + +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) => { + TokenTree::Group(crate::Group::_new(Group::Compiler(tt))) + } + 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()))); + TokenTree::Punct(o) + } + proc_macro::TokenTree::Ident(s) => { + TokenTree::Ident(crate::Ident::_new(Ident::Compiler(s))) + } + proc_macro::TokenTree::Literal(l) => { + TokenTree::Literal(crate::Literal::_new(Literal::Compiler(l))) + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + match self { + TokenTreeIter::Compiler(tts) => tts.size_hint(), + TokenTreeIter::Fallback(tts) => tts.size_hint(), + } + } +} + +#[derive(Copy, Clone)] +pub(crate) enum Span { + Compiler(proc_macro::Span), + Fallback(fallback::Span), +} + +impl Span { + pub(crate) fn call_site() -> Self { + if inside_proc_macro() { + Span::Compiler(proc_macro::Span::call_site()) + } else { + Span::Fallback(fallback::Span::call_site()) + } + } + + pub(crate) 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(crate) fn def_site() -> Self { + if inside_proc_macro() { + Span::Compiler(proc_macro::Span::def_site()) + } else { + Span::Fallback(fallback::Span::def_site()) + } + } + + pub(crate) 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(crate) 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(crate) 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(span_locations)] + pub(crate) fn byte_range(&self) -> Range { + match self { + #[cfg(proc_macro_span)] + Span::Compiler(s) => proc_macro_span::byte_range(s), + #[cfg(not(proc_macro_span))] + Span::Compiler(_) => 0..0, + Span::Fallback(s) => s.byte_range(), + } + } + + #[cfg(span_locations)] + pub(crate) fn start(&self) -> LineColumn { + match self { + #[cfg(proc_macro_span_location)] + Span::Compiler(s) => LineColumn { + line: proc_macro_span_location::line(s), + column: proc_macro_span_location::column(s).saturating_sub(1), + }, + #[cfg(not(proc_macro_span_location))] + Span::Compiler(_) => LineColumn { line: 0, column: 0 }, + Span::Fallback(s) => s.start(), + } + } + + #[cfg(span_locations)] + pub(crate) fn end(&self) -> LineColumn { + match self { + #[cfg(proc_macro_span_location)] + Span::Compiler(s) => { + let end = proc_macro_span_location::end(s); + LineColumn { + line: proc_macro_span_location::line(&end), + column: proc_macro_span_location::column(&end).saturating_sub(1), + } + } + #[cfg(not(proc_macro_span_location))] + Span::Compiler(_) => LineColumn { line: 0, column: 0 }, + Span::Fallback(s) => s.end(), + } + } + + #[cfg(span_locations)] + pub(crate) fn file(&self) -> String { + match self { + #[cfg(proc_macro_span_file)] + Span::Compiler(s) => proc_macro_span_file::file(s), + #[cfg(not(proc_macro_span_file))] + Span::Compiler(_) => "".to_owned(), + Span::Fallback(s) => s.file(), + } + } + + #[cfg(span_locations)] + pub(crate) fn local_file(&self) -> Option { + match self { + #[cfg(proc_macro_span_file)] + Span::Compiler(s) => proc_macro_span_file::local_file(s), + #[cfg(not(proc_macro_span_file))] + Span::Compiler(_) => None, + Span::Fallback(s) => s.local_file(), + } + } + + pub(crate) fn join(&self, other: Span) -> Option { + let ret = match (self, other) { + #[cfg(proc_macro_span)] + (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(proc_macro_span::join(a, b)?), + (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.join(b)?), + _ => return None, + }; + Some(ret) + } + + #[cfg(super_unstable)] + pub(crate) 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(crate) 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(crate) 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(crate) 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(crate) fn stream(&self) -> TokenStream { + match self { + Group::Compiler(g) => TokenStream::Compiler(DeferredTokenStream::new(g.stream())), + Group::Fallback(g) => TokenStream::Fallback(g.stream()), + } + } + + pub(crate) fn span(&self) -> Span { + match self { + Group::Compiler(g) => Span::Compiler(g.span()), + Group::Fallback(g) => Span::Fallback(g.span()), + } + } + + pub(crate) fn span_open(&self) -> Span { + match self { + Group::Compiler(g) => Span::Compiler(g.span_open()), + Group::Fallback(g) => Span::Fallback(g.span_open()), + } + } + + pub(crate) fn span_close(&self) -> Span { + match self { + Group::Compiler(g) => Span::Compiler(g.span_close()), + Group::Fallback(g) => Span::Fallback(g.span_close()), + } + } + + pub(crate) 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(crate) 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)), + } + } + + #[track_caller] + pub(crate) 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(crate) fn span(&self) -> Span { + match self { + Ident::Compiler(t) => Span::Compiler(t.span()), + Ident::Fallback(t) => Span::Fallback(t.span()), + } + } + + pub(crate) 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 From for Ident { + fn from(inner: fallback::Ident) -> Self { + Ident::Fallback(inner) + } +} + +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(crate) 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(crate) 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(crate) fn from_str_checked(repr: &str) -> Result { + if inside_proc_macro() { + let literal = proc_macro::Literal::from_str_checked(repr)?; + Ok(Literal::Compiler(literal)) + } else { + let literal = fallback::Literal::from_str_checked(repr)?; + Ok(Literal::Fallback(literal)) + } + } + + pub(crate) unsafe fn from_str_unchecked(repr: &str) -> Self { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::from_str_unchecked(repr)) + } 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(crate) 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(crate) 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(crate) fn string(string: &str) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::string(string)) + } else { + Literal::Fallback(fallback::Literal::string(string)) + } + } + + pub(crate) fn character(ch: char) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::character(ch)) + } else { + Literal::Fallback(fallback::Literal::character(ch)) + } + } + + pub(crate) 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); + proc_macro::Literal::from_str_unchecked(&fallback.repr) + } + }) + } else { + Literal::Fallback(fallback::Literal::byte_character(byte)) + } + } + + pub(crate) 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(crate) 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); + proc_macro::Literal::from_str_unchecked(&fallback.repr) + } + }) + } else { + Literal::Fallback(fallback::Literal::c_string(string)) + } + } + + pub(crate) fn span(&self) -> Span { + match self { + Literal::Compiler(lit) => Span::Compiler(lit.span()), + Literal::Fallback(lit) => Span::Fallback(lit.span()), + } + } + + pub(crate) 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(crate) fn subspan>(&self, range: R) -> Option { + match self { + #[cfg(proc_macro_span)] + Literal::Compiler(lit) => proc_macro_span::subspan(lit, 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 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" + ); + } + 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..34951f7 --- /dev/null +++ b/vendor/proc-macro2/tests/comments.rs @@ -0,0 +1,105 @@ +#![allow(clippy::assertions_on_result_states, clippy::uninlined_format_args)] + +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..ea1704d --- /dev/null +++ b/vendor/proc-macro2/tests/features.rs @@ -0,0 +1,10 @@ +#![allow(clippy::assertions_on_constants, clippy::ignore_without_reason)] + +#[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..af8932a --- /dev/null +++ b/vendor/proc-macro2/tests/marker.rs @@ -0,0 +1,97 @@ +#![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; + + assert_impl!(LineColumn is Send and Sync); +} + +mod unwind_safe { + #[cfg(procmacro2_semver_exempt)] + use proc_macro2::LineColumn; + use proc_macro2::{ + Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree, + }; + 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 + } +} diff --git a/vendor/proc-macro2/tests/test.rs b/vendor/proc-macro2/tests/test.rs new file mode 100644 index 0000000..1989330 --- /dev/null +++ b/vendor/proc-macro2/tests/test.rs @@ -0,0 +1,1093 @@ +#![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, + clippy::uninlined_format_args +)] + +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(); +} + +#[cfg(procmacro2_semver_exempt)] +#[test] +fn literal_string_value() { + for string in ["", "...", "...\t...", "...\\...", "...\0...", "...\u{1}..."] { + assert_eq!(string, Literal::string(string).str_value().unwrap()); + assert_eq!( + string, + format!("r\"{string}\"") + .parse::() + .unwrap() + .str_value() + .unwrap(), + ); + assert_eq!( + string, + format!("r##\"{string}\"##") + .parse::() + .unwrap() + .str_value() + .unwrap(), + ); + } +} + +#[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(); +} + +#[cfg(procmacro2_semver_exempt)] +#[test] +fn literal_byte_string_value() { + for bytestr in [ + &b""[..], + b"...", + b"...\t...", + b"...\\...", + b"...\0...", + b"...\xF0...", + ] { + assert_eq!( + bytestr, + Literal::byte_string(bytestr).byte_str_value().unwrap(), + ); + if let Ok(string) = str::from_utf8(bytestr) { + assert_eq!( + bytestr, + format!("br\"{string}\"") + .parse::() + .unwrap() + .byte_str_value() + .unwrap(), + ); + assert_eq!( + bytestr, + format!("br##\"{string}\"##") + .parse::() + .unwrap() + .byte_str_value() + .unwrap(), + ); + } + } +} + +#[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); + } + } +} + +#[cfg(procmacro2_semver_exempt)] +#[test] +fn literal_c_string_value() { + for cstr in [ + c"", + c"...", + c"...\t...", + c"...\\...", + c"...\u{1}...", + c"...\xF0...", + ] { + assert_eq!( + cstr.to_bytes_with_nul(), + Literal::c_string(cstr).cstr_value().unwrap(), + ); + if let Ok(string) = cstr.to_str() { + assert_eq!( + cstr.to_bytes_with_nul(), + format!("cr\"{string}\"") + .parse::() + .unwrap() + .cstr_value() + .unwrap(), + ); + assert_eq!( + cstr.to_bytes_with_nul(), + format!("cr##\"{string}\"##") + .parse::() + .unwrap() + .cstr_value() + .unwrap(), + ); + } + } +} + +#[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 lifetimes() { + let mut tokens = "'a 'static 'struct 'r#gen 'r#prefix#lifetime" + .parse::() + .unwrap() + .into_iter(); + assert!(match tokens.next() { + Some(TokenTree::Punct(punct)) => { + punct.as_char() == '\'' && punct.spacing() == Spacing::Joint + } + _ => false, + }); + assert!(match tokens.next() { + Some(TokenTree::Ident(ident)) => ident == "a", + _ => false, + }); + assert!(match tokens.next() { + Some(TokenTree::Punct(punct)) => { + punct.as_char() == '\'' && punct.spacing() == Spacing::Joint + } + _ => false, + }); + assert!(match tokens.next() { + Some(TokenTree::Ident(ident)) => ident == "static", + _ => false, + }); + assert!(match tokens.next() { + Some(TokenTree::Punct(punct)) => { + punct.as_char() == '\'' && punct.spacing() == Spacing::Joint + } + _ => false, + }); + assert!(match tokens.next() { + Some(TokenTree::Ident(ident)) => ident == "struct", + _ => false, + }); + assert!(match tokens.next() { + Some(TokenTree::Punct(punct)) => { + punct.as_char() == '\'' && punct.spacing() == Spacing::Joint + } + _ => false, + }); + assert!(match tokens.next() { + Some(TokenTree::Ident(ident)) => ident == "r#gen", + _ => false, + }); + assert!(match tokens.next() { + Some(TokenTree::Punct(punct)) => { + punct.as_char() == '\'' && punct.spacing() == Spacing::Joint + } + _ => false, + }); + assert!(match tokens.next() { + Some(TokenTree::Ident(ident)) => ident == "r#prefix", + _ => false, + }); + assert!(match tokens.next() { + Some(TokenTree::Punct(punct)) => { + punct.as_char() == '#' && punct.spacing() == Spacing::Alone + } + _ => false, + }); + assert!(match tokens.next() { + Some(TokenTree::Ident(ident)) => ident == "lifetime", + _ => false, + }); + + "' a".parse::().unwrap_err(); + "' r#gen".parse::().unwrap_err(); + "' prefix#lifetime".parse::().unwrap_err(); + "'prefix#lifetime".parse::().unwrap_err(); + "'aa'bb".parse::().unwrap_err(); + "'r#gen'a".parse::().unwrap_err(); +} + +#[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); + assert_eq!(Span::call_site().file(), ""); + assert!(Span::call_site().local_file().is_none()); +} + +#[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().file() != source2[0].span().file()); + assert_eq!(source1[0].span().file(), source1[1].span().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().file(), source1[0].span().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 TokenTree::Punct(punct) = stream.into_iter().next().unwrap() else { + 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_display_ident() { + let ident = Ident::new("proc_macro", Span::call_site()); + assert_eq!(format!("{ident}"), "proc_macro"); + assert_eq!(format!("{ident:-^14}"), "proc_macro"); + + let ident = Ident::new_raw("proc_macro", Span::call_site()); + assert_eq!(format!("{ident}"), "r#proc_macro"); + assert_eq!(format!("{ident:-^14}"), "r#proc_macro"); +} + +#[test] +fn test_debug_ident() { + let ident = Ident::new("proc_macro", Span::call_site()); + let expected = if cfg!(span_locations) { + "Ident { sym: proc_macro }" + } else { + "Ident(proc_macro)" + }; + assert_eq!(expected, format!("{:?}", ident)); + + let ident = Ident::new_raw("proc_macro", Span::call_site()); + let expected = if cfg!(span_locations) { + "Ident { sym: r#proc_macro }" + } else { + "Ident(r#proc_macro)" + }; + assert_eq!(expected, format!("{:?}", ident)); +} + +#[test] +fn test_display_tokenstream() { + let tts = TokenStream::from_str("[a + 1]").unwrap(); + assert_eq!(format!("{tts}"), "[a + 1]"); + assert_eq!(format!("{tts:-^5}"), "[a + 1]"); +} + +#[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..5213b81 --- /dev/null +++ b/vendor/proc-macro2/tests/test_fmt.rs @@ -0,0 +1,26 @@ +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..3361847 --- /dev/null +++ b/vendor/proc-macro2/tests/test_size.rs @@ -0,0 +1,79 @@ +#![allow(unused_attributes)] + +extern crate proc_macro; + +use std::mem; + +#[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); +} + +#[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/pyo3-build-config/.cargo-checksum.json b/vendor/pyo3-build-config/.cargo-checksum.json new file mode 100644 index 0000000..894047c --- /dev/null +++ b/vendor/pyo3-build-config/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo_vcs_info.json":"62631cffb4cec2302abe114e9a2b63fbe62a197585488228d9bfc14310172311","Cargo.lock":"5d1ddc2379c2967275986ca1d92d27f377e197b1bc674a6641489e4d061a4be7","Cargo.toml":"f8dcc21ccccfb2ba65fa980b5d0a24b637eabb1532efceebc29daa667fe04ad3","Cargo.toml.orig":"5a1bac59ad9c6bb92745b5f88087e096931fa4f4915c7a317cf1f84945902960","LICENSE-APACHE":"32c76dbe0e73d79100d5ece77c158399f2e2541bc5c78548a4ba45c1cb53c5c9","LICENSE-MIT":"afcbe3b2e6b37172b5a9ca869ee4c0b8cdc09316e5d4384864154482c33e5af6","src/errors.rs":"64cf02f4dcc9a512bef51e01252f01b24a4d7a147570aa66593112212d7257e9","src/impl_.rs":"3a34d57a0c9ec4d017b9ed08966e1f21b312b32a818a4a44b1ac6b7d836264a6","src/lib.rs":"bc122441147b2e5e3e13bf35e2306ba2b86fd5c7a6a3c1af77b8e7025a63038f"},"package":"f41027e41b4bd03f6e60f9f417fe24a6341a6bb744edd62b6f709f2a52ea30e9"} \ No newline at end of file diff --git a/vendor/pyo3-build-config/.cargo_vcs_info.json b/vendor/pyo3-build-config/.cargo_vcs_info.json new file mode 100644 index 0000000..a461a0e --- /dev/null +++ b/vendor/pyo3-build-config/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "a70d17f898df41b3d1632ee987f624f5222d8d39" + }, + "path_in_vcs": "pyo3-build-config" +} \ No newline at end of file diff --git a/vendor/pyo3-build-config/Cargo.lock b/vendor/pyo3-build-config/Cargo.lock new file mode 100644 index 0000000..327cff8 --- /dev/null +++ b/vendor/pyo3-build-config/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "pyo3-build-config" +version = "0.29.2" +dependencies = [ + "target-lexicon", +] + +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" diff --git a/vendor/pyo3-build-config/Cargo.toml b/vendor/pyo3-build-config/Cargo.toml new file mode 100644 index 0000000..0f2153d --- /dev/null +++ b/vendor/pyo3-build-config/Cargo.toml @@ -0,0 +1,54 @@ +# 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.83" +name = "pyo3-build-config" +version = "0.29.2" +authors = ["PyO3 Project and Contributors "] +build = false +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Build configuration for the PyO3 ecosystem" +homepage = "https://github.com/pyo3/pyo3" +readme = false +keywords = [ + "pyo3", + "python", + "cpython", + "ffi", +] +categories = [ + "api-bindings", + "development-tools::ffi", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/pyo3/pyo3" + +[features] +default = [] +extension-module = [] +generate-import-lib = [] +resolve-config = [] + +[lib] +name = "pyo3_build_config" +path = "src/lib.rs" + +[dependencies.target-lexicon] +version = "0.13.3" + +[build-dependencies.target-lexicon] +version = "0.13.3" diff --git a/vendor/pyo3-build-config/Cargo.toml.orig b/vendor/pyo3-build-config/Cargo.toml.orig new file mode 100644 index 0000000..8258914 --- /dev/null +++ b/vendor/pyo3-build-config/Cargo.toml.orig @@ -0,0 +1,26 @@ +[package] +name = "pyo3-build-config" +version = "0.29.2" +description = "Build configuration for the PyO3 ecosystem" +authors = ["PyO3 Project and Contributors "] +keywords = ["pyo3", "python", "cpython", "ffi"] +homepage = "https://github.com/pyo3/pyo3" +repository = "https://github.com/pyo3/pyo3" +categories = ["api-bindings", "development-tools::ffi"] +license = "MIT OR Apache-2.0" +edition = "2021" +rust-version.workspace = true + +[dependencies] +target-lexicon = "0.13.3" + +[build-dependencies] +target-lexicon = "0.13.3" + +[features] +default = [] + +# deprecated +resolve-config = [] +extension-module = [] +generate-import-lib = [] diff --git a/vendor/pyo3-build-config/LICENSE-APACHE b/vendor/pyo3-build-config/LICENSE-APACHE new file mode 100644 index 0000000..72207b8 --- /dev/null +++ b/vendor/pyo3-build-config/LICENSE-APACHE @@ -0,0 +1,178 @@ +Copyright (c) 2017-present PyO3 Project and Contributors. https://github.com/PyO3 + + 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/pyo3-build-config/LICENSE-MIT b/vendor/pyo3-build-config/LICENSE-MIT new file mode 100644 index 0000000..cd0ad00 --- /dev/null +++ b/vendor/pyo3-build-config/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2023-present PyO3 Project and Contributors. https://github.com/PyO3 + +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/pyo3-build-config/src/errors.rs b/vendor/pyo3-build-config/src/errors.rs new file mode 100644 index 0000000..b11d02f --- /dev/null +++ b/vendor/pyo3-build-config/src/errors.rs @@ -0,0 +1,153 @@ +/// A simple macro for returning an error. Resembles anyhow::bail. +#[macro_export] +#[doc(hidden)] +macro_rules! bail { + ($($args: tt)+) => { return Err(format!($($args)+).into()) }; +} + +/// A simple macro for checking a condition. Resembles anyhow::ensure. +#[macro_export] +#[doc(hidden)] +macro_rules! ensure { + ($condition:expr, $($args: tt)+) => { if !($condition) { bail!($($args)+) } }; +} + +/// Show warning. +#[macro_export] +#[doc(hidden)] +macro_rules! warn { + ($($args: tt)+) => { + println!("{}", $crate::format_warn!($($args)+)) + }; +} + +/// Format warning into string. +#[macro_export] +#[doc(hidden)] +macro_rules! format_warn { + ($($args: tt)+) => { + format!("cargo:warning={}", format_args!($($args)+)) + }; +} + +/// A simple error implementation which allows chaining of errors, inspired somewhat by anyhow. +#[derive(Debug)] +pub struct Error { + value: String, + source: Option>, +} + +/// Error report inspired by +/// +pub struct ErrorReport<'a>(&'a Error); + +impl Error { + pub fn report(&self) -> ErrorReport<'_> { + ErrorReport(self) + } +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.value) + } +} + +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + self.source.as_deref() + } +} + +impl std::fmt::Display for ErrorReport<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use std::error::Error; + self.0.fmt(f)?; + let mut source = self.0.source(); + if source.is_some() { + writeln!(f, "\ncaused by:")?; + let mut index = 0; + while let Some(some_source) = source { + writeln!(f, " - {index}: {some_source}")?; + source = some_source.source(); + index += 1; + } + } + Ok(()) + } +} + +impl From for Error { + fn from(value: String) -> Self { + Self { + value, + source: None, + } + } +} + +impl From<&'_ str> for Error { + fn from(value: &str) -> Self { + value.to_string().into() + } +} + +impl From for Error { + fn from(value: std::convert::Infallible) -> Self { + match value {} + } +} + +pub type Result = std::result::Result; + +pub trait Context { + fn context(self, message: impl Into) -> Result; + fn with_context(self, message: impl FnOnce() -> String) -> Result; +} + +impl Context for Result +where + E: std::error::Error + 'static, +{ + fn context(self, message: impl Into) -> Result { + self.map_err(|error| Error { + value: message.into(), + source: Some(Box::new(error)), + }) + } + + fn with_context(self, message: impl FnOnce() -> String) -> Result { + self.map_err(|error| Error { + value: message(), + source: Some(Box::new(error)), + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn error_report() { + let error: Result<()> = Err(Error::from("there was an internal error")) + .with_context(|| format!("failed to do {}", "something difficult")) + .context("things went wrong"); + + assert_eq!( + error + .unwrap_err() + .report() + .to_string() + .split('\n') + .collect::>(), + vec![ + "things went wrong", + "caused by:", + " - 0: failed to do something difficult", + " - 1: there was an internal error", + "" + ] + ); + } +} diff --git a/vendor/pyo3-build-config/src/impl_.rs b/vendor/pyo3-build-config/src/impl_.rs new file mode 100644 index 0000000..21eefad --- /dev/null +++ b/vendor/pyo3-build-config/src/impl_.rs @@ -0,0 +1,4418 @@ +#[cfg(test)] +use std::cell::RefCell; +use std::{ + collections::{HashMap, HashSet}, + env, + ffi::{OsStr, OsString}, + fmt::Display, + fs::{self, DirEntry}, + io::{BufRead, BufReader, Read, Write}, + path::{Path, PathBuf}, + process::{Command, Stdio}, + str::{self, FromStr}, +}; + +pub use target_lexicon::Triple; + +use target_lexicon::{Architecture, Environment, OperatingSystem, Vendor}; + +use crate::{ + bail, ensure, + errors::{Context, Error, Result}, + warn, +}; + +/// Minimum Python version PyO3 supports. +pub(crate) const MINIMUM_SUPPORTED_VERSION: PythonVersion = PythonVersion { major: 3, minor: 8 }; + +pub(crate) const MINIMUM_SUPPORTED_VERSION_ABI3T: PythonVersion = PythonVersion { + major: 3, + minor: 15, +}; + +/// GraalPy may implement the same CPython version over multiple releases. +const MINIMUM_SUPPORTED_VERSION_GRAALPY: PythonVersion = PythonVersion { + major: 25, + minor: 0, +}; + +/// Maximum Python version that can be used as minimum required Python version with abi3. +pub(crate) const STABLE_ABI_MAX_MINOR: u8 = 15; + +#[cfg(test)] +thread_local! { + static READ_ENV_VARS: RefCell> = const { RefCell::new(Vec::new()) }; +} + +/// Gets an environment variable owned by cargo. +/// +/// Environment variables set by cargo are expected to be valid UTF8. +pub fn cargo_env_var(var: &str) -> Option { + env::var_os(var).map(|os_string| os_string.to_str().unwrap().into()) +} + +/// Gets an external environment variable, and registers the build script to rerun if +/// the variable changes. +pub fn env_var(var: &str) -> Option { + println!("cargo:rerun-if-env-changed={var}"); + #[cfg(test)] + { + READ_ENV_VARS.with(|env_vars| { + env_vars.borrow_mut().push(var.to_owned()); + }); + } + env::var_os(var) +} + +/// Gets the compilation target triple from environment variables set by Cargo. +/// +/// Must be called from a crate build script. +pub fn target_triple_from_env() -> Triple { + env::var("TARGET") + .expect("target_triple_from_env() must be called from a build script") + .parse() + .expect("Unrecognized TARGET environment variable value") +} + +fn sanitize_stable_abi_version( + stable_abi_version: Option, + version: PythonVersion, +) -> Result { + if let Some(min_version) = stable_abi_version { + ensure!( + min_version <= version, + "cannot set a minimum Python version {} higher than the interpreter version {} \ + (the minimum Python version is implied by the abi3-py3{} feature)", + min_version, + version, + min_version.minor + ); + Ok(min_version) + } else { + Ok(version) + } +} + +/// Selects which stable ABI (kind and minimum version) from the `abi3-py3*` +/// and `abi3t-py3*` features (if any) applies to the given interpreter. +/// +/// Interpreters which cannot target the requested stable ABI (e.g. +/// free-threaded CPython before 3.15) get a version-specific build instead. +/// A bare `abi3`/`abi3t` feature request resolves to the interpreter version. +fn applicable_stable_abi( + implementation: PythonImplementation, + version: PythonVersion, + gil_disabled: bool, + abi3_version: Option, + abi3t_version: Option, +) -> Option<(StableAbi, PythonVersion)> { + let exact = |requested: StableAbiVersion| match requested { + StableAbiVersion::Current => version, + StableAbiVersion::Target(target) => target, + }; + let abi3 = abi3_version.map(|v| (StableAbi::Abi3, exact(v))); + let abi3t = abi3t_version.map(|v| (StableAbi::Abi3t, exact(v))); + let selected = if version >= MINIMUM_SUPPORTED_VERSION_ABI3T { + match gil_disabled { + false => abi3t.or(abi3), + true => abi3t, + } + } else { + match gil_disabled { + false => abi3, + true => None, + } + }; + match implementation { + PythonImplementation::PyPy | PythonImplementation::GraalPy => { + selected.map(|(kind, _)| (kind, version)) + } + _ => selected, + } +} + +/// Like [`applicable_stable_abi`], but reads the `abi3-py3*`/`abi3t-py3*` +/// cargo features and keeps the interpreter version rather than the feature +/// minimum, so that `lib_name` matches the real libpython; +/// `apply_build_env` lowers the ABI to the feature minimum afterwards. +fn applicable_stable_abi_at_interpreter_version( + implementation: PythonImplementation, + version: PythonVersion, + gil_disabled: bool, +) -> Option<(StableAbi, PythonVersion)> { + applicable_stable_abi( + implementation, + version, + gil_disabled, + get_abi3_version(), + get_abi3t_version(), + ) + .map(|(kind, _)| (kind, version)) +} + +/// Configuration needed by PyO3 to build for the correct Python implementation. +/// +/// The version and implementation fields correspond to the interpreter +/// used to host a build. These need not be the same as the implementation and +/// version fields set for the build target in the `target_abi` field. +/// +/// Usually this is queried directly from the Python interpreter, or overridden using the +/// `PYO3_CONFIG_FILE` environment variable. +/// +/// When the `PYO3_NO_PYTHON` variable is set, or during cross compile situations, then alternative +/// strategies are used to populate this type. +#[cfg_attr(test, derive(Debug, PartialEq, Eq))] +pub struct InterpreterConfig { + /// The host Python implementation flavor. + /// + /// Serialized to `implementation`. + #[deprecated( + since = "0.29.0", + note = "please use `.implementation()` getter or `InterpreterConfigBuilder` instead" + )] + pub implementation: PythonImplementation, + + /// The host Python `X.Y` version. e.g. `3.9`. + /// + /// Serialized to `version`. + #[deprecated( + since = "0.29.0", + note = "please use `.version()` getter or `InterpreterConfigBuilder` instead" + )] + pub version: PythonVersion, + + /// Whether link library is shared. + /// + /// Serialized to `shared`. + #[deprecated( + since = "0.29.0", + note = "please use `.shared()` getter or `InterpreterConfigBuilder` instead" + )] + pub shared: bool, + + target_abi: PythonAbi, + + /// Serialized to `abi3`. + #[deprecated(since = "0.29.0", note = "please match against target_abi instead")] + pub abi3: bool, + + /// The name of the link library defining Python. + /// + /// This effectively controls the `cargo:rustc-link-lib=` value to + /// control how libpython is linked. Values should not contain the `lib` + /// prefix. + /// + /// Serialized to `lib_name`. + #[deprecated( + since = "0.29.0", + note = "please use `.lib_name()` getter or `InterpreterConfigBuilder` instead" + )] + pub lib_name: Option, + + /// The directory containing the Python library to link against. + /// + /// The effectively controls the `cargo:rustc-link-search=native=` value + /// to add an additional library search path for the linker. + /// + /// Serialized to `lib_dir`. + #[deprecated( + since = "0.29.0", + note = "please use `.lib_dir()` getter or `InterpreterConfigBuilder` instead" + )] + pub lib_dir: Option, + + /// Path of host `python` executable. + /// + /// This is a valid executable capable of running on the host/building machine. + /// For configurations derived by invoking a Python interpreter, it was the + /// executable invoked. + /// + /// Serialized to `executable`. + #[deprecated( + since = "0.29.0", + note = "please use `.executable()` getter or `InterpreterConfigBuilder` instead" + )] + pub executable: Option, + + /// Width in bits of pointers on the target machine. + /// + /// Serialized to `pointer_width`. + #[deprecated( + since = "0.29.0", + note = "please use `.pointer_width()` getter or `InterpreterConfigBuilder` instead" + )] + pub pointer_width: Option, + + /// Additional relevant Python build flags / configuration settings. + /// + /// Serialized to `build_flags`. + #[deprecated( + since = "0.29.0", + note = "please use `.build_flags()` getter or `InterpreterConfigBuilder` instead" + )] + pub build_flags: BuildFlags, + + /// Whether to suppress emitting of `cargo:rustc-link-*` lines from the build script. + /// + /// Typically, `pyo3`'s build script will emit `cargo:rustc-link-lib=` and + /// `cargo:rustc-link-search=` lines derived from other fields in this struct. In + /// advanced building configurations, the default logic to derive these lines may not + /// be sufficient. This field can be set to `Some(true)` to suppress the emission + /// of these lines. + /// + /// If suppression is enabled, `extra_build_script_lines` should contain equivalent + /// functionality or else a build failure is likely. + #[deprecated( + since = "0.29.0", + note = "please use `.suppress_build_script_link_lines()` getter or `InterpreterConfigBuilder` instead" + )] + pub suppress_build_script_link_lines: bool, + + /// Additional lines to `println!()` from Cargo build scripts. + /// + /// This field can be populated to enable the `pyo3` crate to emit additional lines from its + /// its Cargo build script. + /// + /// This crate doesn't populate this field itself. Rather, it is intended to be used with + /// externally provided config files to give them significant control over how the crate + /// is build/configured. + /// + /// Serialized to multiple `extra_build_script_line` values. + #[deprecated( + since = "0.29.0", + note = "please use `.extra_build_script_lines()` getter or `InterpreterConfigBuilder` instead" + )] + pub extra_build_script_lines: Vec, + /// macOS Python3.framework requires special rpath handling + #[deprecated( + since = "0.29.0", + note = "please use `.python_framework_prefix()` getter or `InterpreterConfigBuilder` instead" + )] + pub python_framework_prefix: Option, +} + +// Should no longer be deprecated once the internal fields are private +#[expect(deprecated, reason = "this impl block touches the internal fields")] +impl InterpreterConfig { + /// The Python implementation flavor. + /// + /// Serialized to `implementation`. + pub fn implementation(&self) -> PythonImplementation { + self.implementation + } + + /// Python `X.Y` version. e.g. `3.9`. + /// + /// Serialized to `version`. + pub fn version(&self) -> PythonVersion { + self.version + } + + /// Whether link library is shared. + /// + /// Serialized to `shared`. + pub fn shared(&self) -> bool { + self.shared + } + + /// The ABI to use for the compilation target. + /// See the documentation for the PythonAbi enum for more details. + /// + /// Serialized to `target_abi`. + pub fn target_abi(&self) -> PythonAbi { + self.target_abi + } + + /// Whether linking against the stable/limited Python 3 API. + /// + #[deprecated(since = "0.29.0", note = "please use `target_abi()` instead")] + pub fn abi3(&self) -> bool { + matches!(self.target_abi.kind, PythonAbiKind::Stable(StableAbi::Abi3)) + } + + /// The name of the link library defining Python. + /// + /// This effectively controls the `cargo:rustc-link-lib=` value to + /// control how libpython is linked. Values should not contain the `lib` + /// prefix. + /// + /// Serialized to `lib_name`. + pub fn lib_name(&self) -> Option<&str> { + self.lib_name.as_deref() + } + + /// The directory containing the Python library to link against. + /// + /// The effectively controls the `cargo:rustc-link-search=native=` value + /// to add an additional library search path for the linker. + /// + /// Serialized to `lib_dir`. + pub fn lib_dir(&self) -> Option<&str> { + self.lib_dir.as_deref() + } + + /// Path of host `python` executable. + /// + /// This is a valid executable capable of running on the host/building machine. + /// For configurations derived by invoking a Python interpreter, it was the + /// executable invoked. + /// + /// Serialized to `executable`. + pub fn executable(&self) -> Option<&str> { + self.executable.as_deref() + } + + /// Width in bits of pointers on the target machine. + /// + /// Serialized to `pointer_width`. + pub fn pointer_width(&self) -> Option { + self.pointer_width + } + + /// Additional relevant Python build flags / configuration settings. + /// + /// Serialized to `build_flags`. + pub fn build_flags(&self) -> &BuildFlags { + &self.build_flags + } + + /// Whether to suppress emitting of `cargo:rustc-link-*` lines from the build script. + pub fn suppress_build_script_link_lines(&self) -> bool { + self.suppress_build_script_link_lines + } + + /// Additional lines to `println!()` from Cargo build scripts. + /// + /// Serialized to multiple `extra_build_script_line` values. + pub fn extra_build_script_lines(&self) -> &[String] { + &self.extra_build_script_lines + } + + /// macOS Python3.framework prefix used for special rpath handling. + pub fn python_framework_prefix(&self) -> Option<&str> { + self.python_framework_prefix.as_deref() + } + + #[doc(hidden)] + pub fn build_script_outputs(&self) -> Vec { + // This should have been checked during pyo3-build-config build time. + assert!(self.target_abi.version() >= MINIMUM_SUPPORTED_VERSION); + + let mut out = vec![]; + + for i in MINIMUM_SUPPORTED_VERSION.minor..=self.target_abi.version().minor { + out.push(format!("cargo:rustc-cfg=Py_3_{i}")); + } + + match self.target_abi.implementation() { + PythonImplementation::CPython => {} + PythonImplementation::PyPy => out.push("cargo:rustc-cfg=PyPy".to_owned()), + PythonImplementation::GraalPy => out.push("cargo:rustc-cfg=GraalPy".to_owned()), + PythonImplementation::RustPython => out.push("cargo:rustc-cfg=RustPython".to_owned()), + } + + match self.target_abi.kind() { + PythonAbiKind::Stable(kind) => { + out.push("cargo:rustc-cfg=Py_LIMITED_API".to_owned()); + if kind == StableAbi::Abi3t { + out.push("cargo:rustc-cfg=Py_GIL_DISABLED".to_owned()); + } + } + PythonAbiKind::VersionSpecific(kind) => match kind { + GilUsed::FreeThreaded => { + out.push("cargo:rustc-cfg=Py_GIL_DISABLED".to_owned()); + } + GilUsed::GilEnabled => {} + }, + } + for flag in &self.build_flags.0 { + match flag { + // already handled by target ABI logic above + BuildFlag::Py_GIL_DISABLED => continue, + flag => out.push(format!("cargo:rustc-cfg=py_sys_config=\"{flag}\"")), + } + } + out + } + + fn from_interpreter( + interpreter: impl AsRef, + abi3_version: Option, + abi3t_version: Option, + ) -> Result { + const SCRIPT: &str = r#" +# Allow the script to run on Python 2, so that nicer error can be printed later. +from __future__ import print_function + +import os.path +import platform +import struct +import sys +from sysconfig import get_config_var, get_platform + +PYPY = platform.python_implementation() == "PyPy" +GRAALPY = platform.python_implementation() == "GraalVM" + +if GRAALPY: + graalpy_ver = map(int, __graalpython__.get_graalvm_version().split('.')); + print("graalpy_major", next(graalpy_ver)) + print("graalpy_minor", next(graalpy_ver)) + +# sys.base_prefix is missing on Python versions older than 3.3; this allows the script to continue +# so that the version mismatch can be reported in a nicer way later. +base_prefix = getattr(sys, "base_prefix", None) + +if base_prefix: + # Anaconda based python distributions have a static python executable, but include + # the shared library. Use the shared library for embedding to avoid rust trying to + # LTO the static library (and failing with newer gcc's, because it is old). + ANACONDA = os.path.exists(os.path.join(base_prefix, "conda-meta")) +else: + ANACONDA = False + +def print_if_set(varname, value): + if value is not None: + print(varname, value) + +# Windows always uses shared linking +WINDOWS = platform.system() == "Windows" + +# macOS framework packages use shared linking +FRAMEWORK = bool(get_config_var("PYTHONFRAMEWORK")) +FRAMEWORK_PREFIX = get_config_var("PYTHONFRAMEWORKPREFIX") + +# unix-style shared library enabled +SHARED = bool(get_config_var("Py_ENABLE_SHARED")) + +print("implementation", platform.python_implementation()) +print("version_major", sys.version_info[0]) +print("version_minor", sys.version_info[1]) +print("shared", PYPY or GRAALPY or ANACONDA or WINDOWS or FRAMEWORK or SHARED) +print("python_framework_prefix", FRAMEWORK_PREFIX) +print_if_set("ld_version", get_config_var("LDVERSION")) +print_if_set("libdir", get_config_var("LIBDIR")) +print_if_set("base_prefix", base_prefix) +print("executable", sys.executable) +print("calcsize_pointer", struct.calcsize("P")) +print("mingw", get_platform().startswith("mingw")) +print("cygwin", get_platform().startswith("cygwin")) +print("ext_suffix", get_config_var("EXT_SUFFIX")) +print("gil_disabled", get_config_var("Py_GIL_DISABLED")) +"#; + let output = run_python_script(interpreter.as_ref(), SCRIPT)?; + let map: HashMap = parse_script_output(&output); + + ensure!( + !map.is_empty(), + "broken Python interpreter: {}", + interpreter.as_ref().display() + ); + + if let Some(value) = map.get("graalpy_major") { + let graalpy_version = PythonVersion { + major: value + .parse() + .context("failed to parse GraalPy major version")?, + minor: map["graalpy_minor"] + .parse() + .context("failed to parse GraalPy minor version")?, + }; + ensure!( + graalpy_version >= MINIMUM_SUPPORTED_VERSION_GRAALPY, + "At least GraalPy version {} needed, got {}", + MINIMUM_SUPPORTED_VERSION_GRAALPY, + graalpy_version + ); + }; + + let shared = map["shared"].as_str() == "True"; + let python_framework_prefix = map.get("python_framework_prefix").cloned(); + + let version = PythonVersion { + major: map["version_major"] + .parse() + .context("failed to parse major version")?, + minor: map["version_minor"] + .parse() + .context("failed to parse minor version")?, + }; + + let implementation = map["implementation"].parse()?; + + let gil_disabled = match map["gil_disabled"].as_str() { + "1" => true, + "0" => false, + "None" => false, + _ => panic!("Unknown Py_GIL_DISABLED value"), + }; + + let stable_abi = applicable_stable_abi( + implementation, + version, + gil_disabled, + abi3_version, + abi3t_version, + ); + + let target_abi = + PythonAbi::from_stable_abi(implementation, version, stable_abi, gil_disabled)?; + + let cygwin = map["cygwin"].as_str() == "True"; + + let lib_name = if cfg!(windows) { + default_lib_name_windows( + target_abi, + map["mingw"].as_str() == "True", + // This is the best heuristic currently available to detect debug build + // on Windows from sysconfig - e.g. ext_suffix may be + // `_d.cp312-win_amd64.pyd` for 3.12 debug build + map["ext_suffix"].starts_with("_d."), + )? + } else { + default_lib_name_unix( + target_abi, + cygwin, + map.get("ld_version").map(String::as_str), + )? + }; + + let lib_dir = if cfg!(windows) { + map.get("base_prefix") + .map(|base_prefix| format!("{base_prefix}\\libs")) + } else { + map.get("libdir").cloned() + }; + + // The reason we don't use platform.architecture() here is that it's not + // reliable on macOS. See https://stackoverflow.com/a/1405971/823869. + // Similarly, sys.maxsize is not reliable on Windows. See + // https://stackoverflow.com/questions/1405913/how-do-i-determine-if-my-python-shell-is-executing-in-32bit-or-64bit-mode-on-os/1405971#comment6209952_1405971 + // and https://stackoverflow.com/a/3411134/823869. + let calcsize_pointer: u32 = map["calcsize_pointer"] + .parse() + .context("failed to parse calcsize_pointer")?; + + InterpreterConfigBuilder::new(implementation, version) + .target_abi(target_abi) + .shared(shared) + .lib_name(lib_name) + .lib_dir(lib_dir) + .executable(map["executable"].clone()) + .pointer_width(calcsize_pointer * 8) + .build_flags(BuildFlags::from_interpreter(interpreter)?) + .python_framework_prefix(python_framework_prefix) + .finalize() + } + + /// Generate from parsed sysconfigdata file + /// + /// Use [`parse_sysconfigdata`] to generate a hash map of configuration values which may be + /// used to build an [`InterpreterConfig`]. + pub fn from_sysconfigdata(sysconfigdata: &Sysconfigdata) -> Result { + macro_rules! get_key { + ($sysconfigdata:expr, $key:literal) => { + $sysconfigdata + .get_value($key) + .ok_or(concat!($key, " not found in sysconfigdata file")) + }; + } + + macro_rules! parse_key { + ($sysconfigdata:expr, $key:literal) => { + get_key!($sysconfigdata, $key)? + .parse() + .context(concat!("could not parse value of ", $key)) + }; + } + + let soabi = get_key!(sysconfigdata, "SOABI")?; + let implementation = PythonImplementation::from_soabi(soabi)?; + let version = parse_key!(sysconfigdata, "VERSION")?; + let shared = match sysconfigdata.get_value("Py_ENABLE_SHARED") { + Some("1") | Some("true") | Some("True") => true, + Some("0") | Some("false") | Some("False") => false, + _ => bail!("expected a bool (1/true/True or 0/false/False) for Py_ENABLE_SHARED"), + }; + // macOS framework packages use shared linking (PYTHONFRAMEWORK is the framework name, hence the empty check) + let framework = match sysconfigdata.get_value("PYTHONFRAMEWORK") { + Some(s) => !s.is_empty(), + _ => false, + }; + let python_framework_prefix = sysconfigdata + .get_value("PYTHONFRAMEWORKPREFIX") + .map(str::to_string); + let lib_dir = get_key!(sysconfigdata, "LIBDIR").ok().map(str::to_string); + let gil_disabled = match sysconfigdata.get_value("Py_GIL_DISABLED") { + Some(value) => value == "1", + None => false, + }; + let cygwin = soabi.ends_with("cygwin"); + let stable_abi = + applicable_stable_abi_at_interpreter_version(implementation, version, gil_disabled); + let target_abi = + PythonAbi::from_stable_abi(implementation, version, stable_abi, gil_disabled)?; + let lib_name = + default_lib_name_unix(target_abi, cygwin, sysconfigdata.get_value("LDVERSION"))?; + let pointer_width = parse_key!(sysconfigdata, "SIZEOF_VOID_P") + .map(|bytes_width: u32| bytes_width * 8) + .ok(); + let build_flags = BuildFlags::from_sysconfigdata(sysconfigdata); + + InterpreterConfigBuilder::new(implementation, version) + .target_abi(target_abi) + .shared(shared || framework) + .pointer_width(pointer_width) + .lib_name(lib_name) + .lib_dir(lib_dir) + .python_framework_prefix(python_framework_prefix) + .build_flags(build_flags) + .finalize() + } + + /// Import an externally-provided config file. + /// + /// The `abi3` features, if set, may apply an `abi3` constraint to the Python version. + pub(super) fn from_pyo3_config_file_env(target: &Triple) -> Option> { + env_var("PYO3_CONFIG_FILE").map(|path| { + let path = Path::new(&path); + println!("cargo:rerun-if-changed={}", path.display()); + // Absolute path is necessary because this build script is run with a cwd different to the + // original `cargo build` instruction. + ensure!( + path.is_absolute(), + "PYO3_CONFIG_FILE must be an absolute path" + ); + + let mut config = InterpreterConfig::from_path(path) + .context("failed to parse contents of PYO3_CONFIG_FILE")? + .apply_build_env()?; + + // For config files which don't apply a lib name, apply a default which we can use + // for linking. + if config.lib_name.is_none() { + config.lib_name = Some(default_lib_name_for_target(config.target_abi, target)); + } + + Ok(config) + }) + } + + fn from_path(path: impl AsRef) -> Result { + let path = path.as_ref(); + let config_file = std::fs::File::open(path) + .with_context(|| format!("failed to open PyO3 config file at {}", path.display()))?; + let reader = std::io::BufReader::new(config_file); + InterpreterConfig::from_reader(reader) + } + + /// Environment variable populated via pyo3-ffi's build script + pub(crate) const PYO3_FFI_CONFIG_ENV_VAR: &str = "DEP_PYTHON_PYO3_CONFIG"; + /// Environment variable populated via pyo3's build script by forwarding the value from pyo3-ffi + pub(crate) const PYO3_CONFIG_ENV_VAR: &str = "DEP_PYO3_PYTHON_PYO3_CONFIG"; + + pub(crate) fn from_cargo_dep_env() -> Option> { + cargo_env_var(Self::PYO3_FFI_CONFIG_ENV_VAR) + .or_else(|| cargo_env_var(Self::PYO3_CONFIG_ENV_VAR)) + .map(|buf| InterpreterConfig::from_reader(&*unescape(&buf))) + } + + fn from_reader(reader: impl Read) -> Result { + let reader = BufReader::new(reader); + let lines = reader.lines(); + + macro_rules! parse_value { + ($variable:ident, $value:ident) => { + $variable = Some($value.trim().parse().context(format!( + concat!( + "failed to parse ", + stringify!($variable), + " from config value '{}'" + ), + $value + ))?) + }; + } + + let mut implementation = None; + let mut version = None; + let mut shared = None; + let mut target_abi = None; + // deprecated in the struct but we still allow it to support old config files + let mut abi3 = None; + let mut lib_name = None; + let mut lib_dir = None; + let mut executable = None; + let mut pointer_width = None; + let mut build_flags: Option = None; + let mut suppress_build_script_link_lines: Option = None; + let mut extra_build_script_lines = vec![]; + let mut python_framework_prefix = None; + + for (i, line) in lines.enumerate() { + let line = line.context("failed to read line from config")?; + let mut split = line.splitn(2, '='); + let (key, value) = ( + split + .next() + .expect("first splitn value should always be present"), + split + .next() + .ok_or_else(|| format!("expected key=value pair on line {}", i + 1))?, + ); + match key { + "implementation" => parse_value!(implementation, value), + "version" => parse_value!(version, value), + "shared" => parse_value!(shared, value), + "target_abi" => parse_value!(target_abi, value), + "abi3" => parse_value!(abi3, value), + "lib_name" => parse_value!(lib_name, value), + "lib_dir" => parse_value!(lib_dir, value), + "executable" => parse_value!(executable, value), + "pointer_width" => parse_value!(pointer_width, value), + "build_flags" => parse_value!(build_flags, value), + "suppress_build_script_link_lines" => { + parse_value!(suppress_build_script_link_lines, value) + } + "extra_build_script_line" => { + extra_build_script_lines.push(value.to_string()); + } + "python_framework_prefix" => parse_value!(python_framework_prefix, value), + unknown => warn!("unknown config key `{}`", unknown), + } + } + + let version = version.ok_or("missing value for version")?; + let implementation = implementation.unwrap_or(PythonImplementation::CPython); + let flags_contains_free_threaded = if let Some(ref flags) = build_flags { + flags.0.contains(&BuildFlag::Py_GIL_DISABLED) + } else { + false + }; + let target_abi = if let Some(target_abi) = target_abi { + ensure!( + abi3.is_none(), + "Invalid config that sets both target_abi and abi3." + ); + target_abi + } else if flags_contains_free_threaded { + // This fires even if is_abi3() is True for backward compatibility reasons + PythonAbiBuilder::new(implementation, version) + .free_threaded() + .finalize()? + } else if abi3 == Some(true) { + warn!("abi3 configuration file option is deprecated since pyo3 0.29, set target_abi instead"); + PythonAbiBuilder::new(implementation, version) + .stable_abi(StableAbi::Abi3) + .finalize()? + } else { + PythonAbiBuilder::new(implementation, version).finalize()? + }; + + let builder = InterpreterConfigBuilder::new(implementation, version) + .target_abi(target_abi) + .shared(shared.unwrap_or(true)) + .lib_name(lib_name) + .lib_dir(lib_dir) + .executable(executable) + .pointer_width(pointer_width) + .build_flags(build_flags.unwrap_or_default()) + .suppress_build_script_link_lines(suppress_build_script_link_lines.unwrap_or(false)) + .extra_build_script_lines(extra_build_script_lines) + .python_framework_prefix(python_framework_prefix); + + builder.finalize() + } + + #[doc(hidden)] + /// Serialize the `InterpreterConfig` and print it to the environment for Cargo to pass along + /// to dependent packages during build time. + /// + /// NB: writing to the cargo environment requires the + /// [`links`](https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key) + /// manifest key to be set. In this case that means this is called by the `pyo3-ffi` crate and + /// available for dependent package build scripts in `DEP_PYTHON_PYO3_CONFIG`. See + /// documentation for the + /// [`DEP__`](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts) + /// environment variable. + pub fn to_cargo_dep_env(&self) -> Result<()> { + let mut buf = Vec::new(); + self.to_writer(&mut buf)?; + // escape newlines in env var + println!("cargo:PYO3_CONFIG={}", escape(&buf)); + Ok(()) + } + + #[doc(hidden)] + pub fn to_writer(&self, mut writer: impl Write) -> Result<()> { + macro_rules! write_line { + ($value:ident) => { + writeln!(writer, "{}={}", stringify!($value), self.$value).context(concat!( + "failed to write ", + stringify!($value), + " to config" + )) + }; + } + + macro_rules! write_option_line { + ($value:ident) => { + if let Some(value) = &self.$value { + writeln!(writer, "{}={}", stringify!($value), value).context(concat!( + "failed to write ", + stringify!($value), + " to config" + )) + } else { + Ok(()) + } + }; + } + + write_line!(implementation)?; + write_line!(version)?; + write_line!(shared)?; + write_line!(target_abi)?; + write_option_line!(lib_name)?; + write_option_line!(lib_dir)?; + write_option_line!(executable)?; + write_option_line!(pointer_width)?; + write_line!(build_flags)?; + write_option_line!(python_framework_prefix)?; + write_line!(suppress_build_script_link_lines)?; + for line in &self.extra_build_script_lines { + writeln!(writer, "extra_build_script_line={line}") + .context("failed to write extra_build_script_line")?; + } + Ok(()) + } + + /// Run a python script using the [`InterpreterConfig::executable`]. + /// + /// # Panics + /// + /// This function will panic if the [`executable`](InterpreterConfig::executable) is `None`. + pub fn run_python_script(&self, script: &str) -> Result { + run_python_script_with_envs( + Path::new(self.executable.as_ref().expect("no interpreter executable")), + script, + std::iter::empty::<(&str, &str)>(), + ) + } + + /// Run a python script using the [`InterpreterConfig::executable`] with additional + /// environment variables (e.g. PYTHONPATH) set. + /// + /// # Panics + /// + /// This function will panic if the [`executable`](InterpreterConfig::executable) is `None`. + pub fn run_python_script_with_envs(&self, script: &str, envs: I) -> Result + where + I: IntoIterator, + K: AsRef, + V: AsRef, + { + run_python_script_with_envs( + Path::new(self.executable.as_ref().expect("no interpreter executable")), + script, + envs, + ) + } + + pub fn is_free_threaded(&self) -> bool { + self.target_abi.kind().is_free_threaded() + } + + fn apply_build_env(mut self) -> Result { + // the host `implementation` may differ from the `target_abi` + // implementation; the recomputed ABI must stay on the target + let implementation = self.target_abi.implementation; + let gil_disabled = self.target_abi.kind().is_free_threaded(); + let stable_abi = applicable_stable_abi( + implementation, + self.version, + gil_disabled, + get_abi3_version(), + get_abi3t_version(), + ); + self.target_abi = + PythonAbi::from_stable_abi(implementation, self.version, stable_abi, gil_disabled)?; + Ok(self) + } +} + +#[cfg_attr(test, derive(Debug))] +pub struct PythonAbiBuilder { + implementation: PythonImplementation, + version: PythonVersion, + kind: Option, +} + +impl PythonAbiBuilder { + pub fn new(implementation: PythonImplementation, version: PythonVersion) -> PythonAbiBuilder { + PythonAbiBuilder { + implementation, + version, + kind: None, + } + } + + pub fn stable_abi(self, kind: StableAbi) -> PythonAbiBuilder { + let mut build_version = self.version; + if self.version.minor > STABLE_ABI_MAX_MINOR { + warn!("Automatically falling back to {kind}-py3{STABLE_ABI_MAX_MINOR} because current Python is higher than the maximum supported"); + build_version.minor = STABLE_ABI_MAX_MINOR; + } + + PythonAbiBuilder { + kind: Some(PythonAbiKind::Stable(kind)), + version: build_version, + ..self + } + } + + pub fn free_threaded(self) -> PythonAbiBuilder { + PythonAbiBuilder { + kind: Some(PythonAbiKind::VersionSpecific(GilUsed::FreeThreaded)), + ..self + } + } + + pub fn finalize(self) -> Result { + // default to GIL-enabled version-specific ABI + let kind = self.kind.unwrap_or(match self.implementation { + PythonImplementation::RustPython => PythonAbiKind::Stable(StableAbi::Abi3t), + _ => PythonAbiKind::VersionSpecific(GilUsed::GilEnabled), + }); + if matches!(self.implementation, PythonImplementation::RustPython) { + ensure!(matches!(kind, PythonAbiKind::Stable(StableAbi::Abi3t)), + "RustPython only supports targeting abi3t, it does not allow targeting other Python ABIs. Currently targeting '{kind}'") + } + if matches!(kind, PythonAbiKind::VersionSpecific(GilUsed::FreeThreaded)) + && self.version + < (PythonVersion { + major: 3, + minor: 13, + }) + { + bail!( + "Cannot target free-threaded builds for Python versions before 3.13, tried to build for {}", self.version + ) + } + Ok(PythonAbi { + implementation: self.implementation, + kind, + version: self.version, + }) + } +} + +#[non_exhaustive] +#[derive(Copy, Clone, PartialEq, Eq)] +#[cfg_attr(test, derive(Debug))] +pub struct PythonAbi { + implementation: PythonImplementation, + kind: PythonAbiKind, + version: PythonVersion, +} + +impl Display for PythonAbi { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}-{}-{}", self.implementation, self.kind, self.version) + } +} + +impl FromStr for PythonAbi { + type Err = crate::errors::Error; + + fn from_str(value: &str) -> Result { + let mut parts = value.splitn(3, '-'); + Ok(PythonAbi { + implementation: parts + .next() + .ok_or_else(|| format!("Invalid ABI string representation: {value}"))? + .parse()?, + kind: parts + .next() + .ok_or_else(|| format!("Invalid ABI string representation: {value}"))? + .parse()?, + version: parts + .next() + .ok_or_else(|| format!("Invalid ABI string representation: {value}"))? + .parse()?, + }) + } +} + +impl PythonAbi { + /// Constructs the ABI to target for an interpreter of `version`, given the + /// stable ABI kind and minimum Python version to target, if any. + /// + /// Callers decide whether a stable ABI applies to the interpreter; this + /// does not consult the `abi3`/`abi3t` cargo features. The minimum version + /// must not exceed the interpreter version. Without a stable ABI the + /// result is version-specific, free-threaded when `gil_disabled` is set. + fn from_stable_abi( + implementation: PythonImplementation, + version: PythonVersion, + stable_abi: Option<(StableAbi, PythonVersion)>, + gil_disabled: bool, + ) -> Result { + let builder = match stable_abi { + Some((kind, min_version)) => { + ensure!( + min_version <= version, + "cannot set a minimum Python version {} higher than the interpreter version {} \ + (the minimum Python version is implied by the {}-py3{} feature)", + min_version, + version, + kind, + min_version.minor + ); + PythonAbiBuilder::new(implementation, min_version).stable_abi(kind) + } + None if gil_disabled => PythonAbiBuilder::new(implementation, version).free_threaded(), + None => PythonAbiBuilder::new(implementation, version), + }; + builder.finalize() + } + + pub fn from_build_env( + implementation: PythonImplementation, + version: PythonVersion, + stable_abi_version: Option, + gil_disabled: bool, + ) -> Result { + let builder = PythonAbiBuilder { + implementation, + version: sanitize_stable_abi_version(stable_abi_version, version)?, + kind: None, + }; + let builder = if get_abi3t_version().is_some() && version >= MINIMUM_SUPPORTED_VERSION_ABI3T + { + builder.stable_abi(StableAbi::Abi3t) + } else if get_abi3_version().is_some() && !gil_disabled { + builder.stable_abi(StableAbi::Abi3) + } else if gil_disabled { + builder.free_threaded() + } else { + builder + }; + builder.finalize() + } + + /// The Python implementation flavor. + /// + /// Serialized to `implementation`. + pub fn implementation(&self) -> PythonImplementation { + self.implementation + } + + /// The ABI flavor + /// + /// Serialized to `kind` + pub fn kind(&self) -> PythonAbiKind { + self.kind + } + + /// Python `X.Y` version. e.g. `3.9`. + /// + /// Serialized to `version`. + pub fn version(&self) -> PythonVersion { + self.version + } +} + +/// The "kind" of ABI. +/// +/// Either a variety of stable ABI or a GIL-enabled or free-threaded +/// version-specific ABI. +#[derive(Clone, Copy, PartialEq, Eq)] +#[cfg_attr(test, derive(Debug))] +pub enum PythonAbiKind { + /// One of the stable ABIs, which supports multiple Python versions + Stable(StableAbi), + /// Version specific ABI, which is different on the free-threaded build + VersionSpecific(GilUsed), +} + +impl Display for PythonAbiKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + PythonAbiKind::Stable(stable_abi) => write!(f, "{stable_abi}"), + PythonAbiKind::VersionSpecific(gil_used) => { + write!(f, "{gil_used}") + } + } + } +} + +impl FromStr for PythonAbiKind { + type Err = crate::errors::Error; + + fn from_str(value: &str) -> Result { + match value { + "abi3" => Ok(PythonAbiKind::Stable(StableAbi::Abi3)), + "abi3t" => Ok(PythonAbiKind::Stable(StableAbi::Abi3t)), + "free_threaded" => Ok(PythonAbiKind::VersionSpecific(GilUsed::FreeThreaded)), + "gil_enabled" => Ok(PythonAbiKind::VersionSpecific(GilUsed::GilEnabled)), + _ => Err(format!("Unrecognized ABI name: {value}").into()), + } + } +} + +impl PythonAbiKind { + pub fn is_free_threaded(self) -> bool { + match self { + PythonAbiKind::VersionSpecific(gil_disabled) => gil_disabled == GilUsed::FreeThreaded, + PythonAbiKind::Stable(StableAbi::Abi3) => false, + PythonAbiKind::Stable(StableAbi::Abi3t) => true, + } + } +} + +/// The variety of stable ABI +#[derive(Clone, Copy, PartialEq, Eq)] +#[cfg_attr(test, derive(Debug))] +pub enum StableAbi { + /// The original stable ABI, supporting Python 3.2 and up + Abi3, + /// The free-threaded stable ABI, supporting Python 3.15 and up + Abi3t, +} + +impl Display for StableAbi { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + StableAbi::Abi3 => write!(f, "abi3"), + StableAbi::Abi3t => write!(f, "abi3t"), + } + } +} + +/// Whether the ABI is for the GIL-enabled or free-threaded build. +#[derive(Clone, Copy, PartialEq, Eq)] +#[cfg_attr(test, derive(Debug))] +pub enum GilUsed { + /// The original PyObject layout + GilEnabled, + /// The free-threaded PyObject layout + FreeThreaded, +} + +impl Display for GilUsed { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + GilUsed::GilEnabled => write!(f, "gil_enabled"), + GilUsed::FreeThreaded => write!(f, "free_threaded"), + } + } +} + +#[cfg_attr(test, derive(Debug))] +pub struct InterpreterConfigBuilder { + implementation: PythonImplementation, + version: PythonVersion, + shared: bool, + target_abi: Option, + lib_name: Option, + lib_dir: Option, + executable: Option, + pointer_width: Option, + build_flags: BuildFlags, + suppress_build_script_link_lines: bool, + extra_build_script_lines: Vec, + python_framework_prefix: Option, +} + +impl InterpreterConfigBuilder { + pub fn new( + implementation: PythonImplementation, + version: PythonVersion, + ) -> InterpreterConfigBuilder { + InterpreterConfigBuilder { + implementation, + version, + shared: true, + target_abi: None, + lib_name: None, + lib_dir: None, + executable: None, + pointer_width: None, + build_flags: BuildFlags::default(), + suppress_build_script_link_lines: false, + extra_build_script_lines: vec![], + python_framework_prefix: None, + } + } + + pub fn target_abi(self, target_abi: PythonAbi) -> InterpreterConfigBuilder { + InterpreterConfigBuilder { + target_abi: Some(target_abi), + ..self + } + } + + pub fn stable_abi(self, kind: StableAbi) -> InterpreterConfigBuilder { + let implementation = self.implementation; + let version = self.version; + self.target_abi( + PythonAbiBuilder::new(implementation, version) + .stable_abi(kind) + .finalize() + // Cannot panic + .unwrap(), + ) + } + + pub fn free_threaded(self) -> Result { + let implementation = self.implementation; + let version = self.version; + Ok(self.target_abi( + PythonAbiBuilder::new(implementation, version) + .free_threaded() + .finalize()?, + )) + } + + pub fn lib_name(mut self, lib_name: impl Into>) -> InterpreterConfigBuilder { + self.lib_name = lib_name.into(); + self + } + + pub fn pointer_width( + mut self, + pointer_width: impl Into>, + ) -> InterpreterConfigBuilder { + self.pointer_width = pointer_width.into(); + self + } + + pub fn executable(mut self, executable: impl Into>) -> InterpreterConfigBuilder { + self.executable = executable.into(); + self + } + + pub fn suppress_build_script_link_lines( + mut self, + suppress_build_script_link_lines: bool, + ) -> InterpreterConfigBuilder { + self.suppress_build_script_link_lines = suppress_build_script_link_lines; + self + } + + pub fn extra_build_script_lines( + mut self, + extra_build_script_lines: Vec, + ) -> InterpreterConfigBuilder { + self.extra_build_script_lines = extra_build_script_lines; + self + } + + pub fn lib_dir(mut self, lib_dir: impl Into>) -> InterpreterConfigBuilder { + self.lib_dir = lib_dir.into(); + self + } + + pub fn shared(mut self, shared: bool) -> InterpreterConfigBuilder { + self.shared = shared; + self + } + + pub fn build_flags(mut self, build_flags: BuildFlags) -> InterpreterConfigBuilder { + self.build_flags = build_flags; + self + } + + pub fn python_framework_prefix( + mut self, + python_framework_prefix: impl Into>, + ) -> InterpreterConfigBuilder { + self.python_framework_prefix = python_framework_prefix.into(); + self + } + + pub fn finalize(self) -> Result { + let mut build_flags = self.build_flags.clone(); + let py_gil_disabled = build_flags.0.contains(&BuildFlag::Py_GIL_DISABLED); + let target_abi = match (self.target_abi, py_gil_disabled) { + // No target ABI set, no Py_GIL_DISABLED: default to GIL-enabled version-specific. + (None, false) => PythonAbiBuilder::new(self.implementation, self.version).finalize()?, + // No target ABI set, Py_GIL_DISABLED in build flags: infer free-threaded. + (None, true) => PythonAbiBuilder::new(self.implementation, self.version) + .free_threaded() + .finalize()?, + // Target ABI set, no Py_GIL_DISABLED: use as-is. + (Some(target_abi), false) => target_abi, + // Target ABI set + Py_GIL_DISABLED: reconcile. + (Some(target_abi), true) => match target_abi.kind() { + // abi3 + Py_GIL_DISABLED: the abi3 feature is a no-op on free-threaded + // interpreters, so for backward compatibility fall back to a free-threaded + // version-specific build. + PythonAbiKind::Stable(StableAbi::Abi3) => { + let new_abi = + PythonAbiBuilder::new(target_abi.implementation(), target_abi.version()) + .free_threaded() + .finalize()?; + warn!( + "Targeting an abi3 build but build_flags contains Py_GIL_DISABLED, \ + falling back to a version-specific free-threaded build" + ); + new_abi + } + // GIL-enabled version-specific + Py_GIL_DISABLED is contradictory. + PythonAbiKind::VersionSpecific(GilUsed::GilEnabled) => bail!( + "build_flags contains Py_GIL_DISABLED but target_abi \ + '{target_abi}' is not free-threaded" + ), + // Already free-threaded (Stable(Abi3t) or VersionSpecific(FreeThreaded)). + _ => target_abi, + }, + }; + if target_abi.kind().is_free_threaded() { + build_flags.0.insert(BuildFlag::Py_GIL_DISABLED); + } + #[expect( + deprecated, + reason = "constructing an InterpreterConfig directly, need to write to fields" + )] + Ok(InterpreterConfig { + implementation: self.implementation, + version: self.version, + shared: self.shared, + target_abi, + abi3: matches!(target_abi.kind(), PythonAbiKind::Stable(StableAbi::Abi3)), + lib_name: self.lib_name, + lib_dir: self.lib_dir, + executable: self.executable, + pointer_width: self.pointer_width, + build_flags, + suppress_build_script_link_lines: self.suppress_build_script_link_lines, + extra_build_script_lines: self.extra_build_script_lines, + python_framework_prefix: self.python_framework_prefix, + }) + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct PythonVersion { + pub major: u8, + pub minor: u8, +} + +impl PythonVersion { + #[cfg(test)] + pub(crate) const PY315: Self = PythonVersion { + major: 3, + minor: 15, + }; + #[cfg(test)] + pub(crate) const PY314: Self = PythonVersion { + major: 3, + minor: 14, + }; + #[deprecated( + since = "0.29.0", + note = "please construct `PythonVersion` directly rather than use these constants" + )] + pub const PY313: Self = PythonVersion { + major: 3, + minor: 13, + }; + #[deprecated( + since = "0.29.0", + note = "please construct `PythonVersion` directly rather than use these constants" + )] + pub const PY312: Self = PythonVersion { + major: 3, + minor: 12, + }; + #[cfg(test)] + const PY311: Self = PythonVersion { + major: 3, + minor: 11, + }; + const PY310: Self = PythonVersion { + major: 3, + minor: 10, + }; + #[cfg(test)] + const PY39: Self = PythonVersion { major: 3, minor: 9 }; + #[cfg(test)] + const PY38: Self = PythonVersion { major: 3, minor: 8 }; +} + +impl Display for PythonVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}.{}", self.major, self.minor) + } +} + +impl FromStr for PythonVersion { + type Err = crate::errors::Error; + + fn from_str(value: &str) -> Result { + let mut split = value.splitn(2, '.'); + let (major, minor) = ( + split + .next() + .expect("first splitn value should always be present"), + split.next().ok_or("expected major.minor version")?, + ); + Ok(Self { + major: major.parse().context("failed to parse major version")?, + minor: minor.parse().context("failed to parse minor version")?, + }) + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum PythonImplementation { + CPython, + PyPy, + GraalPy, + RustPython, +} + +impl PythonImplementation { + fn is_pypy(self) -> bool { + self == PythonImplementation::PyPy + } + + fn from_soabi(soabi: &str) -> Result { + if soabi.starts_with("pypy") { + Ok(PythonImplementation::PyPy) + } else if soabi.starts_with("cpython") { + Ok(PythonImplementation::CPython) + } else if soabi.starts_with("graalpy") { + Ok(PythonImplementation::GraalPy) + } else { + bail!("unsupported Python interpreter"); + } + } +} + +impl Display for PythonImplementation { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + PythonImplementation::CPython => write!(f, "CPython"), + PythonImplementation::PyPy => write!(f, "PyPy"), + PythonImplementation::GraalPy => write!(f, "GraalVM"), + PythonImplementation::RustPython => write!(f, "RustPython"), + } + } +} + +impl FromStr for PythonImplementation { + type Err = Error; + fn from_str(s: &str) -> Result { + match s { + "CPython" => Ok(PythonImplementation::CPython), + "PyPy" => Ok(PythonImplementation::PyPy), + "GraalVM" => Ok(PythonImplementation::GraalPy), + "RustPython" => Ok(PythonImplementation::RustPython), + _ => bail!("unknown interpreter: {}", s), + } + } +} + +/// Checks if we should look for a Python interpreter installation +/// to get the target interpreter configuration. +/// +/// Returns `false` if `PYO3_NO_PYTHON` environment variable is set. +fn have_python_interpreter() -> bool { + env_var("PYO3_NO_PYTHON").is_none() +} + +/// The target stable ABI version. +/// +/// For abi3(t)-py* builds a specific version is chosen, otherwise the builds is +/// for the stable ABI exposed by the host python interpreter version. +#[derive(Debug, Copy, Clone)] +pub enum StableAbiVersion { + Current, + Target(PythonVersion), +} + +/// Gets the minimum supported Python version from PyO3 `abi3-py*` features. +/// +/// Must be called from a PyO3 crate build script. Returns None if an `abi3-py*` +/// feature is activated that is unsupported or if no `abi3-py3*` feature is +/// active. +pub fn get_abi3_version() -> Option { + let minor_version = (MINIMUM_SUPPORTED_VERSION.minor..=STABLE_ABI_MAX_MINOR) + .find(|i| cargo_env_var(&format!("CARGO_FEATURE_ABI3_PY3{i}")).is_some()); + minor_version.map_or( + if cargo_env_var("CARGO_FEATURE_ABI3").is_some() { + Some(StableAbiVersion::Current) + } else { + None + }, + |minor| Some(StableAbiVersion::Target(PythonVersion { major: 3, minor })), + ) +} + +/// Gets the minimum supported Python version from PyO3 `abi3t-py*` features. +/// +/// Must be called from a PyO3 crate build script. Returns None if an `abi3t-py*` +/// feature is activated that is unsupported or if no `abi3t-py3*` feature is +/// active. +pub fn get_abi3t_version() -> Option { + let minor_version = (MINIMUM_SUPPORTED_VERSION_ABI3T.minor..=STABLE_ABI_MAX_MINOR) + .find(|i| cargo_env_var(&format!("CARGO_FEATURE_ABI3T_PY3{i}")).is_some()); + minor_version.map_or( + if cargo_env_var("CARGO_FEATURE_ABI3T").is_some() { + Some(StableAbiVersion::Current) + } else { + None + }, + |minor| Some(StableAbiVersion::Target(PythonVersion { major: 3, minor })), + ) +} + +/// Checks if the `extension-module` feature is enabled for the PyO3 crate. +/// +/// This can be triggered either by: +/// - The `extension-module` Cargo feature (deprecated) +/// - Setting the `PYO3_BUILD_EXTENSION_MODULE` environment variable +/// +/// Must be called from a PyO3 crate build script. +pub fn is_extension_module() -> bool { + cargo_env_var("CARGO_FEATURE_EXTENSION_MODULE").is_some() + || env_var("PYO3_BUILD_EXTENSION_MODULE").is_some() +} + +/// Checks if we need to link to `libpython` for the target. +/// +/// Must be called from a PyO3 crate build script. +pub fn is_linking_libpython_for_target(target: &Triple) -> bool { + target.operating_system == OperatingSystem::Windows + // See https://github.com/PyO3/pyo3/issues/4068#issuecomment-2051159852 + || target.operating_system == OperatingSystem::Aix + || target.environment == Environment::Android + || target.environment == Environment::Androideabi + || target.operating_system == OperatingSystem::Cygwin + || matches!(target.operating_system, OperatingSystem::IOS(_)) + || !is_extension_module() +} + +/// Checks if we need to discover the Python library directory +/// to link the extension module binary. +/// +/// Must be called from a PyO3 crate build script. +fn require_libdir_for_target(target: &Triple) -> bool { + // With raw-dylib, Windows targets never need a lib dir — the compiler generates + // import entries directly from `#[link(kind = "raw-dylib")]` attributes. + if target.operating_system == OperatingSystem::Windows { + return false; + } + + is_linking_libpython_for_target(target) +} + +/// Configuration needed by PyO3 to cross-compile for a target platform. +/// +/// Usually this is collected from the environment (i.e. `PYO3_CROSS_*` and `CARGO_CFG_TARGET_*`) +/// when a cross-compilation configuration is detected. +#[derive(Debug, PartialEq, Eq)] +pub struct CrossCompileConfig { + /// The directory containing the Python library to link against. + pub lib_dir: Option, + + /// The version of the Python library to link against. + version: Option, + + /// The target Python implementation hint (CPython, PyPy, GraalPy, ...) + implementation: Option, + + /// The compile target triple (e.g. aarch64-unknown-linux-gnu) + target: Triple, + + /// Python ABI flags, used to detect free-threaded Python builds. + abiflags: Option, +} + +impl CrossCompileConfig { + /// Creates a new cross compile config struct from PyO3 environment variables + /// and the build environment when cross compilation mode is detected. + /// + /// Returns `None` when not cross compiling. + fn try_from_env_vars_host_target( + env_vars: CrossCompileEnvVars, + host: &Triple, + target: &Triple, + ) -> Result> { + if env_vars.any() || Self::is_cross_compiling_from_to(host, target) { + let lib_dir = env_vars.lib_dir_path()?; + let (version, abiflags) = env_vars.parse_version()?; + let implementation = env_vars.parse_implementation()?; + let target = target.clone(); + + Ok(Some(CrossCompileConfig { + lib_dir, + version, + implementation, + target, + abiflags, + })) + } else { + Ok(None) + } + } + + /// Checks if compiling on `host` for `target` required "real" cross compilation. + /// + /// Returns `false` if the target Python interpreter can run on the host. + fn is_cross_compiling_from_to(host: &Triple, target: &Triple) -> bool { + // Not cross-compiling if arch-vendor-os is all the same + // e.g. x86_64-unknown-linux-musl on x86_64-unknown-linux-gnu host + // x86_64-pc-windows-gnu on x86_64-pc-windows-msvc host + let mut compatible = host.architecture == target.architecture + && (host.vendor == target.vendor + // Don't treat `-pc-` to `-win7-` as cross-compiling + || (host.vendor == Vendor::Pc && target.vendor.as_str() == "win7")) + && host.operating_system == target.operating_system; + + // Not cross-compiling to compile for 32-bit Python from windows 64-bit + compatible |= target.operating_system == OperatingSystem::Windows + && host.operating_system == OperatingSystem::Windows + && matches!(target.architecture, Architecture::X86_32(_)) + && host.architecture == Architecture::X86_64; + + // Not cross-compiling to compile for x86-64 Python from macOS arm64 and vice versa + compatible |= matches!(target.operating_system, OperatingSystem::Darwin(_)) + && matches!(host.operating_system, OperatingSystem::Darwin(_)); + + compatible |= matches!(target.operating_system, OperatingSystem::IOS(_)); + + !compatible + } + + /// Converts `lib_dir` member field to an UTF-8 string. + /// + /// The conversion can not fail because `PYO3_CROSS_LIB_DIR` variable + /// is ensured contain a valid UTF-8 string. + fn lib_dir_string(&self) -> Option { + self.lib_dir + .as_ref() + .map(|s| s.to_str().unwrap().to_owned()) + } +} + +/// PyO3-specific cross compile environment variable values +struct CrossCompileEnvVars { + /// `PYO3_CROSS` + pyo3_cross: Option, + /// `PYO3_CROSS_LIB_DIR` + pyo3_cross_lib_dir: Option, + /// `PYO3_CROSS_PYTHON_VERSION` + pyo3_cross_python_version: Option, + /// `PYO3_CROSS_PYTHON_IMPLEMENTATION` + pyo3_cross_python_implementation: Option, +} + +impl CrossCompileEnvVars { + /// Grabs the PyO3 cross-compile variables from the environment. + /// + /// Registers the build script to rerun if any of the variables changes. + fn from_env() -> Self { + CrossCompileEnvVars { + pyo3_cross: env_var("PYO3_CROSS"), + pyo3_cross_lib_dir: env_var("PYO3_CROSS_LIB_DIR"), + pyo3_cross_python_version: env_var("PYO3_CROSS_PYTHON_VERSION"), + pyo3_cross_python_implementation: env_var("PYO3_CROSS_PYTHON_IMPLEMENTATION"), + } + } + + /// Checks if any of the variables is set. + fn any(&self) -> bool { + self.pyo3_cross.is_some() + || self.pyo3_cross_lib_dir.is_some() + || self.pyo3_cross_python_version.is_some() + || self.pyo3_cross_python_implementation.is_some() + } + + /// Parses `PYO3_CROSS_PYTHON_VERSION` environment variable value + /// into `PythonVersion` and ABI flags. + fn parse_version(&self) -> Result<(Option, Option)> { + match self.pyo3_cross_python_version.as_ref() { + Some(os_string) => { + let utf8_str = os_string + .to_str() + .ok_or("PYO3_CROSS_PYTHON_VERSION is not valid a UTF-8 string")?; + let (utf8_str, abiflags) = if let Some(version) = utf8_str.strip_suffix('t') { + (version, Some("t".to_string())) + } else { + (utf8_str, None) + }; + let version = utf8_str + .parse() + .context("failed to parse PYO3_CROSS_PYTHON_VERSION")?; + Ok((Some(version), abiflags)) + } + None => Ok((None, None)), + } + } + + /// Parses `PYO3_CROSS_PYTHON_IMPLEMENTATION` environment variable value + /// into `PythonImplementation`. + fn parse_implementation(&self) -> Result> { + let implementation = self + .pyo3_cross_python_implementation + .as_ref() + .map(|os_string| { + let utf8_str = os_string + .to_str() + .ok_or("PYO3_CROSS_PYTHON_IMPLEMENTATION is not valid a UTF-8 string")?; + utf8_str + .parse() + .context("failed to parse PYO3_CROSS_PYTHON_IMPLEMENTATION") + }) + .transpose()?; + + Ok(implementation) + } + + /// Converts the stored `PYO3_CROSS_LIB_DIR` variable value (if any) + /// into a `PathBuf` instance. + /// + /// Ensures that the path is a valid UTF-8 string. + fn lib_dir_path(&self) -> Result> { + let lib_dir = self.pyo3_cross_lib_dir.as_ref().map(PathBuf::from); + + if let Some(dir) = lib_dir.as_ref() { + ensure!( + dir.to_str().is_some(), + "PYO3_CROSS_LIB_DIR variable value is not a valid UTF-8 string" + ); + } + + Ok(lib_dir) + } +} + +/// Detect whether we are cross compiling and return an assembled CrossCompileConfig if so. +/// +/// This function relies on PyO3 cross-compiling environment variables: +/// +/// * `PYO3_CROSS`: If present, forces PyO3 to configure as a cross-compilation. +/// * `PYO3_CROSS_LIB_DIR`: If present, must be set to the directory containing +/// the target's libpython DSO and the associated `_sysconfigdata*.py` file for +/// Unix-like targets, or the Python DLL import libraries for the Windows target. +/// * `PYO3_CROSS_PYTHON_VERSION`: Major and minor version (e.g. 3.9) of the target Python +/// installation. This variable is only needed if PyO3 cannot determine the version to target +/// from `abi3-py3*` features, or if there are multiple versions of Python present in +/// `PYO3_CROSS_LIB_DIR`. +/// +/// See the [PyO3 User Guide](https://pyo3.rs/) for more info on cross-compiling. +pub fn cross_compiling_from_to( + host: &Triple, + target: &Triple, +) -> Result> { + let env_vars = CrossCompileEnvVars::from_env(); + CrossCompileConfig::try_from_env_vars_host_target(env_vars, host, target) +} + +#[allow(non_camel_case_types)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub enum BuildFlag { + Py_DEBUG, + Py_REF_DEBUG, + #[deprecated(since = "0.29.0", note = "no longer supported by PyO3")] + Py_TRACE_REFS, + Py_GIL_DISABLED, + COUNT_ALLOCS, + Other(String), +} + +impl Display for BuildFlag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + BuildFlag::Other(flag) => write!(f, "{flag}"), + _ => write!(f, "{self:?}"), + } + } +} + +impl FromStr for BuildFlag { + type Err = std::convert::Infallible; + fn from_str(s: &str) -> Result { + match s { + "Py_DEBUG" => Ok(BuildFlag::Py_DEBUG), + "Py_REF_DEBUG" => Ok(BuildFlag::Py_REF_DEBUG), + "Py_GIL_DISABLED" => Ok(BuildFlag::Py_GIL_DISABLED), + "COUNT_ALLOCS" => Ok(BuildFlag::COUNT_ALLOCS), + other => Ok(BuildFlag::Other(other.to_owned())), + } + } +} + +/// A list of python interpreter compile-time preprocessor defines. +/// +/// PyO3 will pick these up and pass to rustc via `--cfg=py_sys_config={varname}`; +/// this allows using them conditional cfg attributes in the .rs files, so +/// +/// ```rust,no_run +/// #[cfg(py_sys_config="{varname}")] +/// # struct Foo; +/// ``` +/// +/// is the equivalent of `#ifdef {varname}` in C. +/// +/// see Misc/SpecialBuilds.txt in the python source for what these mean. +#[cfg_attr(test, derive(Debug, PartialEq, Eq))] +#[derive(Clone, Default)] +pub struct BuildFlags(pub HashSet); + +impl BuildFlags { + const ALL: [BuildFlag; 4] = [ + BuildFlag::Py_DEBUG, + BuildFlag::Py_REF_DEBUG, + BuildFlag::Py_GIL_DISABLED, + BuildFlag::COUNT_ALLOCS, + ]; + + pub fn new() -> Self { + BuildFlags(HashSet::new()) + } + + fn from_sysconfigdata(config_map: &Sysconfigdata) -> Self { + Self( + BuildFlags::ALL + .iter() + .filter(|flag| config_map.get_value(flag.to_string()) == Some("1")) + .cloned() + .collect(), + ) + .fixup() + } + + /// Examine python's compile flags to pass to cfg by launching + /// the interpreter and printing variables of interest from + /// sysconfig.get_config_vars. + fn from_interpreter(interpreter: impl AsRef) -> Result { + // sysconfig is missing all the flags on windows for Python 3.12 and + // older, so we can't actually query the interpreter directly for its + // build flags on those versions. + if cfg!(windows) { + let script = String::from("import sys;print(sys.version_info < (3, 13))"); + let stdout = run_python_script(interpreter.as_ref(), &script)?; + if stdout.trim_end() == "True" { + return Ok(Self::new()); + } + } + + let mut script = String::from("import sysconfig\n"); + script.push_str("config = sysconfig.get_config_vars()\n"); + + for k in &BuildFlags::ALL { + use std::fmt::Write; + writeln!(&mut script, "print(config.get('{k}', '0'))").unwrap(); + } + + let stdout = run_python_script(interpreter.as_ref(), &script)?; + let split_stdout: Vec<&str> = stdout.trim_end().lines().collect(); + ensure!( + split_stdout.len() == BuildFlags::ALL.len(), + "Python stdout len didn't return expected number of lines: {}", + split_stdout.len() + ); + let flags = BuildFlags::ALL + .iter() + .zip(split_stdout) + .filter(|(_, flag_value)| *flag_value == "1") + .map(|(flag, _)| flag.clone()) + .collect(); + + Ok(Self(flags).fixup()) + } + + fn fixup(mut self) -> Self { + if self.0.contains(&BuildFlag::Py_DEBUG) { + self.0.insert(BuildFlag::Py_REF_DEBUG); + } + + self + } +} + +impl Display for BuildFlags { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut first = true; + for flag in &self.0 { + if first { + first = false; + } else { + write!(f, ",")?; + } + write!(f, "{flag}")?; + } + Ok(()) + } +} + +impl FromStr for BuildFlags { + type Err = std::convert::Infallible; + + fn from_str(value: &str) -> Result { + let mut flags = HashSet::new(); + for flag in value.split_terminator(',') { + flags.insert(flag.parse().unwrap()); + } + Ok(BuildFlags(flags)) + } +} + +fn parse_script_output(output: &str) -> HashMap { + output + .lines() + .filter_map(|line| { + let mut i = line.splitn(2, ' '); + Some((i.next()?.into(), i.next()?.into())) + }) + .collect() +} + +/// Parsed data from Python sysconfigdata file +/// +/// A hash map of all values from a sysconfigdata file. +pub struct Sysconfigdata(HashMap); + +impl Sysconfigdata { + pub fn get_value>(&self, k: S) -> Option<&str> { + self.0.get(k.as_ref()).map(String::as_str) + } + + #[cfg(test)] + fn new() -> Self { + Sysconfigdata(HashMap::new()) + } + + #[cfg(test)] + fn insert>(&mut self, k: S, v: S) { + self.0.insert(k.into(), v.into()); + } +} + +/// Parse sysconfigdata file +/// +/// The sysconfigdata is simply a dictionary containing all the build time variables used for the +/// python executable and library. This function necessitates a python interpreter on the host +/// machine to work. Here it is read into a `Sysconfigdata` (hash map), which can be turned into an +/// [`InterpreterConfig`] using +/// [`from_sysconfigdata`](InterpreterConfig::from_sysconfigdata). +pub fn parse_sysconfigdata(sysconfigdata_path: impl AsRef) -> Result { + let sysconfigdata_path = sysconfigdata_path.as_ref(); + let mut script = fs::read_to_string(sysconfigdata_path).with_context(|| { + format!( + "failed to read config from {}", + sysconfigdata_path.display() + ) + })?; + script += r#" +for key, val in build_time_vars.items(): + # (ana)conda(-forge) built Pythons are statically linked but ship the shared library with them. + # We detect them based on the magic prefix directory they have encoded in their builds. + if key == "Py_ENABLE_SHARED" and "_h_env_placehold" in build_time_vars.get("prefix"): + val = 1 + print(key, val) +"#; + + let output = run_python_script(&find_interpreter()?, &script)?; + + Ok(Sysconfigdata(parse_script_output(&output))) +} + +fn starts_with(entry: &DirEntry, pat: &str) -> bool { + let name = entry.file_name(); + name.to_string_lossy().starts_with(pat) +} +fn ends_with(entry: &DirEntry, pat: &str) -> bool { + let name = entry.file_name(); + name.to_string_lossy().ends_with(pat) +} + +/// Finds the sysconfigdata file when the target Python library directory is set. +/// +/// Returns `None` if the library directory is not available, and a runtime error +/// when no or multiple sysconfigdata files are found. +fn find_sysconfigdata(cross: &CrossCompileConfig) -> Result> { + let mut sysconfig_paths = find_all_sysconfigdata(cross)?; + if sysconfig_paths.is_empty() { + if let Some(lib_dir) = cross.lib_dir.as_ref() { + bail!("Could not find _sysconfigdata*.py in {}", lib_dir.display()); + } else { + // Continue with the default configuration when PYO3_CROSS_LIB_DIR is not set. + return Ok(None); + } + } else if sysconfig_paths.len() > 1 { + let mut error_msg = String::from( + "Detected multiple possible Python versions. Please set either the \ + PYO3_CROSS_PYTHON_VERSION variable to the wanted version or the \ + _PYTHON_SYSCONFIGDATA_NAME variable to the wanted sysconfigdata file name.\n\n\ + sysconfigdata files found:", + ); + for path in sysconfig_paths { + use std::fmt::Write; + write!(&mut error_msg, "\n\t{}", path.display()).unwrap(); + } + bail!("{}\n", error_msg); + } + + Ok(Some(sysconfig_paths.remove(0))) +} + +/// Finds `_sysconfigdata*.py` files for detected Python interpreters. +/// +/// From the python source for `_sysconfigdata*.py` is always going to be located at +/// `build/lib.{PLATFORM}-{PY_MINOR_VERSION}` when built from source. The [exact line][1] is defined as: +/// +/// ```py +/// pybuilddir = 'build/lib.%s-%s' % (get_platform(), sys.version_info[:2]) +/// ``` +/// +/// Where get_platform returns a kebab-case formatted string containing the os, the architecture and +/// possibly the os' kernel version (not the case on linux). However, when installed using a package +/// manager, the `_sysconfigdata*.py` file is installed in the `${PREFIX}/lib/python3.Y/` directory. +/// The `_sysconfigdata*.py` is generally in a sub-directory of the location of `libpython3.Y.so`. +/// So we must find the file in the following possible locations: +/// +/// ```sh +/// # distribution from package manager, (lib_dir may or may not include lib/) +/// ${INSTALL_PREFIX}/lib/python3.Y/_sysconfigdata*.py +/// ${INSTALL_PREFIX}/lib/libpython3.Y.so +/// ${INSTALL_PREFIX}/lib/python3.Y/config-3.Y-${HOST_TRIPLE}/libpython3.Y.so +/// +/// # Built from source from host +/// ${CROSS_COMPILED_LOCATION}/build/lib.linux-x86_64-Y/_sysconfigdata*.py +/// ${CROSS_COMPILED_LOCATION}/libpython3.Y.so +/// +/// # if cross compiled, kernel release is only present on certain OS targets. +/// ${CROSS_COMPILED_LOCATION}/build/lib.{OS}(-{OS-KERNEL-RELEASE})?-{ARCH}-Y/_sysconfigdata*.py +/// ${CROSS_COMPILED_LOCATION}/libpython3.Y.so +/// +/// # PyPy includes a similar file since v73 +/// ${INSTALL_PREFIX}/lib/pypy3.Y/_sysconfigdata.py +/// ${INSTALL_PREFIX}/lib_pypy/_sysconfigdata.py +/// ``` +/// +/// [1]: https://github.com/python/cpython/blob/3.5/Lib/sysconfig.py#L389 +/// +/// Returns an empty vector when the target Python library directory +/// is not set via `PYO3_CROSS_LIB_DIR`. +pub fn find_all_sysconfigdata(cross: &CrossCompileConfig) -> Result> { + let sysconfig_paths = if let Some(lib_dir) = cross.lib_dir.as_ref() { + search_lib_dir(lib_dir, cross).with_context(|| { + format!( + "failed to search the lib dir at 'PYO3_CROSS_LIB_DIR={}'", + lib_dir.display() + ) + })? + } else { + return Ok(Vec::new()); + }; + + let sysconfig_name = env_var("_PYTHON_SYSCONFIGDATA_NAME"); + let mut sysconfig_paths = sysconfig_paths + .iter() + .filter_map(|p| { + let canonical = fs::canonicalize(p).ok(); + match &sysconfig_name { + Some(_) => canonical.filter(|p| p.file_stem() == sysconfig_name.as_deref()), + None => canonical, + } + }) + .collect::>(); + + sysconfig_paths.sort(); + sysconfig_paths.dedup(); + + Ok(sysconfig_paths) +} + +fn is_pypy_lib_dir(path: &str, v: &Option) -> bool { + let pypy_version_pat = if let Some(v) = v { + format!("pypy{v}") + } else { + "pypy3.".into() + }; + path == "lib_pypy" || path.starts_with(&pypy_version_pat) +} + +fn is_graalpy_lib_dir(path: &str, v: &Option) -> bool { + let graalpy_version_pat = if let Some(v) = v { + format!("graalpy{v}") + } else { + "graalpy2".into() + }; + path == "lib_graalpython" || path.starts_with(&graalpy_version_pat) +} + +fn is_cpython_lib_dir(path: &str, v: &Option) -> bool { + let cpython_version_pat = if let Some(v) = v { + format!("python{v}") + } else { + "python3.".into() + }; + path.starts_with(&cpython_version_pat) +} + +/// recursive search for _sysconfigdata, returns all possibilities of sysconfigdata paths +fn search_lib_dir(path: impl AsRef, cross: &CrossCompileConfig) -> Result> { + let mut sysconfig_paths = vec![]; + for f in fs::read_dir(path.as_ref()).with_context(|| { + format!( + "failed to list the entries in '{}'", + path.as_ref().display() + ) + })? { + sysconfig_paths.extend(match &f { + // Python 3.7+ sysconfigdata with platform specifics + Ok(f) if starts_with(f, "_sysconfigdata_") && ends_with(f, "py") => vec![f.path()], + Ok(f) if f.metadata().is_ok_and(|metadata| metadata.is_dir()) => { + let file_name = f.file_name(); + let file_name = file_name.to_string_lossy(); + if file_name == "build" || file_name == "lib" { + search_lib_dir(f.path(), cross)? + } else if file_name.starts_with("lib.") { + // check if right target os + if !file_name.contains(&cross.target.operating_system.to_string()) { + continue; + } + // Check if right arch + if !file_name.contains(&cross.target.architecture.to_string()) { + continue; + } + search_lib_dir(f.path(), cross)? + } else if is_cpython_lib_dir(&file_name, &cross.version) + || is_pypy_lib_dir(&file_name, &cross.version) + || is_graalpy_lib_dir(&file_name, &cross.version) + { + search_lib_dir(f.path(), cross)? + } else { + continue; + } + } + _ => continue, + }); + } + // If we got more than one file, only take those that contain the arch name. + // For ubuntu 20.04 with host architecture x86_64 and a foreign architecture of armhf + // this reduces the number of candidates to 1: + // + // $ find /usr/lib/python3.8/ -name '_sysconfigdata*.py' -not -lname '*' + // /usr/lib/python3.8/_sysconfigdata__x86_64-linux-gnu.py + // /usr/lib/python3.8/_sysconfigdata__arm-linux-gnueabihf.py + if sysconfig_paths.len() > 1 { + let temp = sysconfig_paths + .iter() + .filter(|p| { + p.to_string_lossy() + .contains(&cross.target.architecture.to_string()) + }) + .cloned() + .collect::>(); + if !temp.is_empty() { + sysconfig_paths = temp; + } + } + + Ok(sysconfig_paths) +} + +/// Find cross compilation information from sysconfigdata file +/// +/// first find sysconfigdata file which follows the pattern [`_sysconfigdata_{abi}_{platform}_{multiarch}`][1] +/// +/// [1]: https://github.com/python/cpython/blob/3.8/Lib/sysconfig.py#L348 +/// +/// Returns `None` when the target Python library directory is not set. +fn cross_compile_from_sysconfigdata( + cross_compile_config: &CrossCompileConfig, +) -> Result> { + if let Some(path) = find_sysconfigdata(cross_compile_config)? { + let data = parse_sysconfigdata(path)?; + let mut config = InterpreterConfig::from_sysconfigdata(&data)?; + #[expect(deprecated, reason = "modifying config inline")] + if let Some(cross_lib_dir) = cross_compile_config.lib_dir_string() { + config.lib_dir = Some(cross_lib_dir) + } + + Ok(Some(config)) + } else { + Ok(None) + } +} + +fn exact_stable_abi_version(version: Option) -> Option { + version.and_then(|v| match v { + StableAbiVersion::Current => None, + StableAbiVersion::Target(inner) => Some(inner), + }) +} + +/// Generates "default" cross compilation information for the target. +/// +/// This should work for most CPython extension modules when targeting +/// Windows, macOS and Linux. +/// +/// Must be called from a PyO3 crate build script. +fn default_cross_compile(cross_compile_config: &CrossCompileConfig) -> Result { + let version = cross_compile_config + .version + .or_else(|| exact_stable_abi_version(get_abi3_version())) + .or_else(|| exact_stable_abi_version(get_abi3t_version())) + .ok_or_else(|| + format!( + "PYO3_CROSS_PYTHON_VERSION or either an abi3-py3* or abi3t-py3* feature must be specified \ + when cross-compiling and PYO3_CROSS_LIB_DIR is not set.\n\ + = help: see the PyO3 user guide for more information: https://pyo3.rs/v{}/building-and-distribution.html#cross-compiling", + env!("CARGO_PKG_VERSION") + ) + )?; + let gil_disabled = cross_compile_config.abiflags.as_deref() == Some("t"); + + let implementation = cross_compile_config + .implementation + .unwrap_or(PythonImplementation::CPython); + + let stable_abi = + applicable_stable_abi_at_interpreter_version(implementation, version, gil_disabled); + + let target_abi = PythonAbi::from_stable_abi(implementation, version, stable_abi, gil_disabled)?; + + let lib_name = default_lib_name_for_target(target_abi, &cross_compile_config.target); + + let lib_dir = cross_compile_config.lib_dir_string(); + + InterpreterConfigBuilder::new(implementation, version) + .target_abi(target_abi) + .lib_name(lib_name) + .lib_dir(lib_dir) + .finalize() +} + +/// Generates "default" interpreter configuration when compiling stable ABI extensions +/// without a working Python interpreter. +/// +/// `abi3_version` or `abi3t_version` specifies the minimum supported Stable ABI +/// CPython version and which stable ABI to target. +/// +/// This should work for most CPython extension modules when compiling on +/// Windows, macOS and Linux. +/// +/// Must be called from a PyO3 crate build script. +fn default_stable_abi_config( + host: &Triple, + abi3_version: Option, + abi3t_version: Option, +) -> Result { + if abi3_version.is_none() && abi3t_version.is_none() { + bail!("Neither abi3 or abi3t features are enabled") + } + let (stable_abi, version) = if let Some(version) = abi3_version { + (StableAbi::Abi3, version) + } else if let Some(version) = abi3t_version { + (StableAbi::Abi3t, version) + } else { + unreachable!(); + }; + + if stable_abi == StableAbi::Abi3t && version < MINIMUM_SUPPORTED_VERSION_ABI3T { + bail!("Cannot target an abi3t version below {MINIMUM_SUPPORTED_VERSION_ABI3T}") + } + + // FIXME: PyPy & GraalPy do not support the Stable ABI. + let target_abi = PythonAbiBuilder::new(PythonImplementation::CPython, version) + .stable_abi(stable_abi) + .finalize()?; + let builder = InterpreterConfigBuilder::new(PythonImplementation::CPython, version) + .target_abi(target_abi); + if host.operating_system == OperatingSystem::Windows { + builder.lib_name(default_lib_name_windows(target_abi, false, false)?) + } else { + builder + } + .finalize() +} + +/// Detects the cross compilation target interpreter configuration from all +/// available sources (PyO3 environment variables, Python sysconfigdata, etc.). +/// +/// Returns the "default" target interpreter configuration for Windows and +/// when no target Python interpreter is found. +/// +/// Must be called from a PyO3 crate build script. +fn load_cross_compile_config( + cross_compile_config: CrossCompileConfig, +) -> Result { + let windows = cross_compile_config.target.operating_system == OperatingSystem::Windows; + + let config = if windows || !have_python_interpreter() { + // Load the defaults for Windows even when `PYO3_CROSS_LIB_DIR` is set + // since it has no sysconfigdata files in it. + // Also, do not try to look for sysconfigdata when `PYO3_NO_PYTHON` variable is set. + default_cross_compile(&cross_compile_config)? + } else if let Some(config) = cross_compile_from_sysconfigdata(&cross_compile_config)? { + // Try to find and parse sysconfigdata files on other targets. + config + } else { + // Fall back to the defaults when nothing else can be done. + default_cross_compile(&cross_compile_config)? + }; + + Ok(config) +} + +// These contains only the limited ABI symbols. +const WINDOWS_STABLE_ABI_LIB_NAME: &str = "python3"; +const WINDOWS_STABLE_ABI_DEBUG_LIB_NAME: &str = "python3_d"; + +/// Generates the default library name for the target platform. +#[allow(dead_code)] +fn default_lib_name_for_target(abi: PythonAbi, target: &Triple) -> String { + if target.operating_system == OperatingSystem::Windows { + default_lib_name_windows(abi, false, false).unwrap() + } else { + default_lib_name_unix( + abi, + target.operating_system == OperatingSystem::Cygwin, + None, + ) + .unwrap() + } +} + +fn default_lib_name_windows(abi: PythonAbi, mingw: bool, debug: bool) -> Result { + // mingw formats lib names like unix, and uses a "lib" prefix. We could let the linker + // handle "lib" prefix, but that means the `raw-dylib` name is incorrect (where the + // "lib" prefix is not automatically added). + if mingw { + let mut lib_name = default_lib_name_unix(abi, true, None)?; + lib_name.insert_str(0, "lib"); + return Ok(lib_name); + } + + if abi.implementation.is_pypy() { + // PyPy on Windows ships `libpypy3.X-c.dll` (e.g. `libpypy3.11-c.dll`), + // not CPython's `pythonXY.dll`. With raw-dylib linking we need the real + // DLL name rather than the import-library alias. + Ok(format!( + "libpypy{}.{}-c", + abi.version.major, abi.version.minor + )) + } else if debug && abi.version < PythonVersion::PY310 { + // CPython bug: linking against python3_d.dll raises error + // https://github.com/python/cpython/issues/101614 + Ok(format!( + "python{}{}_d", + abi.version.major, abi.version.minor + )) + } else if abi.kind == PythonAbiKind::Stable(StableAbi::Abi3) + || abi.kind == PythonAbiKind::Stable(StableAbi::Abi3t) + { + let mut lib_name = if debug { + WINDOWS_STABLE_ABI_DEBUG_LIB_NAME.to_owned() + } else { + WINDOWS_STABLE_ABI_LIB_NAME.to_owned() + }; + if abi.kind == PythonAbiKind::Stable(StableAbi::Abi3t) { + lib_name = lib_name.replace("python3", "python3t"); + } + Ok(lib_name) + } else if abi.kind().is_free_threaded() { + #[expect(deprecated, reason = "using constant internally")] + { + ensure!(abi.version() >= PythonVersion::PY313, "Cannot compile extensions for the free-threaded build on Python versions earlier than 3.13, found {}.{}", abi.version.major, abi.version.minor); + } + if debug { + Ok(format!( + "python{}{}t_d", + abi.version.major, abi.version.minor + )) + } else { + Ok(format!("python{}{}t", abi.version.major, abi.version.minor)) + } + } else if debug { + Ok(format!( + "python{}{}_d", + abi.version.major, abi.version.minor + )) + } else { + Ok(format!("python{}{}", abi.version.major, abi.version.minor)) + } +} + +fn default_lib_name_unix( + abi: PythonAbi, + use_stable_abi_lib: bool, + ld_version: Option<&str>, +) -> Result { + match abi.implementation { + PythonImplementation::CPython => match ld_version { + Some(ld_version) => Ok(format!("python{ld_version}")), + None => match abi.kind { + PythonAbiKind::Stable(StableAbi::Abi3) if use_stable_abi_lib => { + Ok("python3".to_string()) + } + PythonAbiKind::Stable(StableAbi::Abi3t) if use_stable_abi_lib => { + Ok("python3t".to_string()) + } + _ => { + if abi.kind.is_free_threaded() { + #[expect(deprecated, reason = "using constant internally")] + { + ensure!(abi.version >= PythonVersion::PY313, "Cannot compile extensions for the free-threaded build on Python versions earlier than 3.13, found {}.{}", abi.version.major, abi.version.minor); + } + Ok(format!( + "python{}.{}t", + abi.version.major, abi.version.minor + )) + } else { + Ok(format!("python{}.{}", abi.version.major, abi.version.minor)) + } + } + }, + }, + PythonImplementation::PyPy => match ld_version { + Some(ld_version) => Ok(format!("pypy{ld_version}-c")), + None => Ok(format!("pypy{}.{}-c", abi.version.major, abi.version.minor)), + }, + + PythonImplementation::GraalPy => Ok("python-native".to_string()), + PythonImplementation::RustPython => Ok("rustpython_capi".to_string()), + } +} + +/// Run a python script using the specified interpreter binary. +fn run_python_script(interpreter: &Path, script: &str) -> Result { + run_python_script_with_envs(interpreter, script, std::iter::empty::<(&str, &str)>()) +} + +/// Run a python script using the specified interpreter binary with additional environment +/// variables (e.g. PYTHONPATH) set. +fn run_python_script_with_envs(interpreter: &Path, script: &str, envs: I) -> Result +where + I: IntoIterator, + K: AsRef, + V: AsRef, +{ + let out = Command::new(interpreter) + .env("PYTHONIOENCODING", "utf-8") + .envs(envs) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()) + .spawn() + .and_then(|mut child| { + child + .stdin + .as_mut() + .expect("piped stdin") + .write_all(script.as_bytes())?; + child.wait_with_output() + }); + + match out { + Err(err) => bail!( + "failed to run the Python interpreter at {}: {}", + interpreter.display(), + err + ), + Ok(ok) if !ok.status.success() => bail!("Python script failed"), + Ok(ok) => Ok(String::from_utf8(ok.stdout) + .context("failed to parse Python script output as utf-8")?), + } +} + +fn venv_interpreter(virtual_env: &OsStr, windows: bool) -> PathBuf { + let venv = Path::new(virtual_env); + // Rebuild if the virtual environment configuration changes + println!( + "cargo:rerun-if-changed={}", + venv.join("pyvenv.cfg").display() + ); + if windows { + venv.join("Scripts").join("python.exe") + } else { + venv.join("bin").join("python") + } +} + +fn conda_env_interpreter(conda_prefix: &OsStr, windows: bool) -> PathBuf { + if windows { + Path::new(conda_prefix).join("python.exe") + } else { + Path::new(conda_prefix).join("bin").join("python") + } +} + +fn get_env_interpreter() -> Option { + match (env_var("VIRTUAL_ENV"), env_var("CONDA_PREFIX")) { + // Use cfg rather than CARGO_CFG_TARGET_OS because this affects where files are located on the + // build host + (Some(dir), None) => Some(venv_interpreter(&dir, cfg!(windows))), + (None, Some(dir)) => Some(conda_env_interpreter(&dir, cfg!(windows))), + (Some(_), Some(_)) => { + warn!( + "Both VIRTUAL_ENV and CONDA_PREFIX are set. PyO3 will ignore both of these for \ + locating the Python interpreter until you unset one of them." + ); + None + } + (None, None) => None, + } +} + +/// Attempts to locate a python interpreter. +/// +/// Locations are checked in the order listed: +/// 1. If `PYO3_PYTHON` is set, this interpreter is used. +/// 2. If in a virtualenv, that environment's interpreter is used. +/// 3. `python`, if this is functional a Python 3.x interpreter +/// 4. `python3`, as above +pub fn find_interpreter() -> Result { + // Trigger rebuilds when `PYO3_ENVIRONMENT_SIGNATURE` env var value changes + // See https://github.com/PyO3/pyo3/issues/2724 + println!("cargo:rerun-if-env-changed=PYO3_ENVIRONMENT_SIGNATURE"); + + if let Some(exe) = env_var("PYO3_PYTHON") { + Ok(exe.into()) + } else if let Some(env_interpreter) = get_env_interpreter() { + Ok(env_interpreter) + } else { + println!("cargo:rerun-if-env-changed=PATH"); + ["python", "python3"] + .iter() + .find(|bin| { + if let Ok(out) = Command::new(bin).arg("--version").output() { + // begin with `Python 3.X.X :: additional info` + out.stdout.starts_with(b"Python 3") + || out.stderr.starts_with(b"Python 3") + || out.stdout.starts_with(b"GraalPy 3") + } else { + false + } + }) + .map(PathBuf::from) + .ok_or_else(|| "no Python 3.x interpreter found".into()) + } +} + +/// Locates and extracts the build host Python interpreter configuration. +/// +/// Lowers the configured Python version to `abi3_version` or `abi3t_version` if required. +fn get_host_interpreter( + abi3_version: Option, + abi3t_version: Option, +) -> Result { + let interpreter_path = find_interpreter()?; + + let interpreter_config = + InterpreterConfig::from_interpreter(interpreter_path, abi3_version, abi3t_version)?; + + Ok(interpreter_config) +} + +/// Generates an interpreter config suitable for cross-compilation. +/// +/// This must be called from PyO3's build script, because it relies on environment variables such as +/// CARGO_CFG_TARGET_OS which aren't available at any other time. +pub fn make_cross_compile_config(target: &Triple) -> Result> { + let interpreter_config = + if let Some(cross_config) = cross_compiling_from_to(&Triple::host(), target)? { + Some(load_cross_compile_config(cross_config)?.apply_build_env()?) + } else { + None + }; + + Ok(interpreter_config) +} + +/// Generates an interpreter config suitable for the build host. +pub fn make_interpreter_config() -> Result { + let host = Triple::host(); + let abi3_version = get_abi3_version(); + let abi3t_version = get_abi3t_version(); + + // See if we can safely skip the Python interpreter configuration detection. + // Unix stable ABI extension modules can usually be built without any interpreter. + let need_interpreter = + (abi3_version.is_none() && abi3t_version.is_none()) || require_libdir_for_target(&host); + + if have_python_interpreter() { + match get_host_interpreter(abi3_version, abi3t_version) { + Ok(interpreter_config) => return Ok(interpreter_config), + // Bail if the interpreter configuration is required to build. + Err(e) if need_interpreter => return Err(e), + _ => { + // Fall back to the stable ABI just as if `PYO3_NO_PYTHON` + // environment variable was set. + warn!("Compiling without a working Python interpreter."); + } + } + } + + let interpreter_config = default_stable_abi_config( + &host, + exact_stable_abi_version(abi3_version), + exact_stable_abi_version(abi3t_version), + )?; + + Ok(interpreter_config) +} + +pub(crate) fn escape(bytes: &[u8]) -> String { + let mut escaped = String::with_capacity(2 * bytes.len()); + + for byte in bytes { + const LUT: &[u8; 16] = b"0123456789abcdef"; + + escaped.push(LUT[(byte >> 4) as usize] as char); + escaped.push(LUT[(byte & 0x0F) as usize] as char); + } + + escaped +} + +fn unescape(escaped: &str) -> Vec { + assert_eq!(escaped.len() % 2, 0, "invalid hex encoding"); + + let mut bytes = Vec::with_capacity(escaped.len() / 2); + + for chunk in escaped.as_bytes().chunks_exact(2) { + fn unhex(hex: u8) -> u8 { + match hex { + b'a'..=b'f' => hex - b'a' + 10, + b'0'..=b'9' => hex - b'0', + _ => panic!("invalid hex encoding"), + } + } + + bytes.push((unhex(chunk[0]) << 4) | unhex(chunk[1])); + } + + bytes +} + +#[cfg(test)] +// can remove this expect when fields are private +#[expect(deprecated, reason = "accessing config fields directly for testing")] +mod tests { + use target_lexicon::triple; + + use super::*; + + #[test] + fn test_config_file_roundtrip() { + let implementation = PythonImplementation::CPython; + let version = MINIMUM_SUPPORTED_VERSION; + let config = InterpreterConfigBuilder::new(implementation, version) + .stable_abi(StableAbi::Abi3) + .pointer_width(32) + .executable("executable".to_string()) + .lib_dir("lib_name".to_string()) + .lib_name("lib_name".to_string()) + .extra_build_script_lines(vec!["cargo:test1".to_string(), "cargo:test2".to_string()]) + .finalize() + .unwrap(); + let mut buf: Vec = Vec::new(); + config.to_writer(&mut buf).unwrap(); + + assert_eq!(config, InterpreterConfig::from_reader(&*buf).unwrap()); + + // And some different options, for variety + let version = PythonVersion::PY310; + let implementation = PythonImplementation::PyPy; + let build_flags = { + let mut flags = HashSet::new(); + flags.insert(BuildFlag::Py_DEBUG); + flags.insert(BuildFlag::Other(String::from("Py_SOME_FLAG"))); + BuildFlags(flags) + }; + let config = InterpreterConfigBuilder::new(implementation, version) + .build_flags(build_flags) + .finalize() + .unwrap(); + + let mut buf: Vec = Vec::new(); + config.to_writer(&mut buf).unwrap(); + + assert_eq!(config, InterpreterConfig::from_reader(&*buf).unwrap()); + } + + #[test] + fn test_config_file_roundtrip_with_escaping() { + let implementation = PythonImplementation::CPython; + let version = MINIMUM_SUPPORTED_VERSION; + let config = InterpreterConfigBuilder::new(implementation, version) + .stable_abi(StableAbi::Abi3) + .pointer_width(32) + .executable("executable".to_string()) + .lib_name("lib_name".to_string()) + .lib_dir("lib_dir\\n".to_string()) + .extra_build_script_lines(vec!["cargo:test1".to_string(), "cargo:test2".to_string()]) + .finalize() + .unwrap(); + let mut buf: Vec = Vec::new(); + config.to_writer(&mut buf).unwrap(); + + let buf = unescape(&escape(&buf)); + + assert_eq!(config, InterpreterConfig::from_reader(&*buf).unwrap()); + } + + #[test] + fn test_config_file_defaults() { + // Only version is required + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY38; + assert_eq!( + InterpreterConfig::from_reader("version=3.8".as_bytes()).unwrap(), + InterpreterConfigBuilder::new(implementation, version,) + .finalize() + .unwrap() + ) + } + + #[test] + fn test_config_file_unknown_keys() { + // ext_suffix is unknown to pyo3-build-config, but it shouldn't error + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY38; + assert_eq!( + InterpreterConfig::from_reader("version=3.8\next_suffix=.python38.so".as_bytes()) + .unwrap(), + InterpreterConfigBuilder::new(implementation, version,) + .finalize() + .unwrap() + ) + } + + #[test] + fn test_config_file_invalid_keys() { + assert!( + InterpreterConfig::from_reader("version=3.14\ntarget_abi=foo-bar-baz".as_bytes()) + .is_err() + ); + assert!(InterpreterConfig::from_reader( + "version=3.14\ntarget_abi=CPython-bar-baz".as_bytes() + ) + .is_err()); + assert!(InterpreterConfig::from_reader( + "version=3.14\ntarget_abi=CPython-abi3-baz".as_bytes() + ) + .is_err()); + } + + #[test] + fn gil_disabled_config_file_corner_cases() { + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY313; + // Legacy: build_flags=Py_GIL_DISABLED with no target_abi infers free-threaded. + assert_eq!( + InterpreterConfig::from_reader("version=3.13\nbuild_flags=Py_GIL_DISABLED".as_bytes()) + .unwrap(), + InterpreterConfigBuilder::new(implementation, version) + .free_threaded() + .unwrap() + .finalize() + .unwrap() + ); + // Canonical: target_abi=free_threaded. + assert_eq!( + InterpreterConfig::from_reader( + "version=3.13\ntarget_abi=CPython-free_threaded-3.13".as_bytes() + ) + .unwrap(), + InterpreterConfigBuilder::new(implementation, version) + .free_threaded() + .unwrap() + .finalize() + .unwrap() + ); + // target_abi=gil_enabled with build_flags=Py_GIL_DISABLED is inconsistent and rejected. + assert!(InterpreterConfig::from_reader( + "version=3.13\ntarget_abi=CPython-gil_enabled-3.13\nbuild_flags=Py_GIL_DISABLED" + .as_bytes() + ) + .is_err()); + // build_flags=Py_GIL_DISABLED on a builder without target_abi is ok + let mut flags = BuildFlags::default(); + flags.0.insert(BuildFlag::Py_GIL_DISABLED); + assert!(InterpreterConfigBuilder::new(implementation, version) + .build_flags(flags) + .finalize() + .unwrap() + .target_abi + .kind + .is_free_threaded()); + + let mut flags = BuildFlags::default(); + flags.0.insert(BuildFlag::Py_GIL_DISABLED); + assert!( + InterpreterConfigBuilder::new(implementation, PythonVersion::PY312) + .build_flags(flags) + .finalize() + .is_err() + ); + + let mut flags = BuildFlags::default(); + flags.0.insert(BuildFlag::Py_GIL_DISABLED); + assert!( + InterpreterConfigBuilder::new(implementation, PythonVersion::PY312) + .stable_abi(StableAbi::Abi3) + .build_flags(flags) + .finalize() + .is_err() + ); + + assert!( + InterpreterConfigBuilder::new(implementation, PythonVersion::PY38) + .free_threaded() + .is_err() + ); + } + + #[test] + fn abi3_from_old_config_file() { + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY313; + assert_eq!( + InterpreterConfig::from_reader("version=3.13\nabi3=true".as_bytes()).unwrap(), + InterpreterConfigBuilder::new(implementation, version) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap() + ); + } + + #[test] + fn test_target_abi_and_abi3() { + assert!(InterpreterConfig::from_reader( + "version=3.13\nabi3=true\ntarget_abi=CPython-abi3-3.13".as_bytes() + ) + .unwrap_err() + .to_string() + .contains("Invalid config"),); + } + + #[test] + fn build_flags_default() { + assert_eq!(BuildFlags::default(), BuildFlags::new()); + } + + #[test] + fn build_flags_from_sysconfigdata() { + let mut sysconfigdata = Sysconfigdata::new(); + + assert_eq!( + BuildFlags::from_sysconfigdata(&sysconfigdata).0, + HashSet::new() + ); + + for flag in &BuildFlags::ALL { + sysconfigdata.insert(flag.to_string(), "0".into()); + } + + assert_eq!( + BuildFlags::from_sysconfigdata(&sysconfigdata).0, + HashSet::new() + ); + + let mut expected_flags = HashSet::new(); + for flag in &BuildFlags::ALL { + sysconfigdata.insert(flag.to_string(), "1".into()); + expected_flags.insert(flag.clone()); + } + + assert_eq!( + BuildFlags::from_sysconfigdata(&sysconfigdata).0, + expected_flags + ); + } + + #[test] + fn build_flags_fixup() { + let mut build_flags = BuildFlags::new(); + + build_flags = build_flags.fixup(); + assert!(build_flags.0.is_empty()); + + build_flags.0.insert(BuildFlag::Py_DEBUG); + + build_flags = build_flags.fixup(); + + // Py_DEBUG implies Py_REF_DEBUG + assert!(build_flags.0.contains(&BuildFlag::Py_REF_DEBUG)); + } + + #[test] + fn parse_script_output() { + let output = "foo bar\nbar foobar\n\n"; + let map = super::parse_script_output(output); + assert_eq!(map.len(), 2); + assert_eq!(map["foo"], "bar"); + assert_eq!(map["bar"], "foobar"); + } + + #[test] + fn config_from_interpreter() { + // Smoke test to just see whether this works + // + // PyO3's CI is dependent on Python being installed, so this should be reliable. + assert!(make_interpreter_config().is_ok()) + } + + #[test] + fn config_from_empty_sysconfigdata() { + let sysconfigdata = Sysconfigdata::new(); + assert!(InterpreterConfig::from_sysconfigdata(&sysconfigdata).is_err()); + } + + #[test] + fn config_from_sysconfigdata() { + let mut sysconfigdata = Sysconfigdata::new(); + // these are the minimal values required such that InterpreterConfig::from_sysconfigdata + // does not error + sysconfigdata.insert("SOABI", "cpython-38-x86_64-linux-gnu"); + sysconfigdata.insert("VERSION", "3.8"); + sysconfigdata.insert("Py_ENABLE_SHARED", "1"); + sysconfigdata.insert("LIBDIR", "/usr/lib"); + sysconfigdata.insert("LDVERSION", "3.8"); + sysconfigdata.insert("SIZEOF_VOID_P", "8"); + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY38; + assert_eq!( + InterpreterConfig::from_sysconfigdata(&sysconfigdata).unwrap(), + InterpreterConfigBuilder::new(implementation, version,) + .build_flags(BuildFlags::from_sysconfigdata(&sysconfigdata)) + .lib_dir("/usr/lib".to_string()) + .lib_name("python3.8".to_string()) + .pointer_width(64) + .finalize() + .unwrap() + ); + } + + #[test] + fn config_from_sysconfigdata_framework() { + let mut sysconfigdata = Sysconfigdata::new(); + sysconfigdata.insert("SOABI", "cpython-38-x86_64-linux-gnu"); + sysconfigdata.insert("VERSION", "3.8"); + // PYTHONFRAMEWORK should override Py_ENABLE_SHARED + sysconfigdata.insert("Py_ENABLE_SHARED", "0"); + sysconfigdata.insert("PYTHONFRAMEWORK", "Python"); + sysconfigdata.insert("LIBDIR", "/usr/lib"); + sysconfigdata.insert("LDVERSION", "3.8"); + sysconfigdata.insert("SIZEOF_VOID_P", "8"); + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY38; + assert_eq!( + InterpreterConfig::from_sysconfigdata(&sysconfigdata).unwrap(), + InterpreterConfigBuilder::new(implementation, version,) + .build_flags(BuildFlags::from_sysconfigdata(&sysconfigdata)) + .lib_dir("/usr/lib".to_string()) + .lib_name("python3.8".to_string()) + .pointer_width(64) + .finalize() + .unwrap() + ); + + sysconfigdata = Sysconfigdata::new(); + sysconfigdata.insert("SOABI", "cpython-38-x86_64-linux-gnu"); + sysconfigdata.insert("VERSION", "3.8"); + // An empty PYTHONFRAMEWORK means it is not a framework + sysconfigdata.insert("Py_ENABLE_SHARED", "0"); + sysconfigdata.insert("PYTHONFRAMEWORK", ""); + sysconfigdata.insert("LIBDIR", "/usr/lib"); + sysconfigdata.insert("LDVERSION", "3.8"); + sysconfigdata.insert("SIZEOF_VOID_P", "8"); + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY38; + assert_eq!( + InterpreterConfig::from_sysconfigdata(&sysconfigdata).unwrap(), + InterpreterConfigBuilder::new(implementation, version,) + .build_flags(BuildFlags::from_sysconfigdata(&sysconfigdata)) + .lib_dir("/usr/lib".to_string()) + .lib_name("python3.8".to_string()) + .pointer_width(64) + .shared(false) + .finalize() + .unwrap() + ); + } + + #[test] + fn windows_hardcoded_abi3_compile() { + let host = triple!("x86_64-pc-windows-msvc"); + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY38; + let config = InterpreterConfigBuilder::new(implementation, version) + .stable_abi(StableAbi::Abi3) + .lib_name("python3".to_string()) + .finalize() + .unwrap(); + assert_eq!( + default_stable_abi_config(&host, Some(version), None).unwrap(), + config + ); + } + + #[test] + fn windows_hardcoded_abi3t_compile() { + let host = triple!("x86_64-pc-windows-msvc"); + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY315; + let config = InterpreterConfigBuilder::new(implementation, version) + .stable_abi(StableAbi::Abi3t) + .lib_name("python3t".to_string()) + .finalize() + .unwrap(); + assert_eq!( + default_stable_abi_config(&host, None, Some(version)).unwrap(), + config + ); + } + + #[test] + fn unix_hardcoded_abi3_compile() { + let host = triple!("x86_64-unknown-linux-gnu"); + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY39; + let config = InterpreterConfigBuilder::new(implementation, version) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(); + assert_eq!( + default_stable_abi_config(&host, Some(version), None).unwrap(), + config + ); + } + + #[test] + fn unix_hardcoded_abi3t_compile() { + let host = triple!("x86_64-unknown-linux-gnu"); + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY315; + let config = InterpreterConfigBuilder::new(implementation, version) + .stable_abi(StableAbi::Abi3t) + .finalize() + .unwrap(); + assert_eq!( + default_stable_abi_config(&host, None, Some(version)).unwrap(), + config + ); + } + + #[test] + fn default_stable_abi_config_corner_cases() { + let host = triple!("x86_64-unknown-linux-gnu"); + let py315 = Some("3.15".parse().unwrap()); + let py39 = Some("3.9".parse().unwrap()); + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY39; + let config = InterpreterConfigBuilder::new(implementation, version) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(); + assert_eq!( + default_stable_abi_config(&host, py39, py315).unwrap(), + config + ); + assert!(default_stable_abi_config(&host, None, py39).is_err()); + } + + #[test] + fn windows_hardcoded_cross_compile() { + let env_vars = CrossCompileEnvVars { + pyo3_cross: None, + pyo3_cross_lib_dir: Some("C:\\some\\path".into()), + pyo3_cross_python_implementation: None, + pyo3_cross_python_version: Some("3.8".into()), + }; + + let host = triple!("x86_64-unknown-linux-gnu"); + let target = triple!("i686-pc-windows-msvc"); + let cross_config = + CrossCompileConfig::try_from_env_vars_host_target(env_vars, &host, &target) + .unwrap() + .unwrap(); + + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY38; + let config = InterpreterConfigBuilder::new(implementation, version) + .lib_name("python38".to_string()) + .lib_dir("C:\\some\\path".to_string()) + .finalize() + .unwrap(); + assert_eq!(default_cross_compile(&cross_config).unwrap(), config); + } + + #[test] + fn mingw_hardcoded_cross_compile() { + let env_vars = CrossCompileEnvVars { + pyo3_cross: None, + pyo3_cross_lib_dir: Some("/usr/lib/mingw".into()), + pyo3_cross_python_implementation: None, + pyo3_cross_python_version: Some("3.8".into()), + }; + + let host = triple!("x86_64-unknown-linux-gnu"); + let target = triple!("i686-pc-windows-gnu"); + let cross_config = + CrossCompileConfig::try_from_env_vars_host_target(env_vars, &host, &target) + .unwrap() + .unwrap(); + + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY38; + let config = InterpreterConfigBuilder::new(implementation, version) + .lib_name("python38".to_string()) + .lib_dir("/usr/lib/mingw".to_string()) + .finalize() + .unwrap(); + assert_eq!(default_cross_compile(&cross_config).unwrap(), config); + } + + #[test] + fn unix_hardcoded_cross_compile() { + let env_vars = CrossCompileEnvVars { + pyo3_cross: None, + pyo3_cross_lib_dir: Some("/usr/arm64/lib".into()), + pyo3_cross_python_implementation: None, + pyo3_cross_python_version: Some("3.9".into()), + }; + + let host = triple!("x86_64-unknown-linux-gnu"); + let target = triple!("aarch64-unknown-linux-gnu"); + let cross_config = + CrossCompileConfig::try_from_env_vars_host_target(env_vars, &host, &target) + .unwrap() + .unwrap(); + + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY39; + let config = InterpreterConfigBuilder::new(implementation, version) + .lib_name("python3.9".to_string()) + .lib_dir("/usr/arm64/lib".to_string()) + .finalize() + .unwrap(); + assert_eq!(default_cross_compile(&cross_config).unwrap(), config); + } + + #[test] + fn pypy_hardcoded_cross_compile() { + let env_vars = CrossCompileEnvVars { + pyo3_cross: None, + pyo3_cross_lib_dir: None, + pyo3_cross_python_implementation: Some("PyPy".into()), + pyo3_cross_python_version: Some("3.11".into()), + }; + + let triple = triple!("x86_64-unknown-linux-gnu"); + let cross_config = + CrossCompileConfig::try_from_env_vars_host_target(env_vars, &triple, &triple) + .unwrap() + .unwrap(); + + let implementation = PythonImplementation::PyPy; + let version = PythonVersion::PY311; + let config = InterpreterConfigBuilder::new(implementation, version) + .lib_name("pypy3.11-c".to_string()) + .finalize() + .unwrap(); + assert_eq!(default_cross_compile(&cross_config).unwrap(), config); + } + + // 3.14t cross-compile must produce a version-specific free-threaded ABI: + // 3.14 is below MINIMUM_SUPPORTED_VERSION_ABI3T (3.15) so abi3t is unavailable, + // and the free-threaded build does not support abi3 either. + #[test] + fn unix_free_threaded_pre_315_cross_compile() { + let env_vars = CrossCompileEnvVars { + pyo3_cross: None, + pyo3_cross_lib_dir: None, + pyo3_cross_python_implementation: None, + pyo3_cross_python_version: Some("3.14t".into()), + }; + + let host = triple!("x86_64-unknown-linux-gnu"); + let target = triple!("aarch64-unknown-linux-gnu"); + let cross_config = + CrossCompileConfig::try_from_env_vars_host_target(env_vars, &host, &target) + .unwrap() + .unwrap(); + + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY314; + let config = InterpreterConfigBuilder::new(implementation, version) + .free_threaded() + .unwrap() + .lib_name("python3.14t".to_string()) + .finalize() + .unwrap(); + let result = default_cross_compile(&cross_config).unwrap(); + assert_eq!(result, config); + assert_eq!( + result.target_abi.kind(), + PythonAbiKind::VersionSpecific(GilUsed::FreeThreaded) + ); + } + + #[test] + fn windows_free_threaded_pre_315_cross_compile() { + let env_vars = CrossCompileEnvVars { + pyo3_cross: None, + pyo3_cross_lib_dir: None, + pyo3_cross_python_implementation: None, + pyo3_cross_python_version: Some("3.14t".into()), + }; + + let host = triple!("x86_64-unknown-linux-gnu"); + let target = triple!("x86_64-pc-windows-msvc"); + let cross_config = + CrossCompileConfig::try_from_env_vars_host_target(env_vars, &host, &target) + .unwrap() + .unwrap(); + + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY314; + let config = InterpreterConfigBuilder::new(implementation, version) + .free_threaded() + .unwrap() + .lib_name("python314t".to_string()) + .finalize() + .unwrap(); + let result = default_cross_compile(&cross_config).unwrap(); + assert_eq!(result, config); + assert_eq!( + result.target_abi.kind(), + PythonAbiKind::VersionSpecific(GilUsed::FreeThreaded) + ); + } + + // PYO3_CROSS_PYTHON_VERSION=3.15t with no abi3t-py3* feature active still + // produces a version-specific free-threaded ABI rather than abi3t. + #[test] + fn unix_free_threaded_315_cross_compile() { + let env_vars = CrossCompileEnvVars { + pyo3_cross: None, + pyo3_cross_lib_dir: None, + pyo3_cross_python_implementation: None, + pyo3_cross_python_version: Some("3.15t".into()), + }; + + let host = triple!("x86_64-unknown-linux-gnu"); + let target = triple!("aarch64-unknown-linux-gnu"); + let cross_config = + CrossCompileConfig::try_from_env_vars_host_target(env_vars, &host, &target) + .unwrap() + .unwrap(); + + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY315; + let config = InterpreterConfigBuilder::new(implementation, version) + .free_threaded() + .unwrap() + .lib_name("python3.15t".to_string()) + .finalize() + .unwrap(); + let result = default_cross_compile(&cross_config).unwrap(); + assert_eq!(result, config); + assert_eq!( + result.target_abi.kind(), + PythonAbiKind::VersionSpecific(GilUsed::FreeThreaded) + ); + } + + #[test] + fn default_lib_name_windows() { + assert_eq!( + super::default_lib_name_windows( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY39) + .finalize() + .unwrap(), + false, + false, + ) + .unwrap(), + "python39", + ); + // free-threaded Python 3.9 builds should be impossible + assert!( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY39) + .free_threaded() + .finalize() + .is_err() + ); + assert_eq!( + super::default_lib_name_windows( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY39) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(), + false, + false, + ) + .unwrap(), + "python3", + ); + assert_eq!( + super::default_lib_name_windows( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY39) + .finalize() + .unwrap(), + true, + false, + ) + .unwrap(), + "libpython3.9", + ); + assert_eq!( + super::default_lib_name_windows( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY39) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(), + true, + false, + ) + .unwrap(), + "libpython3", + ); + assert_eq!( + super::default_lib_name_windows( + PythonAbiBuilder::new(PythonImplementation::PyPy, PythonVersion::PY39) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(), + false, + false, + ) + .unwrap(), + "libpypy3.9-c", + ); + assert_eq!( + super::default_lib_name_windows( + PythonAbiBuilder::new(PythonImplementation::PyPy, PythonVersion::PY311) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(), + false, + false, + ) + .unwrap(), + "libpypy3.11-c", + ); + assert_eq!( + super::default_lib_name_windows( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY310) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(), + false, + true, + ) + .unwrap(), + "python3_d", + ); + // abi3 debug builds on windows use version-specific lib on 3.9 and older + // to workaround https://github.com/python/cpython/issues/101614 + assert_eq!( + super::default_lib_name_windows( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY39) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(), + false, + true, + ) + .unwrap(), + "python39_d", + ); + assert_eq!( + super::default_lib_name_windows( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY310) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(), + false, + true, + ) + .unwrap(), + "python3_d", + ); + assert_eq!( + super::default_lib_name_windows( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY313) + .free_threaded() + .finalize() + .unwrap(), + false, + false, + ) + .unwrap(), + "python313t", + ); + assert_eq!( + super::default_lib_name_windows( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY313) + .free_threaded() + .finalize() + .unwrap(), + false, + true, + ) + .unwrap(), + "python313t_d", + ); + assert_eq!( + super::default_lib_name_windows( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY315) + .stable_abi(StableAbi::Abi3t) + .finalize() + .unwrap(), + false, + false, + ) + .unwrap(), + "python3t", + ); + assert_eq!( + super::default_lib_name_windows( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY315) + .stable_abi(StableAbi::Abi3t) + .finalize() + .unwrap(), + false, + true, + ) + .unwrap(), + "python3t_d", + ); + } + + #[test] + fn default_lib_name_unix() { + // Defaults to pythonX.Y for CPython 3.8+ + assert_eq!( + super::default_lib_name_unix( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY38) + .finalize() + .unwrap(), + false, + None, + ) + .unwrap(), + "python3.8", + ); + assert_eq!( + super::default_lib_name_unix( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY39) + .finalize() + .unwrap(), + false, + None, + ) + .unwrap(), + "python3.9", + ); + // Can use ldversion to override for CPython + assert_eq!( + super::default_lib_name_unix( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY39) + .finalize() + .unwrap(), + false, + Some("3.8d"), + ) + .unwrap(), + "python3.8d", + ); + + // PyPy 3.11 includes ldversion + assert_eq!( + super::default_lib_name_unix( + PythonAbiBuilder::new(PythonImplementation::PyPy, PythonVersion::PY311) + .finalize() + .unwrap(), + false, + None, + ) + .unwrap(), + "pypy3.11-c", + ); + + assert_eq!( + super::default_lib_name_unix( + PythonAbiBuilder::new(PythonImplementation::PyPy, PythonVersion::PY39) + .finalize() + .unwrap(), + false, + Some("3.11d"), + ) + .unwrap(), + "pypy3.11d-c", + ); + + // free-threading adds a t suffix + assert_eq!( + super::default_lib_name_unix( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY313) + .free_threaded() + .finalize() + .unwrap(), + false, + None, + ) + .unwrap(), + "python3.13t", + ); + // cygwin abi3 links to unversioned libpython + assert_eq!( + super::default_lib_name_unix( + PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY313) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(), + true, + None, + ) + .unwrap(), + "python3", + ); + } + + #[test] + fn abi_builder_error_paths() { + let builder = PythonAbiBuilder::new(PythonImplementation::CPython, PythonVersion::PY39) + .free_threaded() + .finalize(); + + assert!(builder.is_err()); + assert!(builder.unwrap_err().to_string().contains("Cannot target")); + + assert_eq!( + PythonAbiBuilder::new( + PythonImplementation::CPython, + PythonVersion { + major: 3, + minor: 16, + }, + ) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap() + .version + .minor, + STABLE_ABI_MAX_MINOR + ); + + assert!("invalid".parse::().is_err()); + assert!("CPython-invalid".parse::().is_err()); + assert!("CPython-free_threaded-invalid" + .parse::() + .is_err()); + + let builder = PythonAbiBuilder::new(PythonImplementation::RustPython, PythonVersion::PY315) + .free_threaded(); + let res = builder.finalize(); + + assert!(res.is_err()); + assert!(res + .unwrap_err() + .to_string() + .contains("RustPython only supports targeting abi3t")); + } + + #[test] + fn parse_cross_python_version() { + let env_vars = CrossCompileEnvVars { + pyo3_cross: None, + pyo3_cross_lib_dir: None, + pyo3_cross_python_version: Some("3.9".into()), + pyo3_cross_python_implementation: None, + }; + + assert_eq!( + env_vars.parse_version().unwrap(), + (Some(PythonVersion { major: 3, minor: 9 }), None), + ); + + let env_vars = CrossCompileEnvVars { + pyo3_cross: None, + pyo3_cross_lib_dir: None, + pyo3_cross_python_version: None, + pyo3_cross_python_implementation: None, + }; + + assert_eq!(env_vars.parse_version().unwrap(), (None, None)); + + let env_vars = CrossCompileEnvVars { + pyo3_cross: None, + pyo3_cross_lib_dir: None, + pyo3_cross_python_version: Some("3.13t".into()), + pyo3_cross_python_implementation: None, + }; + + assert_eq!( + env_vars.parse_version().unwrap(), + ( + Some(PythonVersion { + major: 3, + minor: 13 + }), + Some("t".into()) + ), + ); + + let env_vars = CrossCompileEnvVars { + pyo3_cross: None, + pyo3_cross_lib_dir: None, + pyo3_cross_python_version: Some("100".into()), + pyo3_cross_python_implementation: None, + }; + + assert!(env_vars.parse_version().is_err()); + } + + #[test] + fn target_abi3_version_different_from_host() { + let implementation = PythonImplementation::CPython; + let host_version = PythonVersion::PY39; + let target_version = PythonVersion::PY38; + let config = InterpreterConfigBuilder::new(implementation, host_version) + .target_abi( + PythonAbiBuilder::new(implementation, target_version) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(), + ) + .finalize() + .unwrap(); + assert_eq!(config.target_abi.version(), target_version); + assert_eq!(config.version, host_version); + } + + #[test] + fn stable_abi_applicability() { + use PythonImplementation::*; + let abi3 = Some(StableAbiVersion::Target(PythonVersion::PY310)); + let abi3t = Some(StableAbiVersion::Target(PythonVersion::PY315)); + + // 3.14t cannot target any stable ABI, so the features are ignored + // rather than raising an error + assert_eq!( + applicable_stable_abi(CPython, PythonVersion::PY314, true, abi3, abi3t), + None + ); + // GIL-enabled below 3.15: only abi3 applies + assert_eq!( + applicable_stable_abi(CPython, PythonVersion::PY314, false, abi3, abi3t), + Some((StableAbi::Abi3, PythonVersion::PY310)) + ); + assert_eq!( + applicable_stable_abi(CPython, PythonVersion::PY314, false, None, abi3t), + None + ); + // 3.15+ GIL-enabled: abi3t preferred over abi3 + assert_eq!( + applicable_stable_abi(CPython, PythonVersion::PY315, false, abi3, abi3t), + Some((StableAbi::Abi3t, PythonVersion::PY315)) + ); + assert_eq!( + applicable_stable_abi(CPython, PythonVersion::PY315, false, abi3, None), + Some((StableAbi::Abi3, PythonVersion::PY310)) + ); + // 3.15+ free-threaded: only abi3t applies + assert_eq!( + applicable_stable_abi(CPython, PythonVersion::PY315, true, abi3, abi3t), + Some((StableAbi::Abi3t, PythonVersion::PY315)) + ); + assert_eq!( + applicable_stable_abi(CPython, PythonVersion::PY315, true, abi3, None), + None + ); + // a bare abi3/abi3t feature resolves to the interpreter version + assert_eq!( + applicable_stable_abi( + CPython, + PythonVersion::PY314, + false, + Some(StableAbiVersion::Current), + None + ), + Some((StableAbi::Abi3, PythonVersion::PY314)) + ); + assert_eq!( + applicable_stable_abi( + CPython, + PythonVersion::PY315, + true, + None, + Some(StableAbiVersion::Current) + ), + Some((StableAbi::Abi3t, PythonVersion::PY315)) + ); + // PyPy and GraalPy: the kind applies but the version is never lowered + assert_eq!( + applicable_stable_abi(PyPy, PythonVersion::PY311, false, abi3, abi3t), + Some((StableAbi::Abi3, PythonVersion::PY311)) + ); + assert_eq!( + applicable_stable_abi(GraalPy, PythonVersion::PY311, false, abi3, abi3t), + Some((StableAbi::Abi3, PythonVersion::PY311)) + ); + assert_eq!( + applicable_stable_abi(PyPy, PythonVersion::PY311, false, None, abi3t), + None + ); + } + + #[test] + fn apply_build_env_preserves_target_implementation() { + // the host `implementation` may differ from the `target_abi` + // implementation; recomputing the target ABI from the build + // environment must not switch it to the host's + let config = InterpreterConfig::from_reader( + "implementation=CPython\nversion=3.11\ntarget_abi=PyPy-gil_enabled-3.11".as_bytes(), + ) + .unwrap() + .apply_build_env() + .unwrap(); + assert_eq!( + config.target_abi.implementation(), + PythonImplementation::PyPy + ); + assert_eq!( + config.target_abi.kind(), + PythonAbiKind::VersionSpecific(GilUsed::GilEnabled) + ); + assert_eq!(config.target_abi.version(), PythonVersion::PY311); + } + + #[test] + fn python_abi_from_stable_abi() { + let implementation = PythonImplementation::CPython; + + // no stable ABI: version-specific, free-threaded per gil_disabled + let abi = + PythonAbi::from_stable_abi(implementation, PythonVersion::PY314, None, true).unwrap(); + assert_eq!( + abi.kind(), + PythonAbiKind::VersionSpecific(GilUsed::FreeThreaded) + ); + assert_eq!(abi.version(), PythonVersion::PY314); + + let abi = + PythonAbi::from_stable_abi(implementation, PythonVersion::PY314, None, false).unwrap(); + assert_eq!( + abi.kind(), + PythonAbiKind::VersionSpecific(GilUsed::GilEnabled) + ); + + // stable ABI: targets the minimum version + let abi = PythonAbi::from_stable_abi( + implementation, + PythonVersion::PY314, + Some((StableAbi::Abi3, PythonVersion::PY310)), + false, + ) + .unwrap(); + assert_eq!(abi.kind(), PythonAbiKind::Stable(StableAbi::Abi3)); + assert_eq!(abi.version(), PythonVersion::PY310); + + // a minimum above the interpreter version errors, naming the right feature + let error = PythonAbi::from_stable_abi( + implementation, + PythonVersion::PY314, + Some((StableAbi::Abi3t, PythonVersion::PY315)), + true, + ) + .unwrap_err(); + assert!(error.to_string().contains( + "cannot set a minimum Python version 3.15 higher than the interpreter version 3.14 \ + (the minimum Python version is implied by the abi3t-py315 feature)" + )); + } + + #[test] + fn config_file_applies_build_env() { + // no abi3/abi3t cargo features are set when running tests, so + // apply_build_env preserves the version-specific target ABI + let config = InterpreterConfig::from_reader( + "version=3.14\ntarget_abi=CPython-free_threaded-3.14\nbuild_flags=Py_GIL_DISABLED" + .as_bytes(), + ) + .unwrap() + .apply_build_env() + .unwrap(); + assert_eq!( + config.target_abi.kind(), + PythonAbiKind::VersionSpecific(GilUsed::FreeThreaded) + ); + assert_eq!(config.target_abi.version(), PythonVersion::PY314); + + // a stable ABI recorded in the config file is recomputed from the + // (unset) features, so the result is version-specific + let config = + InterpreterConfig::from_reader("version=3.12\ntarget_abi=CPython-abi3-3.10".as_bytes()) + .unwrap() + .apply_build_env() + .unwrap(); + assert_eq!( + config.target_abi.kind(), + PythonAbiKind::VersionSpecific(GilUsed::GilEnabled) + ); + assert_eq!(config.target_abi.version(), PythonVersion::PY312); + } + + #[test] + fn abi3_version_cannot_be_higher_than_interpreter() { + if !have_python_interpreter() { + return; + } + + let host_interpreter = get_host_interpreter(None, None).unwrap(); + let host_version = host_interpreter.version; + let host_free_threaded = host_interpreter.target_abi.kind.is_free_threaded(); + + // skip these tests on 3.14t, pypy, and graalpy because they don't support any stable ABI + if matches!( + host_interpreter.implementation, + PythonImplementation::PyPy | PythonImplementation::GraalPy + ) || ((host_version == PythonVersion::PY314) && host_free_threaded) + { + return; + } + + let interpreter = get_host_interpreter( + Some(StableAbiVersion::Target(PythonVersion { + major: 3, + minor: 45, + })), + None, + ); + if !host_free_threaded { + assert!(interpreter.unwrap_err().to_string().contains( + "cannot set a minimum Python version 3.45 higher than the interpreter version" + )); + if host_version >= PythonVersion::PY313 { + let interpreter = get_host_interpreter( + Some(StableAbiVersion::Target(PythonVersion::PY313)), + None, + ); + assert_eq!( + interpreter.unwrap().target_abi.version(), + PythonVersion::PY313 + ); + } + } + + // If both features abi3 and abi3t features are active, the feature that "wins" depends on the host Python version + if host_version >= PythonVersion::PY313 { + let interpreter = get_host_interpreter( + Some(StableAbiVersion::Target(PythonVersion::PY313)), + Some(StableAbiVersion::Target(PythonVersion::PY315)), + ) + .unwrap(); + assert_eq!( + interpreter.target_abi.version(), + if host_version >= PythonVersion::PY315 { + PythonVersion::PY315 + } else { + PythonVersion::PY313 + } + ); + } + } + + #[test] + #[cfg(all(target_os = "linux", target_arch = "x86_64",))] + fn parse_sysconfigdata() { + // A best effort attempt to get test coverage for the sysconfigdata parsing. + // Might not complete successfully depending on host installation; that's ok as long as + // CI demonstrates this path is covered! + + let Ok(interpreter_config) = make_interpreter_config() else { + // Couldn't get an interpreter config, won't be able to test a matching sysconfigdata, + // never mind. (This is intended for coverage, don't mind if it fails if it doesn't run.) + return; + }; + + let lib_dir = match &interpreter_config.lib_dir { + Some(lib_dir) => Path::new(lib_dir), + // Don't know where to search for sysconfigdata; never mind. + None => return, + }; + + let cross = CrossCompileConfig { + lib_dir: Some(lib_dir.into()), + version: Some(interpreter_config.version), + implementation: Some(interpreter_config.implementation), + target: triple!("x86_64-unknown-linux-gnu"), + abiflags: if interpreter_config.target_abi.kind().is_free_threaded() { + Some("t".into()) + } else { + None + }, + }; + + let sysconfigdata_path = match find_sysconfigdata(&cross) { + Ok(Some(path)) => path, + // Couldn't find a matching sysconfigdata; never mind! + _ => return, + }; + let sysconfigdata = super::parse_sysconfigdata(sysconfigdata_path).unwrap(); + let mut parsed_config = InterpreterConfig::from_sysconfigdata(&sysconfigdata).unwrap(); + + // Workaround case where empty `PYTHONFRAMEWORKPREFIX` is returned as empty string instead of None, + // which causes the assert_eq! below to fail. + // + // TODO: probably should deprecate using this variable at all, seemingly only used in `add_python_framework_link_args` + // which is probably a strictly worse version of `add_libpython_rpath_link_args`. + if parsed_config.python_framework_prefix.as_deref() == Some("") { + parsed_config.python_framework_prefix = None; + } + + assert_eq!(parsed_config.implementation, PythonImplementation::CPython); + assert_eq!( + parsed_config, + InterpreterConfigBuilder::new( + interpreter_config.implementation, + interpreter_config.version, + ) + .build_flags(interpreter_config.build_flags().clone()) + .pointer_width(64) + .lib_dir(interpreter_config.lib_dir().map(str::to_owned)) + .lib_name(interpreter_config.lib_name().map(str::to_owned)) + .finalize() + .unwrap() + ) + } + + #[test] + fn test_venv_interpreter() { + let base = OsStr::new("base"); + assert_eq!( + venv_interpreter(base, true), + PathBuf::from_iter(&["base", "Scripts", "python.exe"]) + ); + assert_eq!( + venv_interpreter(base, false), + PathBuf::from_iter(&["base", "bin", "python"]) + ); + } + + #[test] + fn test_conda_env_interpreter() { + let base = OsStr::new("base"); + assert_eq!( + conda_env_interpreter(base, true), + PathBuf::from_iter(&["base", "python.exe"]) + ); + assert_eq!( + conda_env_interpreter(base, false), + PathBuf::from_iter(&["base", "bin", "python"]) + ); + } + + #[test] + fn test_not_cross_compiling_from_to() { + assert!(cross_compiling_from_to( + &triple!("x86_64-unknown-linux-gnu"), + &triple!("x86_64-unknown-linux-gnu"), + ) + .unwrap() + .is_none()); + + assert!(cross_compiling_from_to( + &triple!("x86_64-apple-darwin"), + &triple!("x86_64-apple-darwin") + ) + .unwrap() + .is_none()); + + assert!(cross_compiling_from_to( + &triple!("aarch64-apple-darwin"), + &triple!("x86_64-apple-darwin") + ) + .unwrap() + .is_none()); + + assert!(cross_compiling_from_to( + &triple!("x86_64-apple-darwin"), + &triple!("aarch64-apple-darwin") + ) + .unwrap() + .is_none()); + + assert!(cross_compiling_from_to( + &triple!("x86_64-pc-windows-msvc"), + &triple!("i686-pc-windows-msvc") + ) + .unwrap() + .is_none()); + + assert!(cross_compiling_from_to( + &triple!("x86_64-unknown-linux-gnu"), + &triple!("x86_64-unknown-linux-musl") + ) + .unwrap() + .is_none()); + + assert!(cross_compiling_from_to( + &triple!("x86_64-pc-windows-msvc"), + &triple!("x86_64-win7-windows-msvc"), + ) + .unwrap() + .is_none()); + } + + #[test] + fn test_is_cross_compiling_from_to() { + assert!(cross_compiling_from_to( + &triple!("x86_64-pc-windows-msvc"), + &triple!("aarch64-pc-windows-msvc") + ) + .unwrap() + .is_some()); + } + + #[test] + fn test_run_python_script() { + // as above, this should be okay in CI where Python is presumed installed + let interpreter = make_interpreter_config() + .expect("could not get InterpreterConfig from installed interpreter"); + let out = interpreter + .run_python_script("print(2 + 2)") + .expect("failed to run Python script"); + assert_eq!(out.trim_end(), "4"); + } + + #[test] + fn test_run_python_script_with_envs() { + // as above, this should be okay in CI where Python is presumed installed + let interpreter = make_interpreter_config() + .expect("could not get InterpreterConfig from installed interpreter"); + let out = interpreter + .run_python_script_with_envs( + "import os; print(os.getenv('PYO3_TEST'))", + vec![("PYO3_TEST", "42")], + ) + .expect("failed to run Python script"); + assert_eq!(out.trim_end(), "42"); + } + + #[test] + fn test_build_script_outputs_base() { + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY311; + let interpreter_config = InterpreterConfigBuilder::new(implementation, version) + .finalize() + .unwrap(); + assert_eq!( + interpreter_config.build_script_outputs(), + [ + "cargo:rustc-cfg=Py_3_8".to_owned(), + "cargo:rustc-cfg=Py_3_9".to_owned(), + "cargo:rustc-cfg=Py_3_10".to_owned(), + "cargo:rustc-cfg=Py_3_11".to_owned(), + ] + ); + + let interpreter_config = InterpreterConfigBuilder::new(PythonImplementation::PyPy, version) + .finalize() + .unwrap(); + assert_eq!( + interpreter_config.build_script_outputs(), + [ + "cargo:rustc-cfg=Py_3_8".to_owned(), + "cargo:rustc-cfg=Py_3_9".to_owned(), + "cargo:rustc-cfg=Py_3_10".to_owned(), + "cargo:rustc-cfg=Py_3_11".to_owned(), + "cargo:rustc-cfg=PyPy".to_owned(), + ] + ); + + let interpreter_config = + InterpreterConfigBuilder::new(PythonImplementation::RustPython, version) + .finalize() + .unwrap(); + assert_eq!( + interpreter_config.build_script_outputs(), + [ + "cargo:rustc-cfg=Py_3_8".to_owned(), + "cargo:rustc-cfg=Py_3_9".to_owned(), + "cargo:rustc-cfg=Py_3_10".to_owned(), + "cargo:rustc-cfg=Py_3_11".to_owned(), + "cargo:rustc-cfg=RustPython".to_owned(), + "cargo:rustc-cfg=Py_LIMITED_API".to_owned(), + "cargo:rustc-cfg=Py_GIL_DISABLED".to_owned(), + ] + ); + } + + #[test] + fn test_build_script_outputs_abi3() { + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY39; + let interpreter_config = InterpreterConfigBuilder::new(implementation, version) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(); + + assert_eq!( + interpreter_config.build_script_outputs(), + [ + "cargo:rustc-cfg=Py_3_8".to_owned(), + "cargo:rustc-cfg=Py_3_9".to_owned(), + "cargo:rustc-cfg=Py_LIMITED_API".to_owned(), + ] + ); + + let interpreter_config = InterpreterConfigBuilder::new(PythonImplementation::PyPy, version) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(); + assert_eq!( + interpreter_config.build_script_outputs(), + [ + "cargo:rustc-cfg=Py_3_8".to_owned(), + "cargo:rustc-cfg=Py_3_9".to_owned(), + "cargo:rustc-cfg=PyPy".to_owned(), + "cargo:rustc-cfg=Py_LIMITED_API".to_owned(), + ] + ); + + let interpreter_config = + InterpreterConfigBuilder::new(PythonImplementation::CPython, PythonVersion::PY315) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(); + assert_eq!( + interpreter_config.build_script_outputs(), + [ + "cargo:rustc-cfg=Py_3_8".to_owned(), + "cargo:rustc-cfg=Py_3_9".to_owned(), + "cargo:rustc-cfg=Py_3_10".to_owned(), + "cargo:rustc-cfg=Py_3_11".to_owned(), + "cargo:rustc-cfg=Py_3_12".to_owned(), + "cargo:rustc-cfg=Py_3_13".to_owned(), + "cargo:rustc-cfg=Py_3_14".to_owned(), + "cargo:rustc-cfg=Py_3_15".to_owned(), + "cargo:rustc-cfg=Py_LIMITED_API".to_owned(), + ] + ); + } + + #[test] + fn test_build_script_outputs_gil_disabled() { + let interpreter_config = + InterpreterConfigBuilder::new(PythonImplementation::CPython, PythonVersion::PY313) + .free_threaded() + .unwrap() + .finalize() + .unwrap(); + assert_eq!( + interpreter_config.build_script_outputs(), + [ + "cargo:rustc-cfg=Py_3_8".to_owned(), + "cargo:rustc-cfg=Py_3_9".to_owned(), + "cargo:rustc-cfg=Py_3_10".to_owned(), + "cargo:rustc-cfg=Py_3_11".to_owned(), + "cargo:rustc-cfg=Py_3_12".to_owned(), + "cargo:rustc-cfg=Py_3_13".to_owned(), + "cargo:rustc-cfg=Py_GIL_DISABLED".to_owned(), + ] + ); + } + + #[test] + fn test_interpreter_config_builder_gil_disabled_flag() { + let builder = InterpreterConfigBuilder::new( + PythonImplementation::CPython, + PythonVersion { + major: 3, + minor: 14, + }, + ); + let mut flags = BuildFlags::new(); + flags.0.insert(BuildFlag::Py_GIL_DISABLED); + let config = builder + .stable_abi(StableAbi::Abi3) + .build_flags(flags) + .finalize() + .unwrap(); + // build flags win due to backward compatibility (abi3 feature is a no-op on ft builds) + assert!(config.target_abi.kind() == PythonAbiKind::VersionSpecific(GilUsed::FreeThreaded)); + + // The reconciliation is order-independent: build_flags first, then stable_abi(Abi3) + // produces the same result as the previous ordering. + let builder = InterpreterConfigBuilder::new( + PythonImplementation::CPython, + PythonVersion { + major: 3, + minor: 14, + }, + ); + let mut flags = BuildFlags::new(); + flags.0.insert(BuildFlag::Py_GIL_DISABLED); + let config = builder + .build_flags(flags) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(); + assert!(config.target_abi.kind() == PythonAbiKind::VersionSpecific(GilUsed::FreeThreaded)); + + // Explicit GIL-enabled target with Py_GIL_DISABLED in build flags is contradictory and + // is rejected at finalize regardless of the order in which the setters were called. + let builder = InterpreterConfigBuilder::new( + PythonImplementation::CPython, + PythonVersion { + major: 3, + minor: 14, + }, + ); + let target_abi = PythonAbiBuilder::new( + PythonImplementation::CPython, + PythonVersion { + major: 3, + minor: 14, + }, + ) + .finalize() + .unwrap(); + let mut flags = BuildFlags::new(); + flags.0.insert(BuildFlag::Py_GIL_DISABLED); + assert!(builder + .target_abi(target_abi) + .build_flags(flags) + .finalize() + .is_err()); + + let builder = InterpreterConfigBuilder::new( + PythonImplementation::CPython, + PythonVersion { + major: 3, + minor: 14, + }, + ); + let config = builder.free_threaded().unwrap().finalize().unwrap(); + assert!(config.target_abi.kind().is_free_threaded()); + assert!(config.build_flags.0.contains(&BuildFlag::Py_GIL_DISABLED)); + } + + #[test] + fn test_build_script_outputs_debug() { + let mut build_flags = BuildFlags::default(); + build_flags.0.insert(BuildFlag::Py_DEBUG); + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY38; + let interpreter_config = InterpreterConfigBuilder::new(implementation, version) + .build_flags(build_flags) + .finalize() + .unwrap(); + assert_eq!( + interpreter_config.build_script_outputs(), + [ + "cargo:rustc-cfg=Py_3_8".to_owned(), + "cargo:rustc-cfg=py_sys_config=\"Py_DEBUG\"".to_owned(), + ] + ); + } + + #[test] + fn test_find_sysconfigdata_in_invalid_lib_dir() { + let e = find_all_sysconfigdata(&CrossCompileConfig { + lib_dir: Some(PathBuf::from("/abc/123/not/a/real/path")), + version: None, + implementation: None, + target: triple!("x86_64-unknown-linux-gnu"), + abiflags: None, + }) + .unwrap_err(); + + // actual error message is platform-dependent, so just check the context we add + assert!(e.report().to_string().starts_with( + "failed to search the lib dir at 'PYO3_CROSS_LIB_DIR=/abc/123/not/a/real/path'\n\ + caused by:\n \ + - 0: failed to list the entries in '/abc/123/not/a/real/path'\n \ + - 1: \ + " + )); + } + + #[test] + fn test_from_pyo3_config_file_env_rebuild() { + READ_ENV_VARS.with(|vars| vars.borrow_mut().clear()); + let _ = InterpreterConfig::from_pyo3_config_file_env(&Triple::host()); + // it's possible that other env vars were also read, hence just checking for contains + READ_ENV_VARS.with(|vars| assert!(vars.borrow().contains(&"PYO3_CONFIG_FILE".to_string()))); + } + + #[test] + fn test_default_lib_name_for_target() { + let cpython = PythonImplementation::CPython; + let pypy = PythonImplementation::PyPy; + let py39 = PythonVersion::PY39; + let py311 = PythonVersion { + major: 3, + minor: 11, + }; + let py313 = PythonVersion { + major: 3, + minor: 13, + }; + let cpy39 = PythonAbiBuilder::new(cpython, py39).finalize().unwrap(); + let pypy311 = PythonAbiBuilder::new(pypy, py311).finalize().unwrap(); + let cpy313t = PythonAbiBuilder::new(cpython, py313) + .free_threaded() + .finalize() + .unwrap(); + let cpy313_abi3 = PythonAbiBuilder::new(cpython, py313) + .stable_abi(StableAbi::Abi3) + .finalize() + .unwrap(); + + let unix = Triple::from_str("x86_64-unknown-linux-gnu").unwrap(); + let win_x64 = Triple::from_str("x86_64-pc-windows-msvc").unwrap(); + let win_arm64 = Triple::from_str("aarch64-pc-windows-msvc").unwrap(); + + let lib_name = default_lib_name_for_target(cpy39, &unix); + assert_eq!(lib_name, "python3.9"); + + let lib_name = default_lib_name_for_target(cpy39, &win_x64); + assert_eq!(lib_name, "python39"); + + let lib_name = default_lib_name_for_target(cpy39, &win_arm64); + assert_eq!(lib_name, "python39"); + + // PyPy + let lib_name = default_lib_name_for_target(pypy311, &unix); + assert_eq!(lib_name, "pypy3.11-c"); + + let lib_name = default_lib_name_for_target(pypy311, &win_x64); + assert_eq!(lib_name, "libpypy3.11-c"); + + // Free-threaded + let lib_name = default_lib_name_for_target(cpy313t, &unix); + assert_eq!(lib_name, "python3.13t"); + + let lib_name = default_lib_name_for_target(cpy313t, &win_x64); + assert_eq!(lib_name, "python313t"); + + let lib_name = default_lib_name_for_target(cpy313t, &win_arm64); + assert_eq!(lib_name, "python313t"); + + // abi3 + let lib_name = default_lib_name_for_target(cpy313_abi3, &unix); + assert_eq!(lib_name, "python3.13"); + + let lib_name = default_lib_name_for_target(cpy313_abi3, &win_x64); + assert_eq!(lib_name, "python3"); + + let lib_name = default_lib_name_for_target(cpy313_abi3, &win_arm64); + assert_eq!(lib_name, "python3"); + } +} diff --git a/vendor/pyo3-build-config/src/lib.rs b/vendor/pyo3-build-config/src/lib.rs new file mode 100644 index 0000000..b39915b --- /dev/null +++ b/vendor/pyo3-build-config/src/lib.rs @@ -0,0 +1,458 @@ +//! Configuration used by PyO3 for conditional support of varying Python versions. +//! +//! This crate exposes functionality to be called from build scripts to simplify building crates +//! which depend on PyO3. +//! +//! It used internally by the PyO3 crate's build script to apply the same configuration. + +#![warn(elided_lifetimes_in_paths, unused_lifetimes)] + +mod errors; +mod impl_; + +use std::{env, process::Command, str::FromStr, sync::LazyLock}; + +pub use impl_::{ + cross_compiling_from_to, find_all_sysconfigdata, parse_sysconfigdata, BuildFlag, BuildFlags, + CrossCompileConfig, GilUsed, InterpreterConfig, InterpreterConfigBuilder, PythonAbi, + PythonAbiBuilder, PythonAbiKind, PythonImplementation, PythonVersion, StableAbi, Triple, +}; + +use target_lexicon::{Architecture, OperatingSystem}; + +/// Adds all the [`#[cfg]` flags](index.html) to the current compilation. +/// +/// This should be called from a build script. +/// +/// The full list of attributes added are the following: +/// +/// | Flag | Description | +/// | ---- | ----------- | +/// | `#[cfg(Py_3_8)]`, `#[cfg(Py_3_9)]`, `#[cfg(Py_3_10)]`, `#[cfg(Py_3_11)]`, ... | These attributes mark code only for a given Python version and up. For example, `#[cfg(Py_3_8)]` marks code which can run on Python 3.8 **and newer**. There is one attribute for each Python version currently supported by PyO3. | +/// | `#[cfg(Py_LIMITED_API)]` | This marks code which is run when compiling with PyO3's `abi3` or abi3t feature enabled. | +/// | `#[cfg(Py_GIL_DISABLED)]` | This marks code which is run on the free-threaded interpreter. | +/// | `#[cfg(PyPy)]` | This marks code which is run when compiling for PyPy. | +/// | `#[cfg(GraalPy)]` | This marks code which is run when compiling for GraalPy. | +/// +/// For examples of how to use these attributes, +#[doc = concat!("[see PyO3's guide](https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/building-and-distribution/multiple-python-versions.html)")] +/// . +pub fn use_pyo3_cfgs() { + print_expected_cfgs(); + for cargo_command in get().build_script_outputs() { + println!("{cargo_command}") + } +} + +/// Adds linker arguments suitable for linking an extension module. +/// +/// This should be called from a build script. +/// +/// The following link flags are added: +/// - macOS: `-undefined dynamic_lookup` +/// - wasm32-unknown-emscripten: for Rust <= 1.95, `-sSIDE_MODULE=2 -sWASM_BIGINT` +/// +/// All other platforms currently are no-ops, however this may change as necessary +/// in future. +pub fn add_extension_module_link_args() { + _add_extension_module_link_args( + &impl_::target_triple_from_env(), + std::io::stdout(), + rustc_minor_version(), + ) +} + +fn _add_extension_module_link_args( + triple: &Triple, + mut writer: impl std::io::Write, + rustc_minor_version: Option, +) { + if matches!(triple.operating_system, OperatingSystem::Darwin(_)) { + writeln!(writer, "cargo:rustc-cdylib-link-arg=-undefined").unwrap(); + writeln!(writer, "cargo:rustc-cdylib-link-arg=dynamic_lookup").unwrap(); + } else if triple == &Triple::from_str("wasm32-unknown-emscripten").unwrap() + && rustc_minor_version.is_some_and(|version| version < 95) + { + writeln!(writer, "cargo:rustc-cdylib-link-arg=-sSIDE_MODULE=2").unwrap(); + writeln!(writer, "cargo:rustc-cdylib-link-arg=-sWASM_BIGINT").unwrap(); + } +} + +/// Adds linker arguments to set rpath when embedding Python within a Rust binary. +/// +/// When running tests or binaries built with PyO3, the Python dynamic library needs +/// to be found at runtime. +/// +/// This can be done by setting environment variables like `DYLD_LIBRARY_PATH` on macOS, +/// `LD_LIBRARY_PATH` on Linux, or `PATH` on Windows. +/// +/// Altrnatively (as per this function) rpath can be set at link time to point to the +/// directory containing the Python dynamic library. This avoids the need to set environment +/// variables, so can be convenient, however may not be appropriate for binaries packaged +/// for distribution. +/// +#[doc = concat!("[See PyO3's guide](https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/building-and-distribution#dynamically-embedding-the-python-interpreter)")] +/// for more details. +pub fn add_libpython_rpath_link_args() { + let target = impl_::target_triple_from_env(); + pyo3_build_script_impl::print_libpython_rpath_link_args(&target, get()); +} + +/// Adds linker arguments suitable for linking against the Python framework on macOS. +/// +/// This should be called from a build script. +/// +/// The following link flags are added: +/// - macOS: `-Wl,-rpath,` +/// +/// All other platforms currently are no-ops. +pub fn add_python_framework_link_args() { + let target = impl_::target_triple_from_env(); + _add_python_framework_link_args( + get(), + &target, + impl_::is_linking_libpython_for_target(&target), + std::io::stdout(), + ) +} + +fn _add_python_framework_link_args( + interpreter_config: &InterpreterConfig, + triple: &Triple, + link_libpython: bool, + mut writer: impl std::io::Write, +) { + if matches!(triple.operating_system, OperatingSystem::Darwin(_)) && link_libpython { + if let Some(framework_prefix) = interpreter_config.python_framework_prefix() { + writeln!(writer, "cargo:rustc-link-arg=-Wl,-rpath,{framework_prefix}").unwrap(); + } + } +} + +/// Loads the configuration determined from the build environment. +/// +/// This function must be called from a build script, and requires a direct dependency on at +/// least one of `pyo3` or `pyo3-ffi`. +pub fn get() -> &'static InterpreterConfig { + static CONFIG: LazyLock = LazyLock::new(get_inner); + &CONFIG +} + +#[track_caller] +fn get_inner() -> InterpreterConfig { + let Some(interpreter_config) = InterpreterConfig::from_cargo_dep_env() else { + panic!("`pyo3_build_config::get()` requires a direct dependency on `pyo3` or `pyo3-ffi`") + }; + interpreter_config.expect("failed to parse PyO3 config") +} + +/// Registers `pyo3`s config names as reachable cfg expressions +/// +/// - +/// - +#[doc(hidden)] +pub fn print_expected_cfgs() { + println!("cargo:rustc-check-cfg=cfg(Py_LIMITED_API)"); + println!("cargo:rustc-check-cfg=cfg(Py_GIL_DISABLED)"); + println!("cargo:rustc-check-cfg=cfg(PyPy)"); + println!("cargo:rustc-check-cfg=cfg(GraalPy)"); + println!("cargo:rustc-check-cfg=cfg(RustPython)"); + println!("cargo:rustc-check-cfg=cfg(py_sys_config, values(\"Py_DEBUG\", \"Py_REF_DEBUG\", \"Py_TRACE_REFS\", \"COUNT_ALLOCS\"))"); + + // allow `Py_3_*` cfgs from the minimum supported version up to the + // maximum minor version (+1 for development for the next) + for i in impl_::MINIMUM_SUPPORTED_VERSION.minor..=impl_::STABLE_ABI_MAX_MINOR + 1 { + println!("cargo:rustc-check-cfg=cfg(Py_3_{i})"); + } +} + +/// Private exports used in PyO3's build.rs +/// +/// Please don't use these - they could change at any time. +#[doc(hidden)] +pub mod pyo3_build_script_impl { + use crate::{ + errors::Result, + impl_::{make_cross_compile_config, make_interpreter_config}, + }; + + use super::*; + + pub mod errors { + pub use crate::errors::*; + } + pub use crate::impl_::{ + cargo_env_var, env_var, is_linking_libpython_for_target, target_triple_from_env, + InterpreterConfig, PythonAbi, PythonAbiKind, PythonVersion, StableAbi, + }; + pub enum BuildConfigSource { + /// Config was provided by `PYO3_CONFIG_FILE`. + ConfigFile, + /// Config was found by an interpreter on the host system. + Host, + /// Config was configured by cross-compilation settings. + CrossCompile, + } + + pub struct BuildConfig { + pub interpreter_config: InterpreterConfig, + pub source: BuildConfigSource, + } + + /// Gets the configuration for use from `pyo3-ffi`'s build script. + pub fn resolve_build_config(target: &Triple) -> Result { + #[allow( + clippy::const_is_empty, + reason = "CONFIG_FILE is generated in build.rs, content can vary" + )] + if let Some(interpreter_config) = + InterpreterConfig::from_pyo3_config_file_env(target).transpose()? + { + Ok(BuildConfig { + interpreter_config, + source: BuildConfigSource::ConfigFile, + }) + } else if let Some(interpreter_config) = make_cross_compile_config(target)? { + Ok(BuildConfig { + interpreter_config, + source: BuildConfigSource::CrossCompile, + }) + } else { + // No config file, and no cross compile config, so fall back to trying to find an interpreter on the host system. + let host_config = make_interpreter_config(); + Ok(BuildConfig { + interpreter_config: host_config?, + source: BuildConfigSource::Host, + }) + } + } + + /// Helper to generate an error message when the configured Python version is newer + /// than PyO3's current supported version. + pub struct MaximumVersionExceeded { + message: String, + } + + impl MaximumVersionExceeded { + pub fn new( + interpreter_config: &InterpreterConfig, + supported_version: PythonVersion, + ) -> Self { + let implementation = match interpreter_config.target_abi().implementation() { + PythonImplementation::CPython => "Python", + PythonImplementation::PyPy => "PyPy", + PythonImplementation::GraalPy => "GraalPy", + PythonImplementation::RustPython => "RustPython", + }; + let version = &interpreter_config.target_abi().version(); + let message = format!( + "the configured {implementation} version ({version}) is newer than PyO3's maximum supported version ({supported_version})\n\ + = help: this package is being built with PyO3 version {current_version}\n\ + = help: check https://crates.io/crates/pyo3 for the latest PyO3 version available\n\ + = help: updating this package to the latest version of PyO3 may provide compatibility with this {implementation} version", + current_version = env!("CARGO_PKG_VERSION") + ); + Self { message } + } + + pub fn add_help(&mut self, help: &str) { + self.message.push_str("\n= help: "); + self.message.push_str(help); + } + + pub fn finish(self) -> String { + self.message + } + } + + /// Detects features which `pyo3` and `pyo3-ffi` depend upon internally, and prints the appropriate + /// `cargo:rustc-cfg` and `cargo:rustc-check-cfg` directives to enable them. + pub fn print_feature_cfgs() { + print_feature_cfg(84, "const_is_null"); + print_feature_cfg(85, "fn_ptr_eq"); + print_feature_cfg(86, "from_bytes_with_nul_error"); + print_feature_cfg(95, "cfg_select"); + } + + /// Helper to print a feature cfg with a minimum rust version required. + fn print_feature_cfg(minor_version_required: u32, cfg: &str) { + println!("cargo:rustc-check-cfg=cfg({cfg})"); + + let minor_version = rustc_minor_version().unwrap_or(0); + if minor_version >= minor_version_required { + println!("cargo:rustc-cfg={cfg}"); + } + } + + /// Emit libpython rpath link args if appropriate for the target and interpreter config. + /// + /// This form exists for pyo3-ffi where `get()` cannot be called. + pub fn print_libpython_rpath_link_args( + target: &Triple, + interpreter_config: &InterpreterConfig, + ) { + let is_linking_libpython = is_linking_libpython_for_target(target); + let is_wasm = matches!( + target.architecture, + Architecture::Wasm32 | Architecture::Wasm64 + ); + let is_emscripten = target.operating_system == OperatingSystem::Emscripten; + let is_cygwin = target.operating_system == OperatingSystem::Cygwin; + let is_windows = target.operating_system == OperatingSystem::Windows; + // webassembly targets generally don't support rpath, emscripten is the only exception currently aware of: + // https://github.com/emscripten-core/emscripten/issues/22126 + if is_linking_libpython && !is_windows && !is_cygwin && (!is_wasm || is_emscripten) { + if let Some(lib_dir) = interpreter_config.lib_dir() { + println!("cargo:rustc-link-arg=-Wl,-rpath,{lib_dir}"); + } + } + } +} + +fn rustc_minor_version() -> Option { + static RUSTC_MINOR_VERSION: LazyLock> = LazyLock::new(|| { + let rustc = env::var_os("RUSTC")?; + let output = Command::new(rustc).arg("--version").output().ok()?; + let version = core::str::from_utf8(&output.stdout).ok()?; + let mut pieces = version.split('.'); + if pieces.next() != Some("rustc 1") { + return None; + } + pieces.next()?.parse().ok() + }); + *RUSTC_MINOR_VERSION +} + +#[cfg(test)] +#[expect(deprecated, reason = "accessing config directly")] +mod tests { + use crate::impl_::escape; + + use super::*; + + #[test] + fn extension_module_link_args() { + let mut buf = Vec::new(); + + // Does nothing on non-mac + _add_extension_module_link_args( + &Triple::from_str("x86_64-pc-windows-msvc").unwrap(), + &mut buf, + None, + ); + assert_eq!(buf, Vec::new()); + + _add_extension_module_link_args( + &Triple::from_str("x86_64-apple-darwin").unwrap(), + &mut buf, + None, + ); + assert_eq!( + std::str::from_utf8(&buf).unwrap(), + "cargo:rustc-cdylib-link-arg=-undefined\n\ + cargo:rustc-cdylib-link-arg=dynamic_lookup\n" + ); + + buf.clear(); + _add_extension_module_link_args( + &Triple::from_str("wasm32-unknown-emscripten").unwrap(), + &mut buf, + Some(94), + ); + assert_eq!( + std::str::from_utf8(&buf).unwrap(), + "cargo:rustc-cdylib-link-arg=-sSIDE_MODULE=2\n\ + cargo:rustc-cdylib-link-arg=-sWASM_BIGINT\n" + ); + buf.clear(); + _add_extension_module_link_args( + &Triple::from_str("wasm32-unknown-emscripten").unwrap(), + &mut buf, + Some(95), + ); + assert_eq!(std::str::from_utf8(&buf).unwrap(), ""); + } + + #[test] + fn python_framework_link_args() { + let mut buf = Vec::new(); + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY313; + let interpreter_config = InterpreterConfigBuilder::new(implementation, version) + .python_framework_prefix( + "/Applications/Xcode.app/Contents/Developer/Library/Frameworks".to_string(), + ) + .finalize() + .unwrap(); + + // Does nothing on non-mac + _add_python_framework_link_args( + &interpreter_config, + &Triple::from_str("x86_64-pc-windows-msvc").unwrap(), + true, + &mut buf, + ); + assert_eq!(buf, Vec::new()); + + _add_python_framework_link_args( + &interpreter_config, + &Triple::from_str("x86_64-apple-darwin").unwrap(), + true, + &mut buf, + ); + assert_eq!( + std::str::from_utf8(&buf).unwrap(), + "cargo:rustc-link-arg=-Wl,-rpath,/Applications/Xcode.app/Contents/Developer/Library/Frameworks\n" + ); + } + + #[test] + fn test_maximum_version_exceeded_formatting() { + let implementation = PythonImplementation::CPython; + let version = PythonVersion::PY313; + let interpreter_config = InterpreterConfigBuilder::new(implementation, version) + .finalize() + .unwrap(); + let mut error = pyo3_build_script_impl::MaximumVersionExceeded::new( + &interpreter_config, + PythonVersion::PY312, + ); + error.add_help("this is a help message"); + let error = error.finish(); + let expected = concat!("\ + the configured Python version (3.13) is newer than PyO3's maximum supported version (3.12)\n\ + = help: this package is being built with PyO3 version ", env!("CARGO_PKG_VERSION"), "\n\ + = help: check https://crates.io/crates/pyo3 for the latest PyO3 version available\n\ + = help: updating this package to the latest version of PyO3 may provide compatibility with this Python version\n\ + = help: this is a help message" + ); + assert_eq!(error, expected); + } + + #[test] + fn test_interpreter_config_from_cargo_env() { + // There should be no other tests or config in the environment + assert!(InterpreterConfig::from_cargo_dep_env().is_none()); + + let interpreter_config = + InterpreterConfigBuilder::new(PythonImplementation::CPython, PythonVersion::PY313) + .finalize() + .unwrap(); + let mut buf = Vec::new(); + interpreter_config.to_writer(&mut buf).unwrap(); + let config_string = escape(&buf); + // SAFETY: no other tests use `crate::get()` + unsafe { std::env::set_var(InterpreterConfig::PYO3_FFI_CONFIG_ENV_VAR, &config_string) }; + + assert_eq!(get_inner(), interpreter_config); + + // Repeat with PyO3 env var + // SAFETY: no other tests use `crate::get()` + unsafe { + std::env::remove_var(InterpreterConfig::PYO3_FFI_CONFIG_ENV_VAR); + std::env::set_var(InterpreterConfig::PYO3_CONFIG_ENV_VAR, &config_string) + } + + assert_eq!(get_inner(), interpreter_config); + } +} diff --git a/vendor/pyo3-ffi/.cargo-checksum.json b/vendor/pyo3-ffi/.cargo-checksum.json new file mode 100644 index 0000000..adbfff0 --- /dev/null +++ b/vendor/pyo3-ffi/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo_vcs_info.json":"039f415d5f61bb089f476da02570152921b93b8f041d2776f65f6bd4c100d07f","ACKNOWLEDGEMENTS":"417ebd38ebf3dfb26a3796b69b6f657215a81bd43032d0efa658515ebd5a9d21","Cargo.lock":"462608d22f721bcde65042c8acdf90e8dbcc0aaba7d2cd3a665751230efae5a7","Cargo.toml":"246de015ba73057315cb602fbc50f0b36fefb8bc4febb4bef54dce8301b15235","Cargo.toml.orig":"a0310fbf6673048715070bfb268026d4c14cc2976679510d85dbce71c24b617c","LICENSE-APACHE":"32c76dbe0e73d79100d5ece77c158399f2e2541bc5c78548a4ba45c1cb53c5c9","LICENSE-MIT":"afcbe3b2e6b37172b5a9ca869ee4c0b8cdc09316e5d4384864154482c33e5af6","README.md":"dd6839b7f554e51a96fa1dc7e5e330dc2fb86848f6e558ce1066c2241b37c59a","build.rs":"cbfa15e537070983f40b946a3d68bbcfb633af3c51a46ae610a6a4c5661f0765","examples/README.md":"598f11a10ce25ac2bd5cfa6311d53ea0595e8a7ee63cedbf94c92b8398e945ef","src/abstract_.rs":"e55baf2e316ed18cb38d91d9079831dcab49e235bd5ce59235cc2272bdb87956","src/bltinmodule.rs":"f8b5e223a10920756debeb3a85b98584050dc70b96aaa3cdc0a4d4056043671e","src/boolobject.rs":"e4db9ab5adc55b985bbb4ce81501b1359f8ede2c8e1e61935b297b38dfc88842","src/bytearrayobject.rs":"344b62759323eec72134dfdcdd7d5c8c2f814c88b3c90e96a02e95521d141c9d","src/bytesobject.rs":"c747c6a8b2a86133dfbaae191114aeda0e0b8e297643475eff0755d3a0ed9fe2","src/ceval.rs":"1b3f8a16754b962486a15e4dca70124644911150e50ca340a02de070cf75b357","src/codecs.rs":"c0f694fa3303438009435cc6fce4d746e3c07f3e5552fd0e18607d47cf0846c6","src/compat/mod.rs":"c17438ce8a051ae78fff5a9bf0c10a0b8dd762cb56dade7cc66c8690f5e80d97","src/compat/py_3_10.rs":"37f523e2febcb692e2caa0e14b8c3849629b4bb5f1061f48027149e58d82b9d6","src/compat/py_3_13.rs":"11398e75f09c998c50ee25134e6ea9390e8c204cc1a19fe8c13c6690e3a0cb40","src/compat/py_3_14.rs":"b0b68b108cca963de26747c2912f279376a10bcf8625977e437ce6da39dd874d","src/compat/py_3_15.rs":"990d28ec3ecae653244f350d2731517f10d1a212ecaa9506db1f1e41064e7b9f","src/compat/py_3_9.rs":"9e66c7623b18962d3f48f0d0150a6df9e1a3d01de86a776880be886a9b52ee3f","src/compile.rs":"021e3c5d871963a2131daf9b5df1aa92ff5d98f05117b5aa30084a3c833214da","src/complexobject.rs":"f70bcccd5f627483855d02d1153539e64e6cec3d1e6acbc3b631b398e6c39bfd","src/context.rs":"c2af1b0448077501d8109d5887dc318dc7dca5ebf0735dcd4fadc45ca9e37367","src/cpython/abstract_.rs":"d6c99359488e7cf340a9a742632b5cf59a34e275822b53bf7951bb970b5f59c1","src/cpython/bytearrayobject.rs":"d25ef262ed6bdda6965d51851bf1688c82f08fb323610917c5c9f985843d99b1","src/cpython/bytesobject.rs":"3737d7070a94d9c90cdedd4830d366dc7a465729b473fbed0eace9d6c8d76b21","src/cpython/cellobject.rs":"828add6165bd149c50536c8af66483374554c56bff4bc97201e22c3631423c31","src/cpython/ceval.rs":"a0e68e1ac57adbe372ba28b5b95f1a4c98a3da865fac3a938561ee00ae71a49e","src/cpython/code.rs":"62d9a0a73f8458dbcdbd9f9b2c79525565443ba6d6fff583077d321524763840","src/cpython/compile.rs":"e52c0dd125f91f2f5f00e17f8aced3e71ded3279454c94d881727f84cb1eeab2","src/cpython/complexobject.rs":"05df15f224ff1658e9c0ffc5d96803ae86218a0444729f819c2560e2322f29b7","src/cpython/critical_section.rs":"95748f8b9453e97c2e972336eb9af802ca8ec7211ba2be1828f6e224f3c38ead","src/cpython/descrobject.rs":"b16827457b8fadf2ddb5f9a6bc6e8a4ff96fd4bd0a5e0e7d3328e99c8ca7a547","src/cpython/dictobject.rs":"5b97cd13f8743f2c7fbc9642a3c654e328f0ffae2627fe4f1d9ae1ededd390b9","src/cpython/floatobject.rs":"4f2fc08244ba38eefb23a7bdceefaa6e8e06a0d9aa836fa1099315510577cb05","src/cpython/frameobject.rs":"c360ab503783c5c70b9b7353f165736ad7c73e04843f4631f3b87ecd300fcebd","src/cpython/funcobject.rs":"88752a9092da3157b1dacac2b3e1a0fb374206b16d963f8af80c6aeccde3d3ac","src/cpython/genobject.rs":"f49038b5ccddafd2f76e743b3c8b348d4364e25a0eb2867077564277cd7cb101","src/cpython/import.rs":"d1eefc11770d5880c98d9eeafd3db20e89052d097763eb9d26f0db505b95727e","src/cpython/initconfig.rs":"17e7c2a1c8508833a02cca1a7af28bc5130c34f2a031bfc08dca3140e3bd0546","src/cpython/listobject.rs":"fc914682189d84615e5a4887f18bac6d70fbea7957c6fd39ac816dd7858993ba","src/cpython/lock.rs":"124292ef80c2b6b66ccf6791775dccb487033dd4133ccd763b8ff991c956e3b0","src/cpython/longintrepr.rs":"a650a5eb187917de17f79f5233b18d76ea45aa1f1fe44bc06befee014c9f8746","src/cpython/longobject.rs":"5b5bb480ef42756462676d7615d0760302ebe213cfca92fb11e3a74dc3ef6809","src/cpython/marshal.rs":"fb732fcecde87bfd5e3aa09662b10855c4e6f758cd03b271aea217682d31bfb8","src/cpython/methodobject.rs":"955800c979658b52d9fd4aa0b800104788e91b65ecc665206344812659670b7b","src/cpython/mod.rs":"85df06d94d3c6cafd0681eb3d9dccc18b3a9b598ce7a92309e5699828cabee7a","src/cpython/object.rs":"677ddddf1331d4022fb121e10fca3c6307dbb94d10f04e33bd8d641c6fd07e3e","src/cpython/objimpl.rs":"a45474b699b6bc52ec72d9ec38c34ef2f6220da960b0ce5d63336ab182eb2949","src/cpython/pyatomic.rs":"4630ae7c572bad349146a28c6ccb5e0b38462579b07edfe78659fa4cdd4c35dc","src/cpython/pydebug.rs":"b20cef1c02466be5b6cbb0b25e1773c755d4cb6b049584a33113d6e581254a07","src/cpython/pyerrors.rs":"21cab54701badb7d1b0639aa9512e3ccd12c1cf30f83e7b7fbb6cf6c1015bff3","src/cpython/pyframe.rs":"6cb9bcaa117e518d9f891cf4147e477cac2bda372f6a26d33226b9eace6bc9f9","src/cpython/pyhash.rs":"3b8a78273a23445f87824e918346a8b975663e25c4b134a4f3692ccdbfb042e3","src/cpython/pylifecycle.rs":"31c777a9f745bc2c1855fc74ed6e94f4f29b65cd4955c51a1323fa7bbbd73eea","src/cpython/pymem.rs":"7dd1aae076e7242ae90782a20f89640170ed3d7a28a6da66a27824e313fe72a4","src/cpython/pystate.rs":"dd0ebaffcc3fb80e2892dfe2dc4fa9790f29ff12ac5324e61c53c3e7f0fae31b","src/cpython/pythonrun.rs":"6aff1b6242c6157ac9445f03f82ece172acd03c8485ca587b6b4c3773a73d615","src/cpython/setobject.rs":"823d7a976c3ffc5a9e1b62f9385048d2d90b2104e784c3ac94805abae8bca5a1","src/cpython/traceback.rs":"fc28afa684beb695c6f462e420f8beb3469d7163642ea1d38c3a5eec5fc591a8","src/cpython/tupleobject.rs":"e5541fb0f5a3e793db8456d76ba34712a64d3749de737ff3047a34917b70ccdd","src/cpython/unicodeobject.rs":"571e8818f8f897ab28703d7f8c89793bcae4b5fa2c6c0cadbe3612c7191a5613","src/cpython/warnings.rs":"3fa3383106bfb5795ad93a7f98fd732518d9dbd40c2bddb7dd808c881145e92a","src/cpython/weakrefobject.rs":"8ac87ae940a47e9fa1045f894b2f452123c8c049f626298f77e2500889337a3c","src/critical_section.rs":"504bcbf6733c23a7c6833179a2ddde8203c96e47b64cf5e668afa0592bdc4829","src/datetime.rs":"cfcb3a34892e2cf11efde258755edf5a4476efdd57fac248a77309942017de22","src/descrobject.rs":"be4abbf6700b25d577708794957beb72af0c4dd394fcd1c28e7c411151a0c2f1","src/dictobject.rs":"c7865c256891bd6055cdcc4829b61633587893cfdba8535aa1f34d130d6e81e4","src/enumobject.rs":"5867695e03c7a7926c38dfd3f4978b944d9485cce4df684912bf5bcacd36fe54","src/fileobject.rs":"ddf82068fbeea6f8c558901bdc39753fbd1b68c910673877dfe96c0a493d1c54","src/fileutils.rs":"54536328c2a9487e9448a612c509b04dc6d72ebc6bf9975e4584827e381ed42d","src/floatobject.rs":"2bd4f9e834dbaaacd770fb2478603996c26defc93664160dd1c3851e7c703c80","src/genericaliasobject.rs":"a2d4090bce356b8e632f2abff894830966e03c511f4c3441eff4a47020225bf9","src/impl_/macros.rs":"84a5a0feb946645d060eed6e6326cc33c47bf9d413532b201be4cd09f4bb7d52","src/impl_/mod.rs":"4771e480230043048eb629de3bc0c6d6ab953e039b62f7aaaf12dddc05591c81","src/import.rs":"b5f341139ee53c44a730e0a826026a7b4358505f0293f54d48a2a74d836b0f37","src/intrcheck.rs":"5edcc2994b88cad641df038509d765d64ec11bb8edb44afeb693da90296aace5","src/iterobject.rs":"30f6da851efd0b7feb3ed92c518a1b13e193f102a674e0b93aa900790e3888bb","src/lib.rs":"58b6a15924e2fb37f12319736186b2605b6f348099b240c751fbf4b98cbc7035","src/listobject.rs":"82e5cb9786f2cbaa076795e9470a34f9376415e5452760c32848b82d2e0303c7","src/longobject.rs":"792f0088b3fa9772ad07ae95c61669dfe43abc98418ddcd83a5c55b2a73ce8fa","src/memoryobject.rs":"9ff7a89f27173e3c0f5b06627bc1ab22f7256647147de584dbbfb452a412668f","src/methodobject.rs":"34e819c496e612019631bce8c36843a34c85811ebf553de1a9a2f2e66b87832a","src/modsupport.rs":"fbb1ced6411e49c6013ba5add33a5cf867c6c198cdf42a5c18713f8f46da4e40","src/moduleobject.rs":"7e8e9a3e2db84a18d7a951fd577232269d3224cb385a6589feb84b135bb4e5a4","src/object.rs":"86af57c5d49578e569d072d7d267bb327f4011c5bad99baaa927dc277ff17dc2","src/objimpl.rs":"87a5500fdff7dcc20f4ca7c5c439e349e9e7c3d4d5bca1719aaa64f08647d9a5","src/osmodule.rs":"940d409571fd8998895140facd688b56bb2e4b548db88d886eb57242124261af","src/pyarena.rs":"d174216593b1aff58383c0c68d3fe2bd7144ed7fe75a0eadae5b50cba615cf30","src/pybuffer.rs":"4ed63aceb52b26567b8e7381bb06477bf65dcbdf0854e038822add2ac1f7de68","src/pycapsule.rs":"42ec0e8b728694d9e892d19ae5780b85f766d42823531aee776f492a0df27431","src/pyerrors.rs":"88091f209e2464236c56791d5beec4733276f288c6fc330f0d4ca39ecd93e7f4","src/pyframe.rs":"3a349b9e787838e57c22df500b3c3994d9417c033b6f79318f70e07e63cbede2","src/pyhash.rs":"c3bccd575dae52478b358c5a2ff155c0a1811ab1b0bb8017acd63bd36445d4b8","src/pylifecycle.rs":"80aefc1da99101a809bc6ea27223c79bf81e3df618c7677f7c87212e76e6ec45","src/pymem.rs":"d0d52b847ccbf687878ae785cfcfed84b339a10e882a88bfc00936a879230bd9","src/pyport.rs":"75c2aa362ef45e17df8f3074b913dcf1acdf0752e7ff9b939cfd6777ab772b8e","src/pystate.rs":"defd84f9088346006c0ebfc6d4f8dc17197690b9fbe93a245a33a1dc5dc45407","src/pystrtod.rs":"657aa45f589030832c02bdeeb62cfd35306a1798c845d307b0d1d823c092b2aa","src/pythonrun.rs":"58db71ebe91d9c5306cbd12be738a4bf6450ec806585276c2a4e9801a1f3fb97","src/pytypedefs.rs":"d302deaa3777b2ccf0a06a83a730087d1b71d2a771a4b6cd30561ceeb84a6b45","src/rangeobject.rs":"6d89e8c4b8954962cecbd3930632fd6f0cde4c3b8de7abcfdc0a01c5da7201b2","src/refcount.rs":"84340e19ca85f69858bff0a6fb5c8bde0840b37486450849ffafd20635e3d147","src/setobject.rs":"2f4d6d032d97ffe26fee38e7c86077f94959c4ff0c67c024c0af00965d2aa0f3","src/sliceobject.rs":"248fefc9d608039996d88c48f42dd2a4ebae94eefd8153624477e6ae846b0e4d","src/slots.rs":"fcca4d197514f21953be2f9f5a3a689835e1d711f2fd4330de2aa622040784fb","src/slots_generated.rs":"5bab166670a89453f6ce5974ec8128babebedea6241b81c3f98f91e5068cfcea","src/structmember.rs":"cec1987eb22666038db964c1a7c0675249ed0ed25aabdb8990d88f85fa7684fe","src/structseq.rs":"23f8b14ede368397ef168db87b3447e2b9ff48940b9d5963754f7d630339db33","src/sysmodule.rs":"70aecbd3b98c86591144ef3bbf9fa2cd48f2d7b4ec3305cc737ff7487493e293","src/traceback.rs":"675f3b960453782c5abfbdf8bed62ef381b3556f3a0f57bea2373671303f4f91","src/tupleobject.rs":"b9316e6990300bd094d096a946994e72a026a56f2d272d699c1da3aff335e2dd","src/unicodeobject.rs":"766640f148ef1f12545d9da7c9331abd990d079d95520b23a7861182e82d5bb1","src/warnings.rs":"2813b95569f42fe8c352c18aaff768a140660c0e239c925633525afff80d91b5","src/weakrefobject.rs":"b0bbdbc78ea10a7984006352804974630220b38eafc11b74326883b32c8b41ea"},"package":"e591a95526fead067432c3b3a33fc74770b87b1e04e73671090d9c2055a2b327"} \ No newline at end of file diff --git a/vendor/pyo3-ffi/.cargo_vcs_info.json b/vendor/pyo3-ffi/.cargo_vcs_info.json new file mode 100644 index 0000000..b57e797 --- /dev/null +++ b/vendor/pyo3-ffi/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "a70d17f898df41b3d1632ee987f624f5222d8d39" + }, + "path_in_vcs": "pyo3-ffi" +} \ No newline at end of file diff --git a/vendor/pyo3-ffi/ACKNOWLEDGEMENTS b/vendor/pyo3-ffi/ACKNOWLEDGEMENTS new file mode 100644 index 0000000..8b20727 --- /dev/null +++ b/vendor/pyo3-ffi/ACKNOWLEDGEMENTS @@ -0,0 +1,6 @@ +This is a Rust reimplementation of the CPython public header files as necessary +for binary compatibility, with additional metadata to support PyPy. + +For original implementations please see: + - https://github.com/python/cpython + - https://github.com/pypy/pypy diff --git a/vendor/pyo3-ffi/Cargo.lock b/vendor/pyo3-ffi/Cargo.lock new file mode 100644 index 0000000..3db42a8 --- /dev/null +++ b/vendor/pyo3-ffi/Cargo.lock @@ -0,0 +1,39 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pyo3-build-config" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f41027e41b4bd03f6e60f9f417fe24a6341a6bb744edd62b6f709f2a52ea30e9" +dependencies = [ + "target-lexicon", +] + +[[package]] +name = "pyo3-ffi" +version = "0.29.2" +dependencies = [ + "libc", + "paste", + "pyo3-build-config", +] + +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" diff --git a/vendor/pyo3-ffi/Cargo.toml b/vendor/pyo3-ffi/Cargo.toml new file mode 100644 index 0000000..2aec455 --- /dev/null +++ b/vendor/pyo3-ffi/Cargo.toml @@ -0,0 +1,121 @@ +# 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.83" +name = "pyo3-ffi" +version = "0.29.2" +authors = ["PyO3 Project and Contributors "] +build = "build.rs" +links = "python" +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Python-API bindings for the PyO3 ecosystem" +homepage = "https://github.com/pyo3/pyo3" +readme = "README.md" +keywords = [ + "pyo3", + "python", + "cpython", + "ffi", +] +categories = [ + "api-bindings", + "development-tools::ffi", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/pyo3/pyo3" + +[package.metadata.cpython] +min-version = "3.8" +max-version = "3.15" + +[package.metadata.pypy] +min-version = "3.11" +max-version = "3.11" + +[package.metadata.graalpy] +min-version = "3.12" +max-version = "3.13" + +[features] +abi3 = [] +abi3-py310 = ["abi3-py311"] +abi3-py311 = ["abi3-py312"] +abi3-py312 = ["abi3-py313"] +abi3-py313 = ["abi3-py314"] +abi3-py314 = ["abi3-py315"] +abi3-py315 = ["abi3"] +abi3-py38 = ["abi3-py39"] +abi3-py39 = ["abi3-py310"] +abi3t = [] +abi3t-py315 = ["abi3t"] +default = [] +extension-module = ["pyo3-build-config/extension-module"] +generate-import-lib = ["pyo3-build-config/generate-import-lib"] + +[lib] +name = "pyo3_ffi" +path = "src/lib.rs" + +[dependencies.libc] +version = "0.2.62" + +[dev-dependencies.paste] +version = "1" + +[build-dependencies.pyo3-build-config] +version = "=0.29.2" + +[lints.clippy] +checked_conversions = "warn" +dbg_macro = "warn" +explicit_into_iter_loop = "warn" +explicit_iter_loop = "warn" +filter_map_next = "warn" +flat_map_option = "warn" +let_unit_value = "warn" +manual_assert = "warn" +manual_ok_or = "warn" +todo = "warn" +undocumented_unsafe_blocks = "warn" +unnecessary_wraps = "warn" +used_underscore_binding = "warn" +useless_transmute = "warn" + +[lints.rust] +elided_lifetimes_in_paths = "warn" +invalid_doc_attributes = "warn" +rust_2021_prelude_collisions = "warn" +unsafe_op_in_unsafe_fn = "warn" +unused_lifetimes = "warn" + +[lints.rust.rust_2018_idioms] +level = "warn" +priority = -1 + +[lints.rust.unexpected_cfgs] +level = "warn" +priority = 0 +check-cfg = [ + "cfg(pyo3_disable_reference_pool)", + "cfg(pyo3_leak_on_drop_without_reference_pool)", + "cfg(pyo3_use_raw_dylib)", + 'cfg(pyo3_dll, values("python3", "python3_d", "python3t", "python3t_d", "python38", "python38_d", "python39", "python39_d", "python310", "python310_d", "python311", "python311_d", "python312", "python312_d", "python313", "python313_d", "python313t", "python313t_d", "python314", "python314_d", "python314t", "python314t_d", "python315", "python315_d", "python315t", "python315t_d", "python316", "python316_d", "python316t", "python316t_d", "libpypy3.11-c"))', +] + +[lints.rustdoc] +bare_urls = "warn" +broken_intra_doc_links = "warn" diff --git a/vendor/pyo3-ffi/Cargo.toml.orig b/vendor/pyo3-ffi/Cargo.toml.orig new file mode 100644 index 0000000..8fc25ab --- /dev/null +++ b/vendor/pyo3-ffi/Cargo.toml.orig @@ -0,0 +1,63 @@ +[package] +name = "pyo3-ffi" +version = "0.29.2" +description = "Python-API bindings for the PyO3 ecosystem" +authors = ["PyO3 Project and Contributors "] +keywords = ["pyo3", "python", "cpython", "ffi"] +homepage = "https://github.com/pyo3/pyo3" +repository = "https://github.com/pyo3/pyo3" +categories = ["api-bindings", "development-tools::ffi"] +license = "MIT OR Apache-2.0" +edition = "2021" +links = "python" +rust-version.workspace = true + +[dependencies] +libc = "0.2.62" + +[features] + +default = [] + +# Use the Python limited API. See https://www.python.org/dev/peps/pep-0384/ for more. +abi3 = [] + +# Use the Free-threaded Python limited API. See https://www.python.org/dev/peps/pep-0803/ for more. +abi3t = [] + +# With abi3, we can manually set the minimum Python version. +abi3-py38 = ["abi3-py39"] +abi3-py39 = ["abi3-py310"] +abi3-py310 = ["abi3-py311"] +abi3-py311 = ["abi3-py312"] +abi3-py312 = ["abi3-py313"] +abi3-py313 = ["abi3-py314"] +abi3-py314 = ["abi3-py315"] +abi3-py315 = ["abi3"] + +abi3t-py315 = ["abi3t"] + +# deprecated +extension-module = ["pyo3-build-config/extension-module"] +generate-import-lib = ["pyo3-build-config/generate-import-lib"] + +[dev-dependencies] +paste = "1" + +[build-dependencies] +pyo3-build-config = { path = "../pyo3-build-config", version = "=0.29.2" } + +[lints] +workspace = true + +[package.metadata.cpython] +min-version = "3.8" +max-version = "3.15" # inclusive + +[package.metadata.pypy] +min-version = "3.11" +max-version = "3.11" # inclusive + +[package.metadata.graalpy] +min-version = "3.12" +max-version = "3.13" # inclusive diff --git a/vendor/pyo3-ffi/LICENSE-APACHE b/vendor/pyo3-ffi/LICENSE-APACHE new file mode 100644 index 0000000..72207b8 --- /dev/null +++ b/vendor/pyo3-ffi/LICENSE-APACHE @@ -0,0 +1,178 @@ +Copyright (c) 2017-present PyO3 Project and Contributors. https://github.com/PyO3 + + 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/pyo3-ffi/LICENSE-MIT b/vendor/pyo3-ffi/LICENSE-MIT new file mode 100644 index 0000000..cd0ad00 --- /dev/null +++ b/vendor/pyo3-ffi/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2023-present PyO3 Project and Contributors. https://github.com/PyO3 + +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/pyo3-ffi/README.md b/vendor/pyo3-ffi/README.md new file mode 100644 index 0000000..8962c3a --- /dev/null +++ b/vendor/pyo3-ffi/README.md @@ -0,0 +1,286 @@ +# pyo3-ffi + +This crate provides [Rust](https://www.rust-lang.org/) FFI declarations for Python 3. +It supports both the stable and the unstable component of the ABI through the use of cfg flags. +Python Versions 3.8+ are supported. +It is meant for advanced users only - regular PyO3 users shouldn't +need to interact with this crate at all. + +The contents of this crate are not documented here, as it would entail +basically copying the documentation from CPython. Consult the [Python/C API Reference +Manual][capi] for up-to-date documentation. + +# Minimum supported Rust and Python versions + +Requires Rust 1.83 or greater. + +`pyo3-ffi` supports the following Python distributions: + - CPython 3.8 or greater + - PyPy 7.3 (Python 3.9+) + - GraalPy 24.0 or greater (Python 3.10+) + +# Example: Building Python Native modules + +PyO3 can be used to generate a native Python module. The easiest way to try this out for the +first time is to use [`maturin`]. `maturin` is a tool for building and publishing Rust-based +Python packages with minimal configuration. The following steps set up some files for an example +Python module, install `maturin`, and then show how to build and import the Python module. + +First, create a new folder (let's call it `string_sum`) containing the following two files: + +**`Cargo.toml`** + +```toml +[lib] +name = "string_sum" +# "cdylib" is necessary to produce a shared library for Python to import from. +# +# Downstream Rust code (including code in `bin/`, `examples/`, and `tests/`) will not be able +# to `use string_sum;` unless the "rlib" or "lib" crate type is also included, e.g.: +# crate-type = ["cdylib", "rlib"] +crate-type = ["cdylib"] + +[dependencies] +pyo3-ffi = "0.29.2" + +[build-dependencies] +# This is only necessary if you need to configure your build based on +# the Python version or the compile-time configuration for the interpreter. +pyo3_build_config = "0.29.2" +``` + +If you need to use conditional compilation based on Python version or how +Python was compiled, you need to add `pyo3-build-config` as a +`build-dependency` in your `Cargo.toml` as in the example above and either +create a new `build.rs` file or modify an existing one so that +`pyo3_build_config::use_pyo3_cfgs()` gets called at build time: + +**`build.rs`** + +```rust,ignore +fn main() { + pyo3_build_config::use_pyo3_cfgs() +} +``` + +**`src/lib.rs`** +```rust,no_run +#[cfg(Py_3_15)] +use std::ffi::c_void; +use std::ffi::{c_char, c_long}; +use std::ptr; + +use pyo3_ffi::*; + +#[cfg(not(Py_3_15))] +static mut MODULE_DEF: PyModuleDef = PyModuleDef { + m_base: PyModuleDef_HEAD_INIT, + m_name: c"string_sum".as_ptr(), + m_doc: c"A Python module written in Rust.".as_ptr(), + m_size: 0, + m_methods: (&raw mut METHODS).cast(), + m_slots: (&raw mut SLOTS).cast(), + m_traverse: None, + m_clear: None, + m_free: None, +}; + +static mut METHODS: [PyMethodDef; 2] = [ + PyMethodDef { + ml_name: c"sum_as_string".as_ptr(), + ml_meth: PyMethodDefPointer { + PyCFunctionFast: sum_as_string, + }, + ml_flags: METH_FASTCALL, + ml_doc: c"returns the sum of two integers as a string".as_ptr(), + }, + // A zeroed PyMethodDef to mark the end of the array. + PyMethodDef::zeroed(), +]; + +#[cfg(Py_3_15)] +PyABIInfo_VAR!(ABI_INFO); + +const SLOTS_LEN: usize = + 1 + cfg!(Py_3_12) as usize + cfg!(Py_GIL_DISABLED) as usize + 4 * (cfg!(Py_3_15) as usize); +static mut SLOTS: [PyModuleDef_Slot; SLOTS_LEN] = [ + #[cfg(Py_3_15)] + PyModuleDef_Slot { + slot: Py_mod_abi, + value: (&raw mut ABI_INFO).cast(), + }, + #[cfg(Py_3_15)] + PyModuleDef_Slot { + slot: Py_mod_name, + // safety: Python does not write to this field + value: c"string_sum".as_ptr() as *mut c_void, + }, + #[cfg(Py_3_15)] + PyModuleDef_Slot { + slot: Py_mod_doc, + // safety: Python does not write to this field + value: c"A Python module written in Rust.".as_ptr() as *mut c_void, + }, + #[cfg(Py_3_15)] + PyModuleDef_Slot { + slot: Py_mod_methods, + value: (&raw mut METHODS).cast(), + }, + #[cfg(Py_3_12)] + PyModuleDef_Slot { + slot: Py_mod_multiple_interpreters, + value: Py_MOD_PER_INTERPRETER_GIL_SUPPORTED, + }, + #[cfg(Py_GIL_DISABLED)] + PyModuleDef_Slot { + slot: Py_mod_gil, + value: Py_MOD_GIL_NOT_USED, + }, + PyModuleDef_Slot { + slot: 0, + value: ptr::null_mut(), + }, +]; + +// The module initialization function +#[cfg(not(Py_3_15))] +#[allow(non_snake_case, reason = "must be named `PyInit_`")] +#[no_mangle] +pub unsafe extern "C" fn PyInit_string_sum() -> *mut PyObject { + PyModuleDef_Init(&raw mut MODULE_DEF) +} + +#[cfg(Py_3_15)] +#[allow(non_snake_case, reason = "must be named `PyModExport_`")] +#[no_mangle] +pub unsafe extern "C" fn PyModExport_string_sum() -> *mut PyModuleDef_Slot { + (&raw mut SLOTS).cast() +} + +/// A helper to parse function arguments +/// If we used PyO3's proc macros they'd handle all of this boilerplate for us :) +unsafe fn parse_arg_as_i32(obj: *mut PyObject, n_arg: usize) -> Option { + if PyLong_Check(obj) == 0 { + let msg = format!( + "sum_as_string expected an int for positional argument {}\0", + n_arg + ); + PyErr_SetString(PyExc_TypeError, msg.as_ptr().cast::()); + return None; + } + + // Let's keep the behaviour consistent on platforms where `c_long` is bigger than 32 bits. + // In particular, it is an i32 on Windows but i64 on most Linux systems + let mut overflow = 0; + let i_long: c_long = PyLong_AsLongAndOverflow(obj, &mut overflow); + + #[allow( + irrefutable_let_patterns, + reason = "some platforms have c_long equal to i32" + )] + if overflow != 0 { + raise_overflowerror(obj); + None + } else if let Ok(i) = i_long.try_into() { + Some(i) + } else { + raise_overflowerror(obj); + None + } +} + +unsafe fn raise_overflowerror(obj: *mut PyObject) { + let obj_repr = PyObject_Str(obj); + if !obj_repr.is_null() { + let mut size = 0; + let p = PyUnicode_AsUTF8AndSize(obj_repr, &mut size); + if !p.is_null() { + let s = std::str::from_utf8_unchecked(std::slice::from_raw_parts( + p.cast::(), + size as usize, + )); + let msg = format!("cannot fit {} in 32 bits\0", s); + + PyErr_SetString(PyExc_OverflowError, msg.as_ptr().cast::()); + } + Py_DECREF(obj_repr); + } +} + +pub unsafe extern "C" fn sum_as_string( + _self: *mut PyObject, + args: *mut *mut PyObject, + nargs: Py_ssize_t, +) -> *mut PyObject { + if nargs != 2 { + PyErr_SetString( + PyExc_TypeError, + c"sum_as_string expected 2 positional arguments".as_ptr(), + ); + return std::ptr::null_mut(); + } + + let (first, second) = (*args, *args.add(1)); + + let first = match parse_arg_as_i32(first, 1) { + Some(x) => x, + None => return std::ptr::null_mut(), + }; + let second = match parse_arg_as_i32(second, 2) { + Some(x) => x, + None => return std::ptr::null_mut(), + }; + + match first.checked_add(second) { + Some(sum) => { + let string = sum.to_string(); + PyUnicode_FromStringAndSize(string.as_ptr().cast::(), string.len() as isize) + } + None => { + PyErr_SetString(PyExc_OverflowError, c"arguments too large to add".as_ptr()); + std::ptr::null_mut() + } + } +} +``` + +With those two files in place, now `maturin` needs to be installed. This can be done using +Python's package manager `pip`. First, load up a new Python `virtualenv`, and install `maturin` +into it: +```bash +$ cd string_sum +$ python -m venv .env +$ source .env/bin/activate +$ pip install maturin +``` + +Now build and execute the module: +```bash +$ maturin develop +# lots of progress output as maturin runs the compilation... +$ python +>>> import string_sum +>>> string_sum.sum_as_string(5, 20) +'25' +``` + +As well as with `maturin`, it is possible to build using [setuptools-rust] or +[manually][manual_builds]. Both offer more flexibility than `maturin` but require further +configuration. + + +While most projects use the safe wrapper provided by PyO3, +you can take a look at the [`orjson`] library as an example on how to use `pyo3-ffi` directly. +For those well versed in C and Rust the [tutorials] from the CPython documentation +can be easily converted to rust as well. + +[tutorials]: https://docs.python.org/3/extending/ +[`orjson`]: https://github.com/ijl/orjson +[capi]: https://docs.python.org/3/c-api/index.html +[`maturin`]: https://github.com/PyO3/maturin "Build and publish crates with pyo3, rust-cpython and cffi bindings as well as rust binaries as python packages" +[`pyo3-build-config`]: https://docs.rs/pyo3-build-config +[feature flags]: https://doc.rust-lang.org/cargo/reference/features.html "Features - The Cargo Book" +[manual_builds]: https://pyo3.rs/latest/building-and-distribution.html#manual-builds "Manual builds - Building and Distribution - PyO3 user guide" +[setuptools-rust]: https://github.com/PyO3/setuptools-rust "Setuptools plugin for Rust extensions" +[PEP 384]: https://www.python.org/dev/peps/pep-0384 "PEP 384 -- Defining a Stable ABI" +[Features chapter of the guide]: https://pyo3.rs/latest/features.html#features-reference "Features Reference - PyO3 user guide" diff --git a/vendor/pyo3-ffi/build.rs b/vendor/pyo3-ffi/build.rs new file mode 100644 index 0000000..7ec773c --- /dev/null +++ b/vendor/pyo3-ffi/build.rs @@ -0,0 +1,369 @@ +use pyo3_build_config::{ + bail, ensure, + pyo3_build_script_impl::{ + cargo_env_var, env_var, errors::Result, is_linking_libpython_for_target, + print_feature_cfgs, print_libpython_rpath_link_args, resolve_build_config, + target_triple_from_env, BuildConfig, BuildConfigSource, MaximumVersionExceeded, + }, + warn, InterpreterConfig, PythonAbiKind, PythonImplementation, PythonVersion, StableAbi, +}; + +/// Minimum Python version PyO3 supports. +struct SupportedVersions { + min: PythonVersion, + max: PythonVersion, +} + +const SUPPORTED_VERSIONS_CPYTHON: SupportedVersions = SupportedVersions { + min: PythonVersion { major: 3, minor: 8 }, + max: PythonVersion { + major: 3, + minor: 15, + }, +}; + +const SUPPORTED_VERSIONS_PYPY: SupportedVersions = SupportedVersions { + min: PythonVersion { + major: 3, + minor: 11, + }, + max: SUPPORTED_VERSIONS_CPYTHON.max, +}; + +const SUPPORTED_VERSIONS_GRAALPY: SupportedVersions = SupportedVersions { + min: PythonVersion { + major: 3, + minor: 10, + }, + max: SUPPORTED_VERSIONS_CPYTHON.max, +}; + +const MIN_FREE_THREADED_VERSION: PythonVersion = PythonVersion { + major: 3, + minor: 14, +}; + +const PY_3_15: PythonVersion = PythonVersion { + major: 3, + minor: 15, +}; + +fn ensure_python_version(interpreter_config: &InterpreterConfig) -> Result<()> { + // This is an undocumented env var which is only really intended to be used in CI / for testing + // and development. + if std::env::var("UNSAFE_PYO3_SKIP_VERSION_CHECK").as_deref() == Ok("1") { + return Ok(()); + } + + match interpreter_config.target_abi().implementation() { + PythonImplementation::CPython => { + let versions = SUPPORTED_VERSIONS_CPYTHON; + let interp_version = interpreter_config.target_abi().version(); + ensure!( + interpreter_config.version() >= versions.min, + "the configured Python interpreter version ({}) is lower than PyO3's minimum supported version ({})", + interpreter_config.version(), + versions.min, + ); + let v_plus_1 = PythonVersion { + major: versions.max.major, + minor: versions.max.minor + 1, + }; + if interp_version == v_plus_1 { + warn!( + "Using experimental support for the Python {}.{} ABI. \ + Build artifacts may not be compatible with the final release of CPython, \ + so do not distribute them.", + v_plus_1.major, v_plus_1.minor, + ); + } else if interp_version > v_plus_1 { + let mut error = MaximumVersionExceeded::new(interpreter_config, versions.max); + if interpreter_config.target_abi().kind().is_free_threaded() { + if interp_version >= PY_3_15 { + if env_var("PYO3_USE_STABLE_ABI_FORWARD_COMPATIBILITY") + .is_none_or(|os_str| os_str != "1") + { + error.add_help( + "set PYO3_USE_STABLE_ABI_FORWARD_COMPATIBILITY=1 to suppress this check and build anyway using the free-threaded stable ABI" + ); + return Err(error.finish().into()); + } + } else { + error.add_help(format!( + "the free-threaded build of CPython {}.{} does not support the limited API so this check cannot be suppressed.", interp_version.major, interp_version.minor + ).as_str()); + return Err(error.finish().into()); + } + } + if env_var("PYO3_USE_ABI3_FORWARD_COMPATIBILITY").is_none_or(|os_str| os_str != "1") + && env_var("PYO3_USE_STABLE_ABI_FORWARD_COMPATIBILITY") + .is_none_or(|os_str| os_str != "1") + { + error.add_help("set PYO3_USE_STABLE_ABI_FORWARD_COMPATIBILITY=1 to suppress this check and build anyway using the stable ABI"); + return Err(error.finish().into()); + } + } + + if interpreter_config.target_abi().kind().is_free_threaded() { + ensure!( + interpreter_config.target_abi().version() >= MIN_FREE_THREADED_VERSION, + "PyO3 does not support the free-threaded build of CPython versions below {}, the selected Python version is {}", + MIN_FREE_THREADED_VERSION, + interpreter_config.target_abi().version(), + ); + } + } + PythonImplementation::PyPy => { + let versions = SUPPORTED_VERSIONS_PYPY; + ensure!( + interpreter_config.target_abi().version() >= versions.min, + "the configured PyPy interpreter version ({}) is lower than PyO3's minimum supported version ({})", + interpreter_config.target_abi().version(), + versions.min, + ); + // PyO3 does not support abi3, so we cannot offer forward compatibility + if interpreter_config.target_abi().version() > versions.max { + let error = MaximumVersionExceeded::new(interpreter_config, versions.max); + return Err(error.finish().into()); + } + } + PythonImplementation::GraalPy => { + let versions = SUPPORTED_VERSIONS_GRAALPY; + ensure!( + interpreter_config.target_abi().version() >= versions.min, + "the configured GraalPy interpreter version ({}) is lower than PyO3's minimum supported version ({})", + interpreter_config.target_abi().version(), + versions.min, + ); + // GraalPy does not support abi3, so we cannot offer forward compatibility + if interpreter_config.target_abi().version() > versions.max { + let error = MaximumVersionExceeded::new(interpreter_config, versions.max); + return Err(error.finish().into()); + } + } + PythonImplementation::RustPython => {} + } + + if let PythonAbiKind::Stable(abi) = interpreter_config.target_abi().kind() { + match interpreter_config.target_abi().implementation() { + PythonImplementation::CPython => match abi { + StableAbi::Abi3t => { + ensure!( + interpreter_config.target_abi().version() >= PY_3_15, + "Abi3t builds are not supported on CPython targets before Python 3.15" + ) + } + StableAbi::Abi3 => {} + }, + PythonImplementation::PyPy => warn!( + "PyPy does not yet support {abi} so the build artifacts will be version-specific. \ + See https://github.com/pypy/pypy/issues/3397 for more information." + ), + PythonImplementation::GraalPy => warn!( + "GraalPy does not support {abi} so the build artifacts will be version-specific." + ), + PythonImplementation::RustPython => {} + } + } + + Ok(()) +} + +fn ensure_target_pointer_width(interpreter_config: &InterpreterConfig) -> Result<()> { + if let Some(pointer_width) = interpreter_config.pointer_width() { + // Try to check whether the target architecture matches the python library + let rust_target = match cargo_env_var("CARGO_CFG_TARGET_POINTER_WIDTH") + .unwrap() + .as_str() + { + "64" => 64, + "32" => 32, + x => bail!("unexpected Rust target pointer width: {}", x), + }; + + ensure!( + rust_target == pointer_width, + "your Rust target architecture ({}-bit) does not match your python interpreter ({}-bit)", + rust_target, + pointer_width + ); + } + Ok(()) +} + +/// `raw-dylib` currently does not support arbitrary names +/// (see https://internals.rust-lang.org/t/support-renames-with-link-name-kind-raw-dylib/24415) +/// so if the lib name is not one of the known subset, we must fall back to full linking. +fn lib_name_is_known_for_raw_dylib(lib_name: &str) -> bool { + // pyo3_dll cfg for raw-dylib linking on Windows + if matches!( + lib_name, + "python3" | "python3_d" | "python3t" | "python3t_d" + ) { + return true; + } + + // support raw-dylib linking for all CPython versions supported, plus the next prerelease + for i in SUPPORTED_VERSIONS_CPYTHON.min.minor..=SUPPORTED_VERSIONS_CPYTHON.max.minor + 1 { + if lib_name == format!("python3{i}") || lib_name == format!("python3{i}_d") { + return true; + } + if i >= 13 && (lib_name == format!("python3{i}t") || lib_name == format!("python3{i}t_d")) { + return true; + } + } + // PyPy DLL names (libpypy3.X-c.dll) + for i in SUPPORTED_VERSIONS_PYPY.min.minor..=SUPPORTED_VERSIONS_PYPY.max.minor { + if lib_name == format!("libpypy3.{i}-c") { + return true; + } + } + + false +} + +/// Whether to use raw-dylib linking. +/// +/// Currently, this only applies if all of the following are true: +/// - The target OS is Windows. +/// - The Python library name is one of the [known subset][lib_name_is_known_for_raw_dylib]. +/// - The `PYO3_USE_RAW_DYLIB` environment variable is not set, or is set to `1`. +/// +/// NB in some cases (e.g. mixed C / Rust builds) it might be necessary to link the full Python +/// library rather than rely on the symbols which PyO3 defines as raw-dylib, which is why +/// we have the opt-out env var. +fn should_use_raw_dylib_linking(lib_name: &str) -> bool { + let target_os = cargo_env_var("CARGO_CFG_TARGET_OS").unwrap(); + if target_os != "windows" { + return false; + } + + match ( + lib_name_is_known_for_raw_dylib(lib_name), + env_var("PYO3_USE_RAW_DYLIB"), + ) { + (true, None) => true, + (true, Some(os_str)) if os_str == "1" => true, + (false, Some(os_str)) if os_str == "1" => { + warn!( + "PYO3_USE_RAW_DYLIB is set to 1 but the Python library name is not recognized. \ + Falling back to full linking." + ); + false + } + _ => false, + } +} + +fn emit_link_config(build_config: &BuildConfig) -> Result<()> { + let target_os = cargo_env_var("CARGO_CFG_TARGET_OS").unwrap(); + let interpreter_config = &build_config.interpreter_config; + + let lib_name = interpreter_config + .lib_name() + .ok_or("attempted to link to Python shared library but config does not contain lib_name")?; + + if should_use_raw_dylib_linking(lib_name) { + // Use raw-dylib linking: emit a cfg so that `extern_libpython!` picks the + // right `#[link(name = "...", kind = "raw-dylib")]` attribute at compile time. + // This eliminates the need for import libraries (.lib files) entirely. + // + // Note: raw-dylib is inherently dynamic linking. Static embedding of the + // Python interpreter on Windows is not supported by this path (and is not + // officially supported by CPython on Windows). + println!("cargo:rustc-cfg=pyo3_use_raw_dylib"); + println!("cargo:rustc-cfg=pyo3_dll=\"{lib_name}\""); + return Ok(()); + } + + println!( + "cargo:rustc-link-lib={link_model}{alias}{lib_name}", + link_model = if interpreter_config.shared() { + "" + } else { + "static=" + }, + // on windows we emit `#[link(name = "pythonXY")]` attributes + // and need this alias here to get the right name for the final link + alias = if target_os == "windows" { + "pythonXY:" + } else { + "" + } + ); + + if let Some(lib_dir) = interpreter_config.lib_dir() { + println!("cargo:rustc-link-search=native={lib_dir}"); + } else if matches!(build_config.source, BuildConfigSource::CrossCompile) { + warn!( + "The output binary will link to libpython, \ + but PYO3_CROSS_LIB_DIR environment variable is not set. \ + Ensure that the target Python library directory is \ + in the rustc native library search path." + ); + } + + Ok(()) +} + +/// Prepares the PyO3 crate for compilation. +/// +/// This uses pyo3-build-config implementation to detect the target Python interpreter and validate +/// it's suitable for building with. +/// +/// Emits the cargo configuration based on this config as well as a few checks of the Rust compiler +/// version to enable features which aren't supported on MSRV. +fn configure_pyo3_ffi() -> Result<()> { + let target = target_triple_from_env(); + let build_config = resolve_build_config(&target)?; + let interpreter_config = &build_config.interpreter_config; + + if env_var("PYO3_PRINT_CONFIG").is_some_and(|os_str| os_str == "1") { + print_config_and_exit(interpreter_config); + } + + ensure_python_version(interpreter_config)?; + ensure_target_pointer_width(interpreter_config)?; + + // Serialize the whole interpreter config into DEP_PYTHON_PYO3_CONFIG env var. + interpreter_config.to_cargo_dep_env()?; + + if is_linking_libpython_for_target(&target) + && !interpreter_config.suppress_build_script_link_lines() + { + emit_link_config(&build_config)?; + } + + for cfg in interpreter_config.build_script_outputs() { + println!("{cfg}") + } + + // Extra lines come last, to support last write wins. + for line in interpreter_config.extra_build_script_lines() { + println!("{line}"); + } + + print_feature_cfgs(); + + // Make `cargo test` etc work with non-system Python installations + print_libpython_rpath_link_args(&target, interpreter_config); + + Ok(()) +} + +fn print_config_and_exit(config: &InterpreterConfig) { + println!("\n-- PYO3_PRINT_CONFIG=1 is set, printing configuration and halting compile --"); + config + .to_writer(std::io::stdout()) + .expect("failed to print config to stdout"); + println!("\nnote: unset the PYO3_PRINT_CONFIG environment variable and retry to compile with the above config"); + std::process::exit(101); +} + +fn main() { + pyo3_build_config::print_expected_cfgs(); + if let Err(e) = configure_pyo3_ffi() { + eprintln!("error: {}", e.report()); + std::process::exit(1) + } +} diff --git a/vendor/pyo3-ffi/examples/README.md b/vendor/pyo3-ffi/examples/README.md new file mode 100644 index 0000000..f02ae4b --- /dev/null +++ b/vendor/pyo3-ffi/examples/README.md @@ -0,0 +1,21 @@ +# `pyo3-ffi` Examples + +These example crates are a collection of toy extension modules built with +`pyo3-ffi`. They are all tested using `nox` in PyO3's CI. + +Below is a brief description of each of these: + +| Example | Description | +| `word-count` | Illustrates how to use pyo3-ffi to write a static rust extension | +| `sequential` | Illustrates how to use pyo3-ffi to write subinterpreter-safe modules using multi-phase module initialization | + +## Creating new projects from these examples + +To copy an example, use [`cargo-generate`](https://crates.io/crates/cargo-generate). Follow the commands below, replacing `` with the example to start from: + +```bash +$ cargo install cargo-generate +$ cargo generate --git https://github.com/PyO3/pyo3 examples/ +``` + +(`cargo generate` will take a little while to clone the PyO3 repo first; be patient when waiting for the command to run.) diff --git a/vendor/pyo3-ffi/src/abstract_.rs b/vendor/pyo3-ffi/src/abstract_.rs new file mode 100644 index 0000000..fe04b66 --- /dev/null +++ b/vendor/pyo3-ffi/src/abstract_.rs @@ -0,0 +1,354 @@ +use crate::object::*; +use crate::pyport::Py_ssize_t; +use core::ffi::{c_char, c_int}; +#[cfg(any(Py_3_12, not(Py_LIMITED_API)))] +use libc::size_t; + +#[inline] +#[cfg(all( + not(Py_3_13), // CPython exposed as a function in 3.13, in object.h + not(all(PyPy, not(Py_3_11))) // PyPy exposed as a function until PyPy 3.10, macro in 3.11+ +))] +pub unsafe fn PyObject_DelAttrString(o: *mut PyObject, attr_name: *const c_char) -> c_int { + PyObject_SetAttrString(o, attr_name, core::ptr::null_mut()) +} + +#[inline] +#[cfg(all( + not(Py_3_13), // CPython exposed as a function in 3.13, in object.h + not(all(PyPy, not(Py_3_11))) // PyPy exposed as a function until PyPy 3.10, macro in 3.11+ +))] +pub unsafe fn PyObject_DelAttr(o: *mut PyObject, attr_name: *mut PyObject) -> c_int { + PyObject_SetAttr(o, attr_name, core::ptr::null_mut()) +} + +extern_libpython! { + #[cfg(all( + not(PyPy), + any(Py_3_10, all(not(Py_LIMITED_API), Py_3_9)) // Added to python in 3.9 but to limited API in 3.10 + ))] + #[cfg_attr(PyPy, link_name = "PyPyObject_CallNoArgs")] + pub fn PyObject_CallNoArgs(func: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_Call")] + pub fn PyObject_Call( + callable_object: *mut PyObject, + args: *mut PyObject, + kw: *mut PyObject, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_CallObject")] + pub fn PyObject_CallObject( + callable_object: *mut PyObject, + args: *mut PyObject, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_CallFunction")] + pub fn PyObject_CallFunction( + callable_object: *mut PyObject, + format: *const c_char, + ... + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_CallMethod")] + pub fn PyObject_CallMethod( + o: *mut PyObject, + method: *const c_char, + format: *const c_char, + ... + ) -> *mut PyObject; + + #[cfg(all(PyPy, not(Py_3_13)))] // called internally in PyUnicodeDecodeError_Create on PyPy + #[cfg_attr(PyPy, link_name = "_PyPyObject_CallFunction_SizeT")] + pub(crate) fn _PyObject_CallFunction_SizeT( + callable_object: *mut PyObject, + format: *const c_char, + ... + ) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyObject_CallFunctionObjArgs")] + pub fn PyObject_CallFunctionObjArgs(callable: *mut PyObject, ...) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_CallMethodObjArgs")] + pub fn PyObject_CallMethodObjArgs( + o: *mut PyObject, + method: *mut PyObject, + ... + ) -> *mut PyObject; + + #[cfg(all(Py_3_12, Py_LIMITED_API))] // is an inline function in cpython/abstract.rs on version-specific ABI + #[cfg_attr(PyPy, link_name = "PyPyVectorcall_NARGS")] + pub fn PyVectorcall_NARGS(nargsf: size_t) -> Py_ssize_t; + + #[cfg_attr(not(any(Py_3_12, PyPy)), link_name = "_PyVectorcall_Call")] // symbol made public in 3.12 + #[cfg_attr(PyPy, link_name = "PyPyVectorcall_Call")] + pub fn PyVectorcall_Call( + callable: *mut PyObject, + tuple: *mut PyObject, + dict: *mut PyObject, + ) -> *mut PyObject; +} + +#[cfg(any(Py_3_12, not(Py_LIMITED_API)))] +pub const PY_VECTORCALL_ARGUMENTS_OFFSET: size_t = (1 as size_t) + .checked_shl((8 * core::mem::size_of::() - 1) as u32) + .expect("size_t should fit the flag bits"); + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyObject_Vectorcall")] + #[cfg(any(Py_3_12, all(Py_3_11, not(Py_LIMITED_API))))] + pub fn PyObject_Vectorcall( + callable: *mut PyObject, + args: *const *mut PyObject, + nargsf: size_t, + kwnames: *mut PyObject, + ) -> *mut PyObject; + + #[cfg(any(Py_3_12, all(Py_3_9, not(any(Py_LIMITED_API, PyPy)))))] + pub fn PyObject_VectorcallMethod( + name: *mut PyObject, + args: *const *mut PyObject, + nargsf: size_t, + kwnames: *mut PyObject, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_Type")] + pub fn PyObject_Type(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_Size")] + pub fn PyObject_Size(o: *mut PyObject) -> Py_ssize_t; + + // PyObject_Length is a direct alias for PyObject_Size + #[cfg_attr(not(PyPy), link_name = "PyObject_Size")] + #[cfg_attr(PyPy, link_name = "PyPyObject_Size")] + pub fn PyObject_Length(o: *mut PyObject) -> Py_ssize_t; + + #[cfg_attr(PyPy, link_name = "PyPyObject_GetItem")] + pub fn PyObject_GetItem(o: *mut PyObject, key: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_SetItem")] + pub fn PyObject_SetItem(o: *mut PyObject, key: *mut PyObject, v: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyObject_DelItemString")] + pub fn PyObject_DelItemString(o: *mut PyObject, key: *const c_char) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyObject_DelItem")] + pub fn PyObject_DelItem(o: *mut PyObject, key: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPyObject_Format")] + pub fn PyObject_Format(obj: *mut PyObject, format_spec: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_GetIter")] + pub fn PyObject_GetIter(arg1: *mut PyObject) -> *mut PyObject; + #[cfg(Py_3_10)] + #[cfg_attr(PyPy, link_name = "PyPyObject_GetAIter")] + pub fn PyObject_GetAIter(arg1: *mut PyObject) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyIter_Check")] + pub fn PyIter_Check(obj: *mut PyObject) -> c_int; + #[cfg(Py_3_10)] + #[cfg_attr(PyPy, link_name = "PyPyAIter_Check")] + pub fn PyAIter_Check(obj: *mut PyObject) -> c_int; + + #[cfg(Py_3_14)] + #[cfg_attr(PyPy, link_name = "PyPyIter_NextItem")] + pub fn PyIter_NextItem(iter: *mut PyObject, item: *mut *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyIter_Next")] + pub fn PyIter_Next(arg1: *mut PyObject) -> *mut PyObject; + #[cfg(all(not(PyPy), Py_3_10))] + #[cfg_attr(PyPy, link_name = "PyPyIter_Send")] + pub fn PyIter_Send( + iter: *mut PyObject, + arg: *mut PyObject, + presult: *mut *mut PyObject, + ) -> PySendResult; + + #[cfg_attr(PyPy, link_name = "PyPyNumber_Check")] + pub fn PyNumber_Check(o: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Add")] + pub fn PyNumber_Add(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Subtract")] + pub fn PyNumber_Subtract(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Multiply")] + pub fn PyNumber_Multiply(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_MatrixMultiply")] + pub fn PyNumber_MatrixMultiply(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_FloorDivide")] + pub fn PyNumber_FloorDivide(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_TrueDivide")] + pub fn PyNumber_TrueDivide(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Remainder")] + pub fn PyNumber_Remainder(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Divmod")] + pub fn PyNumber_Divmod(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Power")] + pub fn PyNumber_Power(o1: *mut PyObject, o2: *mut PyObject, o3: *mut PyObject) + -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Negative")] + pub fn PyNumber_Negative(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Positive")] + pub fn PyNumber_Positive(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Absolute")] + pub fn PyNumber_Absolute(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Invert")] + pub fn PyNumber_Invert(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Lshift")] + pub fn PyNumber_Lshift(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Rshift")] + pub fn PyNumber_Rshift(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_And")] + pub fn PyNumber_And(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Xor")] + pub fn PyNumber_Xor(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Or")] + pub fn PyNumber_Or(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyIndex_Check")] + pub fn PyIndex_Check(o: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPyNumber_Index")] + pub fn PyNumber_Index(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_AsSsize_t")] + pub fn PyNumber_AsSsize_t(o: *mut PyObject, exc: *mut PyObject) -> Py_ssize_t; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Long")] + pub fn PyNumber_Long(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_Float")] + pub fn PyNumber_Float(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceAdd")] + pub fn PyNumber_InPlaceAdd(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceSubtract")] + pub fn PyNumber_InPlaceSubtract(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceMultiply")] + pub fn PyNumber_InPlaceMultiply(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceMatrixMultiply")] + pub fn PyNumber_InPlaceMatrixMultiply(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceFloorDivide")] + pub fn PyNumber_InPlaceFloorDivide(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceTrueDivide")] + pub fn PyNumber_InPlaceTrueDivide(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceRemainder")] + pub fn PyNumber_InPlaceRemainder(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_InPlacePower")] + pub fn PyNumber_InPlacePower( + o1: *mut PyObject, + o2: *mut PyObject, + o3: *mut PyObject, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceLshift")] + pub fn PyNumber_InPlaceLshift(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceRshift")] + pub fn PyNumber_InPlaceRshift(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceAnd")] + pub fn PyNumber_InPlaceAnd(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceXor")] + pub fn PyNumber_InPlaceXor(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceOr")] + pub fn PyNumber_InPlaceOr(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + pub fn PyNumber_ToBase(n: *mut PyObject, base: c_int) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPySequence_Check")] + pub fn PySequence_Check(o: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPySequence_Size")] + pub fn PySequence_Size(o: *mut PyObject) -> Py_ssize_t; + + // PySequence_Length is a direct alias for PySequence_Size + #[cfg_attr(not(PyPy), link_name = "PySequence_Size")] + #[cfg_attr(PyPy, link_name = "PyPySequence_Size")] + pub fn PySequence_Length(o: *mut PyObject) -> Py_ssize_t; + + #[cfg_attr(PyPy, link_name = "PyPySequence_Concat")] + pub fn PySequence_Concat(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPySequence_Repeat")] + pub fn PySequence_Repeat(o: *mut PyObject, count: Py_ssize_t) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPySequence_GetItem")] + pub fn PySequence_GetItem(o: *mut PyObject, i: Py_ssize_t) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPySequence_GetSlice")] + pub fn PySequence_GetSlice(o: *mut PyObject, i1: Py_ssize_t, i2: Py_ssize_t) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPySequence_SetItem")] + pub fn PySequence_SetItem(o: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPySequence_DelItem")] + pub fn PySequence_DelItem(o: *mut PyObject, i: Py_ssize_t) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPySequence_SetSlice")] + pub fn PySequence_SetSlice( + o: *mut PyObject, + i1: Py_ssize_t, + i2: Py_ssize_t, + v: *mut PyObject, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPySequence_DelSlice")] + pub fn PySequence_DelSlice(o: *mut PyObject, i1: Py_ssize_t, i2: Py_ssize_t) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPySequence_Tuple")] + pub fn PySequence_Tuple(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPySequence_List")] + pub fn PySequence_List(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPySequence_Fast")] + pub fn PySequence_Fast(o: *mut PyObject, m: *const c_char) -> *mut PyObject; + pub fn PySequence_Count(o: *mut PyObject, value: *mut PyObject) -> Py_ssize_t; + #[cfg_attr(PyPy, link_name = "PyPySequence_Contains")] + pub fn PySequence_Contains(seq: *mut PyObject, ob: *mut PyObject) -> c_int; + + // PySequence_In is a direct alias for PySequence_Contains + #[cfg_attr(not(PyPy), link_name = "PySequence_Contains")] + #[cfg_attr(PyPy, link_name = "PyPySequence_Contains")] + pub fn PySequence_In(o: *mut PyObject, value: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPySequence_Index")] + pub fn PySequence_Index(o: *mut PyObject, value: *mut PyObject) -> Py_ssize_t; + #[cfg_attr(PyPy, link_name = "PyPySequence_InPlaceConcat")] + pub fn PySequence_InPlaceConcat(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPySequence_InPlaceRepeat")] + pub fn PySequence_InPlaceRepeat(o: *mut PyObject, count: Py_ssize_t) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyMapping_Check")] + pub fn PyMapping_Check(o: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyMapping_Size")] + pub fn PyMapping_Size(o: *mut PyObject) -> Py_ssize_t; + + // PyMapping_Length is a direct alias for PyMapping_Size + #[cfg_attr(not(PyPy), link_name = "PyMapping_Size")] + #[cfg_attr(PyPy, link_name = "PyPyMapping_Size")] + pub fn PyMapping_Length(o: *mut PyObject) -> Py_ssize_t; +} + +#[inline] +pub unsafe fn PyMapping_DelItemString(o: *mut PyObject, key: *mut c_char) -> c_int { + PyObject_DelItemString(o, key) +} + +#[inline] +pub unsafe fn PyMapping_DelItem(o: *mut PyObject, key: *mut PyObject) -> c_int { + PyObject_DelItem(o, key) +} + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyMapping_HasKeyString")] + pub fn PyMapping_HasKeyString(o: *mut PyObject, key: *const c_char) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyMapping_HasKey")] + pub fn PyMapping_HasKey(o: *mut PyObject, key: *mut PyObject) -> c_int; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyMapping_HasKeyWithError")] + pub fn PyMapping_HasKeyWithError(o: *mut PyObject, key: *mut PyObject) -> c_int; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyMapping_HasKeyStringWithError")] + pub fn PyMapping_HasKeyStringWithError(o: *mut PyObject, key: *const c_char) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyMapping_Keys")] + pub fn PyMapping_Keys(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyMapping_Values")] + pub fn PyMapping_Values(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyMapping_Items")] + pub fn PyMapping_Items(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyMapping_GetItemString")] + pub fn PyMapping_GetItemString(o: *mut PyObject, key: *const c_char) -> *mut PyObject; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyMapping_GetOptionalItem")] + pub fn PyMapping_GetOptionalItem( + o: *mut PyObject, + key: *mut PyObject, + result: *mut *mut PyObject, + ) -> c_int; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyMapping_GetOptionalItemString")] + pub fn PyMapping_GetOptionalItemString( + o: *mut PyObject, + key: *const c_char, + result: *mut *mut PyObject, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyMapping_SetItemString")] + pub fn PyMapping_SetItemString( + o: *mut PyObject, + key: *const c_char, + value: *mut PyObject, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyObject_IsInstance")] + pub fn PyObject_IsInstance(object: *mut PyObject, typeorclass: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyObject_IsSubclass")] + pub fn PyObject_IsSubclass(object: *mut PyObject, typeorclass: *mut PyObject) -> c_int; +} diff --git a/vendor/pyo3-ffi/src/bltinmodule.rs b/vendor/pyo3-ffi/src/bltinmodule.rs new file mode 100644 index 0000000..1a014e8 --- /dev/null +++ b/vendor/pyo3-ffi/src/bltinmodule.rs @@ -0,0 +1,7 @@ +use crate::object::PyTypeObject; + +extern_libpython! { + pub static mut PyFilter_Type: PyTypeObject; + pub static mut PyMap_Type: PyTypeObject; + pub static mut PyZip_Type: PyTypeObject; +} diff --git a/vendor/pyo3-ffi/src/boolobject.rs b/vendor/pyo3-ffi/src/boolobject.rs new file mode 100644 index 0000000..bf55c1d --- /dev/null +++ b/vendor/pyo3-ffi/src/boolobject.rs @@ -0,0 +1,69 @@ +#[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))] +use crate::longobject::PyLongObject; +use crate::object::*; +use core::ffi::{c_int, c_long}; + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyBool_Check(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyBool_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PyBool_Check(op: *mut PyObject) -> c_int; + + #[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))] + #[cfg_attr(PyPy, link_name = "_PyPy_FalseStruct")] + static mut _Py_FalseStruct: PyLongObject; + #[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))] + #[cfg_attr(PyPy, link_name = "_PyPy_TrueStruct")] + static mut _Py_TrueStruct: PyLongObject; + + #[cfg(GraalPy)] + static mut _Py_FalseStructReference: *mut PyObject; + #[cfg(GraalPy)] + static mut _Py_TrueStructReference: *mut PyObject; +} + +#[inline] +pub unsafe fn Py_False() -> *mut PyObject { + #[cfg(all(not(GraalPy), all(Py_3_13, Py_LIMITED_API)))] + return Py_GetConstantBorrowed(Py_CONSTANT_FALSE); + + #[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))] + return (&raw mut _Py_FalseStruct).cast(); + + #[cfg(GraalPy)] + return _Py_FalseStructReference; +} + +#[inline] +pub unsafe fn Py_True() -> *mut PyObject { + #[cfg(all(not(GraalPy), all(Py_3_13, Py_LIMITED_API)))] + return Py_GetConstantBorrowed(Py_CONSTANT_TRUE); + + #[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))] + return (&raw mut _Py_TrueStruct).cast(); + + #[cfg(GraalPy)] + return _Py_TrueStructReference; +} + +#[inline] +pub unsafe fn Py_IsTrue(x: *mut PyObject) -> c_int { + Py_Is(x, Py_True()) +} + +#[inline] +pub unsafe fn Py_IsFalse(x: *mut PyObject) -> c_int { + Py_Is(x, Py_False()) +} + +// skipped Py_RETURN_TRUE +// skipped Py_RETURN_FALSE + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyBool_FromLong")] + pub fn PyBool_FromLong(arg1: c_long) -> *mut PyObject; +} diff --git a/vendor/pyo3-ffi/src/bytearrayobject.rs b/vendor/pyo3-ffi/src/bytearrayobject.rs new file mode 100644 index 0000000..713a352 --- /dev/null +++ b/vendor/pyo3-ffi/src/bytearrayobject.rs @@ -0,0 +1,43 @@ +use crate::object::*; +use crate::pyport::Py_ssize_t; +use core::ffi::{c_char, c_int}; + +#[cfg(not(RustPython))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyByteArray_Type")] + pub static mut PyByteArray_Type: PyTypeObject; + + pub static mut PyByteArrayIter_Type: PyTypeObject; +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyByteArray_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, &raw mut PyByteArray_Type) +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyByteArray_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyByteArray_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PyByteArray_Check(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyByteArray_CheckExact(op: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPyByteArray_FromObject")] + pub fn PyByteArray_FromObject(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyByteArray_Concat")] + pub fn PyByteArray_Concat(a: *mut PyObject, b: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyByteArray_FromStringAndSize")] + pub fn PyByteArray_FromStringAndSize(string: *const c_char, len: Py_ssize_t) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyByteArray_Size")] + pub fn PyByteArray_Size(bytearray: *mut PyObject) -> Py_ssize_t; + #[cfg_attr(PyPy, link_name = "PyPyByteArray_AsString")] + pub fn PyByteArray_AsString(bytearray: *mut PyObject) -> *mut c_char; + #[cfg_attr(PyPy, link_name = "PyPyByteArray_Resize")] + pub fn PyByteArray_Resize(bytearray: *mut PyObject, len: Py_ssize_t) -> c_int; +} diff --git a/vendor/pyo3-ffi/src/bytesobject.rs b/vendor/pyo3-ffi/src/bytesobject.rs new file mode 100644 index 0000000..c99e0da --- /dev/null +++ b/vendor/pyo3-ffi/src/bytesobject.rs @@ -0,0 +1,69 @@ +use crate::object::*; +use crate::pyport::Py_ssize_t; +use core::ffi::{c_char, c_int}; + +#[cfg(not(RustPython))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyBytes_Type")] + pub static mut PyBytes_Type: PyTypeObject; + pub static mut PyBytesIter_Type: PyTypeObject; +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyBytes_Check(op: *mut PyObject) -> c_int { + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS) +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyBytes_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyBytes_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PyBytes_Check(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyBytes_CheckExact(op: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPyBytes_FromStringAndSize")] + pub fn PyBytes_FromStringAndSize(arg1: *const c_char, arg2: Py_ssize_t) -> *mut PyObject; + pub fn PyBytes_FromString(arg1: *const c_char) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyBytes_FromObject")] + pub fn PyBytes_FromObject(arg1: *mut PyObject) -> *mut PyObject; + // skipped PyBytes_FromFormatV + //#[cfg_attr(PyPy, link_name = "PyPyBytes_FromFormatV")] + //pub fn PyBytes_FromFormatV(arg1: *const c_char, arg2: va_list) + // -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyBytes_FromFormat")] + pub fn PyBytes_FromFormat(arg1: *const c_char, ...) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyBytes_Size")] + pub fn PyBytes_Size(arg1: *mut PyObject) -> Py_ssize_t; + #[cfg_attr(PyPy, link_name = "PyPyBytes_AsString")] + pub fn PyBytes_AsString(arg1: *mut PyObject) -> *mut c_char; + pub fn PyBytes_Repr(arg1: *mut PyObject, arg2: c_int) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyBytes_Concat")] + pub fn PyBytes_Concat(arg1: *mut *mut PyObject, arg2: *mut PyObject); + #[cfg_attr(PyPy, link_name = "PyPyBytes_ConcatAndDel")] + pub fn PyBytes_ConcatAndDel(arg1: *mut *mut PyObject, arg2: *mut PyObject); + pub fn PyBytes_DecodeEscape( + arg1: *const c_char, + arg2: Py_ssize_t, + arg3: *const c_char, + arg4: Py_ssize_t, + arg5: *const c_char, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyBytes_AsStringAndSize")] + pub fn PyBytes_AsStringAndSize( + obj: *mut PyObject, + s: *mut *mut c_char, + len: *mut Py_ssize_t, + ) -> c_int; +} + +// skipped F_LJUST +// skipped F_SIGN +// skipped F_BLANK +// skipped F_ALT +// skipped F_ZERO diff --git a/vendor/pyo3-ffi/src/ceval.rs b/vendor/pyo3-ffi/src/ceval.rs new file mode 100644 index 0000000..fdc25da --- /dev/null +++ b/vendor/pyo3-ffi/src/ceval.rs @@ -0,0 +1,179 @@ +use crate::object::PyObject; +use crate::pytypedefs::PyThreadState; +use core::ffi::{c_char, c_int, c_void}; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyEval_EvalCode")] + pub fn PyEval_EvalCode( + arg1: *mut PyObject, + arg2: *mut PyObject, + arg3: *mut PyObject, + ) -> *mut PyObject; + + pub fn PyEval_EvalCodeEx( + co: *mut PyObject, + globals: *mut PyObject, + locals: *mut PyObject, + args: *const *mut PyObject, + argc: c_int, + kwds: *const *mut PyObject, + kwdc: c_int, + defs: *const *mut PyObject, + defc: c_int, + kwdefs: *mut PyObject, + closure: *mut PyObject, + ) -> *mut PyObject; + + #[cfg(not(Py_3_13))] + #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] + #[cfg_attr(PyPy, link_name = "PyPyEval_CallObjectWithKeywords")] + pub fn PyEval_CallObjectWithKeywords( + func: *mut PyObject, + obj: *mut PyObject, + kwargs: *mut PyObject, + ) -> *mut PyObject; +} + +#[cfg(not(Py_3_13))] +#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] +#[inline] +pub unsafe fn PyEval_CallObject(func: *mut PyObject, arg: *mut PyObject) -> *mut PyObject { + #[allow(deprecated)] + PyEval_CallObjectWithKeywords(func, arg, core::ptr::null_mut()) +} + +extern_libpython! { + #[cfg(not(Py_3_13))] + #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] + #[cfg_attr(PyPy, link_name = "PyPyEval_CallFunction")] + pub fn PyEval_CallFunction(obj: *mut PyObject, format: *const c_char, ...) -> *mut PyObject; + #[cfg(not(Py_3_13))] + #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] + #[cfg_attr(PyPy, link_name = "PyPyEval_CallMethod")] + pub fn PyEval_CallMethod( + obj: *mut PyObject, + methodname: *const c_char, + format: *const c_char, + ... + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyEval_GetBuiltins")] + pub fn PyEval_GetBuiltins() -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyEval_GetGlobals")] + pub fn PyEval_GetGlobals() -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyEval_GetLocals")] + pub fn PyEval_GetLocals() -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyEval_GetFrame")] + pub fn PyEval_GetFrame() -> *mut crate::PyFrameObject; + + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyEval_GetFrameBuiltins")] + pub fn PyEval_GetFrameBuiltins() -> *mut PyObject; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyEval_GetFrameGlobals")] + pub fn PyEval_GetFrameGlobals() -> *mut PyObject; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyEval_GetFrameLocals")] + pub fn PyEval_GetFrameLocals() -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPy_AddPendingCall")] + pub fn Py_AddPendingCall( + func: Option c_int>, + arg: *mut c_void, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPy_MakePendingCalls")] + pub fn Py_MakePendingCalls() -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPy_SetRecursionLimit")] + pub fn Py_SetRecursionLimit(arg1: c_int); + #[cfg_attr(PyPy, link_name = "PyPy_GetRecursionLimit")] + pub fn Py_GetRecursionLimit() -> c_int; + + #[cfg(Py_3_9)] + #[cfg_attr(PyPy, link_name = "PyPy_EnterRecursiveCall")] + pub fn Py_EnterRecursiveCall(arg1: *const c_char) -> c_int; + #[cfg(Py_3_9)] + #[cfg_attr(PyPy, link_name = "PyPy_LeaveRecursiveCall")] + pub fn Py_LeaveRecursiveCall(); + + #[cfg_attr(PyPy, link_name = "PyPyEval_GetFuncName")] + pub fn PyEval_GetFuncName(arg1: *mut PyObject) -> *const c_char; + #[cfg_attr(PyPy, link_name = "PyPyEval_GetFuncDesc")] + pub fn PyEval_GetFuncDesc(arg1: *mut PyObject) -> *const c_char; + + #[cfg_attr(PyPy, link_name = "PyPyEval_EvalFrame")] + pub fn PyEval_EvalFrame(arg1: *mut crate::PyFrameObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyEval_EvalFrameEx")] + pub fn PyEval_EvalFrameEx(f: *mut crate::PyFrameObject, exc: c_int) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyEval_SaveThread")] + pub fn PyEval_SaveThread() -> *mut PyThreadState; + + #[cfg(not(Py_3_13))] + #[cfg_attr(PyPy, link_name = "PyPyEval_ThreadsInitialized")] + #[cfg_attr( + Py_3_9, + deprecated( + note = "Deprecated in Python 3.9, this function always returns true in Python 3.7 or newer." + ) + )] + pub fn PyEval_ThreadsInitialized() -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyEval_InitThreads")] + #[cfg_attr( + Py_3_9, + deprecated( + note = "Deprecated in Python 3.9, this function does nothing in Python 3.7 or newer." + ) + )] + pub fn PyEval_InitThreads(); + #[cfg(not(Py_3_13))] + #[deprecated(note = "Deprecated in Python 3.2")] + pub fn PyEval_AcquireLock(); + #[cfg(not(Py_3_13))] + #[deprecated(note = "Deprecated in Python 3.2")] + pub fn PyEval_ReleaseLock(); + #[cfg_attr(PyPy, link_name = "PyPyEval_AcquireThread")] + pub fn PyEval_AcquireThread(tstate: *mut PyThreadState); + #[cfg_attr(PyPy, link_name = "PyPyEval_ReleaseThread")] + pub fn PyEval_ReleaseThread(tstate: *mut PyThreadState); +} + +// PyEval_RestoreThread calls take_gil, which calls pthread_exit on non-main threads +// during interpreter finalization on Python < 3.14. Redirect to the "safe" version that hangs instead, +// as Python 3.14 does. +// See https://github.com/rust-lang/rust/issues/135929 +// C-unwind only supported (and necessary) since 1.71. Python 3.14+ does not do +// pthread_exit from PyEval_RestoreThread (https://github.com/python/cpython/issues/87135). +#[cfg(not(any(Py_3_14, target_arch = "wasm32")))] +mod raw { + use crate::pytypedefs::PyThreadState; + extern_libpython! { "C-unwind" { + #[cfg_attr(PyPy, link_name = "PyPyEval_RestoreThread")] + pub fn PyEval_RestoreThread(tstate: *mut PyThreadState); + }} +} + +#[cfg(any(Py_3_14, target_arch = "wasm32"))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyEval_RestoreThread")] + pub fn PyEval_RestoreThread(tstate: *mut PyThreadState); +} + +#[cfg(not(any(Py_3_14, target_arch = "wasm32")))] +pub unsafe extern "C" fn PyEval_RestoreThread(tstate: *mut PyThreadState) { + // Same note as in PyGILState_Ensure + let guard = crate::impl_::HangThread; + raw::PyEval_RestoreThread(tstate); + core::mem::forget(guard); +} + +// skipped Py_BEGIN_ALLOW_THREADS +// skipped Py_BLOCK_THREADS +// skipped Py_UNBLOCK_THREADS +// skipped Py_END_ALLOW_THREADS +// skipped FVC_MASK +// skipped FVC_NONE +// skipped FVC_STR +// skipped FVC_REPR +// skipped FVC_ASCII +// skipped FVS_MASK +// skipped FVS_HAVE_SPEC diff --git a/vendor/pyo3-ffi/src/codecs.rs b/vendor/pyo3-ffi/src/codecs.rs new file mode 100644 index 0000000..4d53f4e --- /dev/null +++ b/vendor/pyo3-ffi/src/codecs.rs @@ -0,0 +1,58 @@ +use crate::object::PyObject; +use core::ffi::{c_char, c_int}; + +extern_libpython! { + pub fn PyCodec_Register(search_function: *mut PyObject) -> c_int; + #[cfg(Py_3_10)] + #[cfg(not(PyPy))] + pub fn PyCodec_Unregister(search_function: *mut PyObject) -> c_int; + // skipped non-limited _PyCodec_Lookup from Include/codecs.h + // skipped non-limited _PyCodec_Forget from Include/codecs.h + pub fn PyCodec_KnownEncoding(encoding: *const c_char) -> c_int; + pub fn PyCodec_Encode( + object: *mut PyObject, + encoding: *const c_char, + errors: *const c_char, + ) -> *mut PyObject; + pub fn PyCodec_Decode( + object: *mut PyObject, + encoding: *const c_char, + errors: *const c_char, + ) -> *mut PyObject; + // skipped non-limited _PyCodec_LookupTextEncoding from Include/codecs.h + // skipped non-limited _PyCodec_EncodeText from Include/codecs.h + // skipped non-limited _PyCodec_DecodeText from Include/codecs.h + // skipped non-limited _PyCodecInfo_GetIncrementalDecoder from Include/codecs.h + // skipped non-limited _PyCodecInfo_GetIncrementalEncoder from Include/codecs.h + pub fn PyCodec_Encoder(encoding: *const c_char) -> *mut PyObject; + pub fn PyCodec_Decoder(encoding: *const c_char) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyCodec_IncrementalEncoder")] + pub fn PyCodec_IncrementalEncoder( + encoding: *const c_char, + errors: *const c_char, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyCodec_IncrementalDecoder")] + pub fn PyCodec_IncrementalDecoder( + encoding: *const c_char, + errors: *const c_char, + ) -> *mut PyObject; + pub fn PyCodec_StreamReader( + encoding: *const c_char, + stream: *mut PyObject, + errors: *const c_char, + ) -> *mut PyObject; + pub fn PyCodec_StreamWriter( + encoding: *const c_char, + stream: *mut PyObject, + errors: *const c_char, + ) -> *mut PyObject; + pub fn PyCodec_RegisterError(name: *const c_char, error: *mut PyObject) -> c_int; + pub fn PyCodec_LookupError(name: *const c_char) -> *mut PyObject; + pub fn PyCodec_StrictErrors(exc: *mut PyObject) -> *mut PyObject; + pub fn PyCodec_IgnoreErrors(exc: *mut PyObject) -> *mut PyObject; + pub fn PyCodec_ReplaceErrors(exc: *mut PyObject) -> *mut PyObject; + pub fn PyCodec_XMLCharRefReplaceErrors(exc: *mut PyObject) -> *mut PyObject; + pub fn PyCodec_BackslashReplaceErrors(exc: *mut PyObject) -> *mut PyObject; + // skipped non-limited PyCodec_NameReplaceErrors from Include/codecs.h + // skipped non-limited Py_hexdigits from Include/codecs.h +} diff --git a/vendor/pyo3-ffi/src/compat/mod.rs b/vendor/pyo3-ffi/src/compat/mod.rs new file mode 100644 index 0000000..2927d5e --- /dev/null +++ b/vendor/pyo3-ffi/src/compat/mod.rs @@ -0,0 +1,64 @@ +//! C API Compatibility Shims +//! +//! Some CPython C API functions added in recent versions of Python are +//! inherently safer to use than older C API constructs. This module +//! exposes functions available on all Python versions that wrap the +//! old C API on old Python versions and wrap the function directly +//! on newer Python versions. + +// Unless otherwise noted, the compatibility shims are adapted from +// the pythoncapi-compat project: https://github.com/python/pythoncapi-compat + +/// Internal helper macro which defines compatibility shims for C API functions, deferring to a +/// re-export when that's available. +macro_rules! compat_function { + ( + originally_defined_for($cfg:meta); + + $(#[$attrs:meta])* + pub unsafe fn $name:ident($($arg_names:ident: $arg_types:ty),* $(,)?) -> $ret:ty $body:block + ) => { + // Define as a standalone function under docsrs cfg so that this shows as a unique function in the docs, + // not a re-export (the re-export has the wrong visibility) + #[cfg(any(docsrs, not($cfg)))] + #[cfg_attr(docsrs, doc(cfg(all())))] + $(#[$attrs])* + pub unsafe fn $name( + $($arg_names: $arg_types,)* + ) -> $ret $body + + #[cfg(all($cfg, not(docsrs)))] + pub use $crate::$name; + + #[cfg(test)] + paste::paste! { + // Test that the compat function does not overlap with the original function. If the + // cfgs line up, then the two glob imports will resolve to the same item via the + // re-export. If the cfgs mismatch, then the use of $name will be ambiguous in cases + // where the function is defined twice, and the test will fail to compile. + #[allow(unused_imports, reason = "imports exist to try to trigger name conflicts")] + mod [] { + use $crate::*; + use $crate::compat::*; + + #[test] + fn test_export() { + let _ = $name; + } + } + } + }; +} + +mod py_3_10; +mod py_3_13; +mod py_3_14; +mod py_3_15; +mod py_3_9; + +pub use self::py_3_10::*; +pub use self::py_3_13::*; +pub use self::py_3_14::*; +#[allow(unused_imports)] +pub use self::py_3_15::*; +pub use self::py_3_9::*; diff --git a/vendor/pyo3-ffi/src/compat/py_3_10.rs b/vendor/pyo3-ffi/src/compat/py_3_10.rs new file mode 100644 index 0000000..5c931de --- /dev/null +++ b/vendor/pyo3-ffi/src/compat/py_3_10.rs @@ -0,0 +1,45 @@ +compat_function!( + originally_defined_for(Py_3_10); + + #[inline] + pub unsafe fn Py_NewRef(obj: *mut crate::PyObject) -> *mut crate::PyObject { + crate::Py_INCREF(obj); + obj + } +); + +compat_function!( + originally_defined_for(Py_3_10); + + #[inline] + pub unsafe fn Py_XNewRef(obj: *mut crate::PyObject) -> *mut crate::PyObject { + crate::Py_XINCREF(obj); + obj + } +); + +compat_function!( + originally_defined_for(Py_3_10); + + #[inline] + pub unsafe fn PyModule_AddObjectRef( + module: *mut crate::PyObject, + name: *const core::ffi::c_char, + value: *mut crate::PyObject, + ) -> core::ffi::c_int { + if value.is_null() && crate::PyErr_Occurred().is_null() { + crate::PyErr_SetString( + crate::PyExc_SystemError, + c"PyModule_AddObjectRef() must be called with an exception raised if value is NULL".as_ptr(), + ); + return -1; + } + + crate::Py_XINCREF(value); + let result = crate::PyModule_AddObject(module, name, value); + if result < 0 { + crate::Py_XDECREF(value); + } + result + } +); diff --git a/vendor/pyo3-ffi/src/compat/py_3_13.rs b/vendor/pyo3-ffi/src/compat/py_3_13.rs new file mode 100644 index 0000000..c2030d9 --- /dev/null +++ b/vendor/pyo3-ffi/src/compat/py_3_13.rs @@ -0,0 +1,216 @@ +compat_function!( + originally_defined_for(Py_3_13); + + #[inline] + pub unsafe fn PyDict_GetItemRef( + dp: *mut crate::PyObject, + key: *mut crate::PyObject, + result: *mut *mut crate::PyObject, + ) -> core::ffi::c_int { + use crate::{compat::Py_NewRef, PyDict_GetItemWithError, PyErr_Occurred}; + + let item = PyDict_GetItemWithError(dp, key); + if !item.is_null() { + *result = Py_NewRef(item); + return 1; // found + } + *result = core::ptr::null_mut(); + if PyErr_Occurred().is_null() { + return 0; // not found + } + -1 + } +); + +compat_function!( + originally_defined_for(Py_3_13); + + #[inline] + pub unsafe fn PyList_GetItemRef( + arg1: *mut crate::PyObject, + arg2: crate::Py_ssize_t, + ) -> *mut crate::PyObject { + use crate::{PyList_GetItem, Py_XINCREF}; + + let item = PyList_GetItem(arg1, arg2); + Py_XINCREF(item); + item + } +); + +compat_function!( + originally_defined_for(Py_3_13); + + #[inline] + pub unsafe fn PyImport_AddModuleRef( + name: *const core::ffi::c_char, + ) -> *mut crate::PyObject { + use crate::{compat::Py_XNewRef, PyImport_AddModule}; + + Py_XNewRef(PyImport_AddModule(name)) + } +); + +compat_function!( + originally_defined_for(Py_3_13); + + #[inline] + pub unsafe fn PyWeakref_GetRef( + reference: *mut crate::PyObject, + pobj: *mut *mut crate::PyObject, + ) -> core::ffi::c_int { + use crate::{ + compat::Py_NewRef, PyErr_SetString, PyExc_TypeError, PyWeakref_Check, + PyWeakref_GetObject, Py_None, + }; + + if !reference.is_null() && PyWeakref_Check(reference) == 0 { + *pobj = core::ptr::null_mut(); + PyErr_SetString(PyExc_TypeError, c"expected a weakref".as_ptr()); + return -1; + } + let obj = PyWeakref_GetObject(reference); + if obj.is_null() { + // SystemError if reference is NULL + *pobj = core::ptr::null_mut(); + return -1; + } + if obj == Py_None() { + *pobj = core::ptr::null_mut(); + return 0; + } + *pobj = Py_NewRef(obj); + 1 + } +); + +compat_function!( + originally_defined_for(Py_3_13); + + #[inline] + pub unsafe fn PyList_Extend( + list: *mut crate::PyObject, + iterable: *mut crate::PyObject, + ) -> core::ffi::c_int { + crate::PyList_SetSlice(list, crate::PY_SSIZE_T_MAX, crate::PY_SSIZE_T_MAX, iterable) + } +); + +compat_function!( + originally_defined_for(Py_3_13); + + #[inline] + pub unsafe fn PyList_Clear(list: *mut crate::PyObject) -> core::ffi::c_int { + crate::PyList_SetSlice(list, 0, crate::PY_SSIZE_T_MAX, core::ptr::null_mut()) + } +); + +compat_function!( + originally_defined_for(Py_3_13); + + #[inline] + pub unsafe fn PyModule_Add( + module: *mut crate::PyObject, + name: *const core::ffi::c_char, + value: *mut crate::PyObject, + ) -> core::ffi::c_int { + let result = crate::compat::PyModule_AddObjectRef(module, name, value); + crate::Py_XDECREF(value); + result + } +); + +#[cfg(not(Py_LIMITED_API))] +compat_function!( + originally_defined_for(Py_3_13); + + #[inline] + pub unsafe fn PyThreadState_GetUnchecked( + ) -> *mut crate::PyThreadState { + crate::_PyThreadState_UncheckedGet() + } +); + +compat_function!( + originally_defined_for(all(Py_3_13, any(not(Py_LIMITED_API), Py_3_15))); + + #[inline] + pub unsafe fn PyDict_SetDefaultRef( + mp: *mut crate::PyObject, + key: *mut crate::PyObject, + default_value: *mut crate::PyObject, + result: *mut *mut crate::PyObject, + ) -> core::ffi::c_int { + use crate::{ + compat::{PyDict_GetItemRef, Py_NewRef}, + PyDict_SetItem, PyObject, Py_DECREF, + }; + let mut value: *mut PyObject = core::ptr::null_mut(); + if PyDict_GetItemRef(mp, key, &mut value) < 0 { + // get error + if !result.is_null() { + *result = core::ptr::null_mut(); + } + return -1; + } + if !value.is_null() { + // present + if !result.is_null() { + *result = value; + } else { + Py_DECREF(value); + } + return 1; + } + + // missing, set the item + if PyDict_SetItem(mp, key, default_value) < 0 { + // set error + if !result.is_null() { + *result = core::ptr::null_mut(); + } + return -1; + } + if !result.is_null() { + *result = Py_NewRef(default_value); + } + 0 + } +); + +compat_function!( + originally_defined_for(Py_3_13); + + #[inline] + pub unsafe fn PyObject_GetOptionalAttr( + obj: *mut crate::PyObject, + name: *mut crate::PyObject, + result: *mut *mut crate::PyObject, + ) -> core::ffi::c_int { + use crate::{PyErr_Clear, PyErr_ExceptionMatches, PyExc_AttributeError, PyObject_GetAttr}; + + let attr = PyObject_GetAttr(obj, name); + if !attr.is_null() { + *result = attr; + return 1; // found + } + *result = core::ptr::null_mut(); + if PyErr_ExceptionMatches(PyExc_AttributeError) != 0 { + PyErr_Clear(); + return 0; // not found + } + -1 // other error + } +); + +compat_function!( + originally_defined_for(Py_3_13); + + #[inline] + pub unsafe fn PyObject_HasAttrWithError(obj: *mut crate::PyObject, attr_name: *mut crate::PyObject) -> core::ffi::c_int { + let mut res: *mut crate::PyObject = core::ptr::null_mut(); + let rc = crate::compat::PyObject_GetOptionalAttr(obj, attr_name, &mut res); + crate::Py_XDECREF(res); + rc + } +); diff --git a/vendor/pyo3-ffi/src/compat/py_3_14.rs b/vendor/pyo3-ffi/src/compat/py_3_14.rs new file mode 100644 index 0000000..879ec93 --- /dev/null +++ b/vendor/pyo3-ffi/src/compat/py_3_14.rs @@ -0,0 +1,45 @@ +compat_function!( + originally_defined_for(all(Py_3_14, not(Py_LIMITED_API))); + + #[inline] + pub unsafe fn Py_HashBuffer( + ptr: *const core::ffi::c_void, + len: crate::Py_ssize_t, + ) -> crate::Py_hash_t { + #[cfg(not(any(Py_LIMITED_API, PyPy)))] + { + crate::_Py_HashBytes(ptr, len) + } + + #[cfg(any(Py_LIMITED_API, PyPy))] + { + let bytes = crate::PyBytes_FromStringAndSize(ptr as *const core::ffi::c_char, len); + if bytes.is_null() { + -1 + } else { + let result = crate::PyObject_Hash(bytes); + crate::Py_DECREF(bytes); + result + } + } + } +); + +compat_function!( + originally_defined_for(Py_3_14); + + #[inline] + pub unsafe fn PyIter_NextItem( + iter: *mut crate::PyObject, + item: *mut *mut crate::PyObject, + ) -> core::ffi::c_int { + *item = crate::PyIter_Next(iter); + if !(*item).is_null() { + 1 + } else if crate::PyErr_Occurred().is_null() { + 0 + } else { + -1 + } + } +); diff --git a/vendor/pyo3-ffi/src/compat/py_3_15.rs b/vendor/pyo3-ffi/src/compat/py_3_15.rs new file mode 100644 index 0000000..c3efc30 --- /dev/null +++ b/vendor/pyo3-ffi/src/compat/py_3_15.rs @@ -0,0 +1,193 @@ +#[cfg(all(Py_3_15, not(Py_LIMITED_API)))] +pub use crate::PyBytesWriter; + +#[cfg(not(Py_LIMITED_API))] +compat_function!( + originally_defined_for(all(Py_3_15, not(Py_LIMITED_API))); + + #[inline] + pub unsafe fn PyBytesWriter_Create( + size: crate::Py_ssize_t, + ) -> *mut PyBytesWriter { + + if size < 0 { + crate::PyErr_SetString(crate::PyExc_ValueError, c"size must be >= 0".as_ptr() as *const _); + return core::ptr::null_mut(); + } + + let writer: *mut PyBytesWriter = crate::PyMem_Malloc(core::mem::size_of::()).cast(); + if writer.is_null() { + crate::PyErr_NoMemory(); + return core::ptr::null_mut(); + } + + (*writer).obj = core::ptr::null_mut(); + (*writer).size = 0; + + if size >=1 { + if _PyBytesWriter_Resize_impl(writer, size, 0) < 0 { + PyBytesWriter_Discard(writer); + return core::ptr::null_mut(); + } + + (*writer).size = size; + } + + writer + } +); + +#[cfg(not(Py_LIMITED_API))] +compat_function!( + originally_defined_for(all(Py_3_15, not(Py_LIMITED_API))); + + #[inline] + pub unsafe fn PyBytesWriter_Discard(writer: *mut PyBytesWriter) -> () { + if writer.is_null() { + return; + } + + crate::Py_XDECREF((*writer).obj); + crate::PyMem_Free(writer.cast()); + } +); + +#[cfg(not(Py_LIMITED_API))] +compat_function!( + originally_defined_for(all(Py_3_15, not(Py_LIMITED_API))); + + #[inline] + pub unsafe fn PyBytesWriter_Finish(writer: *mut PyBytesWriter) -> *mut crate::PyObject { + PyBytesWriter_FinishWithSize(writer, (*writer).size) + } +); + +#[cfg(not(Py_LIMITED_API))] +compat_function!( + originally_defined_for(all(Py_3_15, not(Py_LIMITED_API))); + + #[inline] + pub unsafe fn PyBytesWriter_FinishWithSize(writer: *mut PyBytesWriter, size: crate::Py_ssize_t) -> *mut crate::PyObject { + let result = if size == 0 { + crate::PyBytes_FromStringAndSize(c"".as_ptr(), 0) + } else if (*writer).obj.is_null() { + crate::PyBytes_FromStringAndSize((*writer).small_buffer.as_ptr(), size) + } else { + if size != crate::PyBytes_Size((*writer).obj) && crate::_PyBytes_Resize(&mut (*writer).obj, size) < 0 { + PyBytesWriter_Discard(writer); + return core::ptr::null_mut(); + } + core::mem::replace(&mut (*writer).obj, core::ptr::null_mut()) + }; + + PyBytesWriter_Discard(writer); + result + } +); + +#[cfg(not(Py_LIMITED_API))] +compat_function!( + originally_defined_for(all(Py_3_15, not(Py_LIMITED_API))); + + #[inline] + pub unsafe fn PyBytesWriter_GetData(writer: *mut PyBytesWriter) -> *mut core::ffi::c_void { + if (*writer).obj.is_null() { + (*writer).small_buffer.as_ptr() as *mut _ + } else { + crate::PyBytes_AS_STRING((*writer).obj) as *mut _ + } + } +); + +#[cfg(not(Py_LIMITED_API))] +compat_function!( + originally_defined_for(all(Py_3_15, not(Py_LIMITED_API))); + + #[inline] + pub unsafe fn PyBytesWriter_GetSize(writer: *mut PyBytesWriter) -> crate::Py_ssize_t { + (*writer).size + } +); + +#[cfg(not(Py_LIMITED_API))] +compat_function!( + originally_defined_for(all(Py_3_15, not(Py_LIMITED_API))); + + #[inline] + pub unsafe fn PyBytesWriter_Resize(writer: *mut PyBytesWriter, size: crate::Py_ssize_t) -> core::ffi::c_int { + if size < 0 { + crate::PyErr_SetString(crate::PyExc_ValueError, c"size must be >= 0".as_ptr()); + return -1; + } + if _PyBytesWriter_Resize_impl(writer, size, 1) < 0 { + return -1; + } + (*writer).size = size; + 0 + } +); + +#[repr(C)] +#[cfg(not(any(Py_3_15, Py_LIMITED_API)))] +pub struct PyBytesWriter { + small_buffer: [core::ffi::c_char; 256], + obj: *mut crate::PyObject, + size: crate::Py_ssize_t, +} + +#[inline] +#[cfg(not(any(Py_3_15, Py_LIMITED_API)))] +unsafe fn _PyBytesWriter_Resize_impl( + writer: *mut PyBytesWriter, + mut size: crate::Py_ssize_t, + resize: core::ffi::c_int, +) -> core::ffi::c_int { + let overallocate = resize; + assert!(size >= 0); + + let allocated = if (*writer).obj.is_null() { + core::mem::size_of_val(&(*writer).small_buffer) as _ + } else { + crate::PyBytes_Size((*writer).obj) + }; + + if size <= allocated { + return 0; + } + + if overallocate > 0 { + #[cfg(windows)] + if size <= (crate::PY_SSIZE_T_MAX - size / 2) { + size += size / 2; + } + + #[cfg(not(windows))] + if size <= (crate::PY_SSIZE_T_MAX - size / 4) { + size += size / 4; + } + } + + if !(*writer).obj.is_null() { + if crate::_PyBytes_Resize(&mut (*writer).obj, size) > 0 { + return -1; + } + assert!(!(*writer).obj.is_null()) + } else { + (*writer).obj = crate::PyBytes_FromStringAndSize(core::ptr::null_mut(), size); + if (*writer).obj.is_null() { + return -1; + } + + if resize > 0 { + assert!((size as usize) > core::mem::size_of_val(&(*writer).small_buffer)); + + core::ptr::copy_nonoverlapping( + (*writer).small_buffer.as_ptr(), + crate::PyBytes_AS_STRING((*writer).obj) as *mut _, + core::mem::size_of_val(&(*writer).small_buffer), + ); + } + } + + 0 +} diff --git a/vendor/pyo3-ffi/src/compat/py_3_9.rs b/vendor/pyo3-ffi/src/compat/py_3_9.rs new file mode 100644 index 0000000..fed7e21 --- /dev/null +++ b/vendor/pyo3-ffi/src/compat/py_3_9.rs @@ -0,0 +1,20 @@ +compat_function!( + originally_defined_for(all( + not(PyPy), + any(Py_3_10, all(not(Py_LIMITED_API), Py_3_9)) // Added to python in 3.9 but to limited API in 3.10 + )); + + #[inline] + pub unsafe fn PyObject_CallNoArgs(obj: *mut crate::PyObject) -> *mut crate::PyObject { + crate::PyObject_CallObject(obj, core::ptr::null_mut()) + } +); + +compat_function!( + originally_defined_for(all(Py_3_9, not(any(Py_LIMITED_API, PyPy)))); + + #[inline] + pub unsafe fn PyObject_CallMethodNoArgs(obj: *mut crate::PyObject, name: *mut crate::PyObject) -> *mut crate::PyObject { + crate::PyObject_CallMethodObjArgs(obj, name, core::ptr::null_mut::()) + } +); diff --git a/vendor/pyo3-ffi/src/compile.rs b/vendor/pyo3-ffi/src/compile.rs new file mode 100644 index 0000000..6e5f67f --- /dev/null +++ b/vendor/pyo3-ffi/src/compile.rs @@ -0,0 +1,9 @@ +use core::ffi::c_int; + +pub const Py_single_input: c_int = 256; +pub const Py_file_input: c_int = 257; +pub const Py_eval_input: c_int = 258; +pub const Py_func_type_input: c_int = 345; + +#[cfg(Py_3_9)] +pub const Py_fstring_input: c_int = 800; diff --git a/vendor/pyo3-ffi/src/complexobject.rs b/vendor/pyo3-ffi/src/complexobject.rs new file mode 100644 index 0000000..7e4b08a --- /dev/null +++ b/vendor/pyo3-ffi/src/complexobject.rs @@ -0,0 +1,36 @@ +use crate::object::*; +use core::ffi::{c_double, c_int}; + +#[cfg(not(RustPython))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyComplex_Type")] + pub static mut PyComplex_Type: PyTypeObject; +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyComplex_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, &raw mut PyComplex_Type) +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyComplex_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyComplex_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PyComplex_Check(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyComplex_CheckExact(op: *mut PyObject) -> c_int; + + // skipped non-limited PyComplex_FromCComplex + #[cfg_attr(PyPy, link_name = "PyPyComplex_FromDoubles")] + pub fn PyComplex_FromDoubles(real: c_double, imag: c_double) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyComplex_RealAsDouble")] + pub fn PyComplex_RealAsDouble(op: *mut PyObject) -> c_double; + #[cfg_attr(PyPy, link_name = "PyPyComplex_ImagAsDouble")] + pub fn PyComplex_ImagAsDouble(op: *mut PyObject) -> c_double; +} diff --git a/vendor/pyo3-ffi/src/context.rs b/vendor/pyo3-ffi/src/context.rs new file mode 100644 index 0000000..5defd44 --- /dev/null +++ b/vendor/pyo3-ffi/src/context.rs @@ -0,0 +1,60 @@ +use crate::object::PyObject; +#[cfg(not(RustPython))] +use crate::object::PyTypeObject; +#[cfg(not(RustPython))] +use crate::Py_IS_TYPE; +use core::ffi::{c_char, c_int}; + +#[cfg(not(RustPython))] +extern_libpython! { + pub static mut PyContext_Type: PyTypeObject; + // skipped non-limited opaque PyContext + pub static mut PyContextVar_Type: PyTypeObject; + // skipped non-limited opaque PyContextVar + pub static mut PyContextToken_Type: PyTypeObject; + // skipped non-limited opaque PyContextToken +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyContext_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyContext_Type) +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyContextVar_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyContextVar_Type) +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyContextToken_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyContextToken_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PyContext_CheckExact(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyContextVar_CheckExact(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyContextToken_CheckExact(op: *mut PyObject) -> c_int; + + pub fn PyContext_New() -> *mut PyObject; + pub fn PyContext_Copy(ctx: *mut PyObject) -> *mut PyObject; + pub fn PyContext_CopyCurrent() -> *mut PyObject; + + pub fn PyContext_Enter(ctx: *mut PyObject) -> c_int; + pub fn PyContext_Exit(ctx: *mut PyObject) -> c_int; + + pub fn PyContextVar_New(name: *const c_char, def: *mut PyObject) -> *mut PyObject; + pub fn PyContextVar_Get( + var: *mut PyObject, + default_value: *mut PyObject, + value: *mut *mut PyObject, + ) -> c_int; + pub fn PyContextVar_Set(var: *mut PyObject, value: *mut PyObject) -> *mut PyObject; + pub fn PyContextVar_Reset(var: *mut PyObject, token: *mut PyObject) -> c_int; + // skipped non-limited _PyContext_NewHamtForTests +} diff --git a/vendor/pyo3-ffi/src/cpython/abstract_.rs b/vendor/pyo3-ffi/src/cpython/abstract_.rs new file mode 100644 index 0000000..f8931d5 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/abstract_.rs @@ -0,0 +1,280 @@ +use crate::{vectorcallfunc, PyObject, Py_TYPE, Py_ssize_t}; +#[cfg(all(any(not(PyPy), not(Py_3_11)), not(Py_3_12)))] +use core::ffi::c_char; +#[cfg(not(Py_3_11))] +use core::ffi::c_int; + +#[cfg(not(any(PyPy, GraalPy)))] +use crate::{ + PyListObject, PyList_Check, PyList_GET_ITEM, PyList_GET_SIZE, PyTupleObject, PyTuple_GET_ITEM, + PyTuple_GET_SIZE, +}; + +#[cfg(not(Py_3_11))] +use crate::Py_buffer; + +#[cfg(not(any(PyPy, Py_3_11)))] +use crate::{PyCallable_Check, PyType_HasFeature, Py_TPFLAGS_HAVE_VECTORCALL}; +#[cfg(not(any(Py_3_12, PyPy)))] +use crate::{PyThreadState, PyThreadState_GET, PyTuple_Check}; +use libc::size_t; + +// skipped private _PyObject_CallMethodId +// skipped private _PyStack_AsDict + +#[cfg(not(Py_3_12))] +extern_libpython! { + #[cfg(not(PyPy))] + fn _Py_CheckFunctionResult( + tstate: *mut PyThreadState, + callable: *mut PyObject, + result: *mut PyObject, + where_: *const c_char, + ) -> *mut PyObject; + + #[cfg(not(PyPy))] + fn _PyObject_MakeTpCall( + tstate: *mut PyThreadState, + callable: *mut PyObject, + args: *const *mut PyObject, + nargs: Py_ssize_t, + keywords: *mut PyObject, + ) -> *mut PyObject; +} + +#[cfg(not(Py_3_12))] +const PY_VECTORCALL_ARGUMENTS_OFFSET: size_t = (1 as size_t) + .checked_shl((8 * core::mem::size_of::() - 1) as u32) + .expect("size_t should fit the flag bits"); + +#[cfg(Py_3_12)] // public API from 3.12 +use crate::PY_VECTORCALL_ARGUMENTS_OFFSET; + +#[inline(always)] +pub unsafe fn PyVectorcall_NARGS(n: size_t) -> Py_ssize_t { + let n = n & !PY_VECTORCALL_ARGUMENTS_OFFSET; + n.try_into().expect("cannot fail due to mask") +} + +#[cfg(any(PyPy, Py_3_11))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyVectorcall_Function")] + pub fn PyVectorcall_Function(callable: *mut PyObject) -> Option; +} + +#[cfg(not(any(PyPy, Py_3_11)))] +#[inline(always)] +pub unsafe fn PyVectorcall_Function(callable: *mut PyObject) -> Option { + assert!(!callable.is_null()); + let tp = crate::Py_TYPE(callable); + if PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL) == 0 { + return None; + } + assert!(PyCallable_Check(callable) > 0); + let offset = (*tp).tp_vectorcall_offset; + assert!(offset > 0); + let ptr = callable.cast::().offset(offset).cast(); + *ptr +} + +#[cfg(not(Py_3_12))] +#[cfg(not(PyPy))] +#[inline(always)] +unsafe fn _PyObject_VectorcallTstate( + tstate: *mut PyThreadState, + callable: *mut PyObject, + args: *const *mut PyObject, + nargsf: size_t, + kwnames: *mut PyObject, +) -> *mut PyObject { + assert!(kwnames.is_null() || PyTuple_Check(kwnames) > 0); + assert!(!args.is_null() || PyVectorcall_NARGS(nargsf) == 0); + + match PyVectorcall_Function(callable) { + None => { + let nargs = PyVectorcall_NARGS(nargsf); + _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames) + } + Some(func) => { + let res = func(callable, args, nargsf, kwnames); + _Py_CheckFunctionResult(tstate, callable, res, core::ptr::null_mut()) + } + } +} + +#[cfg(not(any(PyPy, GraalPy, Py_3_11)))] // exported as a function from 3.11, see abstract.rs +#[inline(always)] +pub unsafe fn PyObject_Vectorcall( + callable: *mut PyObject, + args: *const *mut PyObject, + nargsf: size_t, + kwnames: *mut PyObject, +) -> *mut PyObject { + _PyObject_VectorcallTstate(PyThreadState_GET(), callable, args, nargsf, kwnames) +} + +extern_libpython! { + #[cfg_attr( + all(not(any(PyPy, GraalPy)), not(Py_3_9)), + link_name = "_PyObject_VectorcallDict" + )] + #[cfg_attr(all(PyPy, not(Py_3_9)), link_name = "_PyPyObject_VectorcallDict")] + #[cfg_attr(all(PyPy, Py_3_9), link_name = "PyPyObject_VectorcallDict")] + pub fn PyObject_VectorcallDict( + callable: *mut PyObject, + args: *const *mut PyObject, + nargsf: size_t, + kwdict: *mut PyObject, + ) -> *mut PyObject; +} + +#[cfg(not(any(Py_3_12, PyPy)))] +#[inline(always)] +pub unsafe fn PyObject_CallOneArg(func: *mut PyObject, arg: *mut PyObject) -> *mut PyObject { + assert!(!arg.is_null()); + let args_array = [core::ptr::null_mut(), arg]; + let args = args_array.as_ptr().offset(1); // For PY_VECTORCALL_ARGUMENTS_OFFSET + let tstate = PyThreadState_GET(); + let nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; + _PyObject_VectorcallTstate(tstate, func, args, nargsf, core::ptr::null_mut()) +} + +extern_libpython! { + #[cfg(any(Py_3_12, PyPy))] + #[cfg_attr(PyPy, link_name = "PyPyObject_CallOneArg")] + pub fn PyObject_CallOneArg(func: *mut PyObject, arg: *mut PyObject) -> *mut PyObject; +} + +#[cfg(all(Py_3_9, not(PyPy)))] +#[inline(always)] +pub unsafe fn PyObject_CallMethodNoArgs( + self_: *mut PyObject, + name: *mut PyObject, +) -> *mut PyObject { + crate::PyObject_VectorcallMethod( + name, + &self_, + 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, + core::ptr::null_mut(), + ) +} + +#[cfg(all(Py_3_9, not(PyPy)))] +#[inline(always)] +pub unsafe fn PyObject_CallMethodOneArg( + self_: *mut PyObject, + name: *mut PyObject, + arg: *mut PyObject, +) -> *mut PyObject { + let args = [self_, arg]; + assert!(!arg.is_null()); + crate::PyObject_VectorcallMethod( + name, + args.as_ptr(), + 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, + core::ptr::null_mut(), + ) +} + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyObject_LengthHint")] + pub fn PyObject_LengthHint(o: *mut PyObject, arg1: Py_ssize_t) -> Py_ssize_t; + + #[cfg(not(Py_3_11))] // moved to src/buffer.rs from 3.11 + #[cfg(all(Py_3_9, not(PyPy)))] + pub fn PyObject_CheckBuffer(obj: *mut PyObject) -> c_int; +} + +#[cfg(not(any(Py_3_9, PyPy)))] +#[inline] +pub unsafe fn PyObject_CheckBuffer(o: *mut PyObject) -> c_int { + let tp_as_buffer = (*crate::Py_TYPE(o)).tp_as_buffer; + (!tp_as_buffer.is_null() && (*tp_as_buffer).bf_getbuffer.is_some()) as c_int +} + +#[cfg(not(Py_3_11))] // moved to src/buffer.rs from 3.11 +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyObject_GetBuffer")] + pub fn PyObject_GetBuffer(obj: *mut PyObject, view: *mut Py_buffer, flags: c_int) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyBuffer_GetPointer")] + pub fn PyBuffer_GetPointer( + view: *mut Py_buffer, + indices: *mut Py_ssize_t, + ) -> *mut core::ffi::c_void; + #[cfg_attr(PyPy, link_name = "PyPyBuffer_SizeFromFormat")] + #[cfg(not(Py_3_9))] // return value changed from c_int to Py_ssize_t in 3.9 + pub fn PyBuffer_SizeFromFormat(format: *const c_char) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyBuffer_SizeFromFormat")] + #[cfg(Py_3_9)] + pub fn PyBuffer_SizeFromFormat(format: *const c_char) -> Py_ssize_t; + #[cfg_attr(PyPy, link_name = "PyPyBuffer_ToContiguous")] + pub fn PyBuffer_ToContiguous( + buf: *mut core::ffi::c_void, + view: *mut Py_buffer, + len: Py_ssize_t, + order: c_char, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyBuffer_FromContiguous")] + pub fn PyBuffer_FromContiguous( + view: *mut Py_buffer, + buf: *mut core::ffi::c_void, + len: Py_ssize_t, + order: c_char, + ) -> c_int; + pub fn PyObject_CopyData(dest: *mut PyObject, src: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyBuffer_IsContiguous")] + pub fn PyBuffer_IsContiguous(view: *const Py_buffer, fort: c_char) -> c_int; + pub fn PyBuffer_FillContiguousStrides( + ndims: c_int, + shape: *mut Py_ssize_t, + strides: *mut Py_ssize_t, + itemsize: c_int, + fort: c_char, + ); + #[cfg_attr(PyPy, link_name = "PyPyBuffer_FillInfo")] + pub fn PyBuffer_FillInfo( + view: *mut Py_buffer, + o: *mut PyObject, + buf: *mut core::ffi::c_void, + len: Py_ssize_t, + readonly: c_int, + flags: c_int, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyBuffer_Release")] + pub fn PyBuffer_Release(view: *mut Py_buffer); +} + +#[inline(always)] +pub unsafe fn PySequence_ITEM(seq: *mut PyObject, i: Py_ssize_t) -> *mut PyObject { + (*(*Py_TYPE(seq)).tp_as_sequence).sq_item.unwrap_unchecked()(seq, i) +} + +#[inline(always)] +#[cfg(not(any(PyPy, GraalPy)))] +pub unsafe fn PySequence_Fast_GET_SIZE(seq: *mut PyObject) -> Py_ssize_t { + if PyList_Check(seq) == 1 { + PyList_GET_SIZE(seq) + } else { + PyTuple_GET_SIZE(seq) + } +} + +#[inline(always)] +#[cfg(not(any(PyPy, GraalPy)))] +pub unsafe fn PySequence_Fast_GET_ITEM(seq: *mut PyObject, i: Py_ssize_t) -> *mut PyObject { + if PyList_Check(seq) == 1 { + PyList_GET_ITEM(seq, i) + } else { + PyTuple_GET_ITEM(seq, i) + } +} + +#[inline(always)] +#[cfg(not(any(PyPy, GraalPy)))] +pub unsafe fn PySequence_Fast_ITEMS(seq: *mut PyObject) -> *mut *mut PyObject { + if PyList_Check(seq) == 1 { + (*seq.cast::()).ob_item + } else { + (*seq.cast::()).ob_item.as_mut_ptr() + } +} diff --git a/vendor/pyo3-ffi/src/cpython/bytearrayobject.rs b/vendor/pyo3-ffi/src/cpython/bytearrayobject.rs new file mode 100644 index 0000000..52829b4 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/bytearrayobject.rs @@ -0,0 +1,52 @@ +#[cfg(Py_GIL_DISABLED)] +use crate::cpython::pyatomic::_Py_atomic_load_ssize_relaxed; +use crate::object::*; +use crate::pyport::Py_ssize_t; +use crate::PyByteArray_Check; +#[cfg(not(any(PyPy, GraalPy)))] +use core::ffi::c_char; +#[cfg(not(Py_3_9))] +use core::ffi::c_int; + +#[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API)))] +#[repr(C)] +pub struct PyByteArrayObject { + pub ob_base: PyVarObject, + pub ob_alloc: Py_ssize_t, + pub ob_bytes: *mut c_char, + pub ob_start: *mut c_char, + #[cfg(Py_3_9)] + pub ob_exports: Py_ssize_t, + #[cfg(not(Py_3_9))] + pub ob_exports: c_int, + #[cfg(Py_3_15)] + pub ob_bytes_object: *mut PyObject, +} + +#[cfg(any(PyPy, GraalPy))] +opaque_struct!(pub PyByteArrayObject); + +#[inline] +pub(crate) unsafe fn _PyByteArray_CAST(op: *mut PyObject) -> *mut PyByteArrayObject { + debug_assert_eq!(PyByteArray_Check(op), 1); + op.cast() +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +pub unsafe fn PyByteArray_AS_STRING(op: *mut PyObject) -> *mut c_char { + (*_PyByteArray_CAST(op)).ob_start +} + +#[inline] +pub unsafe fn PyByteArray_GET_SIZE(op: *mut PyObject) -> Py_ssize_t { + let byte_array = _PyByteArray_CAST(op); + #[cfg(Py_GIL_DISABLED)] + { + _Py_atomic_load_ssize_relaxed(&raw const (*_PyVarObject_CAST(byte_array.cast())).ob_size) + } + #[cfg(not(Py_GIL_DISABLED))] + { + Py_SIZE(byte_array.cast()) + } +} diff --git a/vendor/pyo3-ffi/src/cpython/bytesobject.rs b/vendor/pyo3-ffi/src/cpython/bytesobject.rs new file mode 100644 index 0000000..755ecb8 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/bytesobject.rs @@ -0,0 +1,62 @@ +use crate::object::*; +use crate::Py_ssize_t; +#[cfg(not(Py_LIMITED_API))] +use core::ffi::c_char; +use core::ffi::c_int; +#[cfg(Py_3_15)] +use core::ffi::c_void; + +#[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API)))] +#[repr(C)] +pub struct PyBytesObject { + pub ob_base: PyVarObject, + #[cfg_attr( + Py_3_11, + deprecated(note = "Deprecated in Python 3.11 and will be removed in a future version.") + )] + pub ob_shash: crate::Py_hash_t, + pub ob_sval: [c_char; 1], +} + +#[cfg(any(PyPy, GraalPy, Py_LIMITED_API))] +opaque_struct!(pub PyBytesObject); + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "_PyPyBytes_Resize")] + pub(crate) fn _PyBytes_Resize(bytes: *mut *mut PyObject, newsize: Py_ssize_t) -> c_int; +} + +#[cfg(not(Py_LIMITED_API))] +#[inline] +pub unsafe fn PyBytes_AS_STRING(op: *mut PyObject) -> *const c_char { + #[cfg(not(any(PyPy, GraalPy)))] + return &(*op.cast::()).ob_sval as *const c_char; + #[cfg(any(PyPy, GraalPy))] + return crate::PyBytes_AsString(op); +} + +#[cfg(Py_3_15)] +opaque_struct!(pub PyBytesWriter); + +#[cfg(Py_3_15)] +extern_libpython! { + + pub fn PyBytesWriter_Create(size: Py_ssize_t) -> *mut PyBytesWriter; + + pub fn PyBytesWriter_Discard(writer: *mut PyBytesWriter); + + pub fn PyBytesWriter_Finish(writer: *mut PyBytesWriter) -> *mut PyObject; + + pub fn PyBytesWriter_FinishWithSize( + writer: *mut PyBytesWriter, + size: Py_ssize_t, + ) -> *mut PyObject; + + pub fn PyBytesWriter_GetData(writer: *mut PyBytesWriter) -> *mut c_void; + + pub fn PyBytesWriter_GetSize(writer: *mut PyBytesWriter) -> Py_ssize_t; + + pub fn PyBytesWriter_Resize(writer: *mut PyBytesWriter, size: Py_ssize_t) -> c_int; + + pub fn PyBytesWriter_Grow(writer: *mut PyBytesWriter, size: Py_ssize_t) -> c_int; +} diff --git a/vendor/pyo3-ffi/src/cpython/cellobject.rs b/vendor/pyo3-ffi/src/cpython/cellobject.rs new file mode 100644 index 0000000..628bfa3 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/cellobject.rs @@ -0,0 +1,24 @@ +use crate::object::*; +use core::ffi::c_int; + +#[cfg(not(any(PyPy, GraalPy)))] +#[repr(C)] +pub struct PyCellObject { + pub ob_base: PyObject, + pub ob_ref: *mut PyObject, +} + +extern_libpython! { + pub fn PyCell_New(o: *mut PyObject) -> *mut PyObject; + pub fn PyCell_Get(o: *mut PyObject) -> *mut PyObject; + pub fn PyCell_Set(o: *mut PyObject, val: *mut PyObject) -> c_int; + pub static mut PyCell_Type: PyTypeObject; +} + +#[inline] +pub unsafe fn PyCell_Check(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyCell_Type) +} + +// skipped PyCell_SET +// skipped PyCell_GET diff --git a/vendor/pyo3-ffi/src/cpython/ceval.rs b/vendor/pyo3-ffi/src/cpython/ceval.rs new file mode 100644 index 0000000..ea12ccf --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/ceval.rs @@ -0,0 +1,46 @@ +use crate::cpython::pystate::Py_tracefunc; +use crate::object::{freefunc, PyObject}; +use crate::Py_ssize_t; + +extern_libpython! { + pub fn PyEval_SetProfile(trace_func: Option, arg1: *mut PyObject); + #[cfg(Py_3_12)] + pub fn PyEval_SetProfileAllThreads(trace_func: Option, arg1: *mut PyObject); + pub fn PyEval_SetTrace(trace_func: Option, arg1: *mut PyObject); + #[cfg(Py_3_12)] + pub fn PyEval_SetTraceAllThreads(trace_func: Option, arg1: *mut PyObject); + + // skipped PyEval_MergeCompilerFlags + + // skipped private _PyEval_EvalFrameDefault + + // was moved to the unstable API tier on Py_3_12, use link_name for older versions + #[cfg_attr(Py_3_12, link_name = "_PyEval_RequestCodeExtraIndex")] + pub fn PyUnstable_Eval_RequestCodeExtraIndex(func: freefunc) -> Py_ssize_t; +} + +#[deprecated( + since = "0.29.0", + note = "renamed to PyUnstable_Eval_RequestCodeExtraIndex" +)] +#[inline] +pub unsafe extern "C" fn _PyEval_RequestCodeExtraIndex(func: freefunc) -> Py_ssize_t { + PyUnstable_Eval_RequestCodeExtraIndex(func) +} + +extern_libpython! { + + // skipped private _PyEval_SliceIndex + // skipped private _PyEval_SliceIndexNotNone + // skipped private _PyEval_UnpackIndices + + // skipped PerfMapState + + // skipped PyUnstable_PerfMapState_Init + // skipped PyUnstable_WritePerfMapEntry + // skipped PyUnstable_PerfMapState_Fini + // skipped PyUnstable_CopyPerfMapFile + // skipped PyUnstable_PerfTrampoline_CompileCode + // skipped PyUnstable_PerfTrampoline_SetPersistAfterFork + +} diff --git a/vendor/pyo3-ffi/src/cpython/code.rs b/vendor/pyo3-ffi/src/cpython/code.rs new file mode 100644 index 0000000..10c25ca --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/code.rs @@ -0,0 +1,177 @@ +use crate::object::*; +use crate::pyport::Py_ssize_t; + +#[cfg(not(GraalPy))] +use crate::PyCodeObject; +#[cfg(not(GraalPy))] +use core::ffi::c_char; +use core::ffi::{c_int, c_void}; + +// skipped private _PY_MONITORING_LOCAL_EVENTS +// skipped private _PY_MONITORING_UNGROUPED_EVENTS +// skipped private _PY_MONITORING_EVENTS + +// skipped private _PyLocalMonitors +// skipped private _Py_GlobalMonitors + +// skipped private _Py_CODEUNIT + +// skipped private _Py_OPCODE +// skipped private _Py_OPARG + +// skipped private _py_make_codeunit + +// skipped private _py_set_opcode + +// skipped private _Py_MAKE_CODEUNIT +// skipped private _Py_SET_OPCODE + +// skipped private _PyCoCached +// skipped private _PyCoLineInstrumentationData +// skipped private _PyCoMonitoringData + +// skipped private _PyExecutorArray + +/* Masks for co_flags */ +pub const CO_OPTIMIZED: c_int = 0x0001; +pub const CO_NEWLOCALS: c_int = 0x0002; +pub const CO_VARARGS: c_int = 0x0004; +pub const CO_VARKEYWORDS: c_int = 0x0008; +pub const CO_NESTED: c_int = 0x0010; +pub const CO_GENERATOR: c_int = 0x0020; +/* The CO_NOFREE flag is set if there are no free or cell variables. + This information is redundant, but it allows a single flag test + to determine whether there is any extra work to be done when the + call frame it setup. +*/ +pub const CO_NOFREE: c_int = 0x0040; +/* The CO_COROUTINE flag is set for coroutine functions (defined with +``async def`` keywords) */ +pub const CO_COROUTINE: c_int = 0x0080; +pub const CO_ITERABLE_COROUTINE: c_int = 0x0100; +pub const CO_ASYNC_GENERATOR: c_int = 0x0200; + +pub const CO_FUTURE_DIVISION: c_int = 0x2000; +pub const CO_FUTURE_ABSOLUTE_IMPORT: c_int = 0x4000; /* do absolute imports by default */ +pub const CO_FUTURE_WITH_STATEMENT: c_int = 0x8000; +pub const CO_FUTURE_PRINT_FUNCTION: c_int = 0x1_0000; +pub const CO_FUTURE_UNICODE_LITERALS: c_int = 0x2_0000; + +pub const CO_FUTURE_BARRY_AS_BDFL: c_int = 0x4_0000; +pub const CO_FUTURE_GENERATOR_STOP: c_int = 0x8_0000; +// skipped CO_FUTURE_ANNOTATIONS +// skipped CO_CELL_NOT_AN_ARG + +pub const CO_MAXBLOCKS: usize = 20; + +#[cfg(not(PyPy))] +extern_libpython! { + pub static mut PyCode_Type: PyTypeObject; +} + +#[inline] +#[cfg(not(PyPy))] +pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyCode_Type) +} + +extern_libpython! { + #[cfg(PyPy)] + #[link_name = "PyPyCode_Check"] + pub fn PyCode_Check(op: *mut PyObject) -> c_int; +} + +// skipped PyCode_GetNumFree (requires knowledge of code object layout) + +extern_libpython! { + #[cfg(not(GraalPy))] + #[cfg_attr(PyPy, link_name = "PyPyCode_New")] + pub fn PyCode_New( + argcount: c_int, + kwonlyargcount: c_int, + nlocals: c_int, + stacksize: c_int, + flags: c_int, + code: *mut PyObject, + consts: *mut PyObject, + names: *mut PyObject, + varnames: *mut PyObject, + freevars: *mut PyObject, + cellvars: *mut PyObject, + filename: *mut PyObject, + name: *mut PyObject, + firstlineno: c_int, + lnotab: *mut PyObject, + ) -> *mut PyCodeObject; + #[cfg(not(GraalPy))] + pub fn PyCode_NewWithPosOnlyArgs( + argcount: c_int, + posonlyargcount: c_int, + kwonlyargcount: c_int, + nlocals: c_int, + stacksize: c_int, + flags: c_int, + code: *mut PyObject, + consts: *mut PyObject, + names: *mut PyObject, + varnames: *mut PyObject, + freevars: *mut PyObject, + cellvars: *mut PyObject, + filename: *mut PyObject, + name: *mut PyObject, + firstlineno: c_int, + lnotab: *mut PyObject, + ) -> *mut PyCodeObject; + #[cfg(not(GraalPy))] + #[cfg_attr(PyPy, link_name = "PyPyCode_NewEmpty")] + pub fn PyCode_NewEmpty( + filename: *const c_char, + funcname: *const c_char, + firstlineno: c_int, + ) -> *mut PyCodeObject; + #[cfg(not(GraalPy))] + pub fn PyCode_Addr2Line(arg1: *mut PyCodeObject, arg2: c_int) -> c_int; + // skipped PyCodeAddressRange "for internal use only" + // skipped _PyCode_CheckLineNumber + // skipped _PyCode_ConstantKey + pub fn PyCode_Optimize( + code: *mut PyObject, + consts: *mut PyObject, + names: *mut PyObject, + lnotab: *mut PyObject, + ) -> *mut PyObject; + + #[cfg_attr(not(Py_3_12), link_name = "_PyCode_GetExtra")] + pub fn PyUnstable_Code_GetExtra( + code: *mut PyObject, + index: Py_ssize_t, + extra: *mut *mut c_void, + ) -> c_int; + + #[cfg_attr(not(Py_3_12), link_name = "_PyCode_SetExtra")] + pub fn PyUnstable_Code_SetExtra( + code: *mut PyObject, + index: Py_ssize_t, + extra: *mut c_void, + ) -> c_int; +} + +#[deprecated(since = "0.29.0", note = "renamed to PyUnstable_Code_GetExtra")] +#[inline] +pub unsafe extern "C" fn _PyCode_GetExtra( + code: *mut PyObject, + index: Py_ssize_t, + extra: *mut *mut c_void, +) -> c_int { + PyUnstable_Code_GetExtra(code, index, extra) +} + +#[deprecated(since = "0.29.0", note = "renamed to PyUnstable_Code_SetExtra")] +#[inline] +pub unsafe extern "C" fn _PyCode_SetExtra( + code: *mut PyObject, + index: Py_ssize_t, + extra: *mut c_void, +) -> c_int { + PyUnstable_Code_SetExtra(code, index, extra) +} diff --git a/vendor/pyo3-ffi/src/cpython/compile.rs b/vendor/pyo3-ffi/src/cpython/compile.rs new file mode 100644 index 0000000..c6e8b25 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/compile.rs @@ -0,0 +1,95 @@ +#[cfg(not(any(PyPy, Py_3_10)))] +use crate::object::PyObject; +#[cfg(not(any(PyPy, Py_3_10)))] +use crate::pyarena::*; +#[cfg(not(any(PyPy, Py_3_10)))] +use crate::pythonrun::*; +#[cfg(not(any(PyPy, Py_3_10)))] +use crate::PyCodeObject; +use crate::INT_MAX; +#[cfg(not(any(PyPy, Py_3_10)))] +use core::ffi::c_char; +use core::ffi::c_int; + +// skipped PyCF_MASK +// skipped PyCF_MASK_OBSOLETE +// skipped PyCF_SOURCE_IS_UTF8 +// skipped PyCF_DONT_IMPLY_DEDENT +// skipped PyCF_ONLY_AST +// skipped PyCF_IGNORE_COOKIE +// skipped PyCF_TYPE_COMMENTS +// skipped PyCF_ALLOW_TOP_LEVEL_AWAIT +// skipped PyCF_OPTIMIZED_AST +// skipped PyCF_COMPILE_MASK + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyCompilerFlags { + pub cf_flags: c_int, + pub cf_feature_version: c_int, +} + +// skipped _PyCompilerFlags_INIT + +// NB this type technically existed in the header until 3.13, when it was +// moved to the internal CPython headers. +// +// We choose not to expose it in the public API past 3.10, as it is +// not used in the public API past that point. +#[cfg(not(any(PyPy, GraalPy, Py_3_10)))] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyFutureFeatures { + pub ff_features: c_int, + pub ff_lineno: c_int, +} + +// FIXME: these constants should probably be &CStr, if they are used at all + +pub const FUTURE_NESTED_SCOPES: &str = "nested_scopes"; +pub const FUTURE_GENERATORS: &str = "generators"; +pub const FUTURE_DIVISION: &str = "division"; +pub const FUTURE_ABSOLUTE_IMPORT: &str = "absolute_import"; +pub const FUTURE_WITH_STATEMENT: &str = "with_statement"; +pub const FUTURE_PRINT_FUNCTION: &str = "print_function"; +pub const FUTURE_UNICODE_LITERALS: &str = "unicode_literals"; +pub const FUTURE_BARRY_AS_BDFL: &str = "barry_as_FLUFL"; +pub const FUTURE_GENERATOR_STOP: &str = "generator_stop"; +pub const FUTURE_ANNOTATIONS: &str = "annotations"; + +#[cfg(not(any(PyPy, GraalPy, Py_3_10)))] +extern_libpython! { + pub fn PyNode_Compile(arg1: *mut _node, arg2: *const c_char) -> *mut PyCodeObject; + + pub fn PyAST_CompileEx( + _mod: *mut _mod, + filename: *const c_char, + flags: *mut PyCompilerFlags, + optimize: c_int, + arena: *mut PyArena, + ) -> *mut PyCodeObject; + + pub fn PyAST_CompileObject( + _mod: *mut _mod, + filename: *mut PyObject, + flags: *mut PyCompilerFlags, + optimize: c_int, + arena: *mut PyArena, + ) -> *mut PyCodeObject; + + pub fn PyFuture_FromAST(_mod: *mut _mod, filename: *const c_char) -> *mut PyFutureFeatures; + + pub fn PyFuture_FromASTObject( + _mod: *mut _mod, + filename: *mut PyObject, + ) -> *mut PyFutureFeatures; +} + +pub const PY_INVALID_STACK_EFFECT: c_int = INT_MAX; + +extern_libpython! { + + pub fn PyCompile_OpcodeStackEffect(opcode: c_int, oparg: c_int) -> c_int; + + pub fn PyCompile_OpcodeStackEffectWithJump(opcode: c_int, oparg: c_int, jump: c_int) -> c_int; +} diff --git a/vendor/pyo3-ffi/src/cpython/complexobject.rs b/vendor/pyo3-ffi/src/cpython/complexobject.rs new file mode 100644 index 0000000..d3d29ce --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/complexobject.rs @@ -0,0 +1,30 @@ +use crate::PyObject; +use core::ffi::c_double; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct Py_complex { + pub real: c_double, + pub imag: c_double, +} + +// skipped private function _Py_c_sum +// skipped private function _Py_c_diff +// skipped private function _Py_c_neg +// skipped private function _Py_c_prod +// skipped private function _Py_c_quot +// skipped private function _Py_c_pow +// skipped private function _Py_c_abs + +#[repr(C)] +pub struct PyComplexObject { + pub ob_base: PyObject, + pub cval: Py_complex, +} + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyComplex_FromCComplex")] + pub fn PyComplex_FromCComplex(v: Py_complex) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyComplex_AsCComplex")] + pub fn PyComplex_AsCComplex(op: *mut PyObject) -> Py_complex; +} diff --git a/vendor/pyo3-ffi/src/cpython/critical_section.rs b/vendor/pyo3-ffi/src/cpython/critical_section.rs new file mode 100644 index 0000000..4862a24 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/critical_section.rs @@ -0,0 +1,11 @@ +use crate::PyMutex; +use crate::{PyCriticalSection, PyCriticalSection2}; + +extern_libpython! { + pub fn PyCriticalSection_BeginMutex(c: *mut PyCriticalSection, m: *mut PyMutex); + pub fn PyCriticalSection2_BeginMutex( + c: *mut PyCriticalSection2, + m1: *mut PyMutex, + m2: *mut PyMutex, + ); +} diff --git a/vendor/pyo3-ffi/src/cpython/descrobject.rs b/vendor/pyo3-ffi/src/cpython/descrobject.rs new file mode 100644 index 0000000..e2e40ef --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/descrobject.rs @@ -0,0 +1,81 @@ +use crate::{PyGetSetDef, PyMethodDef, PyObject, PyTypeObject}; +use core::ffi::{c_char, c_int, c_void}; + +#[cfg(Py_3_11)] +use crate::PyMemberDef; + +pub type wrapperfunc = Option< + unsafe extern "C" fn( + slf: *mut PyObject, + args: *mut PyObject, + wrapped: *mut c_void, + ) -> *mut PyObject, +>; + +pub type wrapperfunc_kwds = Option< + unsafe extern "C" fn( + slf: *mut PyObject, + args: *mut PyObject, + wrapped: *mut c_void, + kwds: *mut PyObject, + ) -> *mut PyObject, +>; + +#[repr(C)] +pub struct wrapperbase { + pub name: *const c_char, + pub offset: c_int, + pub function: *mut c_void, + pub wrapper: wrapperfunc, + pub doc: *const c_char, + pub flags: c_int, + pub name_strobj: *mut PyObject, +} + +pub const PyWrapperFlag_KEYWORDS: c_int = 1; + +#[repr(C)] +pub struct PyDescrObject { + pub ob_base: PyObject, + pub d_type: *mut PyTypeObject, + pub d_name: *mut PyObject, + pub d_qualname: *mut PyObject, +} + +// skipped non-limited PyDescr_TYPE +// skipped non-limited PyDescr_NAME + +#[repr(C)] +pub struct PyMethodDescrObject { + pub d_common: PyDescrObject, + pub d_method: *mut PyMethodDef, + #[cfg(not(PyPy))] + pub vectorcall: Option, +} + +#[repr(C)] +pub struct PyMemberDescrObject { + pub d_common: PyDescrObject, + #[cfg(not(Py_3_11))] + pub d_member: *mut PyGetSetDef, + #[cfg(Py_3_11)] + pub d_member: *mut PyMemberDef, +} + +#[repr(C)] +pub struct PyGetSetDescrObject { + pub d_common: PyDescrObject, + pub d_getset: *mut PyGetSetDef, +} + +#[repr(C)] +pub struct PyWrapperDescrObject { + pub d_common: PyDescrObject, + pub d_base: *mut wrapperbase, + pub d_wrapped: *mut c_void, +} + +// skipped _PyMethodWrapper_Type + +// skipped non-limited PyDescr_NewWrapper +// skipped non-limited PyDescr_IsData diff --git a/vendor/pyo3-ffi/src/cpython/dictobject.rs b/vendor/pyo3-ffi/src/cpython/dictobject.rs new file mode 100644 index 0000000..df98a94 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/dictobject.rs @@ -0,0 +1,114 @@ +#[cfg(not(GraalPy))] +use crate::object::*; +#[cfg(not(any(PyPy, GraalPy)))] +use crate::pyport::Py_ssize_t; +#[cfg(all(GraalPy, Py_3_13))] +use crate::PyObject; + +#[cfg(all(not(PyPy), Py_3_13))] +use core::ffi::c_char; +#[cfg(all(not(PyPy), Py_3_12))] +use core::ffi::c_int; + +#[cfg(not(PyPy))] +opaque_struct!(pub PyDictKeysObject); + +#[cfg(Py_3_11)] +#[cfg(not(PyPy))] +opaque_struct!(pub PyDictValues); + +#[cfg(not(any(GraalPy, PyPy)))] +#[repr(C)] +#[derive(Debug)] +pub struct PyDictObject { + pub ob_base: PyObject, + pub ma_used: Py_ssize_t, + #[cfg_attr( + Py_3_12, + deprecated(note = "Deprecated in Python 3.12 and will be removed in the future.") + )] + #[cfg(not(Py_3_14))] + pub ma_version_tag: u64, + #[cfg(Py_3_14)] + _ma_watcher_tag: u64, + pub ma_keys: *mut PyDictKeysObject, + #[cfg(not(Py_3_11))] + pub ma_values: *mut *mut PyObject, + #[cfg(Py_3_11)] + pub ma_values: *mut PyDictValues, +} + +#[cfg(PyPy)] +#[repr(C)] +#[derive(Debug)] +pub struct PyDictObject { + pub ob_base: PyObject, + _tmpkeys: *mut PyObject, +} + +extern_libpython! { + #[cfg(Py_3_15)] + pub fn PyFrozenDict_New(iterable: *mut PyObject) -> *mut PyObject; +} + +// skipped private _PyDict_GetItem_KnownHash +// skipped private _PyDict_GetItemStringWithError + +extern_libpython! { + #[cfg(not(GraalPy))] + pub fn PyDict_SetDefault( + mp: *mut PyObject, + key: *mut PyObject, + default_obj: *mut PyObject, + ) -> *mut PyObject; + /* + #[cfg(all(Py_3_13, not(Py_3_15)))] + pub fn PyDict_SetDefaultRef( + mp: *mut PyObject, + key: *mut PyObject, + default_obj: *mut PyObject, + result: *mut *mut PyObject, + ) -> c_int; + */ +} + +// skipped PyDict_GET_SIZE + +extern_libpython! { + #[cfg(Py_3_13)] + pub fn PyDict_ContainsString(mp: *mut PyObject, key: *const c_char) -> c_int; +} + +// skipped private _PyDict_NewPresized + +extern_libpython! { + #[cfg(Py_3_13)] + pub fn PyDict_Pop(dict: *mut PyObject, key: *mut PyObject, result: *mut *mut PyObject) + -> c_int; + #[cfg(Py_3_13)] + pub fn PyDict_PopString( + dict: *mut PyObject, + key: *const c_char, + result: *mut *mut PyObject, + ) -> c_int; +} + +// skipped private _PyDict_Pop + +// skipped PY_FOREACH_DICT_EVENT +// skipped PyDict_WatchEvent + +// skipped PyDict_WatchCallback + +// skipped PyDict_AddWatcher + +extern_libpython! { + #[cfg(Py_3_12)] + pub fn PyDict_ClearWatcher(watcher_id: c_int) -> c_int; + #[cfg(Py_3_12)] + #[cfg(not(GraalPy))] + pub fn PyDict_Watch(watcher_id: c_int, dict: *mut PyObject) -> c_int; + #[cfg(Py_3_12)] + #[cfg(not(GraalPy))] + pub fn PyDict_Unwatch(watcher_id: c_int, dict: *mut PyObject) -> c_int; +} diff --git a/vendor/pyo3-ffi/src/cpython/floatobject.rs b/vendor/pyo3-ffi/src/cpython/floatobject.rs new file mode 100644 index 0000000..6dcb213 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/floatobject.rs @@ -0,0 +1,35 @@ +#[cfg(GraalPy)] +use crate::PyFloat_AsDouble; +#[cfg(not(GraalPy))] +use crate::PyFloat_Check; +use crate::PyObject; +use core::ffi::c_double; + +#[repr(C)] +pub struct PyFloatObject { + pub ob_base: PyObject, + pub ob_fval: c_double, +} + +#[inline] +#[cfg(not(GraalPy))] +unsafe fn _PyFloat_CAST(op: *mut PyObject) -> *mut PyFloatObject { + debug_assert_eq!(PyFloat_Check(op), 1); + op.cast() +} + +#[inline] +pub unsafe fn PyFloat_AS_DOUBLE(op: *mut PyObject) -> c_double { + #[cfg(not(GraalPy))] + return (*_PyFloat_CAST(op)).ob_fval; + #[cfg(GraalPy)] + return PyFloat_AsDouble(op); +} + +// skipped PyFloat_Pack2 +// skipped PyFloat_Pack4 +// skipped PyFloat_Pack8 + +// skipped PyFloat_Unpack2 +// skipped PyFloat_Unpack4 +// skipped PyFloat_Unpack8 diff --git a/vendor/pyo3-ffi/src/cpython/frameobject.rs b/vendor/pyo3-ffi/src/cpython/frameobject.rs new file mode 100644 index 0000000..c79d688 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/frameobject.rs @@ -0,0 +1,51 @@ +#[cfg(not(GraalPy))] +use crate::object::*; +#[cfg(not(GraalPy))] +use crate::PyCodeObject; +use crate::PyFrameObject; +#[cfg(not(GraalPy))] +use crate::PyThreadState; +#[cfg(not(any(PyPy, GraalPy, Py_3_11)))] +use core::ffi::c_char; +use core::ffi::c_int; + +#[cfg(not(any(PyPy, GraalPy, Py_3_11)))] +pub type PyFrameState = c_char; + +#[repr(C)] +#[derive(Copy, Clone)] +#[cfg(not(any(PyPy, GraalPy, Py_3_11)))] +pub struct PyTryBlock { + pub b_type: c_int, + pub b_handler: c_int, + pub b_level: c_int, +} + +// skipped _PyFrame_IsRunnable +// skipped _PyFrame_IsExecuting +// skipped _PyFrameHasCompleted + +extern_libpython! { + #[cfg(not(GraalPy))] + #[cfg_attr(PyPy, link_name = "PyPyFrame_New")] + pub fn PyFrame_New( + tstate: *mut PyThreadState, + code: *mut PyCodeObject, + globals: *mut PyObject, + locals: *mut PyObject, + ) -> *mut PyFrameObject; + // skipped _PyFrame_New_NoTrack + + pub fn PyFrame_BlockSetup(f: *mut PyFrameObject, _type: c_int, handler: c_int, level: c_int); + #[cfg(not(any(PyPy, GraalPy, Py_3_11)))] + pub fn PyFrame_BlockPop(f: *mut PyFrameObject) -> *mut PyTryBlock; + + pub fn PyFrame_LocalsToFast(f: *mut PyFrameObject, clear: c_int); + pub fn PyFrame_FastToLocalsWithError(f: *mut PyFrameObject) -> c_int; + pub fn PyFrame_FastToLocals(f: *mut PyFrameObject); + + // skipped _PyFrame_DebugMallocStats + + #[cfg(not(Py_3_9))] + pub fn PyFrame_ClearFreeList() -> c_int; +} diff --git a/vendor/pyo3-ffi/src/cpython/funcobject.rs b/vendor/pyo3-ffi/src/cpython/funcobject.rs new file mode 100644 index 0000000..b1e4c05 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/funcobject.rs @@ -0,0 +1,103 @@ +use crate::{PyObject, Py_IS_TYPE}; +use core::ffi::c_int; + +#[cfg(all(not(any(PyPy, GraalPy)), not(Py_3_10)))] +#[repr(C)] +pub struct PyFunctionObject { + pub ob_base: PyObject, + pub func_code: *mut PyObject, + pub func_globals: *mut PyObject, + pub func_defaults: *mut PyObject, + pub func_kwdefaults: *mut PyObject, + pub func_closure: *mut PyObject, + pub func_doc: *mut PyObject, + pub func_name: *mut PyObject, + pub func_dict: *mut PyObject, + pub func_weakreflist: *mut PyObject, + pub func_module: *mut PyObject, + pub func_annotations: *mut PyObject, + pub func_qualname: *mut PyObject, + pub vectorcall: Option, +} + +#[cfg(all(not(any(PyPy, GraalPy)), Py_3_10))] +#[repr(C)] +pub struct PyFunctionObject { + pub ob_base: PyObject, + pub func_globals: *mut PyObject, + pub func_builtins: *mut PyObject, + pub func_name: *mut PyObject, + pub func_qualname: *mut PyObject, + pub func_code: *mut PyObject, + pub func_defaults: *mut PyObject, + pub func_kwdefaults: *mut PyObject, + pub func_closure: *mut PyObject, + pub func_doc: *mut PyObject, + pub func_dict: *mut PyObject, + pub func_weakreflist: *mut PyObject, + pub func_module: *mut PyObject, + pub func_annotations: *mut PyObject, + #[cfg(Py_3_14)] + pub func_annotate: *mut PyObject, + #[cfg(Py_3_12)] + pub func_typeparams: *mut PyObject, + pub vectorcall: Option, + #[cfg(Py_3_11)] + pub func_version: u32, +} + +#[cfg(PyPy)] +#[repr(C)] +pub struct PyFunctionObject { + pub ob_base: PyObject, + pub func_name: *mut PyObject, +} + +#[cfg(GraalPy)] +pub struct PyFunctionObject { + pub ob_base: PyObject, +} + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyFunction_Type")] + pub static mut PyFunction_Type: crate::PyTypeObject; +} + +#[inline] +pub unsafe fn PyFunction_Check(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyFunction_Type) +} + +extern_libpython! { + pub fn PyFunction_New(code: *mut PyObject, globals: *mut PyObject) -> *mut PyObject; + pub fn PyFunction_NewWithQualName( + code: *mut PyObject, + globals: *mut PyObject, + qualname: *mut PyObject, + ) -> *mut PyObject; + pub fn PyFunction_GetCode(op: *mut PyObject) -> *mut PyObject; + pub fn PyFunction_GetGlobals(op: *mut PyObject) -> *mut PyObject; + pub fn PyFunction_GetModule(op: *mut PyObject) -> *mut PyObject; + pub fn PyFunction_GetDefaults(op: *mut PyObject) -> *mut PyObject; + pub fn PyFunction_SetDefaults(op: *mut PyObject, defaults: *mut PyObject) -> c_int; + pub fn PyFunction_GetKwDefaults(op: *mut PyObject) -> *mut PyObject; + pub fn PyFunction_SetKwDefaults(op: *mut PyObject, defaults: *mut PyObject) -> c_int; + pub fn PyFunction_GetClosure(op: *mut PyObject) -> *mut PyObject; + pub fn PyFunction_SetClosure(op: *mut PyObject, closure: *mut PyObject) -> c_int; + pub fn PyFunction_GetAnnotations(op: *mut PyObject) -> *mut PyObject; + pub fn PyFunction_SetAnnotations(op: *mut PyObject, annotations: *mut PyObject) -> c_int; +} + +// skipped _PyFunction_Vectorcall +// skipped PyFunction_GET_CODE +// skipped PyFunction_GET_GLOBALS +// skipped PyFunction_GET_MODULE +// skipped PyFunction_GET_DEFAULTS +// skipped PyFunction_GET_KW_DEFAULTS +// skipped PyFunction_GET_CLOSURE +// skipped PyFunction_GET_ANNOTATIONS + +// skipped PyClassMethod_Type +// skipped PyStaticMethod_Type +// skipped PyClassMethod_New +// skipped PyStaticMethod_New diff --git a/vendor/pyo3-ffi/src/cpython/genobject.rs b/vendor/pyo3-ffi/src/cpython/genobject.rs new file mode 100644 index 0000000..c97de71 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/genobject.rs @@ -0,0 +1,100 @@ +use crate::object::*; +use crate::PyFrameObject; +#[cfg(all(Py_3_11, not(any(PyPy, GraalPy, Py_3_14))))] +use core::ffi::c_char; +use core::ffi::c_int; + +#[cfg(not(any(PyPy, GraalPy, Py_3_14)))] +#[repr(C)] +pub struct PyGenObject { + pub ob_base: PyObject, + #[cfg(not(Py_3_11))] + pub gi_frame: *mut PyFrameObject, + #[cfg(not(Py_3_10))] + pub gi_running: c_int, + #[cfg(not(Py_3_12))] + pub gi_code: *mut PyObject, + pub gi_weakreflist: *mut PyObject, + pub gi_name: *mut PyObject, + pub gi_qualname: *mut PyObject, + #[allow( + private_interfaces, + reason = "PyGenObject layout was public until 3.14" + )] + pub gi_exc_state: crate::cpython::pystate::_PyErr_StackItem, + #[cfg(Py_3_11)] + pub gi_origin_or_finalizer: *mut PyObject, + #[cfg(Py_3_11)] + pub gi_hooks_inited: c_char, + #[cfg(Py_3_11)] + pub gi_closed: c_char, + #[cfg(Py_3_11)] + pub gi_running_async: c_char, + #[cfg(Py_3_11)] + pub gi_frame_state: i8, + #[cfg(Py_3_11)] + pub gi_iframe: [*mut PyObject; 1], +} + +#[cfg(all(Py_3_14, not(any(PyPy, GraalPy))))] +opaque_struct!(pub PyGenObject); + +extern_libpython! { + pub static mut PyGen_Type: PyTypeObject; +} + +#[inline] +pub unsafe fn PyGen_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, &raw mut PyGen_Type) +} + +#[inline] +pub unsafe fn PyGen_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyGen_Type) +} + +extern_libpython! { + pub fn PyGen_New(frame: *mut PyFrameObject) -> *mut PyObject; + // skipped PyGen_NewWithQualName + // skipped _PyGen_SetStopIterationValue + // skipped _PyGen_FetchStopIterationValue + // skipped _PyGen_yf + // skipped _PyGen_Finalize + #[cfg(not(any(Py_3_9, PyPy)))] + #[deprecated(note = "This function was never documented in the Python API.")] + pub fn PyGen_NeedsFinalizing(op: *mut PyGenObject) -> c_int; +} + +// skipped PyCoroObject + +extern_libpython! { + pub static mut PyCoro_Type: PyTypeObject; +} + +// skipped _PyCoroWrapper_Type + +#[inline] +pub unsafe fn PyCoro_CheckExact(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, &raw mut PyCoro_Type) +} + +// skipped _PyCoro_GetAwaitableIter +// skipped PyCoro_New + +// skipped PyAsyncGenObject + +extern_libpython! { + pub static mut PyAsyncGen_Type: PyTypeObject; + // skipped _PyAsyncGenASend_Type + // skipped _PyAsyncGenWrappedValue_Type + // skipped _PyAsyncGenAThrow_Type +} + +// skipped PyAsyncGen_New + +#[inline] +pub unsafe fn PyAsyncGen_CheckExact(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, &raw mut PyAsyncGen_Type) +} + +// skipped _PyAsyncGenValueWrapperNew diff --git a/vendor/pyo3-ffi/src/cpython/import.rs b/vendor/pyo3-ffi/src/cpython/import.rs new file mode 100644 index 0000000..4b358f0 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/import.rs @@ -0,0 +1,51 @@ +#[cfg(any(not(PyPy), Py_3_14))] +use crate::PyObject; +#[cfg(any(not(PyPy), Py_3_14))] +use core::ffi::c_char; +#[cfg(not(PyPy))] +use core::ffi::{c_int, c_uchar}; + +#[cfg(not(PyPy))] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _inittab { + pub name: *const c_char, + pub initfunc: Option *mut PyObject>, +} + +extern_libpython! { + #[cfg(not(PyPy))] + pub static mut PyImport_Inittab: *mut _inittab; + + #[cfg(not(PyPy))] + pub fn PyImport_ExtendInittab(newtab: *mut _inittab) -> c_int; +} + +#[cfg(not(PyPy))] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _frozen { + pub name: *const c_char, + pub code: *const c_uchar, + pub size: c_int, + #[cfg(Py_3_11)] + pub is_package: c_int, + #[cfg(all(Py_3_11, not(Py_3_13)))] + pub get_code: Option *mut PyObject>, +} + +extern_libpython! { + #[cfg(not(PyPy))] + pub static mut PyImport_FrozenModules: *const _frozen; + + #[cfg(Py_3_14)] + pub fn PyImport_ImportModuleAttr( + mod_name: *mut PyObject, + attr_name: *mut PyObject, + ) -> *mut PyObject; + #[cfg(Py_3_14)] + pub fn PyImport_ImportModuleAttrString( + mod_name: *const c_char, + attr_name: *const c_char, + ) -> *mut PyObject; +} diff --git a/vendor/pyo3-ffi/src/cpython/initconfig.rs b/vendor/pyo3-ffi/src/cpython/initconfig.rs new file mode 100644 index 0000000..4d3696a --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/initconfig.rs @@ -0,0 +1,237 @@ +/* --- PyStatus ----------------------------------------------- */ + +use crate::Py_ssize_t; +use core::ffi::{c_char, c_int, c_ulong}; +use libc::wchar_t; + +#[repr(C)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum _PyStatus_TYPE { + _PyStatus_TYPE_OK = 0, + _PyStatus_TYPE_ERROR = 1, + _PyStatus_TYPE_EXIT = 2, +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyStatus { + pub _type: _PyStatus_TYPE, + pub func: *const c_char, + pub err_msg: *const c_char, + pub exitcode: c_int, +} + +extern_libpython! { + pub fn PyStatus_Ok() -> PyStatus; + pub fn PyStatus_Error(err_msg: *const c_char) -> PyStatus; + pub fn PyStatus_NoMemory() -> PyStatus; + pub fn PyStatus_Exit(exitcode: c_int) -> PyStatus; + pub fn PyStatus_IsError(err: PyStatus) -> c_int; + pub fn PyStatus_IsExit(err: PyStatus) -> c_int; + pub fn PyStatus_Exception(err: PyStatus) -> c_int; +} + +/* --- PyWideStringList ------------------------------------------------ */ + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyWideStringList { + pub length: Py_ssize_t, + pub items: *mut *mut wchar_t, +} + +extern_libpython! { + pub fn PyWideStringList_Append(list: *mut PyWideStringList, item: *const wchar_t) -> PyStatus; + pub fn PyWideStringList_Insert( + list: *mut PyWideStringList, + index: Py_ssize_t, + item: *const wchar_t, + ) -> PyStatus; +} + +/* --- PyPreConfig ----------------------------------------------- */ + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyPreConfig { + pub _config_init: c_int, + pub parse_argv: c_int, + pub isolated: c_int, + pub use_environment: c_int, + pub configure_locale: c_int, + pub coerce_c_locale: c_int, + pub coerce_c_locale_warn: c_int, + + #[cfg(windows)] + pub legacy_windows_fs_encoding: c_int, + + pub utf8_mode: c_int, + pub dev_mode: c_int, + pub allocator: c_int, +} + +extern_libpython! { + pub fn PyPreConfig_InitPythonConfig(config: *mut PyPreConfig); + pub fn PyPreConfig_InitIsolatedConfig(config: *mut PyPreConfig); +} + +/* --- PyConfig ---------------------------------------------- */ + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyConfig { + pub _config_init: c_int, + pub isolated: c_int, + pub use_environment: c_int, + pub dev_mode: c_int, + pub install_signal_handlers: c_int, + pub use_hash_seed: c_int, + pub hash_seed: c_ulong, + pub faulthandler: c_int, + #[cfg(all(Py_3_9, not(Py_3_10)))] + pub _use_peg_parser: c_int, + pub tracemalloc: c_int, + #[cfg(Py_3_12)] + pub perf_profiling: c_int, + #[cfg(Py_3_14)] + pub remote_debug: c_int, + pub import_time: c_int, + #[cfg(Py_3_11)] + pub code_debug_ranges: c_int, + pub show_ref_count: c_int, + #[cfg(not(Py_3_9))] + pub show_alloc_count: c_int, + pub dump_refs: c_int, + #[cfg(Py_3_11)] + pub dump_refs_file: *mut wchar_t, + pub malloc_stats: c_int, + #[cfg(Py_3_15)] + pub pymalloc_hugepages: c_int, + pub filesystem_encoding: *mut wchar_t, + pub filesystem_errors: *mut wchar_t, + pub pycache_prefix: *mut wchar_t, + pub parse_argv: c_int, + #[cfg(Py_3_10)] + pub orig_argv: PyWideStringList, + pub argv: PyWideStringList, + #[cfg(not(Py_3_10))] + pub program_name: *mut wchar_t, + pub xoptions: PyWideStringList, + pub warnoptions: PyWideStringList, + pub site_import: c_int, + pub bytes_warning: c_int, + #[cfg(Py_3_10)] + pub warn_default_encoding: c_int, + pub inspect: c_int, + pub interactive: c_int, + pub optimization_level: c_int, + pub parser_debug: c_int, + pub write_bytecode: c_int, + pub verbose: c_int, + pub quiet: c_int, + pub user_site_directory: c_int, + pub configure_c_stdio: c_int, + pub buffered_stdio: c_int, + pub stdio_encoding: *mut wchar_t, + pub stdio_errors: *mut wchar_t, + + #[cfg(windows)] + pub legacy_windows_stdio: c_int, + + pub check_hash_pycs_mode: *mut wchar_t, + #[cfg(Py_3_11)] + pub use_frozen_modules: c_int, + #[cfg(Py_3_11)] + pub safe_path: c_int, + #[cfg(Py_3_12)] + pub int_max_str_digits: c_int, + #[cfg(Py_3_14)] + pub thread_inherit_context: c_int, + #[cfg(Py_3_14)] + pub context_aware_warnings: c_int, + #[cfg(all(Py_3_14, target_os = "macos"))] + pub use_system_logger: c_int, + #[cfg(Py_3_13)] + pub cpu_count: c_int, + #[cfg(Py_GIL_DISABLED)] + pub enable_gil: c_int, + #[cfg(all(Py_3_14, Py_GIL_DISABLED))] + pub tlbc_enabled: c_int, + #[cfg(Py_3_15)] + pub lazy_imports: c_int, + pub pathconfig_warnings: c_int, + #[cfg(Py_3_10)] + pub program_name: *mut wchar_t, + pub pythonpath_env: *mut wchar_t, + pub home: *mut wchar_t, + #[cfg(Py_3_10)] + pub platlibdir: *mut wchar_t, + + pub module_search_paths_set: c_int, + pub module_search_paths: PyWideStringList, + #[cfg(Py_3_11)] + pub stdlib_dir: *mut wchar_t, + pub executable: *mut wchar_t, + pub base_executable: *mut wchar_t, + pub prefix: *mut wchar_t, + pub base_prefix: *mut wchar_t, + pub exec_prefix: *mut wchar_t, + pub base_exec_prefix: *mut wchar_t, + #[cfg(all(Py_3_9, not(Py_3_10)))] + pub platlibdir: *mut wchar_t, + pub skip_source_first_line: c_int, + pub run_command: *mut wchar_t, + pub run_module: *mut wchar_t, + pub run_filename: *mut wchar_t, + #[cfg(Py_3_13)] + pub sys_path_0: *mut wchar_t, + pub _install_importlib: c_int, + pub _init_main: c_int, + #[cfg(all(Py_3_9, not(Py_3_12)))] + pub _isolated_interpreter: c_int, + #[cfg(Py_3_11)] + pub _is_python_build: c_int, + #[cfg(all(Py_3_9, not(Py_3_10)))] + pub _orig_argv: PyWideStringList, + #[cfg(all(Py_3_13, py_sys_config = "Py_DEBUG"))] + pub run_presite: *mut wchar_t, +} + +extern_libpython! { + pub fn PyConfig_InitPythonConfig(config: *mut PyConfig); + pub fn PyConfig_InitIsolatedConfig(config: *mut PyConfig); + pub fn PyConfig_Clear(config: *mut PyConfig); + pub fn PyConfig_SetString( + config: *mut PyConfig, + config_str: *mut *mut wchar_t, + str: *const wchar_t, + ) -> PyStatus; + pub fn PyConfig_SetBytesString( + config: *mut PyConfig, + config_str: *mut *mut wchar_t, + str: *const c_char, + ) -> PyStatus; + pub fn PyConfig_Read(config: *mut PyConfig) -> PyStatus; + pub fn PyConfig_SetBytesArgv( + config: *mut PyConfig, + argc: Py_ssize_t, + argv: *mut *const c_char, + ) -> PyStatus; + pub fn PyConfig_SetArgv( + config: *mut PyConfig, + argc: Py_ssize_t, + argv: *mut *const wchar_t, + ) -> PyStatus; + pub fn PyConfig_SetWideStringList( + config: *mut PyConfig, + list: *mut PyWideStringList, + length: Py_ssize_t, + items: *mut *mut wchar_t, + ) -> PyStatus; +} + +/* --- Helper functions --------------------------------------- */ + +extern_libpython! { + pub fn Py_GetArgcArgv(argc: *mut c_int, argv: *mut *mut *mut wchar_t); +} diff --git a/vendor/pyo3-ffi/src/cpython/listobject.rs b/vendor/pyo3-ffi/src/cpython/listobject.rs new file mode 100644 index 0000000..d2f2b28 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/listobject.rs @@ -0,0 +1,58 @@ +#[cfg(Py_GIL_DISABLED)] +use crate::cpython::pyatomic::_Py_atomic_load_ssize_relaxed; +use crate::object::*; +#[cfg(not(PyPy))] +use crate::pyport::Py_ssize_t; +#[cfg(not(PyPy))] +use crate::PyList_Check; + +#[cfg(not(PyPy))] +#[repr(C)] +pub struct PyListObject { + pub ob_base: PyVarObject, + pub ob_item: *mut *mut PyObject, + pub allocated: Py_ssize_t, +} + +#[cfg(PyPy)] +pub struct PyListObject { + pub ob_base: PyObject, +} + +#[inline] +#[cfg(not(PyPy))] +pub(crate) unsafe fn _PyList_CAST(op: *mut PyObject) -> *mut PyListObject { + debug_assert_eq!(PyList_Check(op), 1); + op.cast() +} + +#[inline] +#[cfg(not(PyPy))] +pub unsafe fn PyList_GET_SIZE(op: *mut PyObject) -> Py_ssize_t { + let list = _PyList_CAST(op); + #[cfg(Py_GIL_DISABLED)] + { + _Py_atomic_load_ssize_relaxed(&raw const (*_PyVarObject_CAST(list.cast())).ob_size) + } + #[cfg(not(Py_GIL_DISABLED))] + { + Py_SIZE(list.cast()) + } +} + +/// Macro, trading safety for speed +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +pub unsafe fn PyList_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject { + *(*_PyList_CAST(op)).ob_item.offset(i) +} + +/// Macro, *only* to be used to fill in brand new lists +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +pub unsafe fn PyList_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) { + *(*_PyList_CAST(op)).ob_item.offset(i) = v; +} + +// skipped _PyList_Extend +// skipped _PyList_DebugMallocStats diff --git a/vendor/pyo3-ffi/src/cpython/lock.rs b/vendor/pyo3-ffi/src/cpython/lock.rs new file mode 100644 index 0000000..f97b049 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/lock.rs @@ -0,0 +1,26 @@ +#[cfg(Py_3_14)] +use core::ffi::c_int; +use core::sync::atomic::AtomicU8; + +#[repr(transparent)] +#[derive(Debug)] +pub struct PyMutex { + pub(crate) _bits: AtomicU8, +} + +// we don't impl Default because PyO3's safe wrappers don't need it +#[allow(clippy::new_without_default)] +impl PyMutex { + pub const fn new() -> PyMutex { + PyMutex { + _bits: AtomicU8::new(0), + } + } +} + +extern_libpython! { + pub fn PyMutex_Lock(m: *mut PyMutex); + pub fn PyMutex_Unlock(m: *mut PyMutex); + #[cfg(Py_3_14)] + pub fn PyMutex_IsLocked(m: *mut PyMutex) -> c_int; +} diff --git a/vendor/pyo3-ffi/src/cpython/longintrepr.rs b/vendor/pyo3-ffi/src/cpython/longintrepr.rs new file mode 100644 index 0000000..427f067 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/longintrepr.rs @@ -0,0 +1,55 @@ +use crate::{PyObject, Py_ssize_t}; +use core::ffi::{c_int, c_void}; + +use crate::Py_uintptr_t; + +// skipped PyLong_BASE +// skipped PyLong_MASK +// skipped _PyLong_New +// skipped _PyLong_Copy +// skipped _PyLong_FromDigits +// skipped _PyLong_SIGN_MASK +// skipped _PyLong_NON_SIZE_BITS +// skipped PyUnstable_Long_IsCompact +// skipped PyUnstable_Long_CompactValue + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct PyLongLayout { + pub bits_per_digit: u8, + pub digit_size: u8, + pub digits_order: i8, + pub digit_endianness: i8, +} + +extern_libpython! { + pub fn PyLong_GetNativeLayout() -> *const PyLongLayout; +} + +#[repr(C)] +pub struct PyLongExport { + pub value: i64, + pub negative: u8, + pub ndigits: Py_ssize_t, + pub digits: *const c_void, + _reserved: Py_uintptr_t, +} + +extern_libpython! { + pub fn PyLong_Export(obj: *mut PyObject, export_long: *mut PyLongExport) -> c_int; + pub fn PyLong_FreeExport(export_long: *mut PyLongExport); +} + +opaque_struct!(pub PyLongWriter); + +extern_libpython! { + pub fn PyLongWriter_Create( + negative: c_int, + ndigits: Py_ssize_t, + digits: *mut *mut c_void, + ) -> *mut PyLongWriter; + + pub fn PyLongWriter_Finish(writer: *mut PyLongWriter) -> *mut PyObject; + + pub fn PyLongWriter_Discard(writer: *mut PyLongWriter); +} diff --git a/vendor/pyo3-ffi/src/cpython/longobject.rs b/vendor/pyo3-ffi/src/cpython/longobject.rs new file mode 100644 index 0000000..8780bbb --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/longobject.rs @@ -0,0 +1,55 @@ +#[cfg(not(Py_3_13))] +use crate::longobject::*; +use crate::object::*; + +use core::ffi::c_int; + +#[cfg(not(Py_3_13))] +use core::ffi::c_uchar; + +#[cfg(not(Py_3_13))] +use libc::size_t; + +// skipped _PyLong_CAST + +extern_libpython! { + #[cfg(Py_3_13)] + pub fn PyLong_FromUnicodeObject(u: *mut PyObject, base: c_int) -> *mut PyObject; + + // skipped PyUnstable_Long_IsCompact + // skipped PyUnstable_Long_CompactValue + + #[cfg(Py_3_14)] + pub fn PyLong_IsPositive(obj: *mut PyObject) -> c_int; + #[cfg(Py_3_14)] + pub fn PyLong_IsNegative(obj: *mut PyObject) -> c_int; + #[cfg(Py_3_14)] + pub fn PyLong_IsZero(obj: *mut PyObject) -> c_int; + + // skipped PyLong_GetSign + // skipped _PyLong_Sign + // skipped non-limited _PyLong_NumBits + + #[cfg(not(Py_3_13))] + #[cfg_attr(PyPy, link_name = "_PyPyLong_FromByteArray")] + #[doc(hidden)] // used in PyO3's older bytes conversions, but not otherwise public API + pub fn _PyLong_FromByteArray( + bytes: *const c_uchar, + n: size_t, + little_endian: c_int, + is_signed: c_int, + ) -> *mut PyObject; + + #[cfg(not(Py_3_13))] + #[doc(hidden)] // used in PyO3's older bytes conversions, but not otherwise public API + #[cfg_attr(PyPy, link_name = "_PyPyLong_AsByteArrayO")] + pub fn _PyLong_AsByteArray( + v: *mut PyLongObject, + bytes: *mut c_uchar, + n: size_t, + little_endian: c_int, + is_signed: c_int, + ) -> c_int; + + // skipped _PyLong_GCD +} diff --git a/vendor/pyo3-ffi/src/cpython/marshal.rs b/vendor/pyo3-ffi/src/cpython/marshal.rs new file mode 100644 index 0000000..bd09e37 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/marshal.rs @@ -0,0 +1,29 @@ +use crate::{PyObject, Py_ssize_t}; +use core::ffi::{c_char, c_int, c_long}; +use libc::FILE; + +#[cfg(Py_3_15)] +pub const Py_MARSHAL_VERSION: c_int = 6; + +#[cfg(not(Py_3_15))] +pub const Py_MARSHAL_VERSION: c_int = 5; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyMarshal_WriteObjectToString")] + pub fn PyMarshal_WriteObjectToString(object: *mut PyObject, version: c_int) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyMarshal_ReadObjectFromString")] + pub fn PyMarshal_ReadObjectFromString(data: *const c_char, len: Py_ssize_t) -> *mut PyObject; + + pub fn PyMarshal_WriteLongToFile(value: c_long, file: *mut FILE, version: c_int); + + pub fn PyMarshal_WriteObjectToFile(object: *mut PyObject, file: *mut FILE, version: c_int); + + pub fn PyMarshal_ReadLongFromFile(file: *mut FILE) -> c_long; + + pub fn PyMarshal_ReadShortFromFile(file: *mut FILE) -> c_int; + + pub fn PyMarshal_ReadObjectFromFile(file: *mut FILE) -> *mut PyObject; + + pub fn PyMarshal_ReadLastObjectFromFile(file: *mut FILE) -> *mut PyObject; +} diff --git a/vendor/pyo3-ffi/src/cpython/methodobject.rs b/vendor/pyo3-ffi/src/cpython/methodobject.rs new file mode 100644 index 0000000..440701a --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/methodobject.rs @@ -0,0 +1,69 @@ +use crate::object::*; +#[cfg(not(GraalPy))] +use crate::{PyCFunctionObject, PyMethodDefPointer, METH_METHOD, METH_STATIC}; +use core::ffi::c_int; + +#[cfg(not(GraalPy))] +pub struct PyCMethodObject { + pub func: PyCFunctionObject, + pub mm_class: *mut PyTypeObject, +} + +extern_libpython! { + pub static mut PyCMethod_Type: PyTypeObject; +} + +#[inline] +pub unsafe fn PyCMethod_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyCMethod_Type) +} + +#[inline] +pub unsafe fn PyCMethod_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, &raw mut PyCMethod_Type) +} + +#[cfg(not(GraalPy))] +#[inline] +pub unsafe fn PyCFunction_GET_FUNCTION(func: *mut PyObject) -> PyMethodDefPointer { + debug_assert_eq!(PyCMethod_Check(func), 1); + + let func = func.cast::(); + (*(*func).m_ml).ml_meth +} + +#[cfg(not(GraalPy))] +#[inline] +pub unsafe fn PyCFunction_GET_SELF(func: *mut PyObject) -> *mut PyObject { + debug_assert_eq!(PyCMethod_Check(func), 1); + + let func = func.cast::(); + if (*(*func).m_ml).ml_flags & METH_STATIC != 0 { + core::ptr::null_mut() + } else { + (*func).m_self + } +} + +#[cfg(not(GraalPy))] +#[inline] +pub unsafe fn PyCFunction_GET_FLAGS(func: *mut PyObject) -> c_int { + debug_assert_eq!(PyCMethod_Check(func), 1); + + let func = func.cast::(); + (*(*func).m_ml).ml_flags +} + +#[cfg(not(GraalPy))] +#[inline] +pub unsafe fn PyCFunction_GET_CLASS(func: *mut PyObject) -> *mut PyTypeObject { + debug_assert_eq!(PyCMethod_Check(func), 1); + + let func = func.cast::(); + if (*(*func).m_ml).ml_flags & METH_METHOD != 0 { + let func = func.cast::(); + (*func).mm_class + } else { + core::ptr::null_mut() + } +} diff --git a/vendor/pyo3-ffi/src/cpython/mod.rs b/vendor/pyo3-ffi/src/cpython/mod.rs new file mode 100644 index 0000000..8fe5358 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/mod.rs @@ -0,0 +1,102 @@ +pub(crate) mod abstract_; +pub(crate) mod bytearrayobject; +pub(crate) mod bytesobject; +pub(crate) mod cellobject; +#[cfg(not(PyPy))] +pub(crate) mod ceval; +pub(crate) mod code; +pub(crate) mod compile; +pub(crate) mod complexobject; +#[cfg(all(Py_3_14, Py_GIL_DISABLED))] +pub(crate) mod critical_section; +pub(crate) mod descrobject; +pub(crate) mod dictobject; +// skipped fileobject.h +// skipped fileutils.h +pub(crate) mod frameobject; +pub(crate) mod funcobject; +pub(crate) mod genobject; +#[cfg(any(not(PyPy), Py_3_14))] +pub(crate) mod import; +#[cfg(not(PyPy))] +pub(crate) mod initconfig; +// skipped interpreteridobject.h +pub(crate) mod listobject; +#[cfg(Py_3_13)] +pub(crate) mod lock; +#[cfg(Py_3_14)] +pub(crate) mod longintrepr; +pub(crate) mod longobject; +pub(crate) mod marshal; +#[cfg(all(Py_3_9, not(PyPy)))] +pub(crate) mod methodobject; +pub(crate) mod object; +pub(crate) mod objimpl; +pub(crate) mod pyatomic; +pub(crate) mod pydebug; +pub(crate) mod pyerrors; +#[cfg(not(PyPy))] +pub(crate) mod pylifecycle; +pub(crate) mod pymem; +pub(crate) mod pystate; +pub(crate) mod pythonrun; +// skipped sysmodule.h +pub(crate) mod floatobject; +pub(crate) mod pyframe; +pub(crate) mod pyhash; +pub(crate) mod setobject; +pub(crate) mod traceback; +pub(crate) mod tupleobject; +pub(crate) mod unicodeobject; +pub(crate) mod warnings; +pub(crate) mod weakrefobject; + +pub use self::abstract_::*; +pub use self::bytearrayobject::*; +pub use self::bytesobject::*; +pub use self::cellobject::*; +#[cfg(not(PyPy))] +pub use self::ceval::*; +pub use self::code::*; +pub use self::compile::*; +pub use self::complexobject::*; +#[cfg(all(Py_3_14, Py_GIL_DISABLED))] +pub use self::critical_section::{PyCriticalSection2_BeginMutex, PyCriticalSection_BeginMutex}; +pub use self::descrobject::*; +pub use self::dictobject::*; +pub use self::floatobject::*; +pub use self::frameobject::*; +pub use self::funcobject::*; +pub use self::genobject::*; +#[cfg(any(not(PyPy), Py_3_14))] +pub use self::import::*; +#[cfg(not(PyPy))] +pub use self::initconfig::*; +pub use self::listobject::*; +#[cfg(Py_3_13)] +pub use self::lock::*; +#[cfg(Py_3_14)] +pub use self::longintrepr::*; +pub use self::longobject::*; +pub use self::marshal::*; +#[cfg(all(Py_3_9, not(PyPy)))] +pub use self::methodobject::*; +pub use self::object::*; +pub use self::objimpl::*; +pub use self::pydebug::*; +pub use self::pyerrors::*; +pub use self::pyframe::*; +#[cfg(any(not(PyPy), Py_3_13))] +pub use self::pyhash::*; +#[cfg(not(PyPy))] +pub use self::pylifecycle::*; +pub use self::pymem::*; +pub use self::pystate::*; +pub use self::pythonrun::*; +pub use self::setobject::*; +pub use self::traceback::*; +pub use self::tupleobject::*; +pub use self::unicodeobject::*; +pub use self::warnings::*; +#[cfg(not(any(PyPy, GraalPy)))] +pub use self::weakrefobject::*; diff --git a/vendor/pyo3-ffi/src/cpython/object.rs b/vendor/pyo3-ffi/src/cpython/object.rs new file mode 100644 index 0000000..5cba192 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/object.rs @@ -0,0 +1,412 @@ +use crate::vectorcallfunc; +use crate::{object, PyGetSetDef, PyMemberDef, PyMethodDef, PyObject, Py_ssize_t}; +use core::ffi::{c_char, c_int, c_uint, c_void}; + +// skipped private _Py_NewReference +// skipped private _Py_NewReferenceNoTotal +// skipped private _Py_ResurrectReference +// skipped private _Py_ForgetReference + +// skipped private _Py_GetGlobalRefTotal +// skipped private _Py_GetRefTotal +// skipped private _Py_GetLegacyRefTotal +// skipped private _PyInterpreterState_GetRefTotal + +// skipped private _Py_Identifier + +// skipped private _Py_static_string_init +// skipped private _Py_static_string +// skipped private _Py_IDENTIFIER + +#[cfg(not(Py_3_11))] // moved to src/buffer.rs from Python +mod bufferinfo { + use crate::Py_ssize_t; + use core::ffi::{c_char, c_int, c_void}; + use core::ptr; + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct Py_buffer { + pub buf: *mut c_void, + /// Owned reference + pub obj: *mut crate::PyObject, + pub len: Py_ssize_t, + pub itemsize: Py_ssize_t, + pub readonly: c_int, + pub ndim: c_int, + pub format: *mut c_char, + pub shape: *mut Py_ssize_t, + pub strides: *mut Py_ssize_t, + pub suboffsets: *mut Py_ssize_t, + pub internal: *mut c_void, + #[cfg(PyPy)] + pub flags: c_int, + #[cfg(PyPy)] + pub _strides: [Py_ssize_t; PyBUF_MAX_NDIM as usize], + #[cfg(PyPy)] + pub _shape: [Py_ssize_t; PyBUF_MAX_NDIM as usize], + } + + impl Py_buffer { + #[allow(clippy::new_without_default)] + pub const fn new() -> Self { + Py_buffer { + buf: ptr::null_mut(), + obj: ptr::null_mut(), + len: 0, + itemsize: 0, + readonly: 0, + ndim: 0, + format: ptr::null_mut(), + shape: ptr::null_mut(), + strides: ptr::null_mut(), + suboffsets: ptr::null_mut(), + internal: ptr::null_mut(), + #[cfg(PyPy)] + flags: 0, + #[cfg(PyPy)] + _strides: [0; PyBUF_MAX_NDIM as usize], + #[cfg(PyPy)] + _shape: [0; PyBUF_MAX_NDIM as usize], + } + } + } + + pub type getbufferproc = unsafe extern "C" fn( + arg1: *mut crate::PyObject, + arg2: *mut Py_buffer, + arg3: c_int, + ) -> c_int; + pub type releasebufferproc = + unsafe extern "C" fn(arg1: *mut crate::PyObject, arg2: *mut Py_buffer); + + /// Maximum number of dimensions + pub const PyBUF_MAX_NDIM: c_int = if cfg!(PyPy) { 36 } else { 64 }; + + /* Flags for getting buffers */ + pub const PyBUF_SIMPLE: c_int = 0; + pub const PyBUF_WRITABLE: c_int = 0x0001; + /* we used to include an E, backwards compatible alias */ + pub const PyBUF_WRITEABLE: c_int = PyBUF_WRITABLE; + pub const PyBUF_FORMAT: c_int = 0x0004; + pub const PyBUF_ND: c_int = 0x0008; + pub const PyBUF_STRIDES: c_int = 0x0010 | PyBUF_ND; + pub const PyBUF_C_CONTIGUOUS: c_int = 0x0020 | PyBUF_STRIDES; + pub const PyBUF_F_CONTIGUOUS: c_int = 0x0040 | PyBUF_STRIDES; + pub const PyBUF_ANY_CONTIGUOUS: c_int = 0x0080 | PyBUF_STRIDES; + pub const PyBUF_INDIRECT: c_int = 0x0100 | PyBUF_STRIDES; + + pub const PyBUF_CONTIG: c_int = PyBUF_ND | PyBUF_WRITABLE; + pub const PyBUF_CONTIG_RO: c_int = PyBUF_ND; + + pub const PyBUF_STRIDED: c_int = PyBUF_STRIDES | PyBUF_WRITABLE; + pub const PyBUF_STRIDED_RO: c_int = PyBUF_STRIDES; + + pub const PyBUF_RECORDS: c_int = PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT; + pub const PyBUF_RECORDS_RO: c_int = PyBUF_STRIDES | PyBUF_FORMAT; + + pub const PyBUF_FULL: c_int = PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT; + pub const PyBUF_FULL_RO: c_int = PyBUF_INDIRECT | PyBUF_FORMAT; + + pub const PyBUF_READ: c_int = 0x100; + pub const PyBUF_WRITE: c_int = 0x200; +} + +#[cfg(not(Py_3_11))] +pub use self::bufferinfo::*; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyNumberMethods { + pub nb_add: Option, + pub nb_subtract: Option, + pub nb_multiply: Option, + pub nb_remainder: Option, + pub nb_divmod: Option, + pub nb_power: Option, + pub nb_negative: Option, + pub nb_positive: Option, + pub nb_absolute: Option, + pub nb_bool: Option, + pub nb_invert: Option, + pub nb_lshift: Option, + pub nb_rshift: Option, + pub nb_and: Option, + pub nb_xor: Option, + pub nb_or: Option, + pub nb_int: Option, + pub nb_reserved: *mut c_void, + pub nb_float: Option, + pub nb_inplace_add: Option, + pub nb_inplace_subtract: Option, + pub nb_inplace_multiply: Option, + pub nb_inplace_remainder: Option, + pub nb_inplace_power: Option, + pub nb_inplace_lshift: Option, + pub nb_inplace_rshift: Option, + pub nb_inplace_and: Option, + pub nb_inplace_xor: Option, + pub nb_inplace_or: Option, + pub nb_floor_divide: Option, + pub nb_true_divide: Option, + pub nb_inplace_floor_divide: Option, + pub nb_inplace_true_divide: Option, + pub nb_index: Option, + pub nb_matrix_multiply: Option, + pub nb_inplace_matrix_multiply: Option, +} + +#[repr(C)] +#[derive(Clone)] +pub struct PySequenceMethods { + pub sq_length: Option, + pub sq_concat: Option, + pub sq_repeat: Option, + pub sq_item: Option, + pub was_sq_slice: *mut c_void, + pub sq_ass_item: Option, + pub was_sq_ass_slice: *mut c_void, + pub sq_contains: Option, + pub sq_inplace_concat: Option, + pub sq_inplace_repeat: Option, +} + +#[repr(C)] +#[derive(Clone, Default)] +pub struct PyMappingMethods { + pub mp_length: Option, + pub mp_subscript: Option, + pub mp_ass_subscript: Option, +} + +#[cfg(Py_3_10)] +pub type sendfunc = unsafe extern "C" fn( + iter: *mut PyObject, + value: *mut PyObject, + result: *mut *mut PyObject, +) -> object::PySendResult; + +#[repr(C)] +#[derive(Clone, Default)] +pub struct PyAsyncMethods { + pub am_await: Option, + pub am_aiter: Option, + pub am_anext: Option, + #[cfg(Py_3_10)] + pub am_send: Option, +} + +#[repr(C)] +#[derive(Clone, Default)] +pub struct PyBufferProcs { + pub bf_getbuffer: Option, + pub bf_releasebuffer: Option, +} + +pub type printfunc = + unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut ::libc::FILE, arg3: c_int) -> c_int; + +#[repr(C)] +#[derive(Debug)] +pub struct PyTypeObject { + pub ob_base: object::PyVarObject, + pub tp_name: *const c_char, + pub tp_basicsize: Py_ssize_t, + pub tp_itemsize: Py_ssize_t, + pub tp_dealloc: Option, + pub tp_vectorcall_offset: Py_ssize_t, + pub tp_getattr: Option, + pub tp_setattr: Option, + pub tp_as_async: *mut PyAsyncMethods, + pub tp_repr: Option, + pub tp_as_number: *mut PyNumberMethods, + pub tp_as_sequence: *mut PySequenceMethods, + pub tp_as_mapping: *mut PyMappingMethods, + pub tp_hash: Option, + pub tp_call: Option, + pub tp_str: Option, + pub tp_getattro: Option, + pub tp_setattro: Option, + pub tp_as_buffer: *mut PyBufferProcs, + #[cfg(not(Py_GIL_DISABLED))] + pub tp_flags: core::ffi::c_ulong, + #[cfg(Py_GIL_DISABLED)] + pub tp_flags: crate::impl_::AtomicCULong, + pub tp_doc: *const c_char, + pub tp_traverse: Option, + pub tp_clear: Option, + pub tp_richcompare: Option, + pub tp_weaklistoffset: Py_ssize_t, + pub tp_iter: Option, + pub tp_iternext: Option, + pub tp_methods: *mut PyMethodDef, + pub tp_members: *mut PyMemberDef, + pub tp_getset: *mut PyGetSetDef, + pub tp_base: *mut PyTypeObject, + pub tp_dict: *mut object::PyObject, + pub tp_descr_get: Option, + pub tp_descr_set: Option, + pub tp_dictoffset: Py_ssize_t, + pub tp_init: Option, + pub tp_alloc: Option, + pub tp_new: Option, + pub tp_free: Option, + pub tp_is_gc: Option, + pub tp_bases: *mut object::PyObject, + pub tp_mro: *mut object::PyObject, + pub tp_cache: *mut object::PyObject, + pub tp_subclasses: *mut object::PyObject, + pub tp_weaklist: *mut object::PyObject, + pub tp_del: Option, + pub tp_version_tag: c_uint, + pub tp_finalize: Option, + pub tp_vectorcall: Option, + #[cfg(Py_3_12)] + pub tp_watched: c_char, + #[cfg(not(any(PyPy, Py_3_9)))] + pub tp_print: Option, + #[cfg(py_sys_config = "COUNT_ALLOCS")] + pub tp_allocs: Py_ssize_t, + #[cfg(py_sys_config = "COUNT_ALLOCS")] + pub tp_frees: Py_ssize_t, + #[cfg(py_sys_config = "COUNT_ALLOCS")] + pub tp_maxalloc: Py_ssize_t, + #[cfg(py_sys_config = "COUNT_ALLOCS")] + pub tp_prev: *mut PyTypeObject, + #[cfg(py_sys_config = "COUNT_ALLOCS")] + pub tp_next: *mut PyTypeObject, + #[cfg(Py_3_13)] + pub tp_versions_used: u16, + #[cfg(Py_3_15)] + pub _tp_iteritem: Option, +} + +#[cfg(Py_3_11)] +#[repr(C)] +#[derive(Clone)] +struct _specialization_cache { + getitem: *mut PyObject, + #[cfg(Py_3_12)] + getitem_version: u32, + #[cfg(Py_3_13)] + init: *mut PyObject, +} + +#[repr(C)] +pub struct PyHeapTypeObject { + pub ht_type: PyTypeObject, + pub as_async: PyAsyncMethods, + pub as_number: PyNumberMethods, + pub as_mapping: PyMappingMethods, + pub as_sequence: PySequenceMethods, + pub as_buffer: PyBufferProcs, + pub ht_name: *mut object::PyObject, + pub ht_slots: *mut object::PyObject, + pub ht_qualname: *mut object::PyObject, + #[cfg(not(PyPy))] + pub ht_cached_keys: *mut c_void, + #[cfg(Py_3_9)] + pub ht_module: *mut object::PyObject, + #[cfg(all(Py_3_11, not(PyPy)))] + _ht_tpname: *mut c_char, + #[cfg(Py_3_14)] + pub ht_token: *mut c_void, + #[cfg(all(Py_3_11, not(PyPy)))] + _spec_cache: _specialization_cache, + #[cfg(all(Py_GIL_DISABLED, Py_3_14))] + pub unique_id: Py_ssize_t, +} + +#[inline] +#[cfg(not(Py_3_11))] +pub unsafe fn PyHeapType_GET_MEMBERS(etype: *mut PyHeapTypeObject) -> *mut PyMemberDef { + let py_type = object::Py_TYPE(etype as *mut object::PyObject); + let ptr = etype.byte_offset((*py_type).tp_basicsize); + ptr as *mut PyMemberDef +} + +// skipped private _PyType_Name +// skipped private _PyType_Lookup +// skipped private _PyType_LookupRef + +extern_libpython! { + #[cfg(Py_3_12)] + pub fn PyType_GetDict(o: *mut PyTypeObject) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyObject_Print")] + pub fn PyObject_Print(o: *mut PyObject, fp: *mut ::libc::FILE, flags: c_int) -> c_int; + + // skipped private _Py_BreakPoint + // skipped private _PyObject_Dump + + // skipped _PyObject_GetAttrId + + // skipped private _PyObject_GetDictPtr + pub fn PyObject_CallFinalizer(arg1: *mut PyObject); + #[cfg_attr(PyPy, link_name = "PyPyObject_CallFinalizerFromDealloc")] + pub fn PyObject_CallFinalizerFromDealloc(arg1: *mut PyObject) -> c_int; + + // skipped private _PyObject_GenericGetAttrWithDict + // skipped private _PyObject_GenericSetAttrWithDict + // skipped private _PyObject_FunctionStr +} + +// skipped Py_SETREF +// skipped Py_XSETREF + +// skipped private _PyObject_ASSERT_FROM +// skipped private _PyObject_ASSERT_WITH_MSG +// skipped private _PyObject_ASSERT +// skipped private _PyObject_ASSERT_FAILED_MSG +// skipped private _PyObject_AssertFailed + +// skipped private _PyTrash_begin +// skipped private _PyTrash_end + +// skipped _PyTrash_thread_deposit_object +// skipped _PyTrash_thread_destroy_chain + +// skipped Py_TRASHCAN_BEGIN +// skipped Py_TRASHCAN_END + +// skipped PyObject_GetItemData + +// skipped PyObject_VisitManagedDict +// skipped _PyObject_SetManagedDict +// skipped PyObject_ClearManagedDict + +// skipped TYPE_MAX_WATCHERS + +// skipped PyType_WatchCallback +// skipped PyType_AddWatcher +// skipped PyType_ClearWatcher +// skipped PyType_Watch +// skipped PyType_Unwatch + +// skipped PyUnstable_Type_AssignVersionTag + +// skipped PyRefTracerEvent + +// skipped PyRefTracer +// skipped PyRefTracer_SetTracer +// skipped PyRefTracer_GetTracer + +#[cfg(Py_3_14)] +extern_libpython! { + // skipped PyUnstable_Object_EnableDeferredRefcount + + pub fn PyUnstable_Object_IsUniqueReferencedTemporary(obj: *mut PyObject) -> c_int; + + // skipped PyUnstable_IsImmortal + + pub fn PyUnstable_TryIncRef(obj: *mut PyObject) -> c_int; + + pub fn PyUnstable_EnableTryIncRef(obj: *mut PyObject); + + pub fn PyUnstable_Object_IsUniquelyReferenced(op: *mut PyObject) -> c_int; +} + +#[cfg(Py_3_15)] +extern_libpython! { + pub fn PyUnstable_SetImmortal(op: *mut PyObject) -> c_int; +} diff --git a/vendor/pyo3-ffi/src/cpython/objimpl.rs b/vendor/pyo3-ffi/src/cpython/objimpl.rs new file mode 100644 index 0000000..ca01547 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/objimpl.rs @@ -0,0 +1,62 @@ +use core::ffi::c_int; +#[cfg(not(all(Py_3_11, any(PyPy, GraalPy))))] +use libc::size_t; + +#[cfg(not(any(PyPy, GraalPy)))] +use core::ffi::c_void; + +use crate::object::*; + +// skipped _PyObject_SIZE +// skipped _PyObject_VAR_SIZE + +// skipped _Py_GetAllocatedBlocks + +#[cfg(not(any(PyPy, GraalPy)))] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyObjectArenaAllocator { + pub ctx: *mut c_void, + pub alloc: Option *mut c_void>, + pub free: Option, +} + +extern_libpython! { + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyObject_GetArenaAllocator(allocator: *mut PyObjectArenaAllocator); + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyObject_SetArenaAllocator(allocator: *mut PyObjectArenaAllocator); + + #[cfg(Py_3_9)] + pub fn PyObject_IS_GC(o: *mut PyObject) -> c_int; + + #[cfg(all(Py_3_9, not(any(PyPy, GraalPy))))] + pub fn PyObject_GET_WEAKREFS_LISTPTR(o: *mut PyObject) -> *mut *mut PyObject; +} + +#[inline] +#[cfg(not(Py_3_9))] +pub unsafe fn PyObject_GET_WEAKREFS_LISTPTR(o: *mut PyObject) -> *mut *mut PyObject { + let weaklistoffset = (*Py_TYPE(o)).tp_weaklistoffset; + o.byte_offset(weaklistoffset) as *mut *mut PyObject +} + +#[inline] +#[cfg(not(Py_3_9))] +pub unsafe fn PyObject_IS_GC(o: *mut PyObject) -> c_int { + (crate::PyType_IS_GC(Py_TYPE(o)) != 0 + && match (*Py_TYPE(o)).tp_is_gc { + Some(tp_is_gc) => tp_is_gc(o) != 0, + None => true, + }) as c_int +} + +// skipped _PyObject_GC_Malloc +// skipped _PyObject_GC_Calloc + +#[inline] +pub unsafe fn PyType_SUPPORTS_WEAKREFS(t: *mut PyTypeObject) -> c_int { + ((*t).tp_weaklistoffset > 0) as c_int +} + +// skipped PyUnstable_Object_GC_NewWithExtraData diff --git a/vendor/pyo3-ffi/src/cpython/pyatomic.rs b/vendor/pyo3-ffi/src/cpython/pyatomic.rs new file mode 100644 index 0000000..2b13285 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/pyatomic.rs @@ -0,0 +1,165 @@ +use crate::pyport::Py_ssize_t; +use core::sync::atomic::{AtomicIsize, Ordering}; + +// skipped _Py_atomic_add_int +// skipped _Py_atomic_add_int8 +// skipped _Py_atomic_add_int16 +// skipped _Py_atomic_add_int32 +// skipped _Py_atomic_add_int64 +// skipped _Py_atomic_add_intptr +// skipped _Py_atomic_add_uint +// skipped _Py_atomic_add_uint8 +// skipped _Py_atomic_add_uint16 +// skipped _Py_atomic_add_uint32 +// skipped _Py_atomic_add_uint64 +// skipped _Py_atomic_add_uintptr +// skipped _Py_atomic_add_ssize + +// skipped _Py_atomic_compare_exchange_int +// skipped _Py_atomic_compare_exchange_int8 +// skipped _Py_atomic_compare_exchange_int16 +// skipped _Py_atomic_compare_exchange_int32 +// skipped _Py_atomic_compare_exchange_int64 +// skipped _Py_atomic_compare_exchange_intptr +// skipped _Py_atomic_compare_exchange_uint +// skipped _Py_atomic_compare_exchange_uint8 +// skipped _Py_atomic_compare_exchange_uint16 +// skipped _Py_atomic_compare_exchange_uint32 +// skipped _Py_atomic_compare_exchange_uint64 +// skipped _Py_atomic_compare_exchange_uintptr +// skipped _Py_atomic_compare_exchange_ssize +// skipped _Py_atomic_compare_exchange_ptr + +// skipped _Py_atomic_exchange_int +// skipped _Py_atomic_exchange_int8 +// skipped _Py_atomic_exchange_int16 +// skipped _Py_atomic_exchange_int32 +// skipped _Py_atomic_exchange_int64 +// skipped _Py_atomic_exchange_intptr +// skipped _Py_atomic_exchange_uint +// skipped _Py_atomic_exchange_uint8 +// skipped _Py_atomic_exchange_uint16 +// skipped _Py_atomic_exchange_uint32 +// skipped _Py_atomic_exchange_uint64 +// skipped _Py_atomic_exchange_uintptr +// skipped _Py_atomic_exchange_ssize +// skipped _Py_atomic_exchange_ptr + +// skipped _Py_atomic_and_uint8 +// skipped _Py_atomic_and_uint16 +// skipped _Py_atomic_and_uint32 +// skipped _Py_atomic_and_uint64 +// skipped _Py_atomic_and_uintptr + +// skipped _Py_atomic_or_uint8 +// skipped _Py_atomic_or_uint16 +// skipped _Py_atomic_or_uint32 +// skipped _Py_atomic_or_uint64 +// skipped _Py_atomic_or_uintptr + +// skipped _Py_atomic_load_int +// skipped _Py_atomic_load_int8 +// skipped _Py_atomic_load_int16 +// skipped _Py_atomic_load_int32 +// skipped _Py_atomic_load_int64 +// skipped _Py_atomic_load_intptr +// skipped _Py_atomic_load_uint8 +// skipped _Py_atomic_load_uint16 +// skipped _Py_atomic_load_uint32 +// skipped _Py_atomic_load_uint64 +// skipped _Py_atomic_load_uintptr +// skipped _Py_atomic_load_uint +// skipped _Py_atomic_load_ssize +// skipped _Py_atomic_load_ptr + +// skipped _Py_atomic_load_int_relaxed +// skipped _Py_atomic_load_char_relaxed +// skipped _Py_atomic_load_uchar_relaxed +// skipped _Py_atomic_load_short_relaxed +// skipped _Py_atomic_load_ushort_relaxed +// skipped _Py_atomic_load_long_relaxed +// skipped _Py_atomic_load_double_relaxed +// skipped _Py_atomic_load_llong_relaxed +// skipped _Py_atomic_load_int8_relaxed +// skipped _Py_atomic_load_int16_relaxed +// skipped _Py_atomic_load_int32_relaxed +// skipped _Py_atomic_load_int64_relaxed +// skipped _Py_atomic_load_intptr_relaxed +// skipped _Py_atomic_load_uint8_relaxed +// skipped _Py_atomic_load_uint16_relaxed +// skipped _Py_atomic_load_uint32_relaxed +// skipped _Py_atomic_load_uint64_relaxed +// skipped _Py_atomic_load_uintptr_relaxed +// skipped _Py_atomic_load_uint_relaxed + +#[inline] +pub(crate) unsafe fn _Py_atomic_load_ssize_relaxed(value: *const Py_ssize_t) -> Py_ssize_t { + AtomicIsize::from_ptr(value.cast_mut()).load(Ordering::Relaxed) +} + +// skipped _Py_atomic_load_ptr_relaxed +// skipped _Py_atomic_load_ullong_relaxed + +// skipped _Py_atomic_store_int +// skipped _Py_atomic_store_int8 +// skipped _Py_atomic_store_int16 +// skipped _Py_atomic_store_int32 +// skipped _Py_atomic_store_int64 +// skipped _Py_atomic_store_intptr +// skipped _Py_atomic_store_uint8 +// skipped _Py_atomic_store_uint16 +// skipped _Py_atomic_store_uint32 +// skipped _Py_atomic_store_uint64 +// skipped _Py_atomic_store_uintptr +// skipped _Py_atomic_store_uint +// skipped _Py_atomic_store_ptr +// skipped _Py_atomic_store_ssize + +// skipped _Py_atomic_store_int_relaxed +// skipped _Py_atomic_store_int8_relaxed +// skipped _Py_atomic_store_int16_relaxed +// skipped _Py_atomic_store_int32_relaxed +// skipped _Py_atomic_store_int64_relaxed +// skipped _Py_atomic_store_intptr_relaxed +// skipped _Py_atomic_store_uint8_relaxed +// skipped _Py_atomic_store_uint16_relaxed +// skipped _Py_atomic_store_uint32_relaxed +// skipped _Py_atomic_store_uint64_relaxed +// skipped _Py_atomic_store_uintptr_relaxed +// skipped _Py_atomic_store_uint_relaxed +// skipped _Py_atomic_store_ptr_relaxed +// skipped _Py_atomic_store_ssize_relaxed +// skipped _Py_atomic_store_ullong_relaxed +// skipped _Py_atomic_store_char_relaxed +// skipped _Py_atomic_store_uchar_relaxed +// skipped _Py_atomic_store_short_relaxed +// skipped _Py_atomic_store_ushort_relaxed +// skipped _Py_atomic_store_long_relaxed +// skipped _Py_atomic_store_float_relaxed +// skipped _Py_atomic_store_double_relaxed +// skipped _Py_atomic_store_llong_relaxed + +// skipped _Py_atomic_load_ptr_acquire +// skipped _Py_atomic_load_uintptr_acquire +// skipped _Py_atomic_store_ptr_release +// skipped _Py_atomic_store_uintptr_release +// skipped _Py_atomic_store_ssize_release +// skipped _Py_atomic_store_int8_release +// skipped _Py_atomic_store_int_release +// skipped _Py_atomic_load_int_acquire +// skipped _Py_atomic_store_uint_release +// skipped _Py_atomic_store_uint32_release +// skipped _Py_atomic_store_uint64_release +// skipped _Py_atomic_load_uint64_acquire +// skipped _Py_atomic_load_uint32_acquire +// skipped _Py_atomic_load_ssize_acquire + +// skipped _Py_atomic_fence_seq_cst +// skipped _Py_atomic_fence_acquire +// skipped _Py_atomic_fence_release + +// skipped _Py_atomic_load_ptr_consume +// skipped _Py_atomic_load_ulong +// skipped _Py_atomic_load_ulong_relaxed +// skipped _Py_atomic_store_ulong +// skipped _Py_atomic_store_ulong_relaxed diff --git a/vendor/pyo3-ffi/src/cpython/pydebug.rs b/vendor/pyo3-ffi/src/cpython/pydebug.rs new file mode 100644 index 0000000..389c4ea --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/pydebug.rs @@ -0,0 +1,71 @@ +use core::ffi::{c_char, c_int}; + +#[cfg(not(Py_LIMITED_API))] +extern_libpython! { + #[deprecated(note = "Python 3.12")] + #[cfg_attr(PyPy, link_name = "PyPy_DebugFlag")] + pub static mut Py_DebugFlag: c_int; + #[deprecated(note = "Python 3.12")] + #[cfg_attr(PyPy, link_name = "PyPy_VerboseFlag")] + pub static mut Py_VerboseFlag: c_int; + #[deprecated(note = "Python 3.12")] + pub static mut Py_QuietFlag: c_int; + #[deprecated(note = "Python 3.12")] + #[cfg_attr(PyPy, link_name = "PyPy_InteractiveFlag")] + pub static mut Py_InteractiveFlag: c_int; + #[deprecated(note = "Python 3.12")] + #[cfg_attr(PyPy, link_name = "PyPy_InspectFlag")] + pub static mut Py_InspectFlag: c_int; + #[deprecated(note = "Python 3.12")] + #[cfg_attr(PyPy, link_name = "PyPy_OptimizeFlag")] + pub static mut Py_OptimizeFlag: c_int; + #[deprecated(note = "Python 3.12")] + #[cfg_attr(PyPy, link_name = "PyPy_NoSiteFlag")] + pub static mut Py_NoSiteFlag: c_int; + #[deprecated(note = "Python 3.12")] + #[cfg_attr(PyPy, link_name = "PyPy_BytesWarningFlag")] + pub static mut Py_BytesWarningFlag: c_int; + #[deprecated(note = "Python 3.12")] + #[cfg_attr(PyPy, link_name = "PyPy_UseClassExceptionsFlag")] + pub static mut Py_UseClassExceptionsFlag: c_int; + #[deprecated(note = "Python 3.12")] + #[cfg_attr(PyPy, link_name = "PyPy_FrozenFlag")] + pub static mut Py_FrozenFlag: c_int; + #[deprecated(note = "Python 3.12")] + #[cfg_attr(PyPy, link_name = "PyPy_IgnoreEnvironmentFlag")] + pub static mut Py_IgnoreEnvironmentFlag: c_int; + #[deprecated(note = "Python 3.12")] + #[cfg_attr(PyPy, link_name = "PyPy_DontWriteBytecodeFlag")] + pub static mut Py_DontWriteBytecodeFlag: c_int; + #[deprecated(note = "Python 3.12")] + #[cfg_attr(PyPy, link_name = "PyPy_NoUserSiteDirectory")] + pub static mut Py_NoUserSiteDirectory: c_int; + #[deprecated(note = "Python 3.12")] + pub static mut Py_UnbufferedStdioFlag: c_int; + #[cfg_attr(PyPy, link_name = "PyPy_HashRandomizationFlag")] + pub static mut Py_HashRandomizationFlag: c_int; + #[deprecated(note = "Python 3.12")] + pub static mut Py_IsolatedFlag: c_int; + #[cfg(windows)] + #[deprecated(note = "Python 3.12")] + pub static mut Py_LegacyWindowsFSEncodingFlag: c_int; + #[cfg(windows)] + #[deprecated(note = "Python 3.12")] + pub static mut Py_LegacyWindowsStdioFlag: c_int; +} + +extern_libpython! { + #[cfg(Py_3_11)] + pub fn Py_GETENV(name: *const c_char) -> *mut c_char; +} + +#[cfg(not(Py_3_11))] +#[inline(always)] +pub unsafe fn Py_GETENV(name: *const c_char) -> *mut c_char { + #[allow(deprecated)] + if Py_IgnoreEnvironmentFlag != 0 { + core::ptr::null_mut() + } else { + libc::getenv(name) + } +} diff --git a/vendor/pyo3-ffi/src/cpython/pyerrors.rs b/vendor/pyo3-ffi/src/cpython/pyerrors.rs new file mode 100644 index 0000000..c983166 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/pyerrors.rs @@ -0,0 +1,190 @@ +use crate::PyObject; +#[cfg(not(any(PyPy, GraalPy)))] +use crate::Py_ssize_t; + +#[repr(C)] +#[derive(Debug)] +pub struct PyBaseExceptionObject { + pub ob_base: PyObject, + #[cfg(not(PyPy))] + pub dict: *mut PyObject, + #[cfg(not(PyPy))] + pub args: *mut PyObject, + #[cfg(all(Py_3_11, not(PyPy)))] + pub notes: *mut PyObject, + #[cfg(not(PyPy))] + pub traceback: *mut PyObject, + #[cfg(not(PyPy))] + pub context: *mut PyObject, + #[cfg(not(PyPy))] + pub cause: *mut PyObject, + #[cfg(not(PyPy))] + pub suppress_context: char, +} + +#[cfg(not(any(PyPy, GraalPy)))] +#[repr(C)] +#[derive(Debug)] +pub struct PySyntaxErrorObject { + pub ob_base: PyObject, + pub dict: *mut PyObject, + pub args: *mut PyObject, + #[cfg(Py_3_11)] + pub notes: *mut PyObject, + pub traceback: *mut PyObject, + pub context: *mut PyObject, + pub cause: *mut PyObject, + pub suppress_context: char, + + pub msg: *mut PyObject, + pub filename: *mut PyObject, + pub lineno: *mut PyObject, + pub offset: *mut PyObject, + #[cfg(Py_3_10)] + pub end_lineno: *mut PyObject, + #[cfg(Py_3_10)] + pub end_offset: *mut PyObject, + pub text: *mut PyObject, + pub print_file_and_line: *mut PyObject, + #[cfg(Py_3_14)] + pub metadata: *mut PyObject, +} + +#[cfg(not(any(PyPy, GraalPy)))] +#[repr(C)] +#[derive(Debug)] +pub struct PyImportErrorObject { + pub ob_base: PyObject, + pub dict: *mut PyObject, + pub args: *mut PyObject, + #[cfg(Py_3_11)] + pub notes: *mut PyObject, + pub traceback: *mut PyObject, + pub context: *mut PyObject, + pub cause: *mut PyObject, + pub suppress_context: char, + + pub msg: *mut PyObject, + pub name: *mut PyObject, + pub path: *mut PyObject, + #[cfg(Py_3_12)] + pub name_from: *mut PyObject, +} + +#[cfg(not(any(PyPy, GraalPy)))] +#[repr(C)] +#[derive(Debug)] +pub struct PyUnicodeErrorObject { + pub ob_base: PyObject, + pub dict: *mut PyObject, + pub args: *mut PyObject, + #[cfg(Py_3_11)] + pub notes: *mut PyObject, + pub traceback: *mut PyObject, + pub context: *mut PyObject, + pub cause: *mut PyObject, + pub suppress_context: char, + + pub encoding: *mut PyObject, + pub object: *mut PyObject, + pub start: Py_ssize_t, + pub end: Py_ssize_t, + pub reason: *mut PyObject, +} + +#[cfg(not(any(PyPy, GraalPy)))] +#[repr(C)] +#[derive(Debug)] +pub struct PySystemExitObject { + pub ob_base: PyObject, + pub dict: *mut PyObject, + pub args: *mut PyObject, + #[cfg(Py_3_11)] + pub notes: *mut PyObject, + pub traceback: *mut PyObject, + pub context: *mut PyObject, + pub cause: *mut PyObject, + pub suppress_context: char, + + pub code: *mut PyObject, +} + +#[cfg(not(any(PyPy, GraalPy)))] +#[repr(C)] +#[derive(Debug)] +pub struct PyOSErrorObject { + pub ob_base: PyObject, + pub dict: *mut PyObject, + pub args: *mut PyObject, + #[cfg(Py_3_11)] + pub notes: *mut PyObject, + pub traceback: *mut PyObject, + pub context: *mut PyObject, + pub cause: *mut PyObject, + pub suppress_context: char, + + pub myerrno: *mut PyObject, + pub strerror: *mut PyObject, + pub filename: *mut PyObject, + pub filename2: *mut PyObject, + #[cfg(windows)] + pub winerror: *mut PyObject, + pub written: Py_ssize_t, +} + +#[repr(C)] +#[derive(Debug)] +pub struct PyStopIterationObject { + pub ob_base: PyObject, + #[cfg(not(PyPy))] + pub dict: *mut PyObject, + #[cfg(not(PyPy))] + pub args: *mut PyObject, + #[cfg(all(Py_3_11, not(PyPy)))] + pub notes: *mut PyObject, + #[cfg(not(PyPy))] + pub traceback: *mut PyObject, + #[cfg(not(PyPy))] + pub context: *mut PyObject, + #[cfg(not(PyPy))] + pub cause: *mut PyObject, + #[cfg(not(PyPy))] + pub suppress_context: char, + + pub value: *mut PyObject, +} + +// skipped _PyErr_ChainExceptions + +// skipped PyNameErrorObject +// skipped PyAttributeErrorObject + +// skipped PyEnvironmentErrorObject +// skipped PyWindowsErrorObject + +// skipped _PyErr_SetKeyError +// skipped _PyErr_GetTopmostException +// skipped _PyErr_GetExcInfo + +// skipped PyErr_SetFromErrnoWithUnicodeFilename + +// skipped _PyErr_FormatFromCause + +// skipped PyErr_SetFromWindowsErrWithUnicodeFilename +// skipped PyErr_SetExcFromWindowsErrWithUnicodeFilename + +// skipped _PyErr_TrySetFromCause + +// skipped PySignal_SetWakeupFd +// skipped _PyErr_CheckSignals + +// skipped PyErr_SyntaxLocationObject +// skipped PyErr_RangedSyntaxLocationObject +// skipped PyErr_ProgramTextObject + +// skipped _PyErr_ProgramDecodedTextObject +// skipped _PyUnicodeTranslateError_Create +// skipped _PyErr_WriteUnraisableMsg +// skipped _Py_FatalErrorFunc +// skipped _Py_FatalErrorFormat +// skipped Py_FatalError diff --git a/vendor/pyo3-ffi/src/cpython/pyframe.rs b/vendor/pyo3-ffi/src/cpython/pyframe.rs new file mode 100644 index 0000000..7b75f6e --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/pyframe.rs @@ -0,0 +1,76 @@ +#[cfg(any(Py_3_11, all(Py_3_9, not(PyPy))))] +use crate::PyFrameObject; +use crate::{PyObject, PyTypeObject, Py_IS_TYPE}; +#[cfg(Py_3_12)] +use core::ffi::c_char; +use core::ffi::c_int; + +#[cfg(all(Py_3_11, not(PyPy)))] +opaque_struct!(pub _PyInterpreterFrame); + +#[cfg(Py_3_13)] +pub const PyUnstable_EXECUTABLE_KIND_SKIP: c_int = 0; +#[cfg(Py_3_13)] +pub const PyUnstable_EXECUTABLE_KIND_PY_FUNCTION: c_int = 1; +#[cfg(Py_3_13)] +pub const PyUnstable_EXECUTABLE_KIND_BUILTIN_FUNCTION: c_int = 3; +#[cfg(Py_3_13)] +pub const PyUnstable_EXECUTABLE_KIND_METHOD_DESCRIPTOR: c_int = 4; +#[cfg(Py_3_13)] +pub const PyUnstable_EXECUTABLE_KINDS: c_int = 5; + +extern_libpython! { + pub static mut PyFrame_Type: PyTypeObject; + + #[cfg(Py_3_13)] + pub static mut PyFrameLocalsProxy_Type: PyTypeObject; + + #[cfg(Py_3_13)] + pub static PyUnstable_ExecutableKinds: [*const PyTypeObject; 6]; +} + +#[inline] +pub unsafe fn PyFrame_Check(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyFrame_Type) +} + +#[cfg(Py_3_13)] +#[inline] +pub unsafe fn PyFrameLocalsProxy_Check(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyFrameLocalsProxy_Type) +} + +extern_libpython! { + #[cfg(all(Py_3_9, not(PyPy)))] + pub fn PyFrame_GetBack(frame: *mut PyFrameObject) -> *mut PyFrameObject; + + #[cfg(Py_3_11)] + pub fn PyFrame_GetLocals(frame: *mut PyFrameObject) -> *mut PyObject; + + #[cfg(Py_3_11)] + pub fn PyFrame_GetGlobals(frame: *mut PyFrameObject) -> *mut PyObject; + + #[cfg(Py_3_11)] + pub fn PyFrame_GetBuiltins(frame: *mut PyFrameObject) -> *mut PyObject; + + #[cfg(Py_3_11)] + pub fn PyFrame_GetGenerator(frame: *mut PyFrameObject) -> *mut PyObject; + + #[cfg(Py_3_11)] + pub fn PyFrame_GetLasti(frame: *mut PyFrameObject) -> c_int; + + #[cfg(Py_3_12)] + pub fn PyFrame_GetVar(frame: *mut PyFrameObject, name: *mut PyObject) -> *mut PyObject; + + #[cfg(Py_3_12)] + pub fn PyFrame_GetVarString(frame: *mut PyFrameObject, name: *mut c_char) -> *mut PyObject; + + #[cfg(Py_3_12)] + pub fn PyUnstable_InterpreterFrame_GetCode(frame: *mut _PyInterpreterFrame) -> *mut PyObject; + + #[cfg(Py_3_12)] + pub fn PyUnstable_InterpreterFrame_GetLasti(frame: *mut _PyInterpreterFrame) -> c_int; + + #[cfg(Py_3_12)] + pub fn PyUnstable_InterpreterFrame_GetLine(frame: *mut _PyInterpreterFrame) -> c_int; +} diff --git a/vendor/pyo3-ffi/src/cpython/pyhash.rs b/vendor/pyo3-ffi/src/cpython/pyhash.rs new file mode 100644 index 0000000..978849e --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/pyhash.rs @@ -0,0 +1,30 @@ +#[cfg(Py_3_14)] +use crate::Py_ssize_t; +#[cfg(Py_3_13)] +use crate::{PyObject, Py_hash_t}; +#[cfg(any(Py_3_13, not(PyPy)))] +use core::ffi::c_void; +#[cfg(not(PyPy))] +use core::ffi::{c_char, c_int}; + +#[cfg(not(PyPy))] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyHash_FuncDef { + pub hash: + Option crate::Py_hash_t>, + pub name: *const c_char, + pub hash_bits: c_int, + pub seed_bits: c_int, +} + +extern_libpython! { + #[cfg(not(PyPy))] + pub fn PyHash_GetFuncDef() -> *mut PyHash_FuncDef; + #[cfg(Py_3_13)] + pub fn Py_HashPointer(ptr: *const c_void) -> Py_hash_t; + #[cfg(Py_3_13)] + pub fn PyObject_GenericHash(obj: *mut PyObject) -> Py_hash_t; + #[cfg(Py_3_14)] + pub fn Py_HashBuffer(ptr: *const c_void, len: Py_ssize_t) -> Py_hash_t; +} diff --git a/vendor/pyo3-ffi/src/cpython/pylifecycle.rs b/vendor/pyo3-ffi/src/cpython/pylifecycle.rs new file mode 100644 index 0000000..07240d8 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/pylifecycle.rs @@ -0,0 +1,85 @@ +use crate::{PyConfig, PyPreConfig, PyStatus, Py_ssize_t}; +use core::ffi::{c_char, c_int}; +use libc::wchar_t; + +extern_libpython! { + + // skipped Py_FrozenMain + + pub fn Py_PreInitialize(src_config: *const PyPreConfig) -> PyStatus; + pub fn Py_PreInitializeFromBytesArgs( + src_config: *const PyPreConfig, + argc: Py_ssize_t, + argv: *mut *mut c_char, + ) -> PyStatus; + pub fn Py_PreInitializeFromArgs( + src_config: *const PyPreConfig, + argc: Py_ssize_t, + argv: *mut *mut wchar_t, + ) -> PyStatus; + + pub fn Py_InitializeFromConfig(config: *const PyConfig) -> PyStatus; + + pub fn Py_RunMain() -> c_int; + + pub fn Py_ExitStatusException(status: PyStatus) -> !; + + // skipped Py_FdIsInteractive +} + +#[cfg(Py_3_12)] +pub const PyInterpreterConfig_DEFAULT_GIL: c_int = 0; +#[cfg(Py_3_12)] +pub const PyInterpreterConfig_SHARED_GIL: c_int = 1; +#[cfg(Py_3_12)] +pub const PyInterpreterConfig_OWN_GIL: c_int = 2; + +#[cfg(Py_3_12)] +#[repr(C)] +pub struct PyInterpreterConfig { + pub use_main_obmalloc: c_int, + pub allow_fork: c_int, + pub allow_exec: c_int, + pub allow_threads: c_int, + pub allow_daemon_threads: c_int, + pub check_multi_interp_extensions: c_int, + pub gil: c_int, +} + +#[cfg(Py_3_12)] +pub const _PyInterpreterConfig_INIT: PyInterpreterConfig = PyInterpreterConfig { + use_main_obmalloc: 0, + allow_fork: 0, + allow_exec: 0, + allow_threads: 1, + allow_daemon_threads: 0, + check_multi_interp_extensions: 1, + gil: PyInterpreterConfig_OWN_GIL, +}; + +// https://github.com/python/cpython/blob/902de283a8303177eb95bf5bc252d2421fcbd758/Include/cpython/pylifecycle.h#L63-L65 +#[cfg(Py_3_12)] +const _PyInterpreterConfig_LEGACY_CHECK_MULTI_INTERP_EXTENSIONS: c_int = + if cfg!(Py_GIL_DISABLED) { 1 } else { 0 }; + +#[cfg(Py_3_12)] +pub const _PyInterpreterConfig_LEGACY_INIT: PyInterpreterConfig = PyInterpreterConfig { + use_main_obmalloc: 1, + allow_fork: 1, + allow_exec: 1, + allow_threads: 1, + allow_daemon_threads: 1, + check_multi_interp_extensions: _PyInterpreterConfig_LEGACY_CHECK_MULTI_INTERP_EXTENSIONS, + gil: PyInterpreterConfig_SHARED_GIL, +}; + +extern_libpython! { + #[cfg(Py_3_12)] + pub fn Py_NewInterpreterFromConfig( + tstate_p: *mut *mut crate::PyThreadState, + config: *const PyInterpreterConfig, + ) -> PyStatus; +} + +// skipped atexit_datacallbackfunc +// skipped PyUnstable_AtExit diff --git a/vendor/pyo3-ffi/src/cpython/pymem.rs b/vendor/pyo3-ffi/src/cpython/pymem.rs new file mode 100644 index 0000000..808e4a5 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/pymem.rs @@ -0,0 +1,49 @@ +use core::ffi::c_void; +use libc::size_t; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyMem_RawMalloc")] + pub fn PyMem_RawMalloc(size: size_t) -> *mut c_void; + #[cfg_attr(PyPy, link_name = "PyPyMem_RawCalloc")] + pub fn PyMem_RawCalloc(nelem: size_t, elsize: size_t) -> *mut c_void; + #[cfg_attr(PyPy, link_name = "PyPyMem_RawRealloc")] + pub fn PyMem_RawRealloc(ptr: *mut c_void, new_size: size_t) -> *mut c_void; + #[cfg_attr(PyPy, link_name = "PyPyMem_RawFree")] + pub fn PyMem_RawFree(ptr: *mut c_void); + + // skipped _PyMem_GetCurrentAllocatorName + // skipped _PyMem_RawStrdup + // skipped _PyMem_Strdup + // skipped _PyMem_RawWcsdup +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub enum PyMemAllocatorDomain { + PYMEM_DOMAIN_RAW, + PYMEM_DOMAIN_MEM, + PYMEM_DOMAIN_OBJ, +} + +// skipped PyMemAllocatorName +#[cfg(not(any(PyPy, GraalPy)))] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyMemAllocatorEx { + pub ctx: *mut c_void, + pub malloc: Option *mut c_void>, + pub calloc: + Option *mut c_void>, + pub realloc: + Option *mut c_void>, + pub free: Option, +} + +extern_libpython! { + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyMem_GetAllocator(domain: PyMemAllocatorDomain, allocator: *mut PyMemAllocatorEx); + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyMem_SetAllocator(domain: PyMemAllocatorDomain, allocator: *mut PyMemAllocatorEx); + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyMem_SetupDebugHooks(); +} diff --git a/vendor/pyo3-ffi/src/cpython/pystate.rs b/vendor/pyo3-ffi/src/cpython/pystate.rs new file mode 100644 index 0000000..52e1522 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/pystate.rs @@ -0,0 +1,85 @@ +use crate::PyThreadState; +use crate::{PyFrameObject, PyInterpreterState, PyObject}; +use core::ffi::c_int; + +// skipped private _PyInterpreterState_RequiresIDRef +// skipped private _PyInterpreterState_RequireIDRef + +pub type Py_tracefunc = unsafe extern "C" fn( + obj: *mut PyObject, + frame: *mut PyFrameObject, + what: c_int, + arg: *mut PyObject, +) -> c_int; + +pub const PyTrace_CALL: c_int = 0; +pub const PyTrace_EXCEPTION: c_int = 1; +pub const PyTrace_LINE: c_int = 2; +pub const PyTrace_RETURN: c_int = 3; +pub const PyTrace_C_CALL: c_int = 4; +pub const PyTrace_C_EXCEPTION: c_int = 5; +pub const PyTrace_C_RETURN: c_int = 6; +pub const PyTrace_OPCODE: c_int = 7; + +// skipped private _Py_MAX_SCRIPT_PATH_SIZE +// skipped private _PyRemoteDebuggerSupport + +/// Private structure used inline in `PyGenObject` +/// +/// `PyGenObject` was made opaque in Python 3.14, so we don't bother defining this +/// structure for that version and later. +#[cfg(not(any(PyPy, Py_3_14)))] +#[repr(C)] +#[derive(Clone, Copy)] +pub(crate) struct _PyErr_StackItem { + #[cfg(not(Py_3_11))] + exc_type: *mut PyObject, + exc_value: *mut PyObject, + #[cfg(not(Py_3_11))] + exc_traceback: *mut PyObject, + previous_item: *mut _PyErr_StackItem, +} + +// skipped private _PyStackChunk + +// skipped private _PY_DATA_STACK_CHUNK_SIZE +// skipped private _ts (aka PyThreadState) + +extern_libpython! { + #[cfg(Py_3_13)] + pub fn PyThreadState_GetUnchecked() -> *mut PyThreadState; + + #[cfg(not(Py_3_13))] + pub(crate) fn _PyThreadState_UncheckedGet() -> *mut PyThreadState; + + #[cfg(Py_3_11)] + pub fn PyThreadState_EnterTracing(state: *mut PyThreadState); + #[cfg(Py_3_11)] + pub fn PyThreadState_LeaveTracing(state: *mut PyThreadState); + + #[cfg_attr(PyPy, link_name = "PyPyGILState_Check")] + pub fn PyGILState_Check() -> c_int; + + // skipped private _PyThread_CurrentFrames + + // skipped PyUnstable_ThreadState_SetStackProtection + // skipped PyUnstable_ThreadState_ResetStackProtection + + #[cfg(not(PyPy))] + pub fn PyInterpreterState_Main() -> *mut PyInterpreterState; + #[cfg_attr(PyPy, link_name = "PyPyInterpreterState_Head")] + pub fn PyInterpreterState_Head() -> *mut PyInterpreterState; + #[cfg_attr(PyPy, link_name = "PyPyInterpreterState_Next")] + pub fn PyInterpreterState_Next(interp: *mut PyInterpreterState) -> *mut PyInterpreterState; + #[cfg(not(PyPy))] + pub fn PyInterpreterState_ThreadHead(interp: *mut PyInterpreterState) -> *mut PyThreadState; + #[cfg(not(PyPy))] + pub fn PyThreadState_Next(tstate: *mut PyThreadState) -> *mut PyThreadState; + + #[cfg_attr(PyPy, link_name = "PyPyThreadState_DeleteCurrent")] + pub fn PyThreadState_DeleteCurrent(); +} + +// skipped private _PyFrameEvalFunction +// skipped private _PyInterpreterState_GetEvalFrameFunc +// skipped private _PyInterpreterState_SetEvalFrameFunc diff --git a/vendor/pyo3-ffi/src/cpython/pythonrun.rs b/vendor/pyo3-ffi/src/cpython/pythonrun.rs new file mode 100644 index 0000000..e2df4ea --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/pythonrun.rs @@ -0,0 +1,229 @@ +use crate::object::*; +#[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API, Py_3_10)))] +use crate::pyarena::PyArena; +use crate::PyCompilerFlags; +#[cfg(not(any(PyPy, GraalPy, Py_3_10)))] +use crate::{_mod, _node}; +use core::ffi::{c_char, c_int}; +use libc::FILE; + +extern_libpython! { + pub fn PyRun_SimpleStringFlags(arg1: *const c_char, arg2: *mut PyCompilerFlags) -> c_int; + pub fn PyRun_AnyFileExFlags( + fp: *mut FILE, + filename: *const c_char, + closeit: c_int, + flags: *mut PyCompilerFlags, + ) -> c_int; + pub fn PyRun_SimpleFileExFlags( + fp: *mut FILE, + filename: *const c_char, + closeit: c_int, + flags: *mut PyCompilerFlags, + ) -> c_int; + pub fn PyRun_InteractiveOneFlags( + fp: *mut FILE, + filename: *const c_char, + flags: *mut PyCompilerFlags, + ) -> c_int; + pub fn PyRun_InteractiveOneObject( + fp: *mut FILE, + filename: *mut PyObject, + flags: *mut PyCompilerFlags, + ) -> c_int; + pub fn PyRun_InteractiveLoopFlags( + fp: *mut FILE, + filename: *const c_char, + flags: *mut PyCompilerFlags, + ) -> c_int; + + #[cfg(not(any(PyPy, GraalPy, Py_3_10)))] + pub fn PyParser_ASTFromString( + s: *const c_char, + filename: *const c_char, + start: c_int, + flags: *mut PyCompilerFlags, + arena: *mut PyArena, + ) -> *mut _mod; + #[cfg(not(any(PyPy, GraalPy, Py_3_10)))] + pub fn PyParser_ASTFromStringObject( + s: *const c_char, + filename: *mut PyObject, + start: c_int, + flags: *mut PyCompilerFlags, + arena: *mut PyArena, + ) -> *mut _mod; + #[cfg(not(any(PyPy, GraalPy, Py_3_10)))] + pub fn PyParser_ASTFromFile( + fp: *mut FILE, + filename: *const c_char, + enc: *const c_char, + start: c_int, + ps1: *const c_char, + ps2: *const c_char, + flags: *mut PyCompilerFlags, + errcode: *mut c_int, + arena: *mut PyArena, + ) -> *mut _mod; + #[cfg(not(any(PyPy, GraalPy, Py_3_10)))] + pub fn PyParser_ASTFromFileObject( + fp: *mut FILE, + filename: *mut PyObject, + enc: *const c_char, + start: c_int, + ps1: *const c_char, + ps2: *const c_char, + flags: *mut PyCompilerFlags, + errcode: *mut c_int, + arena: *mut PyArena, + ) -> *mut _mod; + + #[cfg_attr(PyPy, link_name = "PyPyRun_StringFlags")] + pub fn PyRun_StringFlags( + arg1: *const c_char, + arg2: c_int, + arg3: *mut PyObject, + arg4: *mut PyObject, + arg5: *mut PyCompilerFlags, + ) -> *mut PyObject; + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyRun_FileExFlags( + fp: *mut FILE, + filename: *const c_char, + start: c_int, + globals: *mut PyObject, + locals: *mut PyObject, + closeit: c_int, + flags: *mut PyCompilerFlags, + ) -> *mut PyObject; + + #[cfg(not(any(PyPy, GraalPy)))] + pub fn Py_CompileStringExFlags( + str: *const c_char, + filename: *const c_char, + start: c_int, + flags: *mut PyCompilerFlags, + optimize: c_int, + ) -> *mut PyObject; + #[cfg(not(Py_LIMITED_API))] + pub fn Py_CompileStringObject( + str: *const c_char, + filename: *mut PyObject, + start: c_int, + flags: *mut PyCompilerFlags, + optimize: c_int, + ) -> *mut PyObject; +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +pub unsafe fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject { + Py_CompileStringExFlags(string, p, s, core::ptr::null_mut(), -1) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +pub unsafe fn Py_CompileStringFlags( + string: *const c_char, + p: *const c_char, + s: c_int, + f: *mut PyCompilerFlags, +) -> *mut PyObject { + Py_CompileStringExFlags(string, p, s, f, -1) +} + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyRun_String")] + pub fn PyRun_String( + string: *const c_char, + s: c_int, + g: *mut PyObject, + l: *mut PyObject, + ) -> *mut PyObject; + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyRun_AnyFile(fp: *mut FILE, name: *const c_char) -> c_int; + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyRun_AnyFileEx(fp: *mut FILE, name: *const c_char, closeit: c_int) -> c_int; + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyRun_AnyFileFlags( + arg1: *mut FILE, + arg2: *const c_char, + arg3: *mut PyCompilerFlags, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyRun_SimpleString")] + pub fn PyRun_SimpleString(s: *const c_char) -> c_int; + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyRun_SimpleFile(f: *mut FILE, p: *const c_char) -> c_int; + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyRun_SimpleFileEx(f: *mut FILE, p: *const c_char, c: c_int) -> c_int; + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyRun_InteractiveOne(f: *mut FILE, p: *const c_char) -> c_int; + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyRun_InteractiveLoop(f: *mut FILE, p: *const c_char) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyRun_File")] + pub fn PyRun_File( + fp: *mut FILE, + p: *const c_char, + s: c_int, + g: *mut PyObject, + l: *mut PyObject, + ) -> *mut PyObject; + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyRun_FileEx( + fp: *mut FILE, + p: *const c_char, + s: c_int, + g: *mut PyObject, + l: *mut PyObject, + c: c_int, + ) -> *mut PyObject; + #[cfg(not(any(PyPy, GraalPy)))] + pub fn PyRun_FileFlags( + fp: *mut FILE, + p: *const c_char, + s: c_int, + g: *mut PyObject, + l: *mut PyObject, + flags: *mut PyCompilerFlags, + ) -> *mut PyObject; +} + +// skipped macro PyRun_String +// skipped macro PyRun_AnyFile +// skipped macro PyRun_AnyFileEx +// skipped macro PyRun_AnyFileFlags + +extern_libpython! { + #[cfg(not(any(PyPy, GraalPy, Py_3_10)))] + #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] + pub fn PyParser_SimpleParseStringFlags( + arg1: *const c_char, + arg2: c_int, + arg3: c_int, + ) -> *mut _node; + #[cfg(not(any(PyPy, GraalPy, Py_3_10)))] + #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] + pub fn PyParser_SimpleParseStringFlagsFilename( + arg1: *const c_char, + arg2: *const c_char, + arg3: c_int, + arg4: c_int, + ) -> *mut _node; + #[cfg(not(any(PyPy, GraalPy, Py_3_10)))] + #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] + pub fn PyParser_SimpleParseFileFlags( + arg1: *mut FILE, + arg2: *const c_char, + arg3: c_int, + arg4: c_int, + ) -> *mut _node; + + #[cfg(PyPy)] + #[cfg_attr(PyPy, link_name = "PyPy_CompileStringFlags")] + pub fn Py_CompileStringFlags( + string: *const c_char, + p: *const c_char, + s: c_int, + f: *mut PyCompilerFlags, + ) -> *mut PyObject; +} diff --git a/vendor/pyo3-ffi/src/cpython/setobject.rs b/vendor/pyo3-ffi/src/cpython/setobject.rs new file mode 100644 index 0000000..2977e43 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/setobject.rs @@ -0,0 +1,50 @@ +#[cfg(Py_GIL_DISABLED)] +use crate::pyatomic::_Py_atomic_load_ssize_relaxed; +#[cfg(not(any(PyPy, GraalPy)))] +use crate::{PyAnySet_Check, PyObject, Py_hash_t, Py_ssize_t}; + +pub const PySet_MINSIZE: usize = 8; + +#[cfg(not(any(PyPy, GraalPy)))] +#[repr(C)] +#[derive(Debug)] +pub struct setentry { + pub key: *mut PyObject, + pub hash: Py_hash_t, +} + +#[cfg(not(any(PyPy, GraalPy)))] +#[repr(C)] +#[derive(Debug)] +pub struct PySetObject { + pub ob_base: PyObject, + pub fill: Py_ssize_t, + pub used: Py_ssize_t, + pub mask: Py_ssize_t, + pub table: *mut setentry, + pub hash: Py_hash_t, + pub finger: Py_ssize_t, + pub smalltable: [setentry; PySet_MINSIZE], + pub weakreflist: *mut PyObject, +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +pub(crate) unsafe fn _PySet_CAST(so: *mut PyObject) -> *mut PySetObject { + debug_assert_eq!(PyAnySet_Check(so), 1); + so.cast() +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +pub unsafe fn PySet_GET_SIZE(so: *mut PyObject) -> Py_ssize_t { + let so = _PySet_CAST(so); + #[cfg(Py_GIL_DISABLED)] + { + _Py_atomic_load_ssize_relaxed(&raw const (*so).used) + } + #[cfg(not(Py_GIL_DISABLED))] + { + (*so).used + } +} diff --git a/vendor/pyo3-ffi/src/cpython/traceback.rs b/vendor/pyo3-ffi/src/cpython/traceback.rs new file mode 100644 index 0000000..41d89c5 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/traceback.rs @@ -0,0 +1,12 @@ +use crate::object::PyObject; +use crate::PyFrameObject; +use core::ffi::c_int; + +#[repr(C)] +pub struct PyTracebackObject { + pub ob_base: PyObject, + pub tb_next: *mut PyTracebackObject, + pub tb_frame: *mut PyFrameObject, + pub tb_lasti: c_int, + pub tb_lineno: c_int, +} diff --git a/vendor/pyo3-ffi/src/cpython/tupleobject.rs b/vendor/pyo3-ffi/src/cpython/tupleobject.rs new file mode 100644 index 0000000..dc1bf8e --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/tupleobject.rs @@ -0,0 +1,40 @@ +use crate::object::*; +#[cfg(Py_3_14)] +use crate::pyport::Py_hash_t; +#[cfg(not(PyPy))] +use crate::pyport::Py_ssize_t; + +#[repr(C)] +pub struct PyTupleObject { + pub ob_base: PyVarObject, + #[cfg(Py_3_14)] + pub ob_hash: Py_hash_t, + pub ob_item: [*mut PyObject; 1], +} + +// skipped _PyTuple_Resize +// skipped _PyTuple_MaybeUntrack + +// skipped _PyTuple_CAST + +/// Macro, trading safety for speed +#[inline] +#[cfg(not(PyPy))] +pub unsafe fn PyTuple_GET_SIZE(op: *mut PyObject) -> Py_ssize_t { + Py_SIZE(op) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +pub unsafe fn PyTuple_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject { + *(*(op as *mut PyTupleObject)).ob_item.as_ptr().offset(i) +} + +/// Macro, *only* to be used to fill in brand new tuples +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +pub unsafe fn PyTuple_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) { + *(*(op as *mut PyTupleObject)).ob_item.as_mut_ptr().offset(i) = v; +} + +// skipped _PyTuple_DebugMallocStats diff --git a/vendor/pyo3-ffi/src/cpython/unicodeobject.rs b/vendor/pyo3-ffi/src/cpython/unicodeobject.rs new file mode 100644 index 0000000..2db3a89 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/unicodeobject.rs @@ -0,0 +1,888 @@ +#[cfg(any(Py_3_11, not(PyPy)))] +use crate::Py_hash_t; +use crate::{PyObject, Py_UCS1, Py_UCS2, Py_UCS4, Py_ssize_t}; +use core::ffi::{c_char, c_int, c_uint, c_void}; +use libc::wchar_t; + +// skipped PY_UNICODE_TYPE + +#[cfg(not(Py_LIMITED_API))] +#[cfg_attr( + Py_3_13, + deprecated(note = "Deprecated since Python 3.13. Use `libc::wchar_t` instead.") +)] +pub type Py_UNICODE = wchar_t; + +// skipped Py_UNICODE_IS_SURROGATE +// skipped Py_UNICODE_IS_HIGH_SURROGATE +// skipped Py_UNICODE_IS_LOW_SURROGATE +// skipped Py_UNICODE_JOIN_SURROGATES +// skipped Py_UNICODE_HIGH_SURROGATE +// skipped Py_UNICODE_LOW_SURROGATE + +// generated by bindgen v0.63.0 (with small adaptations) +#[cfg(not(Py_3_14))] +#[repr(C)] +struct BitfieldUnit { + storage: Storage, +} + +#[cfg(not(Py_3_14))] +impl BitfieldUnit { + #[inline] + pub const fn new(storage: Storage) -> Self { + Self { storage } + } +} + +#[cfg(not(any(GraalPy, Py_3_14)))] +impl BitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + byte & mask == mask + } + + #[inline] + fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + let mut val = 0; + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + + #[inline] + fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self.set_bit(index + bit_offset, val_bit_is_set); + } + } +} + +#[cfg(not(any(GraalPy, Py_3_14)))] +const STATE_INTERNED_INDEX: usize = 0; +#[cfg(not(any(GraalPy, Py_3_14)))] +const STATE_INTERNED_WIDTH: u8 = 2; + +#[cfg(not(any(GraalPy, Py_3_14)))] +const STATE_KIND_INDEX: usize = STATE_INTERNED_WIDTH as usize; +#[cfg(not(any(GraalPy, Py_3_14)))] +const STATE_KIND_WIDTH: u8 = 3; + +#[cfg(not(any(GraalPy, Py_3_14)))] +const STATE_COMPACT_INDEX: usize = (STATE_INTERNED_WIDTH + STATE_KIND_WIDTH) as usize; +#[cfg(not(any(GraalPy, Py_3_14)))] +const STATE_COMPACT_WIDTH: u8 = 1; + +#[cfg(not(any(GraalPy, Py_3_14)))] +const STATE_ASCII_INDEX: usize = + (STATE_INTERNED_WIDTH + STATE_KIND_WIDTH + STATE_COMPACT_WIDTH) as usize; +#[cfg(not(any(GraalPy, Py_3_14)))] +const STATE_ASCII_WIDTH: u8 = 1; + +#[cfg(all(not(any(GraalPy, Py_3_14)), Py_3_12))] +const STATE_STATICALLY_ALLOCATED_INDEX: usize = + (STATE_INTERNED_WIDTH + STATE_KIND_WIDTH + STATE_COMPACT_WIDTH + STATE_ASCII_WIDTH) as usize; +#[cfg(all(not(any(GraalPy, Py_3_14)), Py_3_12))] +const STATE_STATICALLY_ALLOCATED_WIDTH: u8 = 1; + +#[cfg(not(any(Py_3_12, GraalPy)))] +const STATE_READY_INDEX: usize = + (STATE_INTERNED_WIDTH + STATE_KIND_WIDTH + STATE_COMPACT_WIDTH + STATE_ASCII_WIDTH) as usize; +#[cfg(not(any(Py_3_12, GraalPy)))] +const STATE_READY_WIDTH: u8 = 1; + +// generated by bindgen v0.63.0 (with small adaptations) +// The same code is generated for Python 3.8, 3.9, 3.10, and 3.11, but the "ready" field +// has been removed from Python 3.12. + +/// Wrapper around the `PyASCIIObject.state` bitfield with getters and setters that work +/// on most little- and big-endian architectures. +/// +/// Memory layout of C bitfields is implementation defined, so these functions are still +/// unsafe. Users must verify that they work as expected on the architectures they target. +#[cfg(not(Py_3_14))] +#[repr(C)] +struct PyASCIIObjectState { + bitfield_align: [u8; 0], + bitfield: BitfieldUnit<[u8; 4usize]>, +} + +// c_uint and u32 are not necessarily the same type on all targets / architectures +#[cfg(not(any(GraalPy, Py_3_14)))] +#[allow(clippy::useless_transmute)] +impl PyASCIIObjectState { + #[inline] + unsafe fn interned(&self) -> c_uint { + core::mem::transmute( + self.bitfield + .get(STATE_INTERNED_INDEX, STATE_INTERNED_WIDTH) as u32, + ) + } + + #[inline] + unsafe fn set_interned(&mut self, val: c_uint) { + let val: u32 = core::mem::transmute(val); + self.bitfield + .set(STATE_INTERNED_INDEX, STATE_INTERNED_WIDTH, val as u64) + } + + #[inline] + unsafe fn kind(&self) -> c_uint { + core::mem::transmute(self.bitfield.get(STATE_KIND_INDEX, STATE_KIND_WIDTH) as u32) + } + + #[inline] + unsafe fn set_kind(&mut self, val: c_uint) { + let val: u32 = core::mem::transmute(val); + self.bitfield + .set(STATE_KIND_INDEX, STATE_KIND_WIDTH, val as u64) + } + + #[inline] + unsafe fn compact(&self) -> c_uint { + core::mem::transmute(self.bitfield.get(STATE_COMPACT_INDEX, STATE_COMPACT_WIDTH) as u32) + } + + #[inline] + unsafe fn set_compact(&mut self, val: c_uint) { + let val: u32 = core::mem::transmute(val); + self.bitfield + .set(STATE_COMPACT_INDEX, STATE_COMPACT_WIDTH, val as u64) + } + + #[inline] + unsafe fn ascii(&self) -> c_uint { + core::mem::transmute(self.bitfield.get(STATE_ASCII_INDEX, STATE_ASCII_WIDTH) as u32) + } + + #[inline] + unsafe fn set_ascii(&mut self, val: c_uint) { + let val: u32 = core::mem::transmute(val); + self.bitfield + .set(STATE_ASCII_INDEX, STATE_ASCII_WIDTH, val as u64) + } + + #[cfg(Py_3_12)] + #[inline] + unsafe fn statically_allocated(&self) -> c_uint { + core::mem::transmute(self.bitfield.get( + STATE_STATICALLY_ALLOCATED_INDEX, + STATE_STATICALLY_ALLOCATED_WIDTH, + ) as u32) + } + + #[cfg(Py_3_12)] + #[inline] + unsafe fn set_statically_allocated(&mut self, val: c_uint) { + let val: u32 = core::mem::transmute(val); + self.bitfield.set( + STATE_STATICALLY_ALLOCATED_INDEX, + STATE_STATICALLY_ALLOCATED_WIDTH, + val as u64, + ) + } + + #[cfg(not(Py_3_12))] + #[inline] + unsafe fn ready(&self) -> c_uint { + core::mem::transmute(self.bitfield.get(STATE_READY_INDEX, STATE_READY_WIDTH) as u32) + } + + #[cfg(not(Py_3_12))] + #[inline] + unsafe fn set_ready(&mut self, val: c_uint) { + let val: u32 = core::mem::transmute(val); + self.bitfield + .set(STATE_READY_INDEX, STATE_READY_WIDTH, val as u64) + } +} + +#[cfg(not(Py_3_14))] +impl From for PyASCIIObjectState { + #[inline] + fn from(value: u32) -> Self { + PyASCIIObjectState { + bitfield_align: [], + bitfield: BitfieldUnit::new(value.to_ne_bytes()), + } + } +} + +#[cfg(not(Py_3_14))] +impl From for u32 { + #[inline] + fn from(value: PyASCIIObjectState) -> Self { + u32::from_ne_bytes(value.bitfield.storage) + } +} + +#[repr(C)] +pub struct PyASCIIObject { + pub ob_base: PyObject, + pub length: Py_ssize_t, + #[cfg(any(Py_3_11, not(PyPy)))] + pub hash: Py_hash_t, + /// A bit field with various properties. + /// + /// Rust doesn't expose bitfields. So we have accessor functions for + /// retrieving values. + /// + /// Before 3.12: + /// unsigned int interned:2; // SSTATE_* constants. + /// unsigned int kind:3; // PyUnicode_*_KIND constants. + /// unsigned int compact:1; + /// unsigned int ascii:1; + /// unsigned int ready:1; + /// unsigned int :24; + /// + /// 3.12, and 3.13 + /// unsigned int interned:2; // SSTATE_* constants. + /// unsigned int kind:3; // PyUnicode_*_KIND constants. + /// unsigned int compact:1; + /// unsigned int ascii:1; + /// unsigned int statically_allocated:1; + /// unsigned int :24; + /// on 3.14 and higher PyO3 doesn't access the internal state + pub state: u32, + #[cfg(not(Py_3_12))] + pub wstr: *mut wchar_t, +} + +/// Interacting with the bitfield is not actually well-defined, so we mark these APIs unsafe. +#[cfg(not(any(GraalPy, Py_3_14)))] +impl PyASCIIObject { + #[cfg_attr(not(Py_3_12), allow(rustdoc::broken_intra_doc_links))] // SSTATE_INTERNED_IMMORTAL_STATIC requires 3.12 + /// Get the `interned` field of the [`PyASCIIObject`] state bitfield. + /// + /// Returns one of: [`SSTATE_NOT_INTERNED`], [`SSTATE_INTERNED_MORTAL`], + /// [`SSTATE_INTERNED_IMMORTAL`], or [`SSTATE_INTERNED_IMMORTAL_STATIC`]. + #[inline] + pub unsafe fn interned(&self) -> c_uint { + PyASCIIObjectState::from(self.state).interned() + } + + #[cfg_attr(not(Py_3_12), allow(rustdoc::broken_intra_doc_links))] // SSTATE_INTERNED_IMMORTAL_STATIC requires 3.12 + /// Set the `interned` field of the [`PyASCIIObject`] state bitfield. + /// + /// Calling this function with an argument that is not [`SSTATE_NOT_INTERNED`], + /// [`SSTATE_INTERNED_MORTAL`], [`SSTATE_INTERNED_IMMORTAL`], or + /// [`SSTATE_INTERNED_IMMORTAL_STATIC`] is invalid. + #[inline] + pub unsafe fn set_interned(&mut self, val: c_uint) { + let mut state = PyASCIIObjectState::from(self.state); + state.set_interned(val); + self.state = u32::from(state); + } + + /// Get the `kind` field of the [`PyASCIIObject`] state bitfield. + /// + /// Returns one of: + #[cfg_attr(not(Py_3_12), doc = "[`PyUnicode_WCHAR_KIND`], ")] + /// [`PyUnicode_1BYTE_KIND`], [`PyUnicode_2BYTE_KIND`], or [`PyUnicode_4BYTE_KIND`]. + #[inline] + pub unsafe fn kind(&self) -> c_uint { + PyASCIIObjectState::from(self.state).kind() + } + + /// Set the `kind` field of the [`PyASCIIObject`] state bitfield. + /// + /// Calling this function with an argument that is not + #[cfg_attr(not(Py_3_12), doc = "[`PyUnicode_WCHAR_KIND`], ")] + /// [`PyUnicode_1BYTE_KIND`], [`PyUnicode_2BYTE_KIND`], or [`PyUnicode_4BYTE_KIND`] is invalid. + #[inline] + pub unsafe fn set_kind(&mut self, val: c_uint) { + let mut state = PyASCIIObjectState::from(self.state); + state.set_kind(val); + self.state = u32::from(state); + } + + /// Get the `compact` field of the [`PyASCIIObject`] state bitfield. + /// + /// Returns either `0` or `1`. + #[inline] + pub unsafe fn compact(&self) -> c_uint { + PyASCIIObjectState::from(self.state).compact() + } + + /// Set the `compact` flag of the [`PyASCIIObject`] state bitfield. + /// + /// Calling this function with an argument that is neither `0` nor `1` is invalid. + #[inline] + pub unsafe fn set_compact(&mut self, val: c_uint) { + let mut state = PyASCIIObjectState::from(self.state); + state.set_compact(val); + self.state = u32::from(state); + } + + /// Get the `ascii` field of the [`PyASCIIObject`] state bitfield. + /// + /// Returns either `0` or `1`. + #[inline] + pub unsafe fn ascii(&self) -> c_uint { + PyASCIIObjectState::from(self.state).ascii() + } + + /// Set the `ascii` flag of the [`PyASCIIObject`] state bitfield. + /// + /// Calling this function with an argument that is neither `0` nor `1` is invalid. + #[inline] + #[cfg(not(all(Py_3_14, Py_GIL_DISABLED)))] + pub unsafe fn set_ascii(&mut self, val: c_uint) { + let mut state = PyASCIIObjectState::from(self.state); + state.set_ascii(val); + self.state = u32::from(state); + } + + /// Get the `ready` field of the [`PyASCIIObject`] state bitfield. + /// + /// Returns either `0` or `1`. + #[cfg(not(Py_3_12))] + #[inline] + pub unsafe fn ready(&self) -> c_uint { + PyASCIIObjectState::from(self.state).ready() + } + + /// Set the `ready` flag of the [`PyASCIIObject`] state bitfield. + /// + /// Calling this function with an argument that is neither `0` nor `1` is invalid. + #[cfg(not(Py_3_12))] + #[inline] + pub unsafe fn set_ready(&mut self, val: c_uint) { + let mut state = PyASCIIObjectState::from(self.state); + state.set_ready(val); + self.state = u32::from(state); + } + + /// Get the `statically_allocated` field of the [`PyASCIIObject`] state bitfield. + /// + /// Returns either `0` or `1`. + #[inline] + #[cfg(Py_3_12)] + pub unsafe fn statically_allocated(&self) -> c_uint { + PyASCIIObjectState::from(self.state).statically_allocated() + } + + /// Set the `statically_allocated` flag of the [`PyASCIIObject`] state bitfield. + /// + /// Calling this function with an argument that is neither `0` nor `1` is invalid. + #[inline] + #[cfg(Py_3_12)] + pub unsafe fn set_statically_allocated(&mut self, val: c_uint) { + let mut state = PyASCIIObjectState::from(self.state); + state.set_statically_allocated(val); + self.state = u32::from(state); + } +} + +#[repr(C)] +pub struct PyCompactUnicodeObject { + pub _base: PyASCIIObject, + pub utf8_length: Py_ssize_t, + pub utf8: *mut c_char, + #[cfg(not(Py_3_12))] + pub wstr_length: Py_ssize_t, +} + +#[repr(C)] +pub union PyUnicodeObjectData { + pub any: *mut c_void, + pub latin1: *mut Py_UCS1, + pub ucs2: *mut Py_UCS2, + pub ucs4: *mut Py_UCS4, +} + +#[repr(C)] +pub struct PyUnicodeObject { + pub _base: PyCompactUnicodeObject, + pub data: PyUnicodeObjectData, +} + +// skipped private _PyASCIIObject_CAST +// skipped private _PyCompactUnicodeObject_CAST +// skipped private _PyUnicodeObject_CAST + +pub const SSTATE_NOT_INTERNED: c_uint = 0; +pub const SSTATE_INTERNED_MORTAL: c_uint = 1; +pub const SSTATE_INTERNED_IMMORTAL: c_uint = 2; +#[cfg(Py_3_12)] +pub const SSTATE_INTERNED_IMMORTAL_STATIC: c_uint = 3; + +// skipped PyUnicode_CHECK_INTERNED + +#[cfg(any(Py_3_12, GraalPy))] +#[cfg_attr( + Py_3_14, + deprecated(note = "Deprecated since Python 3.14. This API does nothing since Python 3.12.") +)] +#[inline] +pub unsafe fn PyUnicode_IS_READY(_op: *mut PyObject) -> c_uint { + // kept in CPython for backwards compatibility + 1 +} + +#[cfg(not(any(GraalPy, Py_3_12)))] +#[inline] +pub unsafe fn PyUnicode_IS_READY(op: *mut PyObject) -> c_uint { + (*(op as *mut PyASCIIObject)).ready() +} + +// The following functions depend on the bitfield, which we don't support +// from 3.14 onwards + +#[cfg(not(any(GraalPy, Py_3_14)))] +#[inline] +pub unsafe fn PyUnicode_IS_ASCII(op: *mut PyObject) -> c_uint { + debug_assert!(crate::PyUnicode_Check(op) != 0); + #[cfg(not(Py_3_12))] + debug_assert!(PyUnicode_IS_READY(op) != 0); + + (*(op as *mut PyASCIIObject)).ascii() +} + +#[cfg(not(any(GraalPy, Py_3_14)))] +#[inline] +pub unsafe fn PyUnicode_IS_COMPACT(op: *mut PyObject) -> c_uint { + (*(op as *mut PyASCIIObject)).compact() +} + +#[cfg(not(any(GraalPy, Py_3_14)))] +#[inline] +pub unsafe fn PyUnicode_IS_COMPACT_ASCII(op: *mut PyObject) -> c_uint { + ((*(op as *mut PyASCIIObject)).ascii() != 0 && PyUnicode_IS_COMPACT(op) != 0).into() +} + +#[cfg(not(Py_3_12))] +#[deprecated(note = "Removed in Python 3.12")] +pub const PyUnicode_WCHAR_KIND: c_uint = 0; + +pub const PyUnicode_1BYTE_KIND: c_uint = 1; +pub const PyUnicode_2BYTE_KIND: c_uint = 2; +pub const PyUnicode_4BYTE_KIND: c_uint = 4; + +#[cfg(all(not(GraalPy), Py_3_14))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyUnicode_KIND")] + pub fn PyUnicode_KIND(op: *mut PyObject) -> c_uint; +} + +#[cfg(all(not(GraalPy), not(Py_3_14)))] +#[inline] +pub unsafe fn PyUnicode_KIND(op: *mut PyObject) -> c_uint { + debug_assert!(crate::PyUnicode_Check(op) != 0); + #[cfg(not(Py_3_12))] + debug_assert!(PyUnicode_IS_READY(op) != 0); + + (*(op as *mut PyASCIIObject)).kind() +} + +#[cfg(not(any(GraalPy, Py_3_14)))] +#[inline] +unsafe fn _PyUnicode_COMPACT_DATA(op: *mut PyObject) -> *mut c_void { + if PyUnicode_IS_ASCII(op) != 0 { + (op as *mut PyASCIIObject).offset(1) as *mut c_void + } else { + (op as *mut PyCompactUnicodeObject).offset(1) as *mut c_void + } +} + +#[cfg(not(any(GraalPy, PyPy)))] +#[inline] +unsafe fn _PyUnicode_NONCOMPACT_DATA(op: *mut PyObject) -> *mut c_void { + debug_assert!(!(*(op as *mut PyUnicodeObject)).data.any.is_null()); + + (*(op as *mut PyUnicodeObject)).data.any +} + +#[cfg(not(any(GraalPy, PyPy, Py_3_14)))] +#[inline] +pub unsafe fn PyUnicode_DATA(op: *mut PyObject) -> *mut c_void { + debug_assert!(crate::PyUnicode_Check(op) != 0); + + if PyUnicode_IS_COMPACT(op) != 0 { + _PyUnicode_COMPACT_DATA(op) + } else { + _PyUnicode_NONCOMPACT_DATA(op) + } +} + +#[cfg(Py_3_14)] +#[cfg(all(not(GraalPy), Py_3_14))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyUnicode_DATA")] + pub fn PyUnicode_DATA(op: *mut PyObject) -> *mut c_void; +} + +#[cfg(not(any(GraalPy, PyPy)))] +#[inline] +pub unsafe fn PyUnicode_1BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS1 { + PyUnicode_DATA(op) as *mut Py_UCS1 +} + +#[cfg(not(any(GraalPy, PyPy)))] +#[inline] +pub unsafe fn PyUnicode_2BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS2 { + PyUnicode_DATA(op) as *mut Py_UCS2 +} + +#[cfg(not(any(GraalPy, PyPy)))] +#[inline] +pub unsafe fn PyUnicode_4BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS4 { + PyUnicode_DATA(op) as *mut Py_UCS4 +} + +#[cfg(not(GraalPy))] +#[inline] +pub unsafe fn PyUnicode_GET_LENGTH(op: *mut PyObject) -> Py_ssize_t { + debug_assert!(crate::PyUnicode_Check(op) != 0); + #[cfg(not(Py_3_12))] + debug_assert!(PyUnicode_IS_READY(op) != 0); + + (*(op as *mut PyASCIIObject)).length +} + +// skipped PyUnstable_Unicode_GET_CACHED_HASH +// skipped PyUnicode_WRITE +// skipped PyUnicode_READ +// skipped PyUnicode_READ_CHAR +// skipped PyUnicode_MAX_CHAR_VALUE + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyUnicode_New")] + pub fn PyUnicode_New(size: Py_ssize_t, maxchar: Py_UCS4) -> *mut PyObject; +} + +#[cfg(any(Py_3_12, GraalPy))] +#[inline] +pub unsafe fn PyUnicode_READY(_op: *mut PyObject) -> c_int { + 0 +} + +#[cfg(not(any(Py_3_12, GraalPy)))] +#[inline] +pub unsafe fn PyUnicode_READY(op: *mut PyObject) -> c_int { + debug_assert!(crate::PyUnicode_Check(op) != 0); + + if PyUnicode_IS_READY(op) != 0 { + 0 + } else { + _PyUnicode_Ready(op) + } +} + +extern_libpython! { + #[cfg(not(any(Py_3_12, GraalPy)))] + #[cfg_attr(PyPy, link_name = "_PyPyUnicode_Ready")] + fn _PyUnicode_Ready(unicode: *mut PyObject) -> c_int; + + #[cfg(not(PyPy))] + pub fn PyUnicode_CopyCharacters( + to: *mut PyObject, + to_start: Py_ssize_t, + from: *mut PyObject, + from_start: Py_ssize_t, + how_many: Py_ssize_t, + ) -> Py_ssize_t; + + #[cfg(not(PyPy))] + pub fn PyUnicode_Fill( + unicode: *mut PyObject, + start: Py_ssize_t, + length: Py_ssize_t, + fill_char: Py_UCS4, + ) -> Py_ssize_t; + + #[cfg(not(Py_3_12))] + #[deprecated] + #[cfg_attr(PyPy, link_name = "PyPyUnicode_FromUnicode")] + pub fn PyUnicode_FromUnicode(u: *const wchar_t, size: Py_ssize_t) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyUnicode_FromKindAndData")] + pub fn PyUnicode_FromKindAndData( + kind: c_int, + buffer: *const c_void, + size: Py_ssize_t, + ) -> *mut PyObject; + + #[cfg(not(Py_3_12))] + #[deprecated] + #[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUnicode")] + pub fn PyUnicode_AsUnicode(unicode: *mut PyObject) -> *mut wchar_t; + + #[cfg(not(Py_3_12))] + #[deprecated] + #[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUnicodeAndSize")] + pub fn PyUnicode_AsUnicodeAndSize( + unicode: *mut PyObject, + size: *mut Py_ssize_t, + ) -> *mut wchar_t; +} + +#[cfg(Py_3_14)] +opaque_struct!(pub PyUnicodeWriter); + +extern_libpython! { + #[cfg(Py_3_14)] + pub fn PyUnicodeWriter_Create(length: Py_ssize_t) -> *mut PyUnicodeWriter; + #[cfg(Py_3_14)] + pub fn PyUnicodeWriter_Discard(writer: *mut PyUnicodeWriter); + #[cfg(Py_3_14)] + pub fn PyUnicodeWriter_Finish(writer: *mut PyUnicodeWriter) -> *mut PyObject; + + #[cfg(Py_3_14)] + pub fn PyUnicodeWriter_WriteChar(writer: *mut PyUnicodeWriter, ch: Py_UCS4) -> c_int; + #[cfg(Py_3_14)] + pub fn PyUnicodeWriter_WriteUTF8( + writer: *mut PyUnicodeWriter, + str: *const c_char, + size: Py_ssize_t, + ) -> c_int; + // skipped PyUnicodeWriter_WriteASCII + // skipped PyUnicodeWriter_WriteWideChar + // skipped PyUnicodeWriter_WriteUCS4 + + // skipped PyUnicodeWriter_WriteStr + // skipped PyUnicodeWriter_WriteRepr + // skipped PyUnicodeWriter_WriteSubstring + // skipped PyUnicodeWriter_Format + // skipped PyUnicodeWriter_DecodeUTF8Stateful +} + +// skipped private _PyUnicodeWriter +// skipped private _PyUnicodeWriter_Init +// skipped private _PyUnicodeWriter_Prepare +// skipped private _PyUnicodeWriter_PrepareInternal +// skipped private _PyUnicodeWriter_PrepareKind +// skipped private _PyUnicodeWriter_PrepareKindInternal +// skipped private _PyUnicodeWriter_WriteChar +// skipped private _PyUnicodeWriter_WriteStr +// skipped private _PyUnicodeWriter_WriteSubstring +// skipped private _PyUnicodeWriter_WriteASCIIString +// skipped private _PyUnicodeWriter_WriteLatin1String +// skipped private _PyUnicodeWriter_Finish +// skipped private _PyUnicodeWriter_Dealloc + +extern_libpython! { + + #[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF8")] + pub fn PyUnicode_AsUTF8(unicode: *mut PyObject) -> *const c_char; + + // skipped _PyUnicode_AsString + + #[cfg(not(Py_3_11))] + #[deprecated(note = "use `PyUnicode_AsEncodedString` instead")] + pub fn PyUnicode_Encode( + s: *const wchar_t, + size: Py_ssize_t, + encoding: *const c_char, + errors: *const c_char, + ) -> *mut PyObject; + + #[cfg(not(Py_3_11))] + #[deprecated(note = "use `PyUnicode_AsEncodedString` instead")] + pub fn PyUnicode_EncodeUTF7( + data: *const wchar_t, + length: Py_ssize_t, + base64SetO: c_int, + base64WhiteSpace: c_int, + errors: *const c_char, + ) -> *mut PyObject; + + #[cfg(not(Py_3_11))] + #[deprecated(note = "use `PyUnicode_AsUTF8String` instead")] + #[cfg_attr(PyPy, link_name = "PyPyUnicode_EncodeUTF8")] + pub fn PyUnicode_EncodeUTF8( + data: *const wchar_t, + length: Py_ssize_t, + errors: *const c_char, + ) -> *mut PyObject; + + #[cfg(not(Py_3_11))] + #[deprecated(note = "use `PyUnicode_AsUTF32String` instead")] + pub fn PyUnicode_EncodeUTF32( + data: *const wchar_t, + length: Py_ssize_t, + errors: *const c_char, + byteorder: c_int, + ) -> *mut PyObject; + + #[cfg(not(Py_3_11))] + #[deprecated(note = "use `PyUnicode_AsUTF16String` instead")] + pub fn PyUnicode_EncodeUTF16( + data: *const wchar_t, + length: Py_ssize_t, + errors: *const c_char, + byteorder: c_int, + ) -> *mut PyObject; + + #[cfg(not(Py_3_11))] + #[deprecated(note = "use `PyUnicode_AsUnicodeEscapeString` instead")] + pub fn PyUnicode_EncodeUnicodeEscape(data: *const wchar_t, length: Py_ssize_t) + -> *mut PyObject; + + #[cfg(not(Py_3_11))] + #[deprecated(note = "use `PyUnicode_AsRawUnicodeEscapeString` instead")] + pub fn PyUnicode_EncodeRawUnicodeEscape( + data: *const wchar_t, + length: Py_ssize_t, + ) -> *mut PyObject; + + #[cfg(not(Py_3_11))] + #[deprecated(note = "use `PyUnicode_AsLatin1String` instead")] + #[cfg_attr(PyPy, link_name = "PyPyUnicode_EncodeLatin1")] + pub fn PyUnicode_EncodeLatin1( + data: *const wchar_t, + length: Py_ssize_t, + errors: *const c_char, + ) -> *mut PyObject; + + #[cfg(not(Py_3_11))] + #[deprecated(note = "use `PyUnicode_AsASCIIString` instead")] + #[cfg_attr(PyPy, link_name = "PyPyUnicode_EncodeASCII")] + pub fn PyUnicode_EncodeASCII( + data: *const wchar_t, + length: Py_ssize_t, + errors: *const c_char, + ) -> *mut PyObject; + + #[cfg(not(Py_3_11))] + #[deprecated(note = "use `PyUnicode_AsCharmapString` instead")] + pub fn PyUnicode_EncodeCharmap( + data: *const wchar_t, + length: Py_ssize_t, + mapping: *mut PyObject, + errors: *const c_char, + ) -> *mut PyObject; + + #[cfg(not(Py_3_11))] + #[deprecated(note = "use `PyUnicode_Translate` instead")] + pub fn PyUnicode_TranslateCharmap( + data: *const wchar_t, + length: Py_ssize_t, + table: *mut PyObject, + errors: *const c_char, + ) -> *mut PyObject; + + #[cfg(not(Py_3_11))] + #[deprecated(note = "use `Py_UNICODE_TODECIMAL` instead")] + #[cfg_attr(PyPy, link_name = "PyPyUnicode_EncodeDecimal")] + pub fn PyUnicode_EncodeDecimal( + s: *mut wchar_t, + length: Py_ssize_t, + output: *mut c_char, + errors: *const c_char, + ) -> c_int; + + #[cfg(not(Py_3_11))] + #[deprecated(note = "use `Py_UNICODE_TODECIMAL` instead")] + #[cfg_attr(PyPy, link_name = "PyPyUnicode_TransformDecimalToASCII")] + pub fn PyUnicode_TransformDecimalToASCII(s: *mut wchar_t, length: Py_ssize_t) -> *mut PyObject; + + // skipped _PyUnicode_IsLowercase + // skipped _PyUnicode_IsUppercase + // skipped _PyUnicode_IsTitlecase + // skipped _PyUnicode_IsWhitespace + // skipped _PyUnicode_IsLinebreak + // skipped _PyUnicode_ToLowercase + // skipped _PyUnicode_ToUppercase + // skipped _PyUnicode_ToTitlecase + + #[cfg(not(PyPy))] + fn _PyUnicode_ToDecimalDigit(ch: Py_UCS4) -> c_int; + + // skipped _PyUnicode_ToDigit + // skipped _PyUnicode_ToNumeric + // skipped _PyUnicode_IsDecimalDigit + // skipped _PyUnicode_IsDigit + // skipped _PyUnicode_IsNumeric + // skipped _PyUnicode_IsPrintable + // skipped _PyUnicode_IsAlpha + +} + +// skipped _Py_ascii_whitespace +// skipped Py_UNICODE_ISSPACE + +// skipped Py_UNICODE_ISLOWER +// skipped Py_UNICODE_ISUPPER +// skipped Py_UNICODE_ISTITLE +// skipped Py_UNICODE_ISLINEBREAK + +// skipped Py_UNICODE_TOLOWER +// skipped Py_UNICODE_TOUPPER +// skipped Py_UNICODE_TOTITLE + +// skipped Py_UNICODE_ISDECIMAL +// skipped Py_UNICODE_ISDIGIT +// skipped Py_UNICODE_ISNUMERIC +// skipped Py_UNICODE_ISPRINTABLE + +#[cfg(not(PyPy))] +pub unsafe extern "C" fn Py_UNICODE_TODECIMAL(ch: Py_UCS4) -> c_int { + _PyUnicode_ToDecimalDigit(ch) +} + +#[cfg(PyPy)] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPy_UNICODE_TODECIMAL")] + pub fn Py_UNICODE_TODECIMAL(ch: Py_UCS4) -> c_int; +} + +// skipped Py_UNICODE_TODIGIT +// skipped Py_UNICODE_TONUMERIC + +// skipped Py_UNICODE_ISALPHA + +// skipped Py_UNICODE_ISALNUM + +// skipped private _PyUnicode_FromId diff --git a/vendor/pyo3-ffi/src/cpython/warnings.rs b/vendor/pyo3-ffi/src/cpython/warnings.rs new file mode 100644 index 0000000..f3330e6 --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/warnings.rs @@ -0,0 +1,13 @@ +use crate::object::PyObject; +use core::ffi::c_int; + +extern_libpython! { + pub fn PyErr_WarnExplicitObject( + category: *mut PyObject, + message: *mut PyObject, + filename: *mut PyObject, + lineno: c_int, + module: *mut PyObject, + registry: *mut PyObject, + ) -> c_int; +} diff --git a/vendor/pyo3-ffi/src/cpython/weakrefobject.rs b/vendor/pyo3-ffi/src/cpython/weakrefobject.rs new file mode 100644 index 0000000..1c50c7a --- /dev/null +++ b/vendor/pyo3-ffi/src/cpython/weakrefobject.rs @@ -0,0 +1,18 @@ +// NB publicly re-exported in `src/weakrefobject.rs` +#[cfg(not(any(PyPy, GraalPy)))] +pub struct _PyWeakReference { + pub ob_base: crate::PyObject, + pub wr_object: *mut crate::PyObject, + pub wr_callback: *mut crate::PyObject, + pub hash: crate::Py_hash_t, + pub wr_prev: *mut crate::PyWeakReference, + pub wr_next: *mut crate::PyWeakReference, + #[cfg(Py_3_11)] + pub vectorcall: Option, + #[cfg(all(Py_3_13, Py_GIL_DISABLED))] + pub weakrefs_lock: *mut crate::PyMutex, +} + +// skipped _PyWeakref_GetWeakrefCount +// skipped _PyWeakref_ClearRef +// skipped PyWeakRef_GET_OBJECT diff --git a/vendor/pyo3-ffi/src/critical_section.rs b/vendor/pyo3-ffi/src/critical_section.rs new file mode 100644 index 0000000..ca58528 --- /dev/null +++ b/vendor/pyo3-ffi/src/critical_section.rs @@ -0,0 +1,37 @@ +#[cfg(any( + all(Py_GIL_DISABLED, Py_3_13, not(Py_LIMITED_API)), + all(Py_3_15, not(Py_LIMITED_API)) +))] +use crate::PyMutex; +#[cfg(any(all(Py_GIL_DISABLED, Py_3_13), Py_3_15))] +use crate::PyObject; + +#[cfg(all(Py_LIMITED_API, Py_3_13))] +opaque_struct!(pub PyMutex); + +#[cfg(any(all(Py_GIL_DISABLED, Py_3_13, not(Py_LIMITED_API)), Py_3_15,))] +#[repr(C)] +pub struct PyCriticalSection { + _cs_prev: usize, + _cs_mutex: *mut PyMutex, +} + +#[cfg(any(all(Py_GIL_DISABLED, Py_3_13, not(Py_LIMITED_API)), Py_3_15,))] +#[repr(C)] +pub struct PyCriticalSection2 { + _cs_base: PyCriticalSection, + _cs_mutex2: *mut PyMutex, +} + +#[cfg(all(not(Py_GIL_DISABLED), Py_3_13, not(Py_3_15), not(Py_LIMITED_API)))] +opaque_struct!(pub PyCriticalSection); +#[cfg(all(not(Py_GIL_DISABLED), Py_3_13, not(Py_3_15), not(Py_LIMITED_API)))] +opaque_struct!(pub PyCriticalSection2); + +#[cfg(any(all(Py_GIL_DISABLED, Py_3_13), Py_3_15))] +extern_libpython! { + pub fn PyCriticalSection_Begin(c: *mut PyCriticalSection, op: *mut PyObject); + pub fn PyCriticalSection_End(c: *mut PyCriticalSection); + pub fn PyCriticalSection2_Begin(c: *mut PyCriticalSection2, a: *mut PyObject, b: *mut PyObject); + pub fn PyCriticalSection2_End(c: *mut PyCriticalSection2); +} diff --git a/vendor/pyo3-ffi/src/datetime.rs b/vendor/pyo3-ffi/src/datetime.rs new file mode 100644 index 0000000..d202213 --- /dev/null +++ b/vendor/pyo3-ffi/src/datetime.rs @@ -0,0 +1,844 @@ +//! FFI bindings to the functions and structs defined in `datetime.h` +//! +//! This is the unsafe thin wrapper around the [CPython C API](https://docs.python.org/3/c-api/datetime.html), +//! and covers the various date and time related objects in the Python `datetime` +//! standard library module. + +#[cfg(not(PyPy))] +use crate::PyCapsule_Import; +#[cfg(GraalPy)] +use crate::{PyLong_AsLong, PyLong_Check, PyObject_GetAttrString, Py_DecRef}; +use crate::{PyObject, PyObject_TypeCheck, PyTypeObject, Py_IS_TYPE, Py_None}; +use core::ffi::c_char; +use core::ffi::c_int; +use core::ffi::CStr; +use core::ptr; +use core::sync::atomic::{AtomicPtr, Ordering}; +#[cfg(not(PyPy))] +use {crate::Py_hash_t, core::ffi::c_uchar}; +// Type struct wrappers +const _PyDateTime_DATE_DATASIZE: usize = 4; +const _PyDateTime_TIME_DATASIZE: usize = 6; +const _PyDateTime_DATETIME_DATASIZE: usize = 10; + +#[repr(C)] +#[derive(Debug)] +/// Structure representing a `datetime.timedelta`. +pub struct PyDateTime_Delta { + pub ob_base: PyObject, + #[cfg(not(PyPy))] + pub hashcode: Py_hash_t, + pub days: c_int, + pub seconds: c_int, + pub microseconds: c_int, +} + +#[repr(C)] +#[derive(Debug)] +pub struct PyDateTime_TZInfo { + pub ob_base: PyObject, +} + +// skipped non-limited _PyDateTime_BaseTZInfo + +#[cfg(not(any(PyPy, GraalPy)))] +#[repr(C)] +#[derive(Debug)] +/// Structure representing a `datetime.time` without a `tzinfo` member. +pub struct _PyDateTime_BaseTime { + pub ob_base: PyObject, + pub hashcode: Py_hash_t, + pub hastzinfo: c_char, + pub data: [c_uchar; _PyDateTime_TIME_DATASIZE], +} + +#[repr(C)] +#[derive(Debug)] +/// Structure representing a `datetime.time`. +pub struct PyDateTime_Time { + pub ob_base: PyObject, + #[cfg(not(PyPy))] + pub hashcode: Py_hash_t, + pub hastzinfo: c_char, + #[cfg(not(PyPy))] + pub data: [c_uchar; _PyDateTime_TIME_DATASIZE], + #[cfg(not(PyPy))] + pub fold: c_uchar, + /// # Safety + /// + /// Care should be taken when reading this field. If the time does not have a + /// tzinfo then CPython may allocate as a `_PyDateTime_BaseTime` without this field. + pub tzinfo: *mut PyObject, +} + +#[repr(C)] +#[derive(Debug)] +/// Structure representing a `datetime.date` +pub struct PyDateTime_Date { + pub ob_base: PyObject, + #[cfg(not(PyPy))] + pub hashcode: Py_hash_t, + #[cfg(not(PyPy))] + pub hastzinfo: c_char, + #[cfg(not(PyPy))] + pub data: [c_uchar; _PyDateTime_DATE_DATASIZE], +} + +#[cfg(not(any(PyPy, GraalPy)))] +#[repr(C)] +#[derive(Debug)] +/// Structure representing a `datetime.datetime` without a `tzinfo` member. +pub struct _PyDateTime_BaseDateTime { + pub ob_base: PyObject, + pub hashcode: Py_hash_t, + pub hastzinfo: c_char, + pub data: [c_uchar; _PyDateTime_DATETIME_DATASIZE], +} + +#[repr(C)] +#[derive(Debug)] +/// Structure representing a `datetime.datetime`. +pub struct PyDateTime_DateTime { + pub ob_base: PyObject, + #[cfg(not(PyPy))] + pub hashcode: Py_hash_t, + pub hastzinfo: c_char, + #[cfg(not(PyPy))] + pub data: [c_uchar; _PyDateTime_DATETIME_DATASIZE], + #[cfg(not(PyPy))] + pub fold: c_uchar, + /// # Safety + /// + /// Care should be taken when reading this field. If the time does not have a + /// tzinfo then CPython may allocate as a `_PyDateTime_BaseDateTime` without this field. + pub tzinfo: *mut PyObject, +} + +// skipped non-limited _PyDateTime_HAS_TZINFO + +// Accessor functions for PyDateTime_Date and PyDateTime_DateTime +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the year component of a `PyDateTime_Date` or `PyDateTime_DateTime`. +/// Returns a signed integer greater than 0. +pub unsafe fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int { + // This should work for Date or DateTime + let data = (*(o as *mut PyDateTime_Date)).data; + (c_int::from(data[0]) << 8) | c_int::from(data[1]) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the month component of a `PyDateTime_Date` or `PyDateTime_DateTime`. +/// Returns a signed integer in the range `[1, 12]`. +pub unsafe fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int { + let data = (*(o as *mut PyDateTime_Date)).data; + c_int::from(data[2]) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the day component of a `PyDateTime_Date` or `PyDateTime_DateTime`. +/// Returns a signed integer in the interval `[1, 31]`. +pub unsafe fn PyDateTime_GET_DAY(o: *mut PyObject) -> c_int { + let data = (*(o as *mut PyDateTime_Date)).data; + c_int::from(data[3]) +} + +// Accessor macros for times +#[cfg(not(any(PyPy, GraalPy)))] +macro_rules! _PyDateTime_GET_HOUR { + ($o: expr, $offset:expr) => { + c_int::from((*$o).data[$offset + 0]) + }; +} + +#[cfg(not(any(PyPy, GraalPy)))] +macro_rules! _PyDateTime_GET_MINUTE { + ($o: expr, $offset:expr) => { + c_int::from((*$o).data[$offset + 1]) + }; +} + +#[cfg(not(any(PyPy, GraalPy)))] +macro_rules! _PyDateTime_GET_SECOND { + ($o: expr, $offset:expr) => { + c_int::from((*$o).data[$offset + 2]) + }; +} + +#[cfg(not(any(PyPy, GraalPy)))] +macro_rules! _PyDateTime_GET_MICROSECOND { + ($o: expr, $offset:expr) => { + (c_int::from((*$o).data[$offset + 3]) << 16) + | (c_int::from((*$o).data[$offset + 4]) << 8) + | (c_int::from((*$o).data[$offset + 5])) + }; +} + +#[cfg(not(any(PyPy, GraalPy)))] +macro_rules! _PyDateTime_GET_FOLD { + ($o: expr) => { + (*$o).fold + }; +} + +#[cfg(not(any(PyPy, GraalPy)))] +macro_rules! _PyDateTime_GET_TZINFO { + ($o: expr) => { + if (*$o).hastzinfo != 0 { + (*$o).tzinfo + } else { + $crate::Py_None() + } + }; +} + +// Accessor functions for DateTime +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the hour component of a `PyDateTime_DateTime`. +/// Returns a signed integer in the interval `[0, 23]` +pub unsafe fn PyDateTime_DATE_GET_HOUR(o: *mut PyObject) -> c_int { + _PyDateTime_GET_HOUR!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the minute component of a `PyDateTime_DateTime`. +/// Returns a signed integer in the interval `[0, 59]` +pub unsafe fn PyDateTime_DATE_GET_MINUTE(o: *mut PyObject) -> c_int { + _PyDateTime_GET_MINUTE!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the second component of a `PyDateTime_DateTime`. +/// Returns a signed integer in the interval `[0, 59]` +pub unsafe fn PyDateTime_DATE_GET_SECOND(o: *mut PyObject) -> c_int { + _PyDateTime_GET_SECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the microsecond component of a `PyDateTime_DateTime`. +/// Returns a signed integer in the interval `[0, 999999]` +pub unsafe fn PyDateTime_DATE_GET_MICROSECOND(o: *mut PyObject) -> c_int { + _PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the fold component of a `PyDateTime_DateTime`. +/// Returns a signed integer in the interval `[0, 1]` +pub unsafe fn PyDateTime_DATE_GET_FOLD(o: *mut PyObject) -> c_uchar { + _PyDateTime_GET_FOLD!(o as *mut PyDateTime_DateTime) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the tzinfo component of a `PyDateTime_DateTime`. +/// Returns a pointer to a `PyObject` that should be either NULL or an instance +/// of a `datetime.tzinfo` subclass. +pub unsafe fn PyDateTime_DATE_GET_TZINFO(o: *mut PyObject) -> *mut PyObject { + _PyDateTime_GET_TZINFO!(o as *mut PyDateTime_DateTime) +} + +// Accessor functions for Time +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the hour component of a `PyDateTime_Time`. +/// Returns a signed integer in the interval `[0, 23]` +pub unsafe fn PyDateTime_TIME_GET_HOUR(o: *mut PyObject) -> c_int { + _PyDateTime_GET_HOUR!((o as *mut PyDateTime_Time), 0) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the minute component of a `PyDateTime_Time`. +/// Returns a signed integer in the interval `[0, 59]` +pub unsafe fn PyDateTime_TIME_GET_MINUTE(o: *mut PyObject) -> c_int { + _PyDateTime_GET_MINUTE!((o as *mut PyDateTime_Time), 0) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the second component of a `PyDateTime_DateTime`. +/// Returns a signed integer in the interval `[0, 59]` +pub unsafe fn PyDateTime_TIME_GET_SECOND(o: *mut PyObject) -> c_int { + _PyDateTime_GET_SECOND!((o as *mut PyDateTime_Time), 0) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the microsecond component of a `PyDateTime_DateTime`. +/// Returns a signed integer in the interval `[0, 999999]` +pub unsafe fn PyDateTime_TIME_GET_MICROSECOND(o: *mut PyObject) -> c_int { + _PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_Time), 0) +} + +#[cfg(not(any(PyPy, GraalPy)))] +#[inline] +/// Retrieve the fold component of a `PyDateTime_Time`. +/// Returns a signed integer in the interval `[0, 1]` +pub unsafe fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_uchar { + _PyDateTime_GET_FOLD!(o as *mut PyDateTime_Time) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the tzinfo component of a `PyDateTime_Time`. +/// Returns a pointer to a `PyObject` that should be either NULL or an instance +/// of a `datetime.tzinfo` subclass. +pub unsafe fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject { + _PyDateTime_GET_TZINFO!(o as *mut PyDateTime_Time) +} + +// Accessor functions +#[cfg(not(any(PyPy, GraalPy)))] +macro_rules! _access_field { + ($obj:expr, $type: ident, $field:ident) => { + (*($obj as *mut $type)).$field + }; +} + +// Accessor functions for PyDateTime_Delta +#[cfg(not(any(PyPy, GraalPy)))] +macro_rules! _access_delta_field { + ($obj:expr, $field:ident) => { + _access_field!($obj, PyDateTime_Delta, $field) + }; +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the days component of a `PyDateTime_Delta`. +/// +/// Returns a signed integer in the interval [-999999999, 999999999]. +/// +/// Note: This retrieves a component from the underlying structure, it is *not* +/// a representation of the total duration of the structure. +pub unsafe fn PyDateTime_DELTA_GET_DAYS(o: *mut PyObject) -> c_int { + _access_delta_field!(o, days) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the seconds component of a `PyDateTime_Delta`. +/// +/// Returns a signed integer in the interval [0, 86399]. +/// +/// Note: This retrieves a component from the underlying structure, it is *not* +/// a representation of the total duration of the structure. +pub unsafe fn PyDateTime_DELTA_GET_SECONDS(o: *mut PyObject) -> c_int { + _access_delta_field!(o, seconds) +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy)))] +/// Retrieve the seconds component of a `PyDateTime_Delta`. +/// +/// Returns a signed integer in the interval [0, 999999]. +/// +/// Note: This retrieves a component from the underlying structure, it is *not* +/// a representation of the total duration of the structure. +pub unsafe fn PyDateTime_DELTA_GET_MICROSECONDS(o: *mut PyObject) -> c_int { + _access_delta_field!(o, microseconds) +} + +// Accessor functions for GraalPy. The macros on GraalPy work differently, +// but copying them seems suboptimal +#[inline] +#[cfg(GraalPy)] +pub unsafe fn _get_attr(obj: *mut PyObject, field: &core::ffi::CStr) -> c_int { + let result = PyObject_GetAttrString(obj, field.as_ptr()); + Py_DecRef(result); // the original macros are borrowing + if PyLong_Check(result) == 1 { + PyLong_AsLong(result) as c_int + } else { + 0 + } +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int { + _get_attr(o, c"year") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int { + _get_attr(o, c"month") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_GET_DAY(o: *mut PyObject) -> c_int { + _get_attr(o, c"day") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_DATE_GET_HOUR(o: *mut PyObject) -> c_int { + _get_attr(o, c"hour") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_DATE_GET_MINUTE(o: *mut PyObject) -> c_int { + _get_attr(o, c"minute") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_DATE_GET_SECOND(o: *mut PyObject) -> c_int { + _get_attr(o, c"second") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_DATE_GET_MICROSECOND(o: *mut PyObject) -> c_int { + _get_attr(o, c"microsecond") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_DATE_GET_FOLD(o: *mut PyObject) -> c_int { + _get_attr(o, c"fold") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_DATE_GET_TZINFO(o: *mut PyObject) -> *mut PyObject { + let res = PyObject_GetAttrString(o, c"tzinfo".as_ptr().cast()); + Py_DecRef(res); // the original macros are borrowing + res +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_TIME_GET_HOUR(o: *mut PyObject) -> c_int { + _get_attr(o, c"hour") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_TIME_GET_MINUTE(o: *mut PyObject) -> c_int { + _get_attr(o, c"minute") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_TIME_GET_SECOND(o: *mut PyObject) -> c_int { + _get_attr(o, c"second") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_TIME_GET_MICROSECOND(o: *mut PyObject) -> c_int { + _get_attr(o, c"microsecond") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_int { + _get_attr(o, c"fold") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject { + let res = PyObject_GetAttrString(o, c"tzinfo".as_ptr().cast()); + Py_DecRef(res); // the original macros are borrowing + res +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_DELTA_GET_DAYS(o: *mut PyObject) -> c_int { + _get_attr(o, c"days") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_DELTA_GET_SECONDS(o: *mut PyObject) -> c_int { + _get_attr(o, c"seconds") +} + +#[inline] +#[cfg(GraalPy)] +pub unsafe fn PyDateTime_DELTA_GET_MICROSECONDS(o: *mut PyObject) -> c_int { + _get_attr(o, c"microseconds") +} + +#[cfg(PyPy)] +extern_libpython! { + // skipped _PyDateTime_HAS_TZINFO (not in PyPy) + #[link_name = "PyPyDateTime_GET_YEAR"] + pub fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int; + #[link_name = "PyPyDateTime_GET_MONTH"] + pub fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int; + #[link_name = "PyPyDateTime_GET_DAY"] + pub fn PyDateTime_GET_DAY(o: *mut PyObject) -> c_int; + + #[link_name = "PyPyDateTime_DATE_GET_HOUR"] + pub fn PyDateTime_DATE_GET_HOUR(o: *mut PyObject) -> c_int; + #[link_name = "PyPyDateTime_DATE_GET_MINUTE"] + pub fn PyDateTime_DATE_GET_MINUTE(o: *mut PyObject) -> c_int; + #[link_name = "PyPyDateTime_DATE_GET_SECOND"] + pub fn PyDateTime_DATE_GET_SECOND(o: *mut PyObject) -> c_int; + #[link_name = "PyPyDateTime_DATE_GET_MICROSECOND"] + pub fn PyDateTime_DATE_GET_MICROSECOND(o: *mut PyObject) -> c_int; + #[link_name = "PyPyDateTime_GET_FOLD"] + pub fn PyDateTime_DATE_GET_FOLD(o: *mut PyObject) -> c_int; + #[link_name = "PyPyDateTime_DATE_GET_TZINFO"] + #[cfg(Py_3_10)] + pub fn PyDateTime_DATE_GET_TZINFO(o: *mut PyObject) -> *mut PyObject; + + #[link_name = "PyPyDateTime_TIME_GET_HOUR"] + pub fn PyDateTime_TIME_GET_HOUR(o: *mut PyObject) -> c_int; + #[link_name = "PyPyDateTime_TIME_GET_MINUTE"] + pub fn PyDateTime_TIME_GET_MINUTE(o: *mut PyObject) -> c_int; + #[link_name = "PyPyDateTime_TIME_GET_SECOND"] + pub fn PyDateTime_TIME_GET_SECOND(o: *mut PyObject) -> c_int; + #[link_name = "PyPyDateTime_TIME_GET_MICROSECOND"] + pub fn PyDateTime_TIME_GET_MICROSECOND(o: *mut PyObject) -> c_int; + #[link_name = "PyPyDateTime_TIME_GET_FOLD"] + pub fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_int; + #[link_name = "PyPyDateTime_TIME_GET_TZINFO"] + #[cfg(Py_3_10)] + pub fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject; + + #[link_name = "PyPyDateTime_DELTA_GET_DAYS"] + pub fn PyDateTime_DELTA_GET_DAYS(o: *mut PyObject) -> c_int; + #[link_name = "PyPyDateTime_DELTA_GET_SECONDS"] + pub fn PyDateTime_DELTA_GET_SECONDS(o: *mut PyObject) -> c_int; + #[link_name = "PyPyDateTime_DELTA_GET_MICROSECONDS"] + pub fn PyDateTime_DELTA_GET_MICROSECONDS(o: *mut PyObject) -> c_int; +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct PyDateTime_CAPI { + pub DateType: *mut PyTypeObject, + pub DateTimeType: *mut PyTypeObject, + pub TimeType: *mut PyTypeObject, + pub DeltaType: *mut PyTypeObject, + pub TZInfoType: *mut PyTypeObject, + pub TimeZone_UTC: *mut PyObject, + pub Date_FromDate: unsafe extern "C" fn( + year: c_int, + month: c_int, + day: c_int, + cls: *mut PyTypeObject, + ) -> *mut PyObject, + pub DateTime_FromDateAndTime: unsafe extern "C" fn( + year: c_int, + month: c_int, + day: c_int, + hour: c_int, + minute: c_int, + second: c_int, + microsecond: c_int, + tzinfo: *mut PyObject, + cls: *mut PyTypeObject, + ) -> *mut PyObject, + pub Time_FromTime: unsafe extern "C" fn( + hour: c_int, + minute: c_int, + second: c_int, + microsecond: c_int, + tzinfo: *mut PyObject, + cls: *mut PyTypeObject, + ) -> *mut PyObject, + pub Delta_FromDelta: unsafe extern "C" fn( + days: c_int, + seconds: c_int, + microseconds: c_int, + normalize: c_int, + cls: *mut PyTypeObject, + ) -> *mut PyObject, + pub TimeZone_FromTimeZone: + unsafe extern "C" fn(offset: *mut PyObject, name: *mut PyObject) -> *mut PyObject, + + pub DateTime_FromTimestamp: unsafe extern "C" fn( + cls: *mut PyTypeObject, + args: *mut PyObject, + kwargs: *mut PyObject, + ) -> *mut PyObject, + pub Date_FromTimestamp: + unsafe extern "C" fn(cls: *mut PyTypeObject, args: *mut PyObject) -> *mut PyObject, + pub DateTime_FromDateAndTimeAndFold: unsafe extern "C" fn( + year: c_int, + month: c_int, + day: c_int, + hour: c_int, + minute: c_int, + second: c_int, + microsecond: c_int, + tzinfo: *mut PyObject, + fold: c_int, + cls: *mut PyTypeObject, + ) -> *mut PyObject, + pub Time_FromTimeAndFold: unsafe extern "C" fn( + hour: c_int, + minute: c_int, + second: c_int, + microsecond: c_int, + tzinfo: *mut PyObject, + fold: c_int, + cls: *mut PyTypeObject, + ) -> *mut PyObject, +} + +// SAFETY: Python already shares this object between threads, so it's no more evil for us to do it too! +unsafe impl Sync for PyDateTime_CAPI {} + +pub const PyDateTime_CAPSULE_NAME: &CStr = c"datetime.datetime_CAPI"; + +/// Returns a pointer to a `PyDateTime_CAPI` instance +/// +/// # Note +/// This function will return a null pointer until +/// `PyDateTime_IMPORT` is called +#[inline] +pub unsafe fn PyDateTimeAPI() -> *mut PyDateTime_CAPI { + PyDateTimeAPI_impl.load(Ordering::Acquire) +} + +/// Populates the `PyDateTimeAPI` object +pub unsafe fn PyDateTime_IMPORT() { + if PyDateTimeAPI_impl.load(Ordering::Relaxed).is_null() { + // PyPy expects the C-API to be initialized via PyDateTime_Import, so trying to use + // `PyCapsule_Import` will behave unexpectedly in pypy. + #[cfg(PyPy)] + let py_datetime_c_api = PyDateTime_Import(); + + #[cfg(not(PyPy))] + let py_datetime_c_api = + PyCapsule_Import(PyDateTime_CAPSULE_NAME.as_ptr(), 1) as *mut PyDateTime_CAPI; + + if py_datetime_c_api.is_null() { + return; + } + + // Protect against race conditions when the datetime API is concurrently + // initialized in multiple threads. + let _ = PyDateTimeAPI_impl.compare_exchange( + ptr::null_mut(), + py_datetime_c_api, + Ordering::Release, + Ordering::Relaxed, + ); + } +} + +#[inline] +pub unsafe fn PyDateTime_TimeZone_UTC() -> *mut PyObject { + (*PyDateTimeAPI()).TimeZone_UTC +} + +/// Type Check macros +/// +/// These are bindings around the C API typecheck macros, all of them return +/// `1` if True and `0` if False. In all type check macros, the argument (`op`) +/// must not be `NULL`. +#[inline] +/// Check if `op` is a `PyDateTimeAPI.DateType` or subtype. +pub unsafe fn PyDate_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, (*PyDateTimeAPI()).DateType) as c_int +} + +#[inline] +/// Check if `op`'s type is exactly `PyDateTimeAPI.DateType`. +pub unsafe fn PyDate_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, (*PyDateTimeAPI()).DateType) +} + +#[inline] +/// Check if `op` is a `PyDateTimeAPI.DateTimeType` or subtype. +pub unsafe fn PyDateTime_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, (*PyDateTimeAPI()).DateTimeType) as c_int +} + +#[inline] +/// Check if `op`'s type is exactly `PyDateTimeAPI.DateTimeType`. +pub unsafe fn PyDateTime_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, (*PyDateTimeAPI()).DateTimeType) +} + +#[inline] +/// Check if `op` is a `PyDateTimeAPI.TimeType` or subtype. +pub unsafe fn PyTime_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, (*PyDateTimeAPI()).TimeType) as c_int +} + +#[inline] +/// Check if `op`'s type is exactly `PyDateTimeAPI.TimeType`. +pub unsafe fn PyTime_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, (*PyDateTimeAPI()).TimeType) +} + +#[inline] +/// Check if `op` is a `PyDateTimeAPI.DetaType` or subtype. +pub unsafe fn PyDelta_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, (*PyDateTimeAPI()).DeltaType) as c_int +} + +#[inline] +/// Check if `op`'s type is exactly `PyDateTimeAPI.DeltaType`. +pub unsafe fn PyDelta_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, (*PyDateTimeAPI()).DeltaType) +} + +#[inline] +/// Check if `op` is a `PyDateTimeAPI.TZInfoType` or subtype. +pub unsafe fn PyTZInfo_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, (*PyDateTimeAPI()).TZInfoType) as c_int +} + +#[inline] +/// Check if `op`'s type is exactly `PyDateTimeAPI.TZInfoType`. +pub unsafe fn PyTZInfo_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, (*PyDateTimeAPI()).TZInfoType) +} + +pub unsafe fn PyDate_FromDate(year: c_int, month: c_int, day: c_int) -> *mut PyObject { + ((*PyDateTimeAPI()).Date_FromDate)(year, month, day, (*PyDateTimeAPI()).DateType) +} + +#[allow(clippy::too_many_arguments)] +/// See +pub unsafe fn PyDateTime_FromDateAndTime( + year: c_int, + month: c_int, + day: c_int, + hour: c_int, + minute: c_int, + second: c_int, + microsecond: c_int, +) -> *mut PyObject { + ((*PyDateTimeAPI()).DateTime_FromDateAndTime)( + year, + month, + day, + hour, + minute, + second, + microsecond, + Py_None(), + (*PyDateTimeAPI()).DateTimeType, + ) +} + +#[allow(clippy::too_many_arguments)] +/// See +pub unsafe fn PyDateTime_FromDateAndTimeAndFold( + year: c_int, + month: c_int, + day: c_int, + hour: c_int, + minute: c_int, + second: c_int, + microsecond: c_int, + fold: c_int, +) -> *mut PyObject { + ((*PyDateTimeAPI()).DateTime_FromDateAndTimeAndFold)( + year, + month, + day, + hour, + minute, + second, + microsecond, + Py_None(), + fold, + (*PyDateTimeAPI()).DateTimeType, + ) +} + +pub unsafe fn PyTime_FromTime( + hour: c_int, + minute: c_int, + second: c_int, + microsecond: c_int, +) -> *mut PyObject { + ((*PyDateTimeAPI()).Time_FromTime)( + hour, + minute, + second, + microsecond, + Py_None(), + (*PyDateTimeAPI()).TimeType, + ) +} + +pub unsafe fn PyTime_FromTimeAndFold( + hour: c_int, + minute: c_int, + second: c_int, + microsecond: c_int, + fold: c_int, +) -> *mut PyObject { + ((*PyDateTimeAPI()).Time_FromTimeAndFold)( + hour, + minute, + second, + microsecond, + Py_None(), + fold, + (*PyDateTimeAPI()).TimeType, + ) +} + +pub unsafe fn PyDelta_FromDSU(days: c_int, seconds: c_int, microseconds: c_int) -> *mut PyObject { + ((*PyDateTimeAPI()).Delta_FromDelta)( + days, + seconds, + microseconds, + 1, + (*PyDateTimeAPI()).DeltaType, + ) +} + +pub unsafe fn PyTimeZone_FromOffset(offset: *mut PyObject) -> *mut PyObject { + ((*PyDateTimeAPI()).TimeZone_FromTimeZone)(offset, core::ptr::null_mut()) +} + +pub unsafe fn PyTimeZone_FromOffsetAndName( + offset: *mut PyObject, + name: *mut PyObject, +) -> *mut PyObject { + ((*PyDateTimeAPI()).TimeZone_FromTimeZone)(offset, name) +} + +#[cfg(not(PyPy))] +pub unsafe fn PyDateTime_FromTimestamp(args: *mut PyObject) -> *mut PyObject { + let f = (*PyDateTimeAPI()).DateTime_FromTimestamp; + f((*PyDateTimeAPI()).DateTimeType, args, core::ptr::null_mut()) +} + +#[cfg(not(PyPy))] +pub unsafe fn PyDate_FromTimestamp(args: *mut PyObject) -> *mut PyObject { + let f = (*PyDateTimeAPI()).Date_FromTimestamp; + f((*PyDateTimeAPI()).DateType, args) +} + +#[cfg(PyPy)] +extern_libpython! { + #[link_name = "PyPyDate_FromTimestamp"] + pub fn PyDate_FromTimestamp(args: *mut PyObject) -> *mut PyObject; + #[link_name = "PyPyDateTime_FromTimestamp"] + pub fn PyDateTime_FromTimestamp(args: *mut PyObject) -> *mut PyObject; +} + +#[cfg(PyPy)] +extern_libpython! { + #[link_name = "_PyPyDateTime_Import"] + pub fn PyDateTime_Import() -> *mut PyDateTime_CAPI; +} + +// Rust specific implementation details + +static PyDateTimeAPI_impl: AtomicPtr = AtomicPtr::new(ptr::null_mut()); diff --git a/vendor/pyo3-ffi/src/descrobject.rs b/vendor/pyo3-ffi/src/descrobject.rs new file mode 100644 index 0000000..cd65e7b --- /dev/null +++ b/vendor/pyo3-ffi/src/descrobject.rs @@ -0,0 +1,133 @@ +use crate::methodobject::PyMethodDef; +use crate::object::{PyObject, PyTypeObject}; +use crate::Py_ssize_t; +use core::ffi::{c_char, c_int, c_void}; +use core::ptr; + +pub type getter = unsafe extern "C" fn(slf: *mut PyObject, closure: *mut c_void) -> *mut PyObject; +pub type setter = + unsafe extern "C" fn(slf: *mut PyObject, value: *mut PyObject, closure: *mut c_void) -> c_int; + +/// Represents the [PyGetSetDef](https://docs.python.org/3/c-api/structures.html#c.PyGetSetDef) +/// structure. +/// +/// Note that CPython may leave fields uninitialized. You must ensure that +/// `name` != NULL before dereferencing or reading other fields. +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct PyGetSetDef { + pub name: *const c_char, + pub get: Option, + pub set: Option, + pub doc: *const c_char, + pub closure: *mut c_void, +} + +impl Default for PyGetSetDef { + fn default() -> PyGetSetDef { + PyGetSetDef { + name: ptr::null(), + get: None, + set: None, + doc: ptr::null(), + closure: ptr::null_mut(), + } + } +} + +#[cfg(not(RustPython))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyClassMethodDescr_Type")] + pub static mut PyClassMethodDescr_Type: PyTypeObject; + #[cfg_attr(PyPy, link_name = "PyPyGetSetDescr_Type")] + pub static mut PyGetSetDescr_Type: PyTypeObject; + #[cfg_attr(PyPy, link_name = "PyPyMemberDescr_Type")] + pub static mut PyMemberDescr_Type: PyTypeObject; + #[cfg_attr(PyPy, link_name = "PyPyMethodDescr_Type")] + pub static mut PyMethodDescr_Type: PyTypeObject; + #[cfg_attr(PyPy, link_name = "PyPyWrapperDescr_Type")] + pub static mut PyWrapperDescr_Type: PyTypeObject; + #[cfg_attr(PyPy, link_name = "PyPyDictProxy_Type")] + pub static mut PyDictProxy_Type: PyTypeObject; + #[cfg_attr(PyPy, link_name = "PyPyProperty_Type")] + pub static mut PyProperty_Type: PyTypeObject; +} + +extern_libpython! { + pub fn PyDescr_NewMethod(arg1: *mut PyTypeObject, arg2: *mut PyMethodDef) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyDescr_NewClassMethod")] + pub fn PyDescr_NewClassMethod(arg1: *mut PyTypeObject, arg2: *mut PyMethodDef) + -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyDescr_NewMember")] + pub fn PyDescr_NewMember(arg1: *mut PyTypeObject, arg2: *mut PyMemberDef) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyDescr_NewGetSet")] + pub fn PyDescr_NewGetSet(arg1: *mut PyTypeObject, arg2: *mut PyGetSetDef) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyDictProxy_New")] + pub fn PyDictProxy_New(arg1: *mut PyObject) -> *mut PyObject; + pub fn PyWrapper_New(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject; +} + +/// Represents the [PyMemberDef](https://docs.python.org/3/c-api/structures.html#c.PyMemberDef) +/// structure. +/// +/// Note that CPython may leave fields uninitialized. You must always ensure that +/// `name` != NULL before dereferencing or reading other fields. +#[repr(C)] +#[derive(Copy, Clone, Eq, PartialEq)] +pub struct PyMemberDef { + pub name: *const c_char, + pub type_code: c_int, + pub offset: Py_ssize_t, + pub flags: c_int, + pub doc: *const c_char, +} + +impl Default for PyMemberDef { + fn default() -> PyMemberDef { + PyMemberDef { + name: ptr::null_mut(), + type_code: 0, + offset: 0, + flags: 0, + doc: ptr::null_mut(), + } + } +} + +/* Types */ +pub const Py_T_SHORT: c_int = 0; +pub const Py_T_INT: c_int = 1; +pub const Py_T_LONG: c_int = 2; +pub const Py_T_FLOAT: c_int = 3; +pub const Py_T_DOUBLE: c_int = 4; +pub const Py_T_STRING: c_int = 5; +#[deprecated(note = "Use Py_T_OBJECT_EX instead")] +pub const _Py_T_OBJECT: c_int = 6; +pub const Py_T_CHAR: c_int = 7; +pub const Py_T_BYTE: c_int = 8; +pub const Py_T_UBYTE: c_int = 9; +pub const Py_T_USHORT: c_int = 10; +pub const Py_T_UINT: c_int = 11; +pub const Py_T_ULONG: c_int = 12; +pub const Py_T_STRING_INPLACE: c_int = 13; +pub const Py_T_BOOL: c_int = 14; +pub const Py_T_OBJECT_EX: c_int = 16; +pub const Py_T_LONGLONG: c_int = 17; +pub const Py_T_ULONGLONG: c_int = 18; +pub const Py_T_PYSSIZET: c_int = 19; +#[deprecated(note = "Value is always none")] +pub const _Py_T_NONE: c_int = 20; + +/* Flags */ +pub const Py_READONLY: c_int = 1; +#[cfg(Py_3_10)] +pub const Py_AUDIT_READ: c_int = 2; // Added in 3.10, harmless no-op before that +#[deprecated] +pub const _Py_WRITE_RESTRICTED: c_int = 4; // Deprecated, no-op. Do not reuse the value. +pub const Py_RELATIVE_OFFSET: c_int = 8; + +extern_libpython! { + pub fn PyMember_GetOne(addr: *const c_char, l: *mut PyMemberDef) -> *mut PyObject; + pub fn PyMember_SetOne(addr: *mut c_char, l: *mut PyMemberDef, value: *mut PyObject) -> c_int; +} diff --git a/vendor/pyo3-ffi/src/dictobject.rs b/vendor/pyo3-ffi/src/dictobject.rs new file mode 100644 index 0000000..fec8f45 --- /dev/null +++ b/vendor/pyo3-ffi/src/dictobject.rs @@ -0,0 +1,150 @@ +use crate::object::*; +use crate::pyport::Py_ssize_t; +use core::ffi::{c_char, c_int}; + +#[cfg(not(RustPython))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyDict_Type")] + pub static mut PyDict_Type: PyTypeObject; +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyDict_Check(op: *mut PyObject) -> c_int { + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyDict_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyDict_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PyDict_Check(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyDict_CheckExact(op: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPyDict_New")] + pub fn PyDict_New() -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyDict_GetItem")] + pub fn PyDict_GetItem(mp: *mut PyObject, key: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyDict_GetItemWithError")] + pub fn PyDict_GetItemWithError(mp: *mut PyObject, key: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyDict_SetItem")] + pub fn PyDict_SetItem(mp: *mut PyObject, key: *mut PyObject, item: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyDict_DelItem")] + pub fn PyDict_DelItem(mp: *mut PyObject, key: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyDict_Clear")] + pub fn PyDict_Clear(mp: *mut PyObject); + #[cfg_attr(PyPy, link_name = "PyPyDict_Next")] + pub fn PyDict_Next( + mp: *mut PyObject, + pos: *mut Py_ssize_t, + key: *mut *mut PyObject, + value: *mut *mut PyObject, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyDict_Keys")] + pub fn PyDict_Keys(mp: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyDict_Values")] + pub fn PyDict_Values(mp: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyDict_Items")] + pub fn PyDict_Items(mp: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyDict_Size")] + pub fn PyDict_Size(mp: *mut PyObject) -> Py_ssize_t; + #[cfg_attr(PyPy, link_name = "PyPyDict_Copy")] + pub fn PyDict_Copy(mp: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyDict_Contains")] + pub fn PyDict_Contains(mp: *mut PyObject, key: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyDict_Update")] + pub fn PyDict_Update(mp: *mut PyObject, other: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyDict_Merge")] + pub fn PyDict_Merge(mp: *mut PyObject, other: *mut PyObject, _override: c_int) -> c_int; + pub fn PyDict_MergeFromSeq2(d: *mut PyObject, seq2: *mut PyObject, _override: c_int) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyDict_GetItemString")] + pub fn PyDict_GetItemString(dp: *mut PyObject, key: *const c_char) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyDict_SetItemString")] + pub fn PyDict_SetItemString( + dp: *mut PyObject, + key: *const c_char, + item: *mut PyObject, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyDict_DelItemString")] + pub fn PyDict_DelItemString(dp: *mut PyObject, key: *const c_char) -> c_int; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyDict_GetItemRef")] + pub fn PyDict_GetItemRef( + dp: *mut PyObject, + key: *mut PyObject, + result: *mut *mut PyObject, + ) -> c_int; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyDict_GetItemStringRef")] + pub fn PyDict_GetItemStringRef( + dp: *mut PyObject, + key: *const c_char, + result: *mut *mut PyObject, + ) -> c_int; + #[cfg(all(Py_3_13, any(not(Py_LIMITED_API), Py_3_15)))] + pub fn PyDict_SetDefaultRef( + mp: *mut PyObject, + key: *mut PyObject, + default_value: *mut PyObject, + result: *mut *mut PyObject, + ) -> c_int; + // skipped 3.10 / ex-non-limited PyObject_GenericGetDict +} + +#[cfg(not(RustPython))] +extern_libpython! { + pub static mut PyDictKeys_Type: PyTypeObject; + pub static mut PyDictValues_Type: PyTypeObject; + pub static mut PyDictItems_Type: PyTypeObject; +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyDictKeys_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, &raw mut PyDictKeys_Type) +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyDictValues_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, &raw mut PyDictValues_Type) +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyDictItems_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, &raw mut PyDictItems_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PyDictKeys_Check(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyDictValues_Check(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyDictItems_Check(op: *mut PyObject) -> c_int; +} + +#[inline] +pub unsafe fn PyDictViewSet_Check(op: *mut PyObject) -> c_int { + (PyDictKeys_Check(op) != 0 || PyDictItems_Check(op) != 0) as c_int +} + +#[cfg(not(RustPython))] +extern_libpython! { + pub static mut PyDictIterKey_Type: PyTypeObject; + pub static mut PyDictIterValue_Type: PyTypeObject; + pub static mut PyDictIterItem_Type: PyTypeObject; + pub static mut PyDictRevIterKey_Type: PyTypeObject; + pub static mut PyDictRevIterValue_Type: PyTypeObject; + pub static mut PyDictRevIterItem_Type: PyTypeObject; +} + +#[cfg(any(GraalPy, Py_LIMITED_API))] +// TODO: remove (see https://github.com/PyO3/pyo3/pull/1341#issuecomment-751515985) +opaque_struct!(pub PyDictObject); diff --git a/vendor/pyo3-ffi/src/enumobject.rs b/vendor/pyo3-ffi/src/enumobject.rs new file mode 100644 index 0000000..cd2ba09 --- /dev/null +++ b/vendor/pyo3-ffi/src/enumobject.rs @@ -0,0 +1,6 @@ +use crate::object::PyTypeObject; + +extern_libpython! { + pub static mut PyEnum_Type: PyTypeObject; + pub static mut PyReversed_Type: PyTypeObject; +} diff --git a/vendor/pyo3-ffi/src/fileobject.rs b/vendor/pyo3-ffi/src/fileobject.rs new file mode 100644 index 0000000..537e998 --- /dev/null +++ b/vendor/pyo3-ffi/src/fileobject.rs @@ -0,0 +1,37 @@ +use crate::object::PyObject; +use core::ffi::{c_char, c_int}; + +pub const PY_STDIOTEXTMODE: &str = "b"; + +extern_libpython! { + pub fn PyFile_FromFd( + arg1: c_int, + arg2: *const c_char, + arg3: *const c_char, + arg4: c_int, + arg5: *const c_char, + arg6: *const c_char, + arg7: *const c_char, + arg8: c_int, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyFile_GetLine")] + pub fn PyFile_GetLine(arg1: *mut PyObject, arg2: c_int) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyFile_WriteObject")] + pub fn PyFile_WriteObject(arg1: *mut PyObject, arg2: *mut PyObject, arg3: c_int) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyFile_WriteString")] + pub fn PyFile_WriteString(arg1: *const c_char, arg2: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyFile_AsFileDescriptor")] + pub fn PyObject_AsFileDescriptor(arg1: *mut PyObject) -> c_int; +} + +extern_libpython! { + #[deprecated(note = "Python 3.12")] + pub static mut Py_FileSystemDefaultEncoding: *const c_char; + #[deprecated(note = "Python 3.12")] + pub static mut Py_FileSystemDefaultEncodeErrors: *const c_char; + #[deprecated(note = "Python 3.12")] + pub static mut Py_HasFileSystemDefaultEncoding: c_int; + // skipped 3.12-deprecated Py_UTF8Mode +} + +// skipped _PyIsSelectable_fd diff --git a/vendor/pyo3-ffi/src/fileutils.rs b/vendor/pyo3-ffi/src/fileutils.rs new file mode 100644 index 0000000..c80570c --- /dev/null +++ b/vendor/pyo3-ffi/src/fileutils.rs @@ -0,0 +1,9 @@ +use crate::pyport::Py_ssize_t; +use core::ffi::c_char; +use libc::wchar_t; + +extern_libpython! { + pub fn Py_DecodeLocale(arg1: *const c_char, size: *mut Py_ssize_t) -> *mut wchar_t; + + pub fn Py_EncodeLocale(text: *const wchar_t, error_pos: *mut Py_ssize_t) -> *mut c_char; +} diff --git a/vendor/pyo3-ffi/src/floatobject.rs b/vendor/pyo3-ffi/src/floatobject.rs new file mode 100644 index 0000000..5597d6d --- /dev/null +++ b/vendor/pyo3-ffi/src/floatobject.rs @@ -0,0 +1,53 @@ +use crate::object::*; +use core::ffi::{c_double, c_int}; + +#[cfg(Py_LIMITED_API)] +// TODO: remove (see https://github.com/PyO3/pyo3/pull/1341#issuecomment-751515985) +opaque_struct!(pub PyFloatObject); + +extern_libpython! { + #[cfg(not(RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyFloat_Type")] + pub static mut PyFloat_Type: PyTypeObject; + + #[cfg(RustPython)] + pub fn PyFloat_Check(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyFloat_CheckExact(op: *mut PyObject) -> c_int; +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyFloat_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, &raw mut PyFloat_Type) +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyFloat_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyFloat_Type) +} + +// skipped Py_RETURN_NAN +// skipped Py_RETURN_INF + +extern_libpython! { + pub fn PyFloat_GetMax() -> c_double; + pub fn PyFloat_GetMin() -> c_double; + pub fn PyFloat_GetInfo() -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyFloat_FromString")] + pub fn PyFloat_FromString(arg1: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyFloat_FromDouble")] + pub fn PyFloat_FromDouble(arg1: c_double) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyFloat_AsDouble")] + pub fn PyFloat_AsDouble(arg1: *mut PyObject) -> c_double; +} + +// skipped non-limited _PyFloat_Pack2 +// skipped non-limited _PyFloat_Pack4 +// skipped non-limited _PyFloat_Pack8 +// skipped non-limited _PyFloat_Unpack2 +// skipped non-limited _PyFloat_Unpack4 +// skipped non-limited _PyFloat_Unpack8 +// skipped non-limited _PyFloat_DebugMallocStats +// skipped non-limited _PyFloat_FormatAdvancedWriter diff --git a/vendor/pyo3-ffi/src/genericaliasobject.rs b/vendor/pyo3-ffi/src/genericaliasobject.rs new file mode 100644 index 0000000..ccd9678 --- /dev/null +++ b/vendor/pyo3-ffi/src/genericaliasobject.rs @@ -0,0 +1,13 @@ +#[cfg(Py_3_9)] +use crate::PyObject; +#[cfg(all(Py_3_9, not(RustPython)))] +use crate::PyTypeObject; + +extern_libpython! { + #[cfg(Py_3_9)] + #[cfg_attr(PyPy, link_name = "PyPy_GenericAlias")] + pub fn Py_GenericAlias(origin: *mut PyObject, args: *mut PyObject) -> *mut PyObject; + + #[cfg(all(Py_3_9, not(RustPython)))] + pub static mut Py_GenericAliasType: PyTypeObject; +} diff --git a/vendor/pyo3-ffi/src/impl_/macros.rs b/vendor/pyo3-ffi/src/impl_/macros.rs new file mode 100644 index 0000000..1ef2ce9 --- /dev/null +++ b/vendor/pyo3-ffi/src/impl_/macros.rs @@ -0,0 +1,306 @@ +// On x86 Windows, `raw-dylib` with `import_name_type = "undecorated"` removes the +// leading cdecl underscore from function names. This is expected behavior for +// `import_name_type = "undecorated"` (not a rustc bug): it strips the cdecl `_` +// prefix, which collides with symbols whose real names start with `_Py`. +// See https://doc.rust-lang.org/reference/items/external-blocks.html#the-import_name_type-key +// +// That matches ordinary `Py_*` exports, but it breaks CPython's internal `_Py*` +// function exports whose real DLL names already start with an underscore. For +// those functions, ask rustc for one extra underscore so that x86 undecoration +// lands back on CPython's export. +// +// Variables are intentionally excluded here: `import_name_type` does not affect +// variable imports, so `_Py_*` statics continue to work without any rewriting. +#[allow(unused_macros, reason = "used indirectly by extern_libpython_item!")] +macro_rules! extern_libpython_cpython_private_fn { + ($(#[$attrs:meta])* $vis:vis $name:ident($($args:tt)*) $(-> $ret:ty)?) => { + #[cfg_attr( + all(windows, target_arch = "x86", not(any(PyPy, GraalPy))), + link_name = concat!("_", stringify!($name)) + )] + $(#[$attrs])* + $vis fn $name($($args)*) $(-> $ret)?; + }; +} + +// Keep this list in sync with `_Py*` function imports declared through +// `extern_libpython!`. The x86 workaround only needs to apply to functions: +// statics keep their original names even when `import_name_type` is set. Match +// by name only here so the function signature stays in a single generic arm. +// +// TODO: reduce the number of `_Py*` exports from pyo3-ffi over time — the fewer +// CPython-private functions we expose, the smaller this workaround list becomes. +#[allow(unused_macros, reason = "used indirectly by extern_libpython_item!")] +macro_rules! extern_libpython_maybe_private_fn { + ( + [_PyObject_CallFunction_SizeT] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_PyObject_MakeTpCall] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_Py_CheckFunctionResult] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_PyBytes_Resize] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_PyLong_AsByteArray] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_PyLong_FromByteArray] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_PyUnicode_Ready] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_PyUnicode_ToDecimalDigit] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_PyThreadState_UncheckedGet] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_PyObject_GC_New] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_PyObject_GC_NewVar] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_PyObject_GC_Resize] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_PyObject_New] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_PyObject_NewVar] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_Py_HashBytes] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_Py_DECREF_DecRefTotal] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_Py_Dealloc] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_Py_DecRef] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_Py_INCREF_IncRefTotal] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_Py_IncRef] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_Py_NegativeRefcount] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [_PyErr_BadInternalCall] + $(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? } + }; + ( + [$name:ident] + $(#[$attrs:meta])* $vis:vis fn $fn_name:ident($($args:tt)*) $(-> $ret:ty)? + ) => { + $(#[$attrs])* + $vis fn $fn_name($($args)*) $(-> $ret)?; + }; +} + +macro_rules! extern_libpython_item { + ($(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?) => { + extern_libpython_maybe_private_fn! { + [$name] + $(#[$attrs])* + $vis fn $name($($args)*) $(-> $ret)? + } + }; + ($(#[$attrs:meta])* $vis:vis static mut $name:ident: $ty:ty) => { + $(#[$attrs])* + $vis static mut $name: $ty; + }; + ($(#[$attrs:meta])* $vis:vis static $name:ident: $ty:ty) => { + $(#[$attrs])* + $vis static $name: $ty; + }; +} + +macro_rules! extern_libpython_items { + () => {}; + ( + $(#[$attrs:meta])* + $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?; + $($rest:tt)* + ) => { + extern_libpython_item! { + $(#[$attrs])* + $vis fn $name($($args)*) $(-> $ret)? + } + extern_libpython_items! { $($rest)* } + }; + ( + $(#[$attrs:meta])* + $vis:vis static mut $name:ident: $ty:ty; + $($rest:tt)* + ) => { + extern_libpython_item! { + $(#[$attrs])* + $vis static mut $name: $ty + } + extern_libpython_items! { $($rest)* } + }; + ( + $(#[$attrs:meta])* + $vis:vis static $name:ident: $ty:ty; + $($rest:tt)* + ) => { + extern_libpython_item! { + $(#[$attrs])* + $vis static $name: $ty + } + extern_libpython_items! { $($rest)* } + }; +} + +/// Helper macro to declare `extern` blocks that link against libpython on Windows +/// using `raw-dylib`, eliminating the need for import libraries. +/// +/// The build script sets a `pyo3_dll` cfg value to the target DLL name (e.g. `python312`), +/// and this macro expands to the appropriate `#[link(name = "...", kind = "raw-dylib")]` +/// attribute for that DLL. +/// +/// # Usage +/// +/// ```rust,ignore +/// // Default ABI "C" (most common): +/// extern_libpython! { +/// pub fn PyObject_Call( +/// callable: *mut PyObject, +/// args: *mut PyObject, +/// kwargs: *mut PyObject, +/// ) -> *mut PyObject; +/// } +/// +/// // Explicit ABI: +/// extern_libpython! { "C-unwind" { +/// pub fn PyGILState_Ensure() -> PyGILState_STATE; +/// }} +/// ``` +macro_rules! extern_libpython { + // Explicit ABI + ($abi:literal { $($body:tt)* }) => { + extern_libpython!(@impl $abi { $($body)* } + // abi3 + "python3", "python3_d", + // abi3t + "python3t", "python3t_d", + // Python 3.8 - 3.15 + "python38", "python38_d", + "python39", "python39_d", + "python310", "python310_d", + "python311", "python311_d", + "python312", "python312_d", + "python313", "python313_d", + "python314", "python314_d", + "python315", "python315_d", + "python316", "python316_d", + // free-threaded builds (3.13+) + "python313t", "python313t_d", + "python314t", "python314t_d", + "python315t", "python315t_d", + "python316t", "python316t_d", + // PyPy (DLL is libpypy3.X-c.dll, not pythonXY.dll) + "libpypy3.11-c", + ); + }; + // Internal: generate cfg_attr for each DLL name. One of these will be selected + // by `pyo3-ffi`'s `build.rs`. + // + // On x86 Windows, Python DLLs export undecorated symbol names (no leading + // underscore), but the default for raw-dylib on x86 is fully-decorated + // (cdecl adds a `_` prefix). We use `import_name_type = "undecorated"` to + // match. The `import_name_type` key is only valid on x86, so we need + // separate cfg_attr arms per architecture. + (@impl $abi:literal { $($body:tt)* } $($dll:literal),* $(,)?) => { + $( + #[cfg_attr(all(windows, pyo3_use_raw_dylib, target_arch = "x86", pyo3_dll = $dll), + link(name = $dll, kind = "raw-dylib", import_name_type = "undecorated"))] + #[cfg_attr(all(windows, pyo3_use_raw_dylib, not(target_arch = "x86"), pyo3_dll = $dll), + link(name = $dll, kind = "raw-dylib"))] + )* + #[cfg_attr(all(windows, not(pyo3_use_raw_dylib)), link(name = "pythonXY"))] + extern $abi { + extern_libpython_items! { $($body)* } + } + }; + // Default ABI: "C" + ($($body:tt)*) => { + extern_libpython!("C" { $($body)* }); + }; +} diff --git a/vendor/pyo3-ffi/src/impl_/mod.rs b/vendor/pyo3-ffi/src/impl_/mod.rs new file mode 100644 index 0000000..189dec9 --- /dev/null +++ b/vendor/pyo3-ffi/src/impl_/mod.rs @@ -0,0 +1,35 @@ +#[cfg(all(Py_GIL_DISABLED, not(Py_LIMITED_API)))] +mod atomic_c_ulong { + pub struct GetAtomicCULong(); + + pub trait AtomicCULongType { + type Type; + } + impl AtomicCULongType for GetAtomicCULong<32> { + type Type = core::sync::atomic::AtomicU32; + } + impl AtomicCULongType for GetAtomicCULong<64> { + type Type = core::sync::atomic::AtomicU64; + } + + pub type TYPE = + () * 8 }> as AtomicCULongType>::Type; +} + +/// Typedef for an atomic integer to match the platform-dependent c_ulong type. +#[cfg(all(Py_GIL_DISABLED, not(Py_LIMITED_API)))] +#[doc(hidden)] +pub type AtomicCULong = atomic_c_ulong::TYPE; + +/// Guard to hang the current thread indefinitely when dropped. +#[cfg(not(any(Py_3_14, target_arch = "wasm32")))] +pub struct HangThread; + +#[cfg(not(any(Py_3_14, target_arch = "wasm32")))] +impl Drop for HangThread { + fn drop(&mut self) { + loop { + std::thread::park(); // Block forever. + } + } +} diff --git a/vendor/pyo3-ffi/src/import.rs b/vendor/pyo3-ffi/src/import.rs new file mode 100644 index 0000000..974083c --- /dev/null +++ b/vendor/pyo3-ffi/src/import.rs @@ -0,0 +1,87 @@ +use crate::object::PyObject; +use core::ffi::{c_char, c_int, c_long}; + +extern_libpython! { + pub fn PyImport_GetMagicNumber() -> c_long; + pub fn PyImport_GetMagicTag() -> *const c_char; + #[cfg_attr(PyPy, link_name = "PyPyImport_ExecCodeModule")] + pub fn PyImport_ExecCodeModule(name: *const c_char, co: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyImport_ExecCodeModuleEx")] + pub fn PyImport_ExecCodeModuleEx( + name: *const c_char, + co: *mut PyObject, + pathname: *const c_char, + ) -> *mut PyObject; + pub fn PyImport_ExecCodeModuleWithPathnames( + name: *const c_char, + co: *mut PyObject, + pathname: *const c_char, + cpathname: *const c_char, + ) -> *mut PyObject; + pub fn PyImport_ExecCodeModuleObject( + name: *mut PyObject, + co: *mut PyObject, + pathname: *mut PyObject, + cpathname: *mut PyObject, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyImport_GetModuleDict")] + pub fn PyImport_GetModuleDict() -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyImport_GetModule")] + pub fn PyImport_GetModule(name: *mut PyObject) -> *mut PyObject; + pub fn PyImport_AddModuleObject(name: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyImport_AddModule")] + pub fn PyImport_AddModule(name: *const c_char) -> *mut PyObject; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyImport_AddModuleRef")] + pub fn PyImport_AddModuleRef(name: *const c_char) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyImport_ImportModule")] + pub fn PyImport_ImportModule(name: *const c_char) -> *mut PyObject; + #[cfg(not(Py_3_15))] + #[deprecated(note = "Python 3.13")] + #[cfg_attr(PyPy, link_name = "PyPyImport_ImportModuleNoBlock")] + pub fn PyImport_ImportModuleNoBlock(name: *const c_char) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyImport_ImportModuleLevel")] + pub fn PyImport_ImportModuleLevel( + name: *const c_char, + globals: *mut PyObject, + locals: *mut PyObject, + fromlist: *mut PyObject, + level: c_int, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyImport_ImportModuleLevelObject")] + pub fn PyImport_ImportModuleLevelObject( + name: *mut PyObject, + globals: *mut PyObject, + locals: *mut PyObject, + fromlist: *mut PyObject, + level: c_int, + ) -> *mut PyObject; +} + +#[inline] +pub unsafe fn PyImport_ImportModuleEx( + name: *const c_char, + globals: *mut PyObject, + locals: *mut PyObject, + fromlist: *mut PyObject, +) -> *mut PyObject { + PyImport_ImportModuleLevel(name, globals, locals, fromlist, 0) +} + +extern_libpython! { + pub fn PyImport_GetImporter(path: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyImport_Import")] + pub fn PyImport_Import(name: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyImport_ReloadModule")] + pub fn PyImport_ReloadModule(m: *mut PyObject) -> *mut PyObject; + #[cfg(not(Py_3_9))] + #[deprecated(note = "Removed in Python 3.9 as it was \"For internal use only\".")] + pub fn PyImport_Cleanup(); + pub fn PyImport_ImportFrozenModuleObject(name: *mut PyObject) -> c_int; + pub fn PyImport_ImportFrozenModule(name: *const c_char) -> c_int; + + pub fn PyImport_AppendInittab( + name: *const c_char, + initfunc: Option *mut PyObject>, + ) -> c_int; +} diff --git a/vendor/pyo3-ffi/src/intrcheck.rs b/vendor/pyo3-ffi/src/intrcheck.rs new file mode 100644 index 0000000..32702d1 --- /dev/null +++ b/vendor/pyo3-ffi/src/intrcheck.rs @@ -0,0 +1,19 @@ +use core::ffi::c_int; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyOS_InterruptOccurred")] + pub fn PyOS_InterruptOccurred() -> c_int; + #[cfg(not(Py_3_10))] + #[deprecated(note = "Not documented in Python API; see Python 3.10 release notes")] + pub fn PyOS_InitInterrupts(); + + pub fn PyOS_BeforeFork(); + pub fn PyOS_AfterFork_Parent(); + pub fn PyOS_AfterFork_Child(); + #[deprecated(note = "use PyOS_AfterFork_Child instead")] + #[cfg_attr(PyPy, link_name = "PyPyOS_AfterFork")] + pub fn PyOS_AfterFork(); + + // skipped non-limited _PyOS_IsMainThread + // skipped non-limited Windows _PyOS_SigintEvent +} diff --git a/vendor/pyo3-ffi/src/iterobject.rs b/vendor/pyo3-ffi/src/iterobject.rs new file mode 100644 index 0000000..4236a6b --- /dev/null +++ b/vendor/pyo3-ffi/src/iterobject.rs @@ -0,0 +1,36 @@ +use crate::object::*; +use core::ffi::c_int; + +#[cfg(not(RustPython))] +extern_libpython! { + pub static mut PySeqIter_Type: PyTypeObject; + pub static mut PyCallIter_Type: PyTypeObject; +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PySeqIter_Check(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PySeqIter_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PySeqIter_Check(op: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPySeqIter_New")] + pub fn PySeqIter_New(arg1: *mut PyObject) -> *mut PyObject; +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyCallIter_Check(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyCallIter_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PyCallIter_Check(op: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPyCallIter_New")] + pub fn PyCallIter_New(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject; +} diff --git a/vendor/pyo3-ffi/src/lib.rs b/vendor/pyo3-ffi/src/lib.rs new file mode 100644 index 0000000..df977a4 --- /dev/null +++ b/vendor/pyo3-ffi/src/lib.rs @@ -0,0 +1,609 @@ +#![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] +//! Raw FFI declarations for Python's C API. +//! +//! PyO3 can be used to write native Python modules or run Python code and modules from Rust. +//! +//! This crate just provides low level bindings to the Python interpreter. +//! It is meant for advanced users only - regular PyO3 users shouldn't +//! need to interact with this crate at all. +//! +//! The contents of this crate are not documented here, as it would entail +//! basically copying the documentation from CPython. Consult the [Python/C API Reference +//! Manual][capi] for up-to-date documentation. +//! +//! # Safety +//! +//! The functions in this crate lack individual safety documentation, but +//! generally the following apply: +//! - Pointer arguments have to point to a valid Python object of the correct type, +//! although null pointers are sometimes valid input. +//! - The vast majority can only be used safely while the thread is attached to the Python interpreter. +//! - Some functions have additional safety requirements, consult the +//! [Python/C API Reference Manual][capi] +//! for more information. +//! +//! +//! # Feature flags +//! +//! PyO3 uses [feature flags] to enable you to opt-in to additional functionality. For a detailed +//! description, see the [Features chapter of the guide]. +//! +//! ## Optional feature flags +//! +//! The following features customize PyO3's behavior: +//! +//! - `abi3`: Restricts PyO3's API to a subset of the full Python API which is guaranteed by +//! [PEP 384] to be forward-compatible with future Python versions. +//! +//! ## `rustc` environment flags +//! +//! PyO3 uses `rustc`'s `--cfg` flags to enable or disable code used for different Python versions. +//! If you want to do this for your own crate, you can do so with the [`pyo3-build-config`] crate. +//! +//! - `Py_3_8`, `Py_3_9`, `Py_3_10`, `Py_3_11`, `Py_3_12`, `Py_3_13`, `Py_3_14`, `Py_3_15`: Marks code that is +//! only enabled when compiling for a given minimum Python version. +//! - `Py_LIMITED_API`: Marks code enabled when the `abi3` feature flag is enabled. +//! - `Py_GIL_DISABLED`: Marks code that runs only in the free-threaded build of CPython. +//! - `PyPy` - Marks code enabled when compiling for PyPy. +//! - `GraalPy` - Marks code enabled when compiling for GraalPy. +//! +//! Additionally, you can query for the values `Py_DEBUG`, `Py_REF_DEBUG`, +//! `Py_TRACE_REFS`, and `COUNT_ALLOCS` from `py_sys_config` to query for the +//! corresponding C build-time defines. For example, to conditionally define +//! debug code using `Py_DEBUG`, you could do: +//! +//! ```rust,ignore +//! #[cfg(py_sys_config = "Py_DEBUG")] +//! println!("only runs if python was compiled with Py_DEBUG") +//! ``` +//! +//! To use these attributes, add [`pyo3-build-config`] as a build dependency in +//! your `Cargo.toml`: +//! +//! ```toml +//! [build-dependencies] +#![doc = concat!("pyo3-build-config =\"", env!("CARGO_PKG_VERSION"), "\"")] +//! ``` +//! +//! And then either create a new `build.rs` file in the project root or modify +//! the existing `build.rs` file to call `use_pyo3_cfgs()`: +//! +//! ```rust,ignore +//! fn main() { +//! pyo3_build_config::use_pyo3_cfgs(); +//! } +//! ``` +//! +//! # Minimum supported Rust and Python versions +//! +//! `pyo3-ffi` supports the following Python distributions: +//! - CPython 3.8 or greater +//! - PyPy 7.3 (Python 3.11+) +//! - GraalPy 24.0 or greater (Python 3.10+) +//! +//! # Example: Building Python Native modules +//! +//! PyO3 can be used to generate a native Python module. The easiest way to try this out for the +//! first time is to use [`maturin`]. `maturin` is a tool for building and publishing Rust-based +//! Python packages with minimal configuration. The following steps set up some files for an example +//! Python module, install `maturin`, and then show how to build and import the Python module. +//! +//! First, create a new folder (let's call it `string_sum`) containing the following two files: +//! +//! **`Cargo.toml`** +//! +//! ```toml +//! [lib] +//! name = "string_sum" +//! # "cdylib" is necessary to produce a shared library for Python to import from. +//! # +//! # Downstream Rust code (including code in `bin/`, `examples/`, and `tests/`) will not be able +//! # to `use string_sum;` unless the "rlib" or "lib" crate type is also included, e.g.: +//! # crate-type = ["cdylib", "rlib"] +//! crate-type = ["cdylib"] +//! +//! [dependencies] +#![doc = concat!("pyo3-ffi = \"", env!("CARGO_PKG_VERSION"), "\"")] +//! +//! [build-dependencies] +//! # This is only necessary if you need to configure your build based on +//! # the Python version or the compile-time configuration for the interpreter. +#![doc = concat!("pyo3_build_config = \"", env!("CARGO_PKG_VERSION"), "\"")] +//! ``` +//! +//! If you need to use conditional compilation based on Python version or how +//! Python was compiled, you need to add `pyo3-build-config` as a +//! `build-dependency` in your `Cargo.toml` as in the example above and either +//! create a new `build.rs` file or modify an existing one so that +//! `pyo3_build_config::use_pyo3_cfgs()` gets called at build time: +//! +//! **`build.rs`** +//! ```rust,ignore +//! fn main() { +//! pyo3_build_config::use_pyo3_cfgs() +//! } +//! ``` +//! +//! **`src/lib.rs`** +//! ```rust,no_run +//! #[cfg(Py_3_15)] +//! use core::ffi::c_void; +//! #[cfg(not(Py_3_15))] +//! use core::ffi::c_int; +//! use core::ffi::{c_char, c_long}; +//! use core::ptr; +//! +//! use pyo3_ffi::*; +//! +//! #[cfg(not(Py_3_15))] +//! static mut MODULE_DEF: PyModuleDef = PyModuleDef { +//! m_base: PyModuleDef_HEAD_INIT, +//! m_name: c"string_sum".as_ptr(), +//! m_doc: c"A Python module written in Rust.".as_ptr(), +//! m_size: 0, +//! m_methods: (&raw mut METHODS).cast(), +//! m_slots: (&raw mut SLOTS).cast(), +//! m_traverse: None, +//! m_clear: None, +//! m_free: None, +//! }; +//! +//! static mut METHODS: [PyMethodDef; 2] = [ +//! PyMethodDef { +//! ml_name: c"sum_as_string".as_ptr(), +//! ml_meth: PyMethodDefPointer { +//! PyCFunctionFast: sum_as_string, +//! }, +//! ml_flags: METH_FASTCALL, +//! ml_doc: c"returns the sum of two integers as a string".as_ptr(), +//! }, +//! // A zeroed PyMethodDef to mark the end of the array. +//! PyMethodDef::zeroed(), +//! ]; +//! +//! const SLOTS_LEN: usize = +//! 1 + cfg!(Py_3_12) as usize + cfg!(Py_GIL_DISABLED) as usize + 4 * (cfg!(Py_3_15) as usize); +//! +//! #[cfg(not(Py_3_15))] +//! static mut SLOTS: [PyModuleDef_Slot; SLOTS_LEN] = [ +//! #[cfg(Py_3_12)] +//! PyModuleDef_Slot { +//! slot: Py_mod_multiple_interpreters, +//! value: Py_MOD_PER_INTERPRETER_GIL_SUPPORTED, +//! }, +//! #[cfg(Py_GIL_DISABLED)] +//! PyModuleDef_Slot { +//! slot: Py_mod_gil, +//! value: Py_MOD_GIL_NOT_USED, +//! }, +//! PyModuleDef_Slot { +//! slot: 0, +//! value: ptr::null_mut(), +//! }, +//! ]; +//! +//! #[cfg(Py_3_15)] +//! PyABIInfo_VAR!(ABI_INFO); +//! +//! #[cfg(Py_3_15)] +//! static mut SLOTS: [PySlot; SLOTS_LEN] = [ +//! PySlot_STATIC_DATA(Py_mod_abi, core::ptr::addr_of_mut!(ABI_INFO).cast()), +//! PySlot_STATIC_DATA(Py_mod_name, c"string_sum".as_ptr() as *mut c_void), +//! PySlot_STATIC_DATA(Py_mod_doc, c"A Python module written in Rust.".as_ptr() as *mut c_void), +//! PySlot_STATIC_DATA(Py_mod_methods, (&raw mut METHODS).cast()), +//! PySlot_DATA(Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED), +//! #[cfg(Py_GIL_DISABLED)] +//! PySlot_DATA(Py_mod_gil, Py_MOD_GIL_NOT_USED), +//! PySlot_END(), +//! ]; +//! +//! // The module initialization function +//! #[cfg(not(Py_3_15))] +//! #[allow(non_snake_case, reason = "must be named `PyInit_`")] +//! #[no_mangle] +//! pub unsafe extern "C" fn PyInit_string_sum() -> *mut PyObject { +//! PyModuleDef_Init(&raw mut MODULE_DEF) +//! } +//! +//! #[cfg(Py_3_15)] +//! #[allow(non_snake_case, reason = "must be named `PyModExport_`")] +//! #[no_mangle] +//! pub unsafe extern "C" fn PyModExport_string_sum() -> *mut PySlot { +//! (&raw mut SLOTS).cast() +//! } +//! +//! /// A helper to parse function arguments +//! /// If we used PyO3's proc macros they'd handle all of this boilerplate for us :) +//! unsafe fn parse_arg_as_i32(obj: *mut PyObject, n_arg: usize) -> Option { +//! if PyLong_Check(obj) == 0 { +//! let msg = format!( +//! "sum_as_string expected an int for positional argument {}\0", +//! n_arg +//! ); +//! PyErr_SetString(PyExc_TypeError, msg.as_ptr().cast::()); +//! return None; +//! } +//! +//! // Let's keep the behaviour consistent on platforms where `c_long` is bigger than 32 bits. +//! // In particular, it is an i32 on Windows but i64 on most Linux systems +//! let mut overflow = 0; +//! let i_long: c_long = PyLong_AsLongAndOverflow(obj, &mut overflow); +//! +//! #[allow( +//! irrefutable_let_patterns, +//! reason = "some platforms have c_long equal to i32" +//! )] +//! if overflow != 0 { +//! raise_overflowerror(obj); +//! None +//! } else if let Ok(i) = i_long.try_into() { +//! Some(i) +//! } else { +//! raise_overflowerror(obj); +//! None +//! } +//! } +//! +//! unsafe fn raise_overflowerror(obj: *mut PyObject) { +//! let obj_repr = PyObject_Str(obj); +//! if !obj_repr.is_null() { +//! let mut size = 0; +//! let p = PyUnicode_AsUTF8AndSize(obj_repr, &mut size); +//! if !p.is_null() { +//! let s = core::str::from_utf8_unchecked(core::slice::from_raw_parts( +//! p.cast::(), +//! size as usize, +//! )); +//! let msg = format!("cannot fit {} in 32 bits\0", s); +//! +//! PyErr_SetString(PyExc_OverflowError, msg.as_ptr().cast::()); +//! } +//! Py_DECREF(obj_repr); +//! } +//! } +//! +//! pub unsafe extern "C" fn sum_as_string( +//! _self: *mut PyObject, +//! args: *mut *mut PyObject, +//! nargs: Py_ssize_t, +//! ) -> *mut PyObject { +//! if nargs != 2 { +//! PyErr_SetString( +//! PyExc_TypeError, +//! c"sum_as_string expected 2 positional arguments".as_ptr(), +//! ); +//! return core::ptr::null_mut(); +//! } +//! +//! let (first, second) = (*args, *args.add(1)); +//! +//! let first = match parse_arg_as_i32(first, 1) { +//! Some(x) => x, +//! None => return core::ptr::null_mut(), +//! }; +//! let second = match parse_arg_as_i32(second, 2) { +//! Some(x) => x, +//! None => return core::ptr::null_mut(), +//! }; +//! +//! match first.checked_add(second) { +//! Some(sum) => { +//! let string = sum.to_string(); +//! PyUnicode_FromStringAndSize(string.as_ptr().cast::(), string.len() as isize) +//! } +//! None => { +//! PyErr_SetString(PyExc_OverflowError, c"arguments too large to add".as_ptr()); +//! core::ptr::null_mut() +//! } +//! } +//! } +//! ``` +//! +//! With those two files in place, now `maturin` needs to be installed. This can be done using +//! Python's package manager `pip`. First, load up a new Python `virtualenv`, and install `maturin` +//! into it: +//! ```bash +//! $ cd string_sum +//! $ python -m venv .env +//! $ source .env/bin/activate +//! $ pip install maturin +//! ``` +//! +//! Now build and execute the module: +//! ```bash +//! $ maturin develop +//! # lots of progress output as maturin runs the compilation... +//! $ python +//! >>> import string_sum +//! >>> string_sum.sum_as_string(5, 20) +//! '25' +//! ``` +//! +//! As well as with `maturin`, it is possible to build using [setuptools-rust] or +//! [manually][manual_builds]. Both offer more flexibility than `maturin` but require further +//! configuration. +//! +//! This example stores the module definition statically and uses the `PyModule_Create` function +//! in the CPython C API to register the module. This is the "old" style for registering modules +//! and has the limitation that it cannot support subinterpreters. You can also create a module +//! using the new multi-phase initialization API that does support subinterpreters. See the +//! `sequential` project located in the `examples` directory at the root of the `pyo3-ffi` crate +//! for a worked example of how to this using `pyo3-ffi`. +//! +//! # Using Python from Rust +//! +//! To embed Python into a Rust binary, you need to ensure that your Python installation contains a +//! shared library. The following steps demonstrate how to ensure this (for Ubuntu). +//! +//! To install the Python shared library on Ubuntu: +//! ```bash +//! sudo apt install python3-dev +//! ``` +//! +//! While most projects use the safe wrapper provided by pyo3, +//! you can take a look at the [`orjson`] library as an example on how to use `pyo3-ffi` directly. +//! For those well versed in C and Rust the [tutorials] from the CPython documentation +//! can be easily converted to rust as well. +//! +//! [tutorials]: https://docs.python.org/3/extending/ +//! [`orjson`]: https://github.com/ijl/orjson +//! [capi]: https://docs.python.org/3/c-api/index.html +//! [`maturin`]: https://github.com/PyO3/maturin "Build and publish crates with pyo3, rust-cpython and cffi bindings as well as rust binaries as python packages" +//! [`pyo3-build-config`]: https://docs.rs/pyo3-build-config +//! [feature flags]: https://doc.rust-lang.org/cargo/reference/features.html "Features - The Cargo Book" +#![doc = concat!("[manual_builds]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/building-and-distribution.html#manual-builds \"Manual builds - Building and Distribution - PyO3 user guide\"")] +//! [setuptools-rust]: https://github.com/PyO3/setuptools-rust "Setuptools plugin for Rust extensions" +//! [PEP 384]: https://www.python.org/dev/peps/pep-0384 "PEP 384 -- Defining a Stable ABI" +#![doc = concat!("[Features chapter of the guide]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/features.html#features-reference \"Features reference - PyO3 user guide\"")] +#![allow( + missing_docs, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + clippy::upper_case_acronyms, + clippy::missing_safety_doc, + clippy::ptr_eq +)] +#![warn( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core +)] +#![warn(elided_lifetimes_in_paths, unused_lifetimes)] +// This crate is a hand-maintained translation of CPython's headers, so requiring "unsafe" +// blocks within those translations increases maintenance burden without providing any +// additional safety. The safety of the functions in this crate is determined by the +// original CPython headers +#![allow(unsafe_op_in_unsafe_fn)] + +#[cfg(not(PyPy))] +extern crate alloc; +#[cfg(not(any(Py_3_14, target_arch = "wasm32")))] +extern crate std; + +// Until `extern type` is stabilized, use the recommended approach to +// model opaque types: +// https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs +macro_rules! opaque_struct { + ($(#[$attrs:meta])* $pub:vis $name:ident) => { + $(#[$attrs])* + #[repr(C)] + $pub struct $name { + _data: (), + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, + } + }; +} + +/// This is a helper macro to create a `&'static CStr`. +/// +/// It can be used on all Rust versions supported by PyO3, unlike c"" literals which +/// were stabilised in Rust 1.77. +/// +/// Due to the nature of PyO3 making heavy use of C FFI interop with Python, it is +/// common for PyO3 to use CStr. +/// +/// Examples: +/// +/// ```rust,no_run +/// use core::ffi::CStr; +/// +/// const HELLO: &CStr = pyo3_ffi::c_str!("hello"); +/// static WORLD: &CStr = pyo3_ffi::c_str!("world"); +/// ``` +#[macro_export] +macro_rules! c_str { + // TODO: deprecate this now MSRV is above 1.77 + ($s:expr) => { + $crate::_cstr_from_utf8_with_nul_checked(concat!($s, "\0")) + }; +} + +/// Private helper for `c_str!` macro. +#[doc(hidden)] +pub const fn _cstr_from_utf8_with_nul_checked(s: &str) -> &core::ffi::CStr { + match core::ffi::CStr::from_bytes_with_nul(s.as_bytes()) { + Ok(cstr) => cstr, + Err(_) => panic!("string contains nul bytes"), + } +} + +// Macros for declaring `extern` blocks that link against libpython. +// See `impl_/macros.rs` for the implementation. +include!("impl_/macros.rs"); + +pub mod compat; +mod impl_; + +pub use self::abstract_::*; +#[cfg(not(RustPython))] +pub use self::bltinmodule::*; +pub use self::boolobject::*; +pub use self::bytearrayobject::*; +pub use self::bytesobject::*; +pub use self::ceval::*; +pub use self::codecs::*; +pub use self::compile::*; +pub use self::complexobject::*; +#[cfg(not(Py_LIMITED_API))] +pub use self::context::*; +#[cfg(Py_3_13)] +pub use self::critical_section::*; +#[cfg(not(Py_LIMITED_API))] +pub use self::datetime::*; +pub use self::descrobject::*; +pub use self::dictobject::*; +#[cfg(not(RustPython))] +pub use self::enumobject::*; +pub use self::fileobject::*; +pub use self::fileutils::*; +pub use self::floatobject::*; +#[cfg(Py_3_9)] +pub use self::genericaliasobject::*; +pub use self::import::*; +pub use self::intrcheck::*; +pub use self::iterobject::*; +pub use self::listobject::*; +pub use self::longobject::*; +pub use self::memoryobject::*; +pub use self::methodobject::*; +pub use self::modsupport::*; +pub use self::moduleobject::*; +pub use self::object::*; +pub use self::objimpl::*; +pub use self::osmodule::*; +#[cfg(not(any(PyPy, Py_LIMITED_API, Py_3_10)))] +pub use self::pyarena::*; +#[cfg(Py_3_11)] +pub use self::pybuffer::*; +pub use self::pycapsule::*; +pub use self::pyerrors::*; +pub use self::pyframe::*; +pub use self::pyhash::*; +pub use self::pylifecycle::*; +pub use self::pymem::*; +pub use self::pyport::*; +pub use self::pystate::*; +pub use self::pystrtod::*; +pub use self::pythonrun::*; +pub use self::pytypedefs::*; +pub use self::rangeobject::*; +pub use self::refcount::*; +pub use self::setobject::*; +pub use self::sliceobject::*; +#[cfg(Py_3_15)] +pub use self::slots::*; +pub use self::slots_generated::*; +pub use self::structseq::*; +pub use self::sysmodule::*; +pub use self::traceback::*; +pub use self::tupleobject::*; +pub use self::unicodeobject::*; +pub use self::warnings::*; +pub use self::weakrefobject::*; + +mod abstract_; +// skipped asdl.h +// skipped ast.h +#[cfg(not(RustPython))] +mod bltinmodule; +mod boolobject; +mod bytearrayobject; +mod bytesobject; +// skipped cellobject.h +mod ceval; +// skipped classobject.h +mod codecs; +mod compile; +mod complexobject; +#[cfg(not(Py_LIMITED_API))] +mod context; +mod critical_section; +#[cfg(not(Py_LIMITED_API))] +pub(crate) mod datetime; +mod descrobject; +mod dictobject; +// skipped dynamic_annotations.h +#[cfg(not(RustPython))] +mod enumobject; +// skipped errcode.h +// skipped exports.h +mod fileobject; +mod fileutils; +mod floatobject; +// skipped empty frameobject.h +mod genericaliasobject; +mod import; +// skipped interpreteridobject.h +mod intrcheck; +mod iterobject; +mod listobject; +mod longobject; +mod memoryobject; +mod methodobject; +mod modsupport; +mod moduleobject; +// skipped namespaceobject.h +mod object; +mod objimpl; +// skipped odictobject.h +// skipped opcode.h +// skipped osdefs.h +mod osmodule; +// skipped parser_interface.h +// skipped patchlevel.h +// skipped picklebufobject.h +// skipped pyctype.h +// skipped py_curses.h +#[cfg(not(any(PyPy, Py_LIMITED_API, Py_3_10)))] +mod pyarena; +#[cfg(Py_3_11)] +mod pybuffer; +mod pycapsule; +// skipped pydtrace.h +mod pyerrors; +// skipped pyexpat.h +// skipped pyfpe.h +mod pyframe; +mod pyhash; +mod pylifecycle; +// skipped pymacconfig.h +// skipped pymacro.h +// skipped pymath.h +mod pymem; +mod pyport; +mod pystate; +// skipped pystats.h +mod pythonrun; +// skipped pystrhex.h +// skipped pystrcmp.h +mod pystrtod; +// skipped pythread.h +// skipped pytime.h +mod pytypedefs; +mod rangeobject; +mod refcount; +mod setobject; +mod sliceobject; +mod slots; +mod slots_generated; +mod structseq; +mod sysmodule; +mod traceback; +// skipped tracemalloc.h +mod tupleobject; +mod unicodeobject; +mod warnings; +mod weakrefobject; + +// Additional headers that are not exported by Python.h +#[deprecated(note = "Python 3.12")] +pub mod structmember; + +// "Limited API" definitions matching Python's `include/cpython` directory. +#[cfg(not(any(Py_LIMITED_API, RustPython)))] +mod cpython; + +#[cfg(not(any(Py_LIMITED_API, RustPython)))] +pub use self::cpython::*; diff --git a/vendor/pyo3-ffi/src/listobject.rs b/vendor/pyo3-ffi/src/listobject.rs new file mode 100644 index 0000000..ed5f1cd --- /dev/null +++ b/vendor/pyo3-ffi/src/listobject.rs @@ -0,0 +1,82 @@ +use crate::object::*; +use crate::pyport::Py_ssize_t; +use core::ffi::c_int; + +#[cfg(not(RustPython))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyList_Type")] + pub static mut PyList_Type: PyTypeObject; + pub static mut PyListIter_Type: PyTypeObject; + pub static mut PyListRevIter_Type: PyTypeObject; +} + +#[cfg(not(RustPython))] +#[inline] +pub unsafe fn PyList_Check(op: *mut PyObject) -> c_int { + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyList_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyList_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PyList_Check(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyList_CheckExact(op: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPyList_New")] + pub fn PyList_New(size: Py_ssize_t) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyList_Size")] + pub fn PyList_Size(arg1: *mut PyObject) -> Py_ssize_t; + #[cfg_attr(PyPy, link_name = "PyPyList_GetItem")] + pub fn PyList_GetItem(arg1: *mut PyObject, arg2: Py_ssize_t) -> *mut PyObject; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyList_GetItemRef")] + pub fn PyList_GetItemRef(arg1: *mut PyObject, arg2: Py_ssize_t) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyList_SetItem")] + pub fn PyList_SetItem(arg1: *mut PyObject, arg2: Py_ssize_t, arg3: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyList_Insert")] + pub fn PyList_Insert(arg1: *mut PyObject, arg2: Py_ssize_t, arg3: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyList_Append")] + pub fn PyList_Append(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyList_GetSlice")] + pub fn PyList_GetSlice( + arg1: *mut PyObject, + arg2: Py_ssize_t, + arg3: Py_ssize_t, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyList_SetSlice")] + pub fn PyList_SetSlice( + arg1: *mut PyObject, + arg2: Py_ssize_t, + arg3: Py_ssize_t, + arg4: *mut PyObject, + ) -> c_int; + #[cfg(Py_3_13)] + pub fn PyList_Extend(list: *mut PyObject, iterable: *mut PyObject) -> c_int; + #[cfg(Py_3_13)] + pub fn PyList_Clear(list: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyList_Sort")] + pub fn PyList_Sort(arg1: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyList_Reverse")] + pub fn PyList_Reverse(arg1: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyList_AsTuple")] + pub fn PyList_AsTuple(arg1: *mut PyObject) -> *mut PyObject; + + // CPython macros exported as functions on PyPy or GraalPy + #[cfg(any(PyPy, GraalPy))] + #[cfg_attr(PyPy, link_name = "PyPyList_GET_ITEM")] + #[cfg_attr(GraalPy, link_name = "PyList_GetItem")] + pub fn PyList_GET_ITEM(arg1: *mut PyObject, arg2: Py_ssize_t) -> *mut PyObject; + #[cfg(PyPy)] + #[cfg_attr(PyPy, link_name = "PyPyList_GET_SIZE")] + pub fn PyList_GET_SIZE(arg1: *mut PyObject) -> Py_ssize_t; + #[cfg(any(PyPy, GraalPy))] + #[cfg_attr(PyPy, link_name = "PyPyList_SET_ITEM")] + #[cfg_attr(GraalPy, link_name = "_PyList_SET_ITEM")] + pub fn PyList_SET_ITEM(arg1: *mut PyObject, arg2: Py_ssize_t, arg3: *mut PyObject); +} diff --git a/vendor/pyo3-ffi/src/longobject.rs b/vendor/pyo3-ffi/src/longobject.rs new file mode 100644 index 0000000..7c777fe --- /dev/null +++ b/vendor/pyo3-ffi/src/longobject.rs @@ -0,0 +1,145 @@ +use crate::object::*; +use crate::pyport::Py_ssize_t; +use core::ffi::{c_char, c_double, c_int, c_long, c_longlong, c_ulong, c_ulonglong, c_void}; +use libc::size_t; + +opaque_struct!(pub PyLongObject); + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyLong_Check(op: *mut PyObject) -> c_int { + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyLong_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyLong_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PyLong_Check(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyLong_CheckExact(op: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPyLong_FromLong")] + pub fn PyLong_FromLong(arg1: c_long) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyLong_FromUnsignedLong")] + pub fn PyLong_FromUnsignedLong(arg1: c_ulong) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyLong_FromSize_t")] + pub fn PyLong_FromSize_t(arg1: size_t) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyLong_FromSsize_t")] + pub fn PyLong_FromSsize_t(arg1: Py_ssize_t) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyLong_FromDouble")] + pub fn PyLong_FromDouble(arg1: c_double) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyLong_AsLong")] + pub fn PyLong_AsLong(arg1: *mut PyObject) -> c_long; + #[cfg_attr(PyPy, link_name = "PyPyLong_AsLongAndOverflow")] + pub fn PyLong_AsLongAndOverflow(arg1: *mut PyObject, arg2: *mut c_int) -> c_long; + #[cfg_attr(PyPy, link_name = "PyPyLong_AsSsize_t")] + pub fn PyLong_AsSsize_t(arg1: *mut PyObject) -> Py_ssize_t; + #[cfg_attr(PyPy, link_name = "PyPyLong_AsSize_t")] + pub fn PyLong_AsSize_t(arg1: *mut PyObject) -> size_t; + #[cfg_attr(PyPy, link_name = "PyPyLong_AsUnsignedLong")] + pub fn PyLong_AsUnsignedLong(arg1: *mut PyObject) -> c_ulong; + #[cfg_attr(PyPy, link_name = "PyPyLong_AsUnsignedLongMask")] + pub fn PyLong_AsUnsignedLongMask(arg1: *mut PyObject) -> c_ulong; + + // skipped non-limited PyLong_AsInt + + #[cfg(Py_3_14)] + pub fn PyLong_FromInt32(arg1: i32) -> *mut PyObject; + #[cfg(Py_3_14)] + pub fn PyLong_FromUInt32(arg1: u32) -> *mut PyObject; + #[cfg(Py_3_14)] + pub fn PyLong_FromInt64(arg1: i64) -> *mut PyObject; + #[cfg(Py_3_14)] + pub fn PyLong_FromUInt64(arg1: u64) -> *mut PyObject; + + #[cfg(Py_3_14)] + pub fn PyLong_AsInt32(arg1: *mut PyObject, arg2: *mut i32) -> c_int; + #[cfg(Py_3_14)] + pub fn PyLong_AsUInt32(arg1: *mut PyObject, arg2: *mut u32) -> c_int; + #[cfg(Py_3_14)] + pub fn PyLong_AsInt64(arg1: *mut PyObject, arg2: *mut i64) -> c_int; + #[cfg(Py_3_14)] + pub fn PyLong_AsUInt64(arg1: *mut PyObject, arg2: *mut u64) -> c_int; +} + +#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))] +pub const Py_ASNATIVEBYTES_DEFAULTS: c_int = -1; +#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))] +pub const Py_ASNATIVEBYTES_BIG_ENDIAN: c_int = 0; +#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))] +pub const Py_ASNATIVEBYTES_LITTLE_ENDIAN: c_int = 1; +#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))] +pub const Py_ASNATIVEBYTES_NATIVE_ENDIAN: c_int = 3; +#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))] +pub const Py_ASNATIVEBYTES_UNSIGNED_BUFFER: c_int = 4; +#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))] +pub const Py_ASNATIVEBYTES_REJECT_NEGATIVE: c_int = 8; +#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))] +pub const Py_ASNATIVEBYTES_ALLOW_INDEX: c_int = 16; + +extern_libpython! { + #[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))] + pub fn PyLong_AsNativeBytes( + v: *mut PyObject, + buffer: *mut c_void, + n_bytes: Py_ssize_t, + flags: c_int, + ) -> Py_ssize_t; + + #[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))] + pub fn PyLong_FromNativeBytes( + buffer: *const c_void, + n_bytes: size_t, + flags: c_int, + ) -> *mut PyObject; + + #[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))] + pub fn PyLong_FromUnsignedNativeBytes( + buffer: *const c_void, + n_bytes: size_t, + flags: c_int, + ) -> *mut PyObject; + + pub fn PyLong_GetInfo() -> *mut PyObject; + // skipped PyLong_AS_LONG + + // skipped PyLong_FromPid + // skipped PyLong_AsPid + // skipped _Py_PARSE_INTPTR + // skipped _Py_PARSE_UINTPTR + + #[cfg_attr(PyPy, link_name = "PyPyLong_AsDouble")] + pub fn PyLong_AsDouble(arg1: *mut PyObject) -> c_double; + #[cfg_attr(PyPy, link_name = "PyPyLong_FromVoidPtr")] + pub fn PyLong_FromVoidPtr(arg1: *mut c_void) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyLong_AsVoidPtr")] + pub fn PyLong_AsVoidPtr(arg1: *mut PyObject) -> *mut c_void; + #[cfg_attr(PyPy, link_name = "PyPyLong_FromLongLong")] + pub fn PyLong_FromLongLong(arg1: c_longlong) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyLong_FromUnsignedLongLong")] + pub fn PyLong_FromUnsignedLongLong(arg1: c_ulonglong) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyLong_AsLongLong")] + pub fn PyLong_AsLongLong(arg1: *mut PyObject) -> c_longlong; + #[cfg_attr(PyPy, link_name = "PyPyLong_AsUnsignedLongLong")] + pub fn PyLong_AsUnsignedLongLong(arg1: *mut PyObject) -> c_ulonglong; + #[cfg_attr(PyPy, link_name = "PyPyLong_AsUnsignedLongLongMask")] + pub fn PyLong_AsUnsignedLongLongMask(arg1: *mut PyObject) -> c_ulonglong; + #[cfg_attr(PyPy, link_name = "PyPyLong_AsLongLongAndOverflow")] + pub fn PyLong_AsLongLongAndOverflow(arg1: *mut PyObject, arg2: *mut c_int) -> c_longlong; + #[cfg_attr(PyPy, link_name = "PyPyLong_FromString")] + pub fn PyLong_FromString( + arg1: *const c_char, + arg2: *mut *mut c_char, + arg3: c_int, + ) -> *mut PyObject; +} + +extern_libpython! { + pub fn PyOS_strtoul(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_ulong; + pub fn PyOS_strtol(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_long; +} diff --git a/vendor/pyo3-ffi/src/memoryobject.rs b/vendor/pyo3-ffi/src/memoryobject.rs new file mode 100644 index 0000000..7ebc2a2 --- /dev/null +++ b/vendor/pyo3-ffi/src/memoryobject.rs @@ -0,0 +1,48 @@ +use crate::object::*; +use crate::pyport::Py_ssize_t; +use core::ffi::{c_char, c_int}; + +// skipped _PyManagedBuffer_Type + +extern_libpython! { + #[cfg(not(RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyMemoryView_Type")] + pub static mut PyMemoryView_Type: PyTypeObject; + + #[cfg(RustPython)] + pub fn PyMemoryView_Check(op: *mut PyObject) -> c_int; +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyMemoryView_Check(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyMemoryView_Type) +} + +// skipped non-limited PyMemoryView_GET_BUFFER +// skipped non-limited PyMemoryView_GET_BASE + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyMemoryView_FromObject")] + pub fn PyMemoryView_FromObject(base: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyMemoryView_FromMemory")] + pub fn PyMemoryView_FromMemory( + mem: *mut c_char, + size: Py_ssize_t, + flags: c_int, + ) -> *mut PyObject; + #[cfg(any(Py_3_11, not(Py_LIMITED_API)))] + #[cfg_attr(PyPy, link_name = "PyPyMemoryView_FromBuffer")] + pub fn PyMemoryView_FromBuffer(view: *const crate::Py_buffer) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyMemoryView_GetContiguous")] + pub fn PyMemoryView_GetContiguous( + base: *mut PyObject, + buffertype: c_int, + order: c_char, + ) -> *mut PyObject; +} + +// skipped remainder of file with comment: +/* The structs are declared here so that macros can work, but they shouldn't +be considered public. Don't access their fields directly, use the macros +and functions instead! */ diff --git a/vendor/pyo3-ffi/src/methodobject.rs b/vendor/pyo3-ffi/src/methodobject.rs new file mode 100644 index 0000000..b4ee2c5 --- /dev/null +++ b/vendor/pyo3-ffi/src/methodobject.rs @@ -0,0 +1,293 @@ +use crate::object::{PyObject, PyTypeObject}; +#[cfg(Py_3_9)] +#[cfg(not(RustPython))] +use crate::PyObject_TypeCheck; +#[cfg(not(RustPython))] +use crate::Py_IS_TYPE; +use core::ffi::{c_char, c_int, c_void}; +use core::{mem, ptr}; + +#[cfg(all(Py_3_9, not(Py_LIMITED_API), not(GraalPy)))] +pub struct PyCFunctionObject { + pub ob_base: PyObject, + pub m_ml: *mut PyMethodDef, + pub m_self: *mut PyObject, + pub m_module: *mut PyObject, + pub m_weakreflist: *mut PyObject, + #[cfg(not(PyPy))] + pub vectorcall: Option, +} + +extern_libpython! { + #[cfg(not(RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyCFunction_Type")] + pub static mut PyCFunction_Type: PyTypeObject; + + #[cfg(RustPython)] + pub fn PyCFunction_CheckExact(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyCFunction_Check(op: *mut PyObject) -> c_int; +} + +#[cfg(all(Py_3_9, not(RustPython)))] +#[inline] +pub unsafe fn PyCFunction_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyCFunction_Type) +} + +#[cfg(all(Py_3_9, not(RustPython)))] +#[inline] +pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, &raw mut PyCFunction_Type) +} + +#[cfg(not(any(Py_3_9, RustPython)))] +#[inline] +pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyCFunction_Type) +} + +pub type PyCFunction = + unsafe extern "C" fn(slf: *mut PyObject, args: *mut PyObject) -> *mut PyObject; + +#[cfg(any(Py_3_10, not(Py_LIMITED_API)))] +pub type PyCFunctionFast = unsafe extern "C" fn( + slf: *mut PyObject, + args: *mut *mut PyObject, + nargs: crate::pyport::Py_ssize_t, +) -> *mut PyObject; + +#[cfg(any(Py_3_10, not(Py_LIMITED_API)))] +#[deprecated(note = "renamed to `PyCFunctionFast`")] +pub type _PyCFunctionFast = PyCFunctionFast; + +pub type PyCFunctionWithKeywords = unsafe extern "C" fn( + slf: *mut PyObject, + args: *mut PyObject, + kwds: *mut PyObject, +) -> *mut PyObject; + +#[cfg(any(Py_3_10, not(Py_LIMITED_API)))] +pub type PyCFunctionFastWithKeywords = unsafe extern "C" fn( + slf: *mut PyObject, + args: *const *mut PyObject, + nargs: crate::pyport::Py_ssize_t, + kwnames: *mut PyObject, +) -> *mut PyObject; + +#[cfg(any(Py_3_10, not(Py_LIMITED_API)))] +#[deprecated(note = "renamed to `PyCFunctionFastWithKeywords`")] +pub type _PyCFunctionFastWithKeywords = PyCFunctionFastWithKeywords; + +#[cfg(all(Py_3_9, not(Py_LIMITED_API)))] +pub type PyCMethod = unsafe extern "C" fn( + slf: *mut PyObject, + defining_class: *mut PyTypeObject, + args: *const *mut PyObject, + nargs: crate::pyport::Py_ssize_t, + kwnames: *mut PyObject, +) -> *mut PyObject; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyCFunction_GetFunction")] + pub fn PyCFunction_GetFunction(f: *mut PyObject) -> Option; + pub fn PyCFunction_GetSelf(f: *mut PyObject) -> *mut PyObject; + pub fn PyCFunction_GetFlags(f: *mut PyObject) -> c_int; + #[cfg(not(Py_3_13))] + #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] + pub fn PyCFunction_Call( + f: *mut PyObject, + args: *mut PyObject, + kwds: *mut PyObject, + ) -> *mut PyObject; +} + +/// Represents the [PyMethodDef](https://docs.python.org/3/c-api/structures.html#c.PyMethodDef) +/// structure. +/// +/// Note that CPython may leave fields uninitialized. You must ensure that +/// `ml_name` != NULL before dereferencing or reading other fields. +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct PyMethodDef { + pub ml_name: *const c_char, + pub ml_meth: PyMethodDefPointer, + pub ml_flags: c_int, + pub ml_doc: *const c_char, +} + +impl PyMethodDef { + pub const fn zeroed() -> PyMethodDef { + PyMethodDef { + ml_name: ptr::null(), + ml_meth: PyMethodDefPointer { + Void: ptr::null_mut(), + }, + ml_flags: 0, + ml_doc: ptr::null(), + } + } +} + +impl Default for PyMethodDef { + fn default() -> PyMethodDef { + PyMethodDef { + ml_name: ptr::null(), + ml_meth: PyMethodDefPointer { + Void: ptr::null_mut(), + }, + ml_flags: 0, + ml_doc: ptr::null(), + } + } +} + +/// Function types used to implement Python callables. +/// +/// This function pointer must be accompanied by the correct [ml_flags](PyMethodDef::ml_flags), +/// otherwise the behavior is undefined. +/// +/// See the [Python C API documentation][1] for more information. +/// +/// [1]: https://docs.python.org/3/c-api/structures.html#implementing-functions-and-methods +#[repr(C)] +#[derive(Copy, Clone, Eq)] +pub union PyMethodDefPointer { + /// This variant corresponds with [`METH_VARARGS`] *or* [`METH_NOARGS`] *or* [`METH_O`]. + pub PyCFunction: PyCFunction, + + /// This variant corresponds with [`METH_VARARGS`] | [`METH_KEYWORDS`]. + pub PyCFunctionWithKeywords: PyCFunctionWithKeywords, + + /// This variant corresponds with [`METH_FASTCALL`]. + #[cfg(any(Py_3_10, not(Py_LIMITED_API)))] + #[deprecated(note = "renamed to `PyCFunctionFast`")] + pub _PyCFunctionFast: PyCFunctionFast, + + /// This variant corresponds with [`METH_FASTCALL`]. + #[cfg(any(Py_3_10, not(Py_LIMITED_API)))] + pub PyCFunctionFast: PyCFunctionFast, + + /// This variant corresponds with [`METH_FASTCALL`] | [`METH_KEYWORDS`]. + #[cfg(any(Py_3_10, not(Py_LIMITED_API)))] + #[deprecated(note = "renamed to `PyCFunctionFastWithKeywords`")] + pub _PyCFunctionFastWithKeywords: PyCFunctionFastWithKeywords, + + /// This variant corresponds with [`METH_FASTCALL`] | [`METH_KEYWORDS`]. + #[cfg(any(Py_3_10, not(Py_LIMITED_API)))] + pub PyCFunctionFastWithKeywords: PyCFunctionFastWithKeywords, + + /// This variant corresponds with [`METH_METHOD`] | [`METH_FASTCALL`] | [`METH_KEYWORDS`]. + #[cfg(all(Py_3_9, not(Py_LIMITED_API)))] + pub PyCMethod: PyCMethod, + + Void: *mut c_void, +} + +impl PyMethodDefPointer { + pub fn as_ptr(&self) -> *mut c_void { + // SAFETY: self is pointer sized + unsafe { self.Void } + } + + pub fn is_null(&self) -> bool { + self.as_ptr().is_null() + } + + pub const fn zeroed() -> PyMethodDefPointer { + PyMethodDefPointer { + Void: ptr::null_mut(), + } + } +} + +impl PartialEq for PyMethodDefPointer { + fn eq(&self, other: &Self) -> bool { + self.as_ptr() == other.as_ptr() + } +} + +impl core::fmt::Pointer for PyMethodDefPointer { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let ptr = self.as_ptr(); + core::fmt::Pointer::fmt(&ptr, f) + } +} + +const _: () = + assert!(mem::size_of::() == mem::size_of::>()); + +#[cfg(not(Py_3_9))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyCFunction_New")] + pub fn PyCFunction_New(ml: *mut PyMethodDef, slf: *mut PyObject) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyCFunction_NewEx")] + pub fn PyCFunction_NewEx( + ml: *mut PyMethodDef, + slf: *mut PyObject, + module: *mut PyObject, + ) -> *mut PyObject; +} + +#[cfg(Py_3_9)] +#[inline] +pub unsafe fn PyCFunction_New(ml: *mut PyMethodDef, slf: *mut PyObject) -> *mut PyObject { + PyCFunction_NewEx(ml, slf, core::ptr::null_mut()) +} + +#[cfg(Py_3_9)] +#[inline] +pub unsafe fn PyCFunction_NewEx( + ml: *mut PyMethodDef, + slf: *mut PyObject, + module: *mut PyObject, +) -> *mut PyObject { + PyCMethod_New(ml, slf, module, core::ptr::null_mut()) +} + +#[cfg(Py_3_9)] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyCMethod_New")] + pub fn PyCMethod_New( + ml: *mut PyMethodDef, + slf: *mut PyObject, + module: *mut PyObject, + cls: *mut PyTypeObject, + ) -> *mut PyObject; +} + +/* Flag passed to newmethodobject */ +pub const METH_VARARGS: c_int = 0x0001; +pub const METH_KEYWORDS: c_int = 0x0002; +/* METH_NOARGS and METH_O must not be combined with the flags above. */ +pub const METH_NOARGS: c_int = 0x0004; +pub const METH_O: c_int = 0x0008; + +/* METH_CLASS and METH_STATIC are a little different; these control +the construction of methods for a class. These cannot be used for +functions in modules. */ +pub const METH_CLASS: c_int = 0x0010; +pub const METH_STATIC: c_int = 0x0020; + +/* METH_COEXIST allows a method to be entered eventhough a slot has +already filled the entry. When defined, the flag allows a separate +method, "__contains__" for example, to coexist with a defined +slot like sq_contains. */ + +pub const METH_COEXIST: c_int = 0x0040; + +/* METH_FASTCALL indicates the PEP 590 Vectorcall calling format. It may +be specified alone or with METH_KEYWORDS. */ +#[cfg(any(Py_3_10, not(Py_LIMITED_API)))] +pub const METH_FASTCALL: c_int = 0x0080; + +// skipped METH_STACKLESS + +#[cfg(all(Py_3_9, not(Py_LIMITED_API)))] +pub const METH_METHOD: c_int = 0x0200; + +extern_libpython! { + #[cfg(not(Py_3_9))] + pub fn PyCFunction_ClearFreeList() -> c_int; +} diff --git a/vendor/pyo3-ffi/src/modsupport.rs b/vendor/pyo3-ffi/src/modsupport.rs new file mode 100644 index 0000000..9971556 --- /dev/null +++ b/vendor/pyo3-ffi/src/modsupport.rs @@ -0,0 +1,191 @@ +use crate::methodobject::PyMethodDef; +use crate::moduleobject::PyModuleDef; +use crate::object::PyObject; +use crate::pyport::Py_ssize_t; +use core::ffi::{c_char, c_int, c_long}; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyArg_Parse")] + pub fn PyArg_Parse(arg1: *mut PyObject, arg2: *const c_char, ...) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyArg_ParseTuple")] + pub fn PyArg_ParseTuple(arg1: *mut PyObject, arg2: *const c_char, ...) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyArg_ParseTupleAndKeywords")] + pub fn PyArg_ParseTupleAndKeywords( + arg1: *mut PyObject, + arg2: *mut PyObject, + arg3: *const c_char, + #[cfg(not(Py_3_13))] arg4: *mut *mut c_char, + #[cfg(Py_3_13)] arg4: *const *const c_char, + ... + ) -> c_int; + + // skipped PyArg_VaParse + // skipped PyArg_VaParseTupleAndKeywords + + pub fn PyArg_ValidateKeywordArguments(arg1: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyArg_UnpackTuple")] + pub fn PyArg_UnpackTuple( + arg1: *mut PyObject, + arg2: *const c_char, + arg3: Py_ssize_t, + arg4: Py_ssize_t, + ... + ) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPy_BuildValue")] + pub fn Py_BuildValue(arg1: *const c_char, ...) -> *mut PyObject; + // skipped Py_VaBuildValue + + #[cfg(Py_3_13)] + pub fn PyModule_Add(module: *mut PyObject, name: *const c_char, value: *mut PyObject) -> c_int; + #[cfg(Py_3_10)] + #[cfg_attr(PyPy, link_name = "PyPyModule_AddObjectRef")] + pub fn PyModule_AddObjectRef( + module: *mut PyObject, + name: *const c_char, + value: *mut PyObject, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyModule_AddObject")] + pub fn PyModule_AddObject( + module: *mut PyObject, + name: *const c_char, + value: *mut PyObject, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyModule_AddIntConstant")] + pub fn PyModule_AddIntConstant( + module: *mut PyObject, + name: *const c_char, + value: c_long, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyModule_AddStringConstant")] + pub fn PyModule_AddStringConstant( + module: *mut PyObject, + name: *const c_char, + value: *const c_char, + ) -> c_int; + #[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))] + #[cfg_attr(PyPy, link_name = "PyPyModule_AddType")] + pub fn PyModule_AddType( + module: *mut PyObject, + type_: *mut crate::object::PyTypeObject, + ) -> c_int; + // skipped PyModule_AddIntMacro + // skipped PyModule_AddStringMacro + pub fn PyModule_SetDocString(arg1: *mut PyObject, arg2: *const c_char) -> c_int; + pub fn PyModule_AddFunctions(arg1: *mut PyObject, arg2: *mut PyMethodDef) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyModule_ExecDef")] + pub fn PyModule_ExecDef(module: *mut PyObject, def: *mut PyModuleDef) -> c_int; +} + +pub const Py_CLEANUP_SUPPORTED: i32 = 0x2_0000; + +pub const PYTHON_API_VERSION: i32 = 1013; +pub const PYTHON_ABI_VERSION: i32 = 3; + +extern_libpython! { + + #[cfg_attr(PyPy, link_name = "PyPyModule_Create2")] + pub fn PyModule_Create2(module: *mut PyModuleDef, apiver: c_int) -> *mut PyObject; +} + +#[inline] +pub unsafe fn PyModule_Create(module: *mut PyModuleDef) -> *mut PyObject { + PyModule_Create2( + module, + if cfg!(Py_LIMITED_API) { + PYTHON_ABI_VERSION + } else { + PYTHON_API_VERSION + }, + ) +} + +extern_libpython! { + + #[cfg_attr(PyPy, link_name = "PyPyModule_FromDefAndSpec2")] + pub fn PyModule_FromDefAndSpec2( + def: *mut PyModuleDef, + spec: *mut PyObject, + module_api_version: c_int, + ) -> *mut PyObject; + +} + +#[inline] +pub unsafe fn PyModule_FromDefAndSpec(def: *mut PyModuleDef, spec: *mut PyObject) -> *mut PyObject { + PyModule_FromDefAndSpec2( + def, + spec, + if cfg!(Py_LIMITED_API) { + PYTHON_ABI_VERSION + } else { + PYTHON_API_VERSION + }, + ) +} + +#[cfg(Py_3_15)] +#[repr(C)] +pub struct PyABIInfo { + pub abiinfo_major_version: u8, + pub abiinfo_minor_version: u8, + pub flags: u16, + pub build_version: u32, + pub abi_version: u32, +} +#[cfg(Py_3_15)] +pub const PyABIInfo_STABLE: u16 = 0x0001; +#[cfg(Py_3_15)] +pub const PyABIInfo_GIL: u16 = 0x0002; +#[cfg(Py_3_15)] +pub const PyABIInfo_FREETHREADED: u16 = 0x0004; +#[cfg(Py_3_15)] +pub const PyABIInfo_INTERNAL: u16 = 0x0008; + +#[cfg(Py_3_15)] +pub const PyABIInfo_FREETHREADING_AGNOSTIC: u16 = PyABIInfo_GIL | PyABIInfo_FREETHREADED; + +#[cfg(Py_3_15)] +extern_libpython! { + pub fn PyABIInfo_Check(info: *mut PyABIInfo, module_name: *const c_char) -> c_int; +} + +#[cfg(all(Py_LIMITED_API, Py_3_15))] +const _PyABIInfo_DEFAULT_FLAG_STABLE: u16 = PyABIInfo_STABLE; +#[cfg(all(Py_3_15, not(Py_LIMITED_API)))] +const _PyABIInfo_DEFAULT_FLAG_STABLE: u16 = 0; + +// skipped PyABIInfo_DEFAULT_ABI_VERSION: depends on Py_VERSION_HEX + +#[cfg(all(Py_3_15, all(Py_LIMITED_API, Py_GIL_DISABLED)))] +const _PyABIInfo_DEFAULT_FLAG_FT: u16 = PyABIInfo_FREETHREADING_AGNOSTIC; +#[cfg(all(Py_3_15, Py_GIL_DISABLED, not(Py_LIMITED_API)))] +const _PyABIInfo_DEFAULT_FLAG_FT: u16 = PyABIInfo_FREETHREADED; +#[cfg(all(Py_3_15, not(Py_GIL_DISABLED)))] +const _PyABIInfo_DEFAULT_FLAG_FT: u16 = PyABIInfo_GIL; + +#[cfg(Py_3_15)] +// has an alternate definition if Py_BUILD_CORE is set, ignore that +const _PyABIInfo_DEFAULT_FLAG_INTERNAL: u16 = 0; + +#[cfg(Py_3_15)] +pub const PyABIInfo_DEFAULT_FLAGS: u16 = + _PyABIInfo_DEFAULT_FLAG_STABLE | _PyABIInfo_DEFAULT_FLAG_FT | _PyABIInfo_DEFAULT_FLAG_INTERNAL; + +#[cfg(Py_3_15)] +// must be pub because it is used by PyABIInfo_VAR +pub const _PyABIInfo_DEFAULT: PyABIInfo = PyABIInfo { + abiinfo_major_version: 1, + abiinfo_minor_version: 0, + flags: PyABIInfo_DEFAULT_FLAGS, + build_version: 0, + abi_version: 0, +}; + +#[cfg(Py_3_15)] +#[macro_export] +macro_rules! PyABIInfo_VAR { + ($name:ident) => { + static mut $name: pyo3_ffi::PyABIInfo = pyo3_ffi::_PyABIInfo_DEFAULT; + }; +} diff --git a/vendor/pyo3-ffi/src/moduleobject.rs b/vendor/pyo3-ffi/src/moduleobject.rs new file mode 100644 index 0000000..f4ff551 --- /dev/null +++ b/vendor/pyo3-ffi/src/moduleobject.rs @@ -0,0 +1,149 @@ +#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))] +use crate::methodobject::PyMethodDef; +use crate::object::*; +use crate::pyport::Py_ssize_t; +// this is pub to avoid unnecessary churn elsewhere +#[cfg(all(Py_LIMITED_API, Py_GIL_DISABLED))] +pub use crate::pytypedefs::PyModuleDef; +#[cfg(Py_3_15)] +use crate::slots::PySlot; +use core::ffi::{c_char, c_int, c_void}; + +#[cfg(not(RustPython))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyModule_Type")] + pub static mut PyModule_Type: PyTypeObject; +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyModule_Check(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, &raw mut PyModule_Type) +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyModule_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyModule_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PyModule_Check(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyModule_CheckExact(op: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPyModule_NewObject")] + pub fn PyModule_NewObject(name: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyModule_New")] + pub fn PyModule_New(name: *const c_char) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyModule_GetDict")] + pub fn PyModule_GetDict(arg1: *mut PyObject) -> *mut PyObject; + #[cfg(not(PyPy))] + pub fn PyModule_GetNameObject(arg1: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyModule_GetName")] + pub fn PyModule_GetName(arg1: *mut PyObject) -> *const c_char; + #[cfg(not(all(windows, PyPy)))] + #[deprecated(note = "Python 3.2")] + pub fn PyModule_GetFilename(arg1: *mut PyObject) -> *const c_char; + #[cfg(not(PyPy))] + pub fn PyModule_GetFilenameObject(arg1: *mut PyObject) -> *mut PyObject; + // skipped non-limited _PyModule_Clear + // skipped non-limited _PyModule_ClearDict + // skipped non-limited _PyModuleSpec_IsInitializing + #[cfg_attr(PyPy, link_name = "PyPyModule_GetDef")] + pub fn PyModule_GetDef(arg1: *mut PyObject) -> *mut PyModuleDef; + #[cfg_attr(PyPy, link_name = "PyPyModule_GetState")] + pub fn PyModule_GetState(arg1: *mut PyObject) -> *mut c_void; + #[cfg_attr(PyPy, link_name = "PyPyModuleDef_Init")] + pub fn PyModuleDef_Init(arg1: *mut PyModuleDef) -> *mut PyObject; + + #[cfg(not(RustPython))] + pub static mut PyModuleDef_Type: PyTypeObject; +} + +#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))] +#[repr(C)] +pub struct PyModuleDef_Base { + pub ob_base: PyObject, + // Rust function pointers are non-null so an Option is needed here. + pub m_init: Option *mut PyObject>, + pub m_index: Py_ssize_t, + pub m_copy: *mut PyObject, +} + +#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))] +#[allow( + clippy::declare_interior_mutable_const, + reason = "contains atomic refcount on free-threaded builds" +)] +pub const PyModuleDef_HEAD_INIT: PyModuleDef_Base = PyModuleDef_Base { + ob_base: PyObject_HEAD_INIT, + m_init: None, + m_index: 0, + m_copy: core::ptr::null_mut(), +}; + +#[repr(C)] +#[derive(Copy, Clone, Eq, PartialEq)] +pub struct PyModuleDef_Slot { + pub slot: c_int, + pub value: *mut c_void, +} + +impl Default for PyModuleDef_Slot { + fn default() -> PyModuleDef_Slot { + PyModuleDef_Slot { + slot: 0, + value: core::ptr::null_mut(), + } + } +} + +#[cfg(Py_3_12)] +#[allow( + clippy::zero_ptr, + reason = "matches the way that the rest of these constants are defined" +)] +pub const Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED: *mut c_void = 0 as *mut c_void; +#[cfg(Py_3_12)] +pub const Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED: *mut c_void = 1 as *mut c_void; +#[cfg(Py_3_12)] +pub const Py_MOD_PER_INTERPRETER_GIL_SUPPORTED: *mut c_void = 2 as *mut c_void; + +#[cfg(Py_3_13)] +#[allow( + clippy::zero_ptr, + reason = "matches the way that the rest of these constants are defined" +)] +pub const Py_MOD_GIL_USED: *mut c_void = 0 as *mut c_void; +#[cfg(Py_3_13)] +pub const Py_MOD_GIL_NOT_USED: *mut c_void = 1 as *mut c_void; + +extern_libpython! { + #[cfg(all(not(Py_LIMITED_API), Py_GIL_DISABLED))] + pub fn PyUnstable_Module_SetGIL(module: *mut PyObject, gil: *mut c_void) -> c_int; +} + +#[cfg(Py_3_15)] +extern_libpython! { + pub fn PyModule_FromSlotsAndSpec(slots: *const PySlot, spec: *mut PyObject) -> *mut PyObject; + pub fn PyModule_Exec(_mod: *mut PyObject) -> c_int; + pub fn PyModule_GetStateSize(_mod: *mut PyObject, result: *mut Py_ssize_t) -> c_int; + pub fn PyModule_GetToken(module: *mut PyObject, result: *mut *mut c_void) -> c_int; +} + +#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))] +#[repr(C)] +pub struct PyModuleDef { + pub m_base: PyModuleDef_Base, + pub m_name: *const c_char, + pub m_doc: *const c_char, + pub m_size: Py_ssize_t, + pub m_methods: *mut PyMethodDef, + pub m_slots: *mut PyModuleDef_Slot, + // Rust function pointers are non-null so an Option is needed here. + pub m_traverse: Option, + pub m_clear: Option, + pub m_free: Option, +} diff --git a/vendor/pyo3-ffi/src/object.rs b/vendor/pyo3-ffi/src/object.rs new file mode 100644 index 0000000..a9bc476 --- /dev/null +++ b/vendor/pyo3-ffi/src/object.rs @@ -0,0 +1,774 @@ +use crate::pyport::{Py_hash_t, Py_ssize_t}; +// these re-exports are pub because it would be awkward to +// thread the different origins for these types on this build +// everywhere else +#[cfg(Py_LIMITED_API)] +pub use crate::pytypedefs::PyTypeObject; +#[cfg(all(Py_LIMITED_API, Py_GIL_DISABLED))] +pub use crate::pytypedefs::{PyObject, PyVarObject}; +#[cfg(Py_3_15)] +use crate::PySlot; +#[cfg(all(Py_GIL_DISABLED, not(Py_LIMITED_API)))] +use crate::{refcount, PyMutex}; +use core::ffi::{c_char, c_int, c_uint, c_ulong, c_void}; +use core::mem; +#[cfg(all(Py_GIL_DISABLED, not(Py_LIMITED_API)))] +use core::sync::atomic::{AtomicIsize, AtomicU32}; + +#[cfg(not(Py_LIMITED_API))] +pub use crate::cpython::object::PyTypeObject; + +// skip PyObject_HEAD + +#[repr(C)] +#[derive(Copy, Clone)] +#[cfg(all( + target_pointer_width = "64", + Py_3_14, + not(Py_GIL_DISABLED), + target_endian = "big" +))] +/// This struct is anonymous in CPython, so the name was given by PyO3 because +/// Rust structs need a name. +pub struct PyObjectObFlagsAndRefcnt { + pub ob_flags: u16, + pub ob_overflow: u16, + pub ob_refcnt: u32, +} + +#[repr(C)] +#[derive(Copy, Clone)] +#[cfg(all( + target_pointer_width = "64", + Py_3_14, + not(Py_GIL_DISABLED), + target_endian = "little" +))] +/// This struct is anonymous in CPython, so the name was given by PyO3 because +/// Rust structs need a name. +pub struct PyObjectObFlagsAndRefcnt { + pub ob_refcnt: u32, + pub ob_overflow: u16, + pub ob_flags: u16, +} + +// 4-byte alignment comes from value of _PyObject_MIN_ALIGNMENT + +#[cfg(all(not(Py_GIL_DISABLED), Py_3_15))] +#[repr(C, align(4))] +#[derive(Copy, Clone)] +struct Aligner(c_char); + +#[repr(C)] +#[derive(Copy, Clone)] +#[cfg(all(Py_3_12, not(Py_GIL_DISABLED)))] +/// This union is anonymous in CPython, so the name was given by PyO3 because +/// Rust union need a name. +pub union PyObjectObRefcnt { + #[cfg(all(target_pointer_width = "64", Py_3_14))] + pub ob_refcnt_full: crate::PY_INT64_T, + #[cfg(all(target_pointer_width = "64", Py_3_14))] + pub refcnt_and_flags: PyObjectObFlagsAndRefcnt, + pub ob_refcnt: Py_ssize_t, + #[cfg(all(target_pointer_width = "64", not(Py_3_14)))] + pub ob_refcnt_split: [crate::PY_UINT32_T; 2], + #[cfg(all(not(Py_GIL_DISABLED), Py_3_15))] + _aligner: Aligner, +} + +#[cfg(all(Py_3_12, not(Py_GIL_DISABLED)))] +impl core::fmt::Debug for PyObjectObRefcnt { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + // SAFETY: always valid to print `ob_refcnt` as a number + write!(f, "{}", unsafe { self.ob_refcnt }) + } +} + +#[cfg(all(not(Py_3_12), not(Py_GIL_DISABLED)))] +pub type PyObjectObRefcnt = Py_ssize_t; + +const _PyObject_MIN_ALIGNMENT: usize = 4; + +// PyObject_HEAD_INIT comes before the PyObject definition in object.h +// but we put it after PyObject because HEAD_INIT uses PyObject + +// repr(align(4)) corresponds to the use of _Py_ALIGNED_DEF in object.h. It is +// not currently possible to use constant variables with repr(align()), see +// https://github.com/rust-lang/rust/issues/52840 + +#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))] +#[cfg_attr(not(all(Py_3_15, Py_GIL_DISABLED)), repr(C))] +#[cfg_attr(all(Py_3_15, Py_GIL_DISABLED), repr(C, align(4)))] +#[derive(Debug)] +pub struct PyObject { + #[cfg(Py_GIL_DISABLED)] + pub ob_tid: libc::uintptr_t, + #[cfg(all(Py_GIL_DISABLED, not(Py_3_14)))] + pub _padding: u16, + #[cfg(all(Py_GIL_DISABLED, Py_3_14))] + pub ob_flags: u16, + #[cfg(Py_GIL_DISABLED)] + pub ob_mutex: PyMutex, // per-object lock + #[cfg(Py_GIL_DISABLED)] + pub ob_gc_bits: u8, // gc-related state + #[cfg(Py_GIL_DISABLED)] + pub ob_ref_local: AtomicU32, // local reference count + #[cfg(Py_GIL_DISABLED)] + pub ob_ref_shared: AtomicIsize, // shared reference count + #[cfg(not(Py_GIL_DISABLED))] + pub ob_refcnt: PyObjectObRefcnt, + #[cfg(PyPy)] + pub ob_pypy_link: Py_ssize_t, + pub ob_type: *mut PyTypeObject, +} + +#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))] +const _: () = assert!(core::mem::align_of::() >= _PyObject_MIN_ALIGNMENT); + +#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))] +#[allow( + clippy::declare_interior_mutable_const, + reason = "contains atomic refcount on free-threaded builds" +)] +pub const PyObject_HEAD_INIT: PyObject = PyObject { + #[cfg(Py_GIL_DISABLED)] + ob_tid: 0, + #[cfg(all(Py_GIL_DISABLED, Py_3_15))] + ob_flags: refcount::_Py_STATICALLY_ALLOCATED_FLAG as u16, + #[cfg(all(Py_GIL_DISABLED, all(Py_3_14, not(Py_3_15))))] + ob_flags: 0, + #[cfg(all(Py_GIL_DISABLED, not(Py_3_14)))] + _padding: 0, + #[cfg(Py_GIL_DISABLED)] + ob_mutex: PyMutex::new(), + #[cfg(Py_GIL_DISABLED)] + ob_gc_bits: 0, + #[cfg(Py_GIL_DISABLED)] + ob_ref_local: AtomicU32::new(refcount::_Py_IMMORTAL_REFCNT_LOCAL), + #[cfg(Py_GIL_DISABLED)] + ob_ref_shared: AtomicIsize::new(0), + #[cfg(all(not(Py_GIL_DISABLED), Py_3_12))] + ob_refcnt: PyObjectObRefcnt { ob_refcnt: 1 }, + #[cfg(not(Py_3_12))] + ob_refcnt: 1, + #[cfg(PyPy)] + ob_pypy_link: 0, + ob_type: core::ptr::null_mut(), +}; + +// skipped _Py_UNOWNED_TID + +// skipped _PyObject_CAST + +#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))] +#[repr(C)] +#[derive(Debug)] +pub struct PyVarObject { + pub ob_base: PyObject, + #[cfg(not(GraalPy))] + pub ob_size: Py_ssize_t, + // On GraalPy the field is physically there, but not always populated. We hide it to prevent accidental misuse + #[cfg(GraalPy)] + pub _ob_size_graalpy: Py_ssize_t, +} + +#[inline] +pub(crate) unsafe fn _PyVarObject_CAST(op: *mut PyObject) -> *mut PyVarObject { + op.cast() +} + +#[inline] +#[cfg(not(any(GraalPy, PyPy, RustPython)))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub unsafe fn Py_Is(x: *mut PyObject, y: *mut PyObject) -> c_int { + (x == y).into() +} + +#[cfg(any(GraalPy, PyPy, RustPython))] +#[cfg_attr(docsrs, doc(cfg(all())))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPy_Is")] + pub fn Py_Is(x: *mut PyObject, y: *mut PyObject) -> c_int; +} + +// skipped _Py_GetThreadLocal_Addr + +// skipped _Py_ThreadID + +// skipped _Py_IsOwnedByCurrentThread + +#[cfg(GraalPy)] +extern_libpython! { + #[cfg(GraalPy)] + fn _Py_TYPE(arg1: *const PyObject) -> *mut PyTypeObject; + + #[cfg(GraalPy)] + fn _Py_SIZE(arg1: *const PyObject) -> Py_ssize_t; +} + +#[inline] +#[cfg(not(all(Py_LIMITED_API, Py_3_14)))] +pub unsafe fn Py_TYPE(ob: *mut PyObject) -> *mut PyTypeObject { + #[cfg(not(GraalPy))] + return (*ob).ob_type; + #[cfg(GraalPy)] + return _Py_TYPE(ob); +} + +#[cfg(all(Py_LIMITED_API, Py_3_14))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPy_TYPE")] + pub fn Py_TYPE(ob: *mut PyObject) -> *mut PyTypeObject; +} + +// skip _Py_TYPE compat shim + +#[cfg(not(RustPython))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyLong_Type")] + pub static mut PyLong_Type: PyTypeObject; + #[cfg_attr(PyPy, link_name = "PyPyBool_Type")] + pub static mut PyBool_Type: PyTypeObject; +} + +#[cfg(not(all(Py_LIMITED_API, Py_3_15)))] +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn Py_SIZE(ob: *mut PyObject) -> Py_ssize_t { + #[cfg(not(GraalPy))] + { + debug_assert_ne!((*ob).ob_type, &raw mut crate::PyLong_Type); + debug_assert_ne!((*ob).ob_type, &raw mut crate::PyBool_Type); + (*ob.cast::()).ob_size + } + #[cfg(GraalPy)] + _Py_SIZE(ob) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn Py_SIZE(ob: *mut PyObject) -> Py_ssize_t; + #[cfg(any(all(Py_LIMITED_API, Py_3_15), RustPython))] + pub fn Py_IS_TYPE(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_int; +} + +#[inline] +#[cfg(not(any(all(Py_LIMITED_API, Py_3_15), RustPython)))] +pub unsafe fn Py_IS_TYPE(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_int { + (Py_TYPE(ob) == tp) as c_int +} + +// skipped Py_SET_TYPE + +// skipped Py_SET_SIZE + +pub type unaryfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject; +pub type binaryfunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject) -> *mut PyObject; +pub type ternaryfunc = + unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> *mut PyObject; +pub type inquiry = unsafe extern "C" fn(*mut PyObject) -> c_int; +pub type lenfunc = unsafe extern "C" fn(*mut PyObject) -> Py_ssize_t; +pub type ssizeargfunc = unsafe extern "C" fn(*mut PyObject, Py_ssize_t) -> *mut PyObject; +pub type ssizessizeargfunc = + unsafe extern "C" fn(*mut PyObject, Py_ssize_t, Py_ssize_t) -> *mut PyObject; +pub type ssizeobjargproc = unsafe extern "C" fn(*mut PyObject, Py_ssize_t, *mut PyObject) -> c_int; +pub type ssizessizeobjargproc = + unsafe extern "C" fn(*mut PyObject, Py_ssize_t, Py_ssize_t, arg4: *mut PyObject) -> c_int; +pub type objobjargproc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int; + +pub type objobjproc = unsafe extern "C" fn(*mut PyObject, *mut PyObject) -> c_int; +pub type visitproc = unsafe extern "C" fn(object: *mut PyObject, arg: *mut c_void) -> c_int; +pub type traverseproc = + unsafe extern "C" fn(slf: *mut PyObject, visit: visitproc, arg: *mut c_void) -> c_int; + +pub type freefunc = unsafe extern "C" fn(*mut c_void); +pub type destructor = unsafe extern "C" fn(*mut PyObject); +pub type getattrfunc = unsafe extern "C" fn(*mut PyObject, *mut c_char) -> *mut PyObject; +pub type getattrofunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject) -> *mut PyObject; +pub type setattrfunc = unsafe extern "C" fn(*mut PyObject, *mut c_char, *mut PyObject) -> c_int; +pub type setattrofunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int; +pub type reprfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject; +pub type hashfunc = unsafe extern "C" fn(*mut PyObject) -> Py_hash_t; +pub type richcmpfunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, c_int) -> *mut PyObject; +pub type getiterfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject; +pub type iternextfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject; +#[cfg(Py_3_15)] +#[repr(C)] +pub struct _PyObjectIndexPair { + pub object: *mut PyObject, + pub index: Py_ssize_t, +} +#[cfg(Py_3_15)] +pub type _Py_iteritemfunc = unsafe extern "C" fn(*mut PyObject, Py_ssize_t) -> _PyObjectIndexPair; +pub type descrgetfunc = + unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> *mut PyObject; +pub type descrsetfunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int; +pub type initproc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int; +pub type newfunc = + unsafe extern "C" fn(*mut PyTypeObject, *mut PyObject, *mut PyObject) -> *mut PyObject; +pub type allocfunc = unsafe extern "C" fn(*mut PyTypeObject, Py_ssize_t) -> *mut PyObject; +pub type vectorcallfunc = unsafe extern "C" fn( + callable: *mut PyObject, + args: *const *mut PyObject, + nargsf: libc::size_t, + kwnames: *mut PyObject, +) -> *mut PyObject; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyType_Slot { + pub slot: c_int, + pub pfunc: *mut c_void, +} + +impl Default for PyType_Slot { + fn default() -> PyType_Slot { + // SAFETY: CPython treats a zeroed slot as a sentinel value to mean the end of the slots array. + unsafe { mem::zeroed() } + } +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyType_Spec { + pub name: *const c_char, + pub basicsize: c_int, + pub itemsize: c_int, + pub flags: c_uint, + pub slots: *mut PyType_Slot, +} + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyType_FromSpec")] + pub fn PyType_FromSpec(arg1: *mut PyType_Spec) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyType_FromSpecWithBases")] + pub fn PyType_FromSpecWithBases(arg1: *mut PyType_Spec, arg2: *mut PyObject) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyType_GetSlot")] + pub fn PyType_GetSlot(arg1: *mut PyTypeObject, arg2: c_int) -> *mut c_void; + + #[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))] + #[cfg_attr(PyPy, link_name = "PyPyType_FromModuleAndSpec")] + pub fn PyType_FromModuleAndSpec( + module: *mut PyObject, + spec: *mut PyType_Spec, + bases: *mut PyObject, + ) -> *mut PyObject; + + #[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))] + #[cfg_attr(PyPy, link_name = "PyPyType_GetModule")] + pub fn PyType_GetModule(arg1: *mut PyTypeObject) -> *mut PyObject; + + #[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))] + #[cfg_attr(PyPy, link_name = "PyPyType_GetModuleState")] + pub fn PyType_GetModuleState(arg1: *mut PyTypeObject) -> *mut c_void; + + #[cfg(Py_3_11)] + #[cfg_attr(PyPy, link_name = "PyPyType_GetName")] + pub fn PyType_GetName(arg1: *mut PyTypeObject) -> *mut PyObject; + + #[cfg(Py_3_11)] + #[cfg_attr(PyPy, link_name = "PyPyType_GetQualName")] + pub fn PyType_GetQualName(arg1: *mut PyTypeObject) -> *mut PyObject; + + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyType_GetFullyQualifiedName")] + pub fn PyType_GetFullyQualifiedName(arg1: *mut PyTypeObject) -> *mut PyObject; + + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyType_GetModuleName")] + pub fn PyType_GetModuleName(arg1: *mut PyTypeObject) -> *mut PyObject; + + #[cfg(Py_3_12)] + #[cfg_attr(PyPy, link_name = "PyPyType_FromMetaclass")] + pub fn PyType_FromMetaclass( + metaclass: *mut PyTypeObject, + module: *mut PyObject, + spec: *mut PyType_Spec, + bases: *mut PyObject, + ) -> *mut PyObject; + + #[cfg(Py_3_12)] + #[cfg_attr(PyPy, link_name = "PyPyObject_GetTypeData")] + pub fn PyObject_GetTypeData(obj: *mut PyObject, cls: *mut PyTypeObject) -> *mut c_void; + + #[cfg(Py_3_12)] + #[cfg_attr(PyPy, link_name = "PyPyType_GetTypeDataSize")] + pub fn PyType_GetTypeDataSize(cls: *mut PyTypeObject) -> Py_ssize_t; + + #[cfg(Py_3_14)] + #[cfg_attr(PyPy, link_name = "PyPyType_GetBaseByToken")] + pub fn PyType_GetBaseByToken( + type_: *mut PyTypeObject, + token: *mut c_void, + result: *mut *mut PyTypeObject, + ) -> c_int; + + #[cfg(Py_3_15)] + #[cfg_attr(PyPy, link_name = "PyPyType_FromSlot")] + pub fn PyType_FromSlots(slots: *mut PySlot) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyType_IsSubtype")] + pub fn PyType_IsSubtype(a: *mut PyTypeObject, b: *mut PyTypeObject) -> c_int; +} + +#[inline] +pub unsafe fn PyObject_TypeCheck(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_int { + (Py_IS_TYPE(ob, tp) != 0 || PyType_IsSubtype(Py_TYPE(ob), tp) != 0) as c_int +} + +extern_libpython! { + /// built-in 'type' + #[cfg(not(RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyType_Type")] + pub static mut PyType_Type: PyTypeObject; + /// built-in 'object' + #[cfg(not(RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyBaseObject_Type")] + pub static mut PyBaseObject_Type: PyTypeObject; + /// built-in 'super' + #[cfg(not(RustPython))] + pub static mut PySuper_Type: PyTypeObject; + + pub fn PyType_GetFlags(arg1: *mut PyTypeObject) -> c_ulong; + + #[cfg_attr(PyPy, link_name = "PyPyType_Ready")] + pub fn PyType_Ready(t: *mut PyTypeObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyType_GenericAlloc")] + pub fn PyType_GenericAlloc(t: *mut PyTypeObject, nitems: Py_ssize_t) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyType_GenericNew")] + pub fn PyType_GenericNew( + t: *mut PyTypeObject, + args: *mut PyObject, + kwds: *mut PyObject, + ) -> *mut PyObject; + pub fn PyType_ClearCache() -> c_uint; + #[cfg_attr(PyPy, link_name = "PyPyType_Modified")] + pub fn PyType_Modified(t: *mut PyTypeObject); + + #[cfg_attr(PyPy, link_name = "PyPyObject_Repr")] + pub fn PyObject_Repr(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_Str")] + pub fn PyObject_Str(o: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_ASCII")] + pub fn PyObject_ASCII(arg1: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_Bytes")] + pub fn PyObject_Bytes(arg1: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_RichCompare")] + pub fn PyObject_RichCompare( + arg1: *mut PyObject, + arg2: *mut PyObject, + arg3: c_int, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_RichCompareBool")] + pub fn PyObject_RichCompareBool(arg1: *mut PyObject, arg2: *mut PyObject, arg3: c_int) + -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyObject_GetAttrString")] + pub fn PyObject_GetAttrString(arg1: *mut PyObject, arg2: *const c_char) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_SetAttrString")] + pub fn PyObject_SetAttrString( + arg1: *mut PyObject, + arg2: *const c_char, + arg3: *mut PyObject, + ) -> c_int; + #[cfg(any(Py_3_13, all(PyPy, not(Py_3_11))))] // CPython defined in 3.12 as an inline function in abstract.h + #[cfg_attr(PyPy, link_name = "PyPyObject_DelAttrString")] + pub fn PyObject_DelAttrString(arg1: *mut PyObject, arg2: *const c_char) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyObject_HasAttrString")] + pub fn PyObject_HasAttrString(arg1: *mut PyObject, arg2: *const c_char) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyObject_GetAttr")] + pub fn PyObject_GetAttr(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyObject_GetOptionalAttr")] + pub fn PyObject_GetOptionalAttr( + arg1: *mut PyObject, + arg2: *mut PyObject, + arg3: *mut *mut PyObject, + ) -> c_int; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyObject_GetOptionalAttrString")] + pub fn PyObject_GetOptionalAttrString( + arg1: *mut PyObject, + arg2: *const c_char, + arg3: *mut *mut PyObject, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyObject_SetAttr")] + pub fn PyObject_SetAttr(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject) + -> c_int; + #[cfg(any(Py_3_13, all(PyPy, not(Py_3_11))))] // CPython defined in 3.12 as an inline function in abstract.h + #[cfg_attr(PyPy, link_name = "PyPyObject_DelAttr")] + pub fn PyObject_DelAttr(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyObject_HasAttr")] + pub fn PyObject_HasAttr(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyObject_HasAttrWithError")] + pub fn PyObject_HasAttrWithError(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyObject_HasAttrStringWithError")] + pub fn PyObject_HasAttrStringWithError(arg1: *mut PyObject, arg2: *const c_char) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyObject_SelfIter")] + pub fn PyObject_SelfIter(arg1: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_GenericGetAttr")] + pub fn PyObject_GenericGetAttr(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_GenericSetAttr")] + pub fn PyObject_GenericSetAttr( + arg1: *mut PyObject, + arg2: *mut PyObject, + arg3: *mut PyObject, + ) -> c_int; + #[cfg(not(all(Py_LIMITED_API, not(Py_3_10))))] + #[cfg_attr(PyPy, link_name = "PyPyObject_GenericGetDict")] + pub fn PyObject_GenericGetDict(arg1: *mut PyObject, arg2: *mut c_void) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_GenericSetDict")] + pub fn PyObject_GenericSetDict( + arg1: *mut PyObject, + arg2: *mut PyObject, + arg3: *mut c_void, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyObject_Hash")] + pub fn PyObject_Hash(arg1: *mut PyObject) -> Py_hash_t; + #[cfg_attr(PyPy, link_name = "PyPyObject_HashNotImplemented")] + pub fn PyObject_HashNotImplemented(arg1: *mut PyObject) -> Py_hash_t; + #[cfg_attr(PyPy, link_name = "PyPyObject_IsTrue")] + pub fn PyObject_IsTrue(arg1: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyObject_Not")] + pub fn PyObject_Not(arg1: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyCallable_Check")] + pub fn PyCallable_Check(arg1: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyObject_ClearWeakRefs")] + pub fn PyObject_ClearWeakRefs(arg1: *mut PyObject); + + #[cfg_attr(PyPy, link_name = "PyPyObject_Dir")] + pub fn PyObject_Dir(arg1: *mut PyObject) -> *mut PyObject; + pub fn Py_ReprEnter(arg1: *mut PyObject) -> c_int; + pub fn Py_ReprLeave(arg1: *mut PyObject); +} + +// Flag bits for printing: +pub const Py_PRINT_RAW: c_int = 1; // No string quotes etc. + +// skipped because is a private API +// const _Py_TPFLAGS_STATIC_BUILTIN: c_ulong = 1 << 1; + +#[cfg(all(Py_3_12, not(Py_LIMITED_API)))] +pub const Py_TPFLAGS_MANAGED_WEAKREF: c_ulong = 1 << 3; + +#[cfg(all(Py_3_11, not(Py_LIMITED_API)))] +pub const Py_TPFLAGS_MANAGED_DICT: c_ulong = 1 << 4; + +#[cfg(all(Py_3_10, not(Py_LIMITED_API)))] +pub const Py_TPFLAGS_SEQUENCE: c_ulong = 1 << 5; + +#[cfg(all(Py_3_10, not(Py_LIMITED_API)))] +pub const Py_TPFLAGS_MAPPING: c_ulong = 1 << 6; + +#[cfg(Py_3_10)] +pub const Py_TPFLAGS_DISALLOW_INSTANTIATION: c_ulong = 1 << 7; + +#[cfg(Py_3_10)] +pub const Py_TPFLAGS_IMMUTABLETYPE: c_ulong = 1 << 8; + +/// Set if the type object is dynamically allocated +pub const Py_TPFLAGS_HEAPTYPE: c_ulong = 1 << 9; + +/// Set if the type allows subclassing +pub const Py_TPFLAGS_BASETYPE: c_ulong = 1 << 10; + +/// Set if the type implements the vectorcall protocol (PEP 590) +#[cfg(any(Py_3_12, not(Py_LIMITED_API)))] +pub const Py_TPFLAGS_HAVE_VECTORCALL: c_ulong = 1 << 11; +// skipped backwards-compatibility alias _Py_TPFLAGS_HAVE_VECTORCALL + +/// Set if the type is 'ready' -- fully initialized +pub const Py_TPFLAGS_READY: c_ulong = 1 << 12; + +/// Set while the type is being 'readied', to prevent recursive ready calls +pub const Py_TPFLAGS_READYING: c_ulong = 1 << 13; + +/// Objects support garbage collection (see objimp.h) +pub const Py_TPFLAGS_HAVE_GC: c_ulong = 1 << 14; + +const Py_TPFLAGS_HAVE_STACKLESS_EXTENSION: c_ulong = 0; +pub const Py_TPFLAGS_METHOD_DESCRIPTOR: c_ulong = 1 << 17; + +pub const Py_TPFLAGS_VALID_VERSION_TAG: c_ulong = 1 << 19; + +/* Type is abstract and cannot be instantiated */ +pub const Py_TPFLAGS_IS_ABSTRACT: c_ulong = 1 << 20; + +// skipped non-limited / 3.10 Py_TPFLAGS_HAVE_AM_SEND +#[cfg(Py_3_12)] +pub const Py_TPFLAGS_ITEMS_AT_END: c_ulong = 1 << 23; + +/* These flags are used to determine if a type is a subclass. */ +pub const Py_TPFLAGS_LONG_SUBCLASS: c_ulong = 1 << 24; +pub const Py_TPFLAGS_LIST_SUBCLASS: c_ulong = 1 << 25; +pub const Py_TPFLAGS_TUPLE_SUBCLASS: c_ulong = 1 << 26; +pub const Py_TPFLAGS_BYTES_SUBCLASS: c_ulong = 1 << 27; +pub const Py_TPFLAGS_UNICODE_SUBCLASS: c_ulong = 1 << 28; +pub const Py_TPFLAGS_DICT_SUBCLASS: c_ulong = 1 << 29; +pub const Py_TPFLAGS_BASE_EXC_SUBCLASS: c_ulong = 1 << 30; +pub const Py_TPFLAGS_TYPE_SUBCLASS: c_ulong = 1 << 31; + +pub const Py_TPFLAGS_DEFAULT: c_ulong = if cfg!(Py_3_10) { + Py_TPFLAGS_HAVE_STACKLESS_EXTENSION +} else { + Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | Py_TPFLAGS_HAVE_VERSION_TAG +}; + +pub const Py_TPFLAGS_HAVE_FINALIZE: c_ulong = 1; +pub const Py_TPFLAGS_HAVE_VERSION_TAG: c_ulong = 1 << 18; + +#[cfg(Py_3_13)] +pub const Py_CONSTANT_NONE: c_uint = 0; +#[cfg(Py_3_13)] +pub const Py_CONSTANT_FALSE: c_uint = 1; +#[cfg(Py_3_13)] +pub const Py_CONSTANT_TRUE: c_uint = 2; +#[cfg(Py_3_13)] +pub const Py_CONSTANT_ELLIPSIS: c_uint = 3; +#[cfg(Py_3_13)] +pub const Py_CONSTANT_NOT_IMPLEMENTED: c_uint = 4; +#[cfg(Py_3_13)] +pub const Py_CONSTANT_ZERO: c_uint = 5; +#[cfg(Py_3_13)] +pub const Py_CONSTANT_ONE: c_uint = 6; +#[cfg(Py_3_13)] +pub const Py_CONSTANT_EMPTY_STR: c_uint = 7; +#[cfg(Py_3_13)] +pub const Py_CONSTANT_EMPTY_BYTES: c_uint = 8; +#[cfg(Py_3_13)] +pub const Py_CONSTANT_EMPTY_TUPLE: c_uint = 9; + +extern_libpython! { + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPy_GetConstant")] + pub fn Py_GetConstant(constant_id: c_uint) -> *mut PyObject; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPy_GetConstantBorrowed")] + pub fn Py_GetConstantBorrowed(constant_id: c_uint) -> *mut PyObject; + + #[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))] + #[cfg_attr(PyPy, link_name = "_PyPy_NoneStruct")] + static mut _Py_NoneStruct: PyObject; + + #[cfg(GraalPy)] + static mut _Py_NoneStructReference: *mut PyObject; +} + +#[inline] +pub unsafe fn Py_None() -> *mut PyObject { + #[cfg(all(not(GraalPy), all(Py_3_13, Py_LIMITED_API)))] + return Py_GetConstantBorrowed(Py_CONSTANT_NONE); + + #[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))] + return &raw mut _Py_NoneStruct; + + #[cfg(GraalPy)] + return _Py_NoneStructReference; +} + +#[inline] +pub unsafe fn Py_IsNone(x: *mut PyObject) -> c_int { + Py_Is(x, Py_None()) +} + +// skipped Py_RETURN_NONE + +extern_libpython! { + #[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))] + #[cfg_attr(PyPy, link_name = "_PyPy_NotImplementedStruct")] + static mut _Py_NotImplementedStruct: PyObject; + + #[cfg(GraalPy)] + static mut _Py_NotImplementedStructReference: *mut PyObject; +} + +#[inline] +pub unsafe fn Py_NotImplemented() -> *mut PyObject { + #[cfg(all(not(GraalPy), all(Py_3_13, Py_LIMITED_API)))] + return Py_GetConstantBorrowed(Py_CONSTANT_NOT_IMPLEMENTED); + + #[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))] + return &raw mut _Py_NotImplementedStruct; + + #[cfg(GraalPy)] + return _Py_NotImplementedStructReference; +} + +// skipped Py_RETURN_NOTIMPLEMENTED + +/* Rich comparison opcodes */ +pub const Py_LT: c_int = 0; +pub const Py_LE: c_int = 1; +pub const Py_EQ: c_int = 2; +pub const Py_NE: c_int = 3; +pub const Py_GT: c_int = 4; +pub const Py_GE: c_int = 5; + +#[cfg(Py_3_10)] +#[repr(C)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum PySendResult { + PYGEN_RETURN = 0, + PYGEN_ERROR = -1, + PYGEN_NEXT = 1, +} + +// skipped Py_RETURN_RICHCOMPARE + +#[inline] +pub unsafe fn PyType_HasFeature(ty: *mut PyTypeObject, feature: c_ulong) -> c_int { + #[cfg(Py_LIMITED_API)] + let flags = PyType_GetFlags(ty); + + #[cfg(all(not(Py_LIMITED_API), Py_GIL_DISABLED))] + let flags = (*ty).tp_flags.load(core::sync::atomic::Ordering::Relaxed); + + #[cfg(all(not(Py_LIMITED_API), not(Py_GIL_DISABLED)))] + let flags = (*ty).tp_flags; + + ((flags & feature) != 0) as c_int +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyType_FastSubclass(t: *mut PyTypeObject, f: c_ulong) -> c_int { + PyType_HasFeature(t, f) +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyType_Check(op: *mut PyObject) -> c_int { + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS) +} + +// skipped _PyType_CAST + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyType_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyType_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PyType_Check(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyType_CheckExact(op: *mut PyObject) -> c_int; + + #[cfg(any(Py_3_13, all(Py_3_11, not(Py_LIMITED_API))))] + #[cfg_attr(PyPy, link_name = "PyPyType_GetModuleByDef")] + pub fn PyType_GetModuleByDef( + arg1: *mut crate::PyTypeObject, + arg2: *mut crate::PyModuleDef, + ) -> *mut PyObject; + + #[cfg(Py_3_14)] + pub fn PyType_Freeze(tp: *mut crate::PyTypeObject) -> c_int; + + #[cfg(Py_3_15)] + pub fn PyType_GetModuleByToken(_type: *mut PyTypeObject, token: *const c_void) + -> *mut PyObject; +} diff --git a/vendor/pyo3-ffi/src/objimpl.rs b/vendor/pyo3-ffi/src/objimpl.rs new file mode 100644 index 0000000..bad80a1 --- /dev/null +++ b/vendor/pyo3-ffi/src/objimpl.rs @@ -0,0 +1,121 @@ +use core::ffi::{c_int, c_void}; +use libc::size_t; + +use crate::object::*; +use crate::pyport::Py_ssize_t; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyObject_Malloc")] + pub fn PyObject_Malloc(size: size_t) -> *mut c_void; + #[cfg_attr(PyPy, link_name = "PyPyObject_Calloc")] + pub fn PyObject_Calloc(nelem: size_t, elsize: size_t) -> *mut c_void; + #[cfg_attr(PyPy, link_name = "PyPyObject_Realloc")] + pub fn PyObject_Realloc(ptr: *mut c_void, new_size: size_t) -> *mut c_void; + #[cfg_attr(PyPy, link_name = "PyPyObject_Free")] + pub fn PyObject_Free(ptr: *mut c_void); + + // skipped PyObject_MALLOC + // skipped PyObject_REALLOC + // skipped PyObject_FREE + // skipped PyObject_Del + // skipped PyObject_DEL + + #[cfg_attr(PyPy, link_name = "PyPyObject_Init")] + pub fn PyObject_Init(arg1: *mut PyObject, arg2: *mut PyTypeObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyObject_InitVar")] + pub fn PyObject_InitVar( + arg1: *mut PyVarObject, + arg2: *mut PyTypeObject, + arg3: Py_ssize_t, + ) -> *mut PyVarObject; + + // skipped PyObject_INIT + // skipped PyObject_INIT_VAR + + #[cfg_attr(PyPy, link_name = "_PyPyObject_New")] + fn _PyObject_New(typeobj: *mut PyTypeObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "_PyPyObject_NewVar")] + fn _PyObject_NewVar(typeobj: *mut PyTypeObject, n: Py_ssize_t) -> *mut PyVarObject; +} + +#[inline] +pub unsafe fn PyObject_New(typeobj: *mut PyTypeObject) -> *mut T { + _PyObject_New(typeobj).cast() +} + +// skipped PyObject_NEW + +#[inline] +pub unsafe fn PyObject_NewVar(typeobj: *mut PyTypeObject, n: Py_ssize_t) -> *mut T { + _PyObject_NewVar(typeobj, n).cast() +} + +// skipped PyObject_NEW_VAR + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyGC_Collect")] + pub fn PyGC_Collect() -> Py_ssize_t; + + #[cfg(Py_3_10)] + #[cfg_attr(PyPy, link_name = "PyPyGC_Enable")] + pub fn PyGC_Enable() -> c_int; + + #[cfg(Py_3_10)] + #[cfg_attr(PyPy, link_name = "PyPyGC_Disable")] + pub fn PyGC_Disable() -> c_int; + + #[cfg(Py_3_10)] + #[cfg_attr(PyPy, link_name = "PyPyGC_IsEnabled")] + pub fn PyGC_IsEnabled() -> c_int; +} + +#[inline] +pub unsafe fn PyType_IS_GC(t: *mut PyTypeObject) -> c_int { + PyType_HasFeature(t, Py_TPFLAGS_HAVE_GC) +} + +extern_libpython! { + fn _PyObject_GC_Resize(op: *mut PyVarObject, n: Py_ssize_t) -> *mut PyVarObject; +} + +#[inline] +pub unsafe fn PyObject_GC_Resize(op: *mut PyObject, n: Py_ssize_t) -> *mut T { + _PyObject_GC_Resize(op.cast(), n).cast() +} + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "_PyPyObject_GC_New")] + fn _PyObject_GC_New(typeobj: *mut PyTypeObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "_PyPyObject_GC_NewVar")] + fn _PyObject_GC_NewVar(typeobj: *mut PyTypeObject, n: Py_ssize_t) -> *mut PyVarObject; + + #[cfg(not(PyPy))] + pub fn PyObject_GC_Track(arg1: *mut c_void); + + #[cfg(not(PyPy))] + pub fn PyObject_GC_UnTrack(arg1: *mut c_void); + + #[cfg_attr(PyPy, link_name = "PyPyObject_GC_Del")] + pub fn PyObject_GC_Del(arg1: *mut c_void); +} + +#[inline] +pub unsafe fn PyObject_GC_New(typeobj: *mut PyTypeObject) -> *mut T { + _PyObject_GC_New(typeobj).cast() +} + +#[inline] +pub unsafe fn PyObject_GC_NewVar(typeobj: *mut PyTypeObject, n: Py_ssize_t) -> *mut T { + _PyObject_GC_NewVar(typeobj, n).cast() +} + +extern_libpython! { + #[cfg(any(all(Py_3_9, not(PyPy)), Py_3_10))] // added in 3.9, or 3.10 on PyPy + #[cfg_attr(PyPy, link_name = "PyPyObject_GC_IsTracked")] + pub fn PyObject_GC_IsTracked(arg1: *mut PyObject) -> c_int; + #[cfg(any(all(Py_3_9, not(PyPy)), Py_3_10))] // added in 3.9, or 3.10 on PyPy + #[cfg_attr(PyPy, link_name = "PyPyObject_GC_IsFinalized")] + pub fn PyObject_GC_IsFinalized(arg1: *mut PyObject) -> c_int; +} + +// skipped Py_VISIT diff --git a/vendor/pyo3-ffi/src/osmodule.rs b/vendor/pyo3-ffi/src/osmodule.rs new file mode 100644 index 0000000..84ce095 --- /dev/null +++ b/vendor/pyo3-ffi/src/osmodule.rs @@ -0,0 +1,6 @@ +use crate::object::PyObject; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyOS_FSPath")] + pub fn PyOS_FSPath(path: *mut PyObject) -> *mut PyObject; +} diff --git a/vendor/pyo3-ffi/src/pyarena.rs b/vendor/pyo3-ffi/src/pyarena.rs new file mode 100644 index 0000000..1200de3 --- /dev/null +++ b/vendor/pyo3-ffi/src/pyarena.rs @@ -0,0 +1 @@ +opaque_struct!(pub PyArena); diff --git a/vendor/pyo3-ffi/src/pybuffer.rs b/vendor/pyo3-ffi/src/pybuffer.rs new file mode 100644 index 0000000..83975c7 --- /dev/null +++ b/vendor/pyo3-ffi/src/pybuffer.rs @@ -0,0 +1,134 @@ +use crate::object::PyObject; +use crate::pyport::Py_ssize_t; +use core::ffi::{c_char, c_int, c_void}; +use core::ptr; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct Py_buffer { + pub buf: *mut c_void, + /// Owned reference + pub obj: *mut crate::PyObject, + pub len: Py_ssize_t, + pub itemsize: Py_ssize_t, + pub readonly: c_int, + pub ndim: c_int, + pub format: *mut c_char, + pub shape: *mut Py_ssize_t, + pub strides: *mut Py_ssize_t, + pub suboffsets: *mut Py_ssize_t, + pub internal: *mut c_void, + #[cfg(PyPy)] + pub flags: c_int, + #[cfg(PyPy)] + pub _strides: [Py_ssize_t; PyBUF_MAX_NDIM], + #[cfg(PyPy)] + pub _shape: [Py_ssize_t; PyBUF_MAX_NDIM], +} + +impl Py_buffer { + #[allow(clippy::new_without_default)] + pub const fn new() -> Self { + Py_buffer { + buf: ptr::null_mut(), + obj: ptr::null_mut(), + len: 0, + itemsize: 0, + readonly: 0, + ndim: 0, + format: ptr::null_mut(), + shape: ptr::null_mut(), + strides: ptr::null_mut(), + suboffsets: ptr::null_mut(), + internal: ptr::null_mut(), + #[cfg(PyPy)] + flags: 0, + #[cfg(PyPy)] + _strides: [0; PyBUF_MAX_NDIM], + #[cfg(PyPy)] + _shape: [0; PyBUF_MAX_NDIM], + } + } +} + +pub type getbufferproc = unsafe extern "C" fn(*mut PyObject, *mut crate::Py_buffer, c_int) -> c_int; +pub type releasebufferproc = unsafe extern "C" fn(*mut PyObject, *mut crate::Py_buffer); + +/* Return 1 if the getbuffer function is available, otherwise return 0. */ +extern_libpython! { + #[cfg(not(PyPy))] + pub fn PyObject_CheckBuffer(obj: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPyObject_GetBuffer")] + pub fn PyObject_GetBuffer(obj: *mut PyObject, view: *mut Py_buffer, flags: c_int) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyBuffer_GetPointer")] + pub fn PyBuffer_GetPointer(view: *const Py_buffer, indices: *const Py_ssize_t) -> *mut c_void; + #[cfg_attr(PyPy, link_name = "PyPyBuffer_SizeFromFormat")] + pub fn PyBuffer_SizeFromFormat(format: *const c_char) -> Py_ssize_t; + #[cfg_attr(PyPy, link_name = "PyPyBuffer_ToContiguous")] + pub fn PyBuffer_ToContiguous( + buf: *mut c_void, + view: *const Py_buffer, + len: Py_ssize_t, + order: c_char, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyBuffer_FromContiguous")] + pub fn PyBuffer_FromContiguous( + view: *const Py_buffer, + buf: *const c_void, + len: Py_ssize_t, + order: c_char, + ) -> c_int; + pub fn PyObject_CopyData(dest: *mut PyObject, src: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyBuffer_IsContiguous")] + pub fn PyBuffer_IsContiguous(view: *const Py_buffer, fort: c_char) -> c_int; + pub fn PyBuffer_FillContiguousStrides( + ndims: c_int, + shape: *mut Py_ssize_t, + strides: *mut Py_ssize_t, + itemsize: c_int, + fort: c_char, + ); + #[cfg_attr(PyPy, link_name = "PyPyBuffer_FillInfo")] + pub fn PyBuffer_FillInfo( + view: *mut Py_buffer, + o: *mut PyObject, + buf: *mut c_void, + len: Py_ssize_t, + readonly: c_int, + flags: c_int, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyBuffer_Release")] + pub fn PyBuffer_Release(view: *mut Py_buffer); +} + +/// Maximum number of dimensions +pub const PyBUF_MAX_NDIM: usize = 64; + +/* Flags for getting buffers */ +pub const PyBUF_SIMPLE: c_int = 0; +pub const PyBUF_WRITABLE: c_int = 0x0001; +/* we used to include an E, backwards compatible alias */ +pub const PyBUF_WRITEABLE: c_int = PyBUF_WRITABLE; +pub const PyBUF_FORMAT: c_int = 0x0004; +pub const PyBUF_ND: c_int = 0x0008; +pub const PyBUF_STRIDES: c_int = 0x0010 | PyBUF_ND; +pub const PyBUF_C_CONTIGUOUS: c_int = 0x0020 | PyBUF_STRIDES; +pub const PyBUF_F_CONTIGUOUS: c_int = 0x0040 | PyBUF_STRIDES; +pub const PyBUF_ANY_CONTIGUOUS: c_int = 0x0080 | PyBUF_STRIDES; +pub const PyBUF_INDIRECT: c_int = 0x0100 | PyBUF_STRIDES; + +pub const PyBUF_CONTIG: c_int = PyBUF_ND | PyBUF_WRITABLE; +pub const PyBUF_CONTIG_RO: c_int = PyBUF_ND; + +pub const PyBUF_STRIDED: c_int = PyBUF_STRIDES | PyBUF_WRITABLE; +pub const PyBUF_STRIDED_RO: c_int = PyBUF_STRIDES; + +pub const PyBUF_RECORDS: c_int = PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT; +pub const PyBUF_RECORDS_RO: c_int = PyBUF_STRIDES | PyBUF_FORMAT; + +pub const PyBUF_FULL: c_int = PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT; +pub const PyBUF_FULL_RO: c_int = PyBUF_INDIRECT | PyBUF_FORMAT; + +pub const PyBUF_READ: c_int = 0x100; +pub const PyBUF_WRITE: c_int = 0x200; diff --git a/vendor/pyo3-ffi/src/pycapsule.rs b/vendor/pyo3-ffi/src/pycapsule.rs new file mode 100644 index 0000000..a5a3df9 --- /dev/null +++ b/vendor/pyo3-ffi/src/pycapsule.rs @@ -0,0 +1,51 @@ +use crate::object::*; +use core::ffi::{c_char, c_int, c_void}; + +#[cfg(not(RustPython))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyCapsule_Type")] + pub static mut PyCapsule_Type: PyTypeObject; +} + +pub type PyCapsule_Destructor = unsafe extern "C" fn(o: *mut PyObject); + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyCapsule_CheckExact(ob: *mut PyObject) -> c_int { + (Py_TYPE(ob) == &raw mut PyCapsule_Type) as c_int +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PyCapsule_CheckExact(ob: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPyCapsule_New")] + pub fn PyCapsule_New( + pointer: *mut c_void, + name: *const c_char, + destructor: Option, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyCapsule_GetPointer")] + pub fn PyCapsule_GetPointer(capsule: *mut PyObject, name: *const c_char) -> *mut c_void; + #[cfg_attr(PyPy, link_name = "PyPyCapsule_GetDestructor")] + pub fn PyCapsule_GetDestructor(capsule: *mut PyObject) -> Option; + #[cfg_attr(PyPy, link_name = "PyPyCapsule_GetName")] + pub fn PyCapsule_GetName(capsule: *mut PyObject) -> *const c_char; + #[cfg_attr(PyPy, link_name = "PyPyCapsule_GetContext")] + pub fn PyCapsule_GetContext(capsule: *mut PyObject) -> *mut c_void; + #[cfg_attr(PyPy, link_name = "PyPyCapsule_IsValid")] + pub fn PyCapsule_IsValid(capsule: *mut PyObject, name: *const c_char) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyCapsule_SetPointer")] + pub fn PyCapsule_SetPointer(capsule: *mut PyObject, pointer: *mut c_void) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyCapsule_SetDestructor")] + pub fn PyCapsule_SetDestructor( + capsule: *mut PyObject, + destructor: Option, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyCapsule_SetName")] + pub fn PyCapsule_SetName(capsule: *mut PyObject, name: *const c_char) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyCapsule_SetContext")] + pub fn PyCapsule_SetContext(capsule: *mut PyObject, context: *mut c_void) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyCapsule_Import")] + pub fn PyCapsule_Import(name: *const c_char, no_block: c_int) -> *mut c_void; +} diff --git a/vendor/pyo3-ffi/src/pyerrors.rs b/vendor/pyo3-ffi/src/pyerrors.rs new file mode 100644 index 0000000..29892bd --- /dev/null +++ b/vendor/pyo3-ffi/src/pyerrors.rs @@ -0,0 +1,397 @@ +use crate::object::*; +use crate::pyport::Py_ssize_t; +use core::ffi::{c_char, c_int}; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyErr_SetNone")] + pub fn PyErr_SetNone(arg1: *mut PyObject); + #[cfg_attr(PyPy, link_name = "PyPyErr_SetObject")] + pub fn PyErr_SetObject(arg1: *mut PyObject, arg2: *mut PyObject); + #[cfg_attr(PyPy, link_name = "PyPyErr_SetString")] + pub fn PyErr_SetString(exception: *mut PyObject, string: *const c_char); + #[cfg_attr(PyPy, link_name = "PyPyErr_Occurred")] + pub fn PyErr_Occurred() -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyErr_Clear")] + pub fn PyErr_Clear(); + #[cfg_attr(Py_3_12, deprecated(note = "Use PyErr_GetRaisedException() instead."))] + #[cfg_attr(PyPy, link_name = "PyPyErr_Fetch")] + pub fn PyErr_Fetch( + arg1: *mut *mut PyObject, + arg2: *mut *mut PyObject, + arg3: *mut *mut PyObject, + ); + #[cfg_attr(Py_3_12, deprecated(note = "Use PyErr_SetRaisedException() instead."))] + #[cfg_attr(PyPy, link_name = "PyPyErr_Restore")] + pub fn PyErr_Restore(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject); + #[cfg_attr(PyPy, link_name = "PyPyErr_GetExcInfo")] + pub fn PyErr_GetExcInfo( + arg1: *mut *mut PyObject, + arg2: *mut *mut PyObject, + arg3: *mut *mut PyObject, + ); + #[cfg_attr(PyPy, link_name = "PyPyErr_SetExcInfo")] + pub fn PyErr_SetExcInfo(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject); + #[cfg_attr(PyPy, link_name = "PyPy_FatalError")] + pub fn Py_FatalError(message: *const c_char) -> !; + #[cfg_attr(PyPy, link_name = "PyPyErr_GivenExceptionMatches")] + pub fn PyErr_GivenExceptionMatches(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyErr_ExceptionMatches")] + pub fn PyErr_ExceptionMatches(arg1: *mut PyObject) -> c_int; + #[cfg_attr( + Py_3_12, + deprecated( + note = "Use PyErr_GetRaisedException() instead, to avoid any possible de-normalization." + ) + )] + #[cfg_attr(PyPy, link_name = "PyPyErr_NormalizeException")] + pub fn PyErr_NormalizeException( + arg1: *mut *mut PyObject, + arg2: *mut *mut PyObject, + arg3: *mut *mut PyObject, + ); + #[cfg(Py_3_12)] + pub fn PyErr_GetRaisedException() -> *mut PyObject; + #[cfg(Py_3_12)] + pub fn PyErr_SetRaisedException(exc: *mut PyObject); + #[cfg(Py_3_11)] + #[cfg_attr(PyPy, link_name = "PyPyErr_GetHandledException")] + pub fn PyErr_GetHandledException() -> *mut PyObject; + #[cfg(Py_3_11)] + #[cfg_attr(PyPy, link_name = "PyPyErr_SetHandledException")] + pub fn PyErr_SetHandledException(exc: *mut PyObject); + #[cfg_attr(PyPy, link_name = "PyPyException_SetTraceback")] + pub fn PyException_SetTraceback(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyException_GetTraceback")] + pub fn PyException_GetTraceback(arg1: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyException_GetCause")] + pub fn PyException_GetCause(arg1: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyException_SetCause")] + pub fn PyException_SetCause(arg1: *mut PyObject, arg2: *mut PyObject); + #[cfg_attr(PyPy, link_name = "PyPyException_GetContext")] + pub fn PyException_GetContext(arg1: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyException_SetContext")] + pub fn PyException_SetContext(arg1: *mut PyObject, arg2: *mut PyObject); + + #[cfg(RustPython)] + pub fn PyExceptionClass_Check(x: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyExceptionInstance_Check(x: *mut PyObject) -> c_int; + + #[cfg(PyPy)] + #[link_name = "PyPyExceptionInstance_Class"] + pub fn PyExceptionInstance_Class(x: *mut PyObject) -> *mut PyObject; +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyExceptionClass_Check(x: *mut PyObject) -> c_int { + (PyType_Check(x) != 0 + && PyType_FastSubclass(x as *mut PyTypeObject, Py_TPFLAGS_BASE_EXC_SUBCLASS) != 0) + as c_int +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyExceptionInstance_Check(x: *mut PyObject) -> c_int { + PyType_FastSubclass(Py_TYPE(x), Py_TPFLAGS_BASE_EXC_SUBCLASS) +} + +#[inline] +#[cfg(not(PyPy))] +pub unsafe fn PyExceptionInstance_Class(x: *mut PyObject) -> *mut PyObject { + Py_TYPE(x) as *mut PyObject +} + +// ported from cpython exception.c (line 2096) +#[cfg(PyPy)] +pub unsafe fn PyUnicodeDecodeError_Create( + encoding: *const c_char, + object: *const c_char, + length: Py_ssize_t, + start: Py_ssize_t, + end: Py_ssize_t, + reason: *const c_char, +) -> *mut PyObject { + crate::_PyObject_CallFunction_SizeT( + PyExc_UnicodeDecodeError, + c"sy#nns".as_ptr(), + encoding, + object, + length, + start, + end, + reason, + ) +} + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyExc_BaseException")] + pub static mut PyExc_BaseException: *mut PyObject; + #[cfg(Py_3_11)] + #[cfg_attr(PyPy, link_name = "PyPyExc_BaseExceptionGroup")] + pub static mut PyExc_BaseExceptionGroup: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_Exception")] + pub static mut PyExc_Exception: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_StopAsyncIteration")] + pub static mut PyExc_StopAsyncIteration: *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyExc_StopIteration")] + pub static mut PyExc_StopIteration: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_GeneratorExit")] + pub static mut PyExc_GeneratorExit: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_ArithmeticError")] + pub static mut PyExc_ArithmeticError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_LookupError")] + pub static mut PyExc_LookupError: *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyExc_AssertionError")] + pub static mut PyExc_AssertionError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_AttributeError")] + pub static mut PyExc_AttributeError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_BufferError")] + pub static mut PyExc_BufferError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_EOFError")] + pub static mut PyExc_EOFError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_FloatingPointError")] + pub static mut PyExc_FloatingPointError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_OSError")] + pub static mut PyExc_OSError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_ImportError")] + pub static mut PyExc_ImportError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_ModuleNotFoundError")] + pub static mut PyExc_ModuleNotFoundError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_IndexError")] + pub static mut PyExc_IndexError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_KeyError")] + pub static mut PyExc_KeyError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_KeyboardInterrupt")] + pub static mut PyExc_KeyboardInterrupt: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_MemoryError")] + pub static mut PyExc_MemoryError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_NameError")] + pub static mut PyExc_NameError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_OverflowError")] + pub static mut PyExc_OverflowError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_RuntimeError")] + pub static mut PyExc_RuntimeError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_RecursionError")] + pub static mut PyExc_RecursionError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_NotImplementedError")] + pub static mut PyExc_NotImplementedError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_SyntaxError")] + pub static mut PyExc_SyntaxError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_IndentationError")] + pub static mut PyExc_IndentationError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_TabError")] + pub static mut PyExc_TabError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_ReferenceError")] + pub static mut PyExc_ReferenceError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_SystemError")] + pub static mut PyExc_SystemError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_SystemExit")] + pub static mut PyExc_SystemExit: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_TypeError")] + pub static mut PyExc_TypeError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_UnboundLocalError")] + pub static mut PyExc_UnboundLocalError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_UnicodeError")] + pub static mut PyExc_UnicodeError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_UnicodeEncodeError")] + pub static mut PyExc_UnicodeEncodeError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_UnicodeDecodeError")] + pub static mut PyExc_UnicodeDecodeError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_UnicodeTranslateError")] + pub static mut PyExc_UnicodeTranslateError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_ValueError")] + pub static mut PyExc_ValueError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_ZeroDivisionError")] + pub static mut PyExc_ZeroDivisionError: *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyExc_BlockingIOError")] + pub static mut PyExc_BlockingIOError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_BrokenPipeError")] + pub static mut PyExc_BrokenPipeError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_ChildProcessError")] + pub static mut PyExc_ChildProcessError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_ConnectionError")] + pub static mut PyExc_ConnectionError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_ConnectionAbortedError")] + pub static mut PyExc_ConnectionAbortedError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_ConnectionRefusedError")] + pub static mut PyExc_ConnectionRefusedError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_ConnectionResetError")] + pub static mut PyExc_ConnectionResetError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_FileExistsError")] + pub static mut PyExc_FileExistsError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_FileNotFoundError")] + pub static mut PyExc_FileNotFoundError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_InterruptedError")] + pub static mut PyExc_InterruptedError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_IsADirectoryError")] + pub static mut PyExc_IsADirectoryError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_NotADirectoryError")] + pub static mut PyExc_NotADirectoryError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_PermissionError")] + pub static mut PyExc_PermissionError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_ProcessLookupError")] + pub static mut PyExc_ProcessLookupError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_TimeoutError")] + pub static mut PyExc_TimeoutError: *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyExc_OSError")] + pub static mut PyExc_EnvironmentError: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_OSError")] + pub static mut PyExc_IOError: *mut PyObject; + #[cfg(windows)] + #[cfg_attr(PyPy, link_name = "PyPyExc_OSError")] + pub static mut PyExc_WindowsError: *mut PyObject; + + pub static mut PyExc_RecursionErrorInst: *mut PyObject; + + /* Predefined warning categories */ + #[cfg_attr(PyPy, link_name = "PyPyExc_Warning")] + pub static mut PyExc_Warning: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_UserWarning")] + pub static mut PyExc_UserWarning: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_DeprecationWarning")] + pub static mut PyExc_DeprecationWarning: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_PendingDeprecationWarning")] + pub static mut PyExc_PendingDeprecationWarning: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_SyntaxWarning")] + pub static mut PyExc_SyntaxWarning: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_RuntimeWarning")] + pub static mut PyExc_RuntimeWarning: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_FutureWarning")] + pub static mut PyExc_FutureWarning: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_ImportWarning")] + pub static mut PyExc_ImportWarning: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_UnicodeWarning")] + pub static mut PyExc_UnicodeWarning: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_BytesWarning")] + pub static mut PyExc_BytesWarning: *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyExc_ResourceWarning")] + pub static mut PyExc_ResourceWarning: *mut PyObject; + #[cfg(Py_3_10)] + #[cfg_attr(PyPy, link_name = "PyPyExc_EncodingWarning")] + pub static mut PyExc_EncodingWarning: *mut PyObject; +} + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyErr_BadArgument")] + pub fn PyErr_BadArgument() -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyErr_NoMemory")] + pub fn PyErr_NoMemory() -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyErr_SetFromErrno")] + pub fn PyErr_SetFromErrno(arg1: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyErr_SetFromErrnoWithFilenameObject")] + pub fn PyErr_SetFromErrnoWithFilenameObject( + arg1: *mut PyObject, + arg2: *mut PyObject, + ) -> *mut PyObject; + pub fn PyErr_SetFromErrnoWithFilenameObjects( + arg1: *mut PyObject, + arg2: *mut PyObject, + arg3: *mut PyObject, + ) -> *mut PyObject; + pub fn PyErr_SetFromErrnoWithFilename( + exc: *mut PyObject, + filename: *const c_char, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyErr_Format")] + pub fn PyErr_Format(exception: *mut PyObject, format: *const c_char, ...) -> *mut PyObject; + pub fn PyErr_SetImportErrorSubclass( + arg1: *mut PyObject, + arg2: *mut PyObject, + arg3: *mut PyObject, + arg4: *mut PyObject, + ) -> *mut PyObject; + pub fn PyErr_SetImportError( + arg1: *mut PyObject, + arg2: *mut PyObject, + arg3: *mut PyObject, + ) -> *mut PyObject; + #[cfg(PyPy)] + #[cfg_attr(PyPy, link_name = "PyPyErr_BadInternalCall")] + pub fn PyErr_BadInternalCall(); + + #[cfg(not(PyPy))] + fn _PyErr_BadInternalCall(filename: *const c_char, lineno: c_int); +} + +#[cfg(not(PyPy))] +#[track_caller] +#[inline] +pub unsafe fn PyErr_BadInternalCall() { + let location = core::panic::Location::caller(); + let filename = alloc::ffi::CString::new(location.file()).unwrap(); + // SAFETY: `filename` is null terminated, `location.line()` saturates if exceeds c_int + unsafe { + _PyErr_BadInternalCall( + filename.as_ptr(), + location.line().try_into().unwrap_or(c_int::MAX), + ) + } +} + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyErr_NewException")] + pub fn PyErr_NewException( + name: *const c_char, + base: *mut PyObject, + dict: *mut PyObject, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyErr_NewExceptionWithDoc")] + pub fn PyErr_NewExceptionWithDoc( + name: *const c_char, + doc: *const c_char, + base: *mut PyObject, + dict: *mut PyObject, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyErr_WriteUnraisable")] + pub fn PyErr_WriteUnraisable(arg1: *mut PyObject); + #[cfg_attr(PyPy, link_name = "PyPyErr_CheckSignals")] + pub fn PyErr_CheckSignals() -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyErr_SetInterrupt")] + pub fn PyErr_SetInterrupt(); + #[cfg(Py_3_10)] + #[cfg_attr(PyPy, link_name = "PyPyErr_SetInterruptEx")] + pub fn PyErr_SetInterruptEx(signum: c_int) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyErr_SyntaxLocation")] + pub fn PyErr_SyntaxLocation(filename: *const c_char, lineno: c_int); + #[cfg_attr(PyPy, link_name = "PyPyErr_SyntaxLocationEx")] + pub fn PyErr_SyntaxLocationEx(filename: *const c_char, lineno: c_int, col_offset: c_int); + #[cfg_attr(PyPy, link_name = "PyPyErr_ProgramText")] + pub fn PyErr_ProgramText(filename: *const c_char, lineno: c_int) -> *mut PyObject; + #[cfg(not(PyPy))] + pub fn PyUnicodeDecodeError_Create( + encoding: *const c_char, + object: *const c_char, + length: Py_ssize_t, + start: Py_ssize_t, + end: Py_ssize_t, + reason: *const c_char, + ) -> *mut PyObject; + pub fn PyUnicodeEncodeError_GetEncoding(arg1: *mut PyObject) -> *mut PyObject; + pub fn PyUnicodeDecodeError_GetEncoding(arg1: *mut PyObject) -> *mut PyObject; + pub fn PyUnicodeEncodeError_GetObject(arg1: *mut PyObject) -> *mut PyObject; + pub fn PyUnicodeDecodeError_GetObject(arg1: *mut PyObject) -> *mut PyObject; + pub fn PyUnicodeTranslateError_GetObject(arg1: *mut PyObject) -> *mut PyObject; + pub fn PyUnicodeEncodeError_GetStart(arg1: *mut PyObject, arg2: *mut Py_ssize_t) -> c_int; + pub fn PyUnicodeDecodeError_GetStart(arg1: *mut PyObject, arg2: *mut Py_ssize_t) -> c_int; + pub fn PyUnicodeTranslateError_GetStart(arg1: *mut PyObject, arg2: *mut Py_ssize_t) -> c_int; + pub fn PyUnicodeEncodeError_SetStart(arg1: *mut PyObject, arg2: Py_ssize_t) -> c_int; + pub fn PyUnicodeDecodeError_SetStart(arg1: *mut PyObject, arg2: Py_ssize_t) -> c_int; + pub fn PyUnicodeTranslateError_SetStart(arg1: *mut PyObject, arg2: Py_ssize_t) -> c_int; + pub fn PyUnicodeEncodeError_GetEnd(arg1: *mut PyObject, arg2: *mut Py_ssize_t) -> c_int; + pub fn PyUnicodeDecodeError_GetEnd(arg1: *mut PyObject, arg2: *mut Py_ssize_t) -> c_int; + pub fn PyUnicodeTranslateError_GetEnd(arg1: *mut PyObject, arg2: *mut Py_ssize_t) -> c_int; + pub fn PyUnicodeEncodeError_SetEnd(arg1: *mut PyObject, arg2: Py_ssize_t) -> c_int; + pub fn PyUnicodeDecodeError_SetEnd(arg1: *mut PyObject, arg2: Py_ssize_t) -> c_int; + pub fn PyUnicodeTranslateError_SetEnd(arg1: *mut PyObject, arg2: Py_ssize_t) -> c_int; + pub fn PyUnicodeEncodeError_GetReason(arg1: *mut PyObject) -> *mut PyObject; + pub fn PyUnicodeDecodeError_GetReason(arg1: *mut PyObject) -> *mut PyObject; + pub fn PyUnicodeTranslateError_GetReason(arg1: *mut PyObject) -> *mut PyObject; + pub fn PyUnicodeEncodeError_SetReason(exc: *mut PyObject, reason: *const c_char) -> c_int; + pub fn PyUnicodeDecodeError_SetReason(exc: *mut PyObject, reason: *const c_char) -> c_int; + pub fn PyUnicodeTranslateError_SetReason(exc: *mut PyObject, reason: *const c_char) -> c_int; +} diff --git a/vendor/pyo3-ffi/src/pyframe.rs b/vendor/pyo3-ffi/src/pyframe.rs new file mode 100644 index 0000000..fca98ac --- /dev/null +++ b/vendor/pyo3-ffi/src/pyframe.rs @@ -0,0 +1,13 @@ +#[cfg(not(GraalPy))] +#[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))] +use crate::PyCodeObject; +use crate::PyFrameObject; +use core::ffi::c_int; + +extern_libpython! { + pub fn PyFrame_GetLineNumber(frame: *mut PyFrameObject) -> c_int; + + #[cfg(not(GraalPy))] + #[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))] + pub fn PyFrame_GetCode(frame: *mut PyFrameObject) -> *mut PyCodeObject; +} diff --git a/vendor/pyo3-ffi/src/pyhash.rs b/vendor/pyo3-ffi/src/pyhash.rs new file mode 100644 index 0000000..ca6a3c7 --- /dev/null +++ b/vendor/pyo3-ffi/src/pyhash.rs @@ -0,0 +1,31 @@ +#[cfg(not(any(Py_LIMITED_API, PyPy, Py_3_14)))] +use crate::pyport::{Py_hash_t, Py_ssize_t}; +#[cfg(not(any(Py_LIMITED_API, PyPy, Py_3_14)))] +use core::ffi::c_void; + +use core::ffi::{c_int, c_ulong}; + +extern_libpython! { + // skipped non-limited _Py_HashDouble + // skipped non-limited _Py_HashPointer + // skipped non-limited _Py_HashPointerRaw + + #[cfg(not(any(Py_LIMITED_API, PyPy, Py_3_14)))] + pub(crate) fn _Py_HashBytes(src: *const c_void, len: Py_ssize_t) -> Py_hash_t; +} + +pub const _PyHASH_MULTIPLIER: c_ulong = 1000003; + +// skipped _PyHASH_BITS + +// skipped non-limited _Py_HashSecret_t + +// skipped Py_HASH_CUTOFF + +pub const Py_HASH_EXTERNAL: c_int = 0; +pub const Py_HASH_SIPHASH24: c_int = 1; +pub const Py_HASH_FNV: c_int = 2; +#[cfg(Py_3_11)] +pub const Py_HASH_SIPHASH13: c_int = 3; + +// skipped Py_HASH_ALGORITHM diff --git a/vendor/pyo3-ffi/src/pylifecycle.rs b/vendor/pyo3-ffi/src/pylifecycle.rs new file mode 100644 index 0000000..758f522 --- /dev/null +++ b/vendor/pyo3-ffi/src/pylifecycle.rs @@ -0,0 +1,104 @@ +use crate::pytypedefs::PyThreadState; + +use core::ffi::{c_char, c_int}; +use libc::wchar_t; + +extern_libpython! { + pub fn Py_Initialize(); + pub fn Py_InitializeEx(arg1: c_int); + pub fn Py_Finalize(); + pub fn Py_FinalizeEx() -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPy_IsInitialized")] + pub fn Py_IsInitialized() -> c_int; + + pub fn Py_NewInterpreter() -> *mut PyThreadState; + pub fn Py_EndInterpreter(arg1: *mut PyThreadState); + + #[cfg_attr(PyPy, link_name = "PyPy_AtExit")] + pub fn Py_AtExit(func: Option) -> c_int; + + pub fn Py_Exit(arg1: c_int) -> !; + + pub fn Py_Main(argc: c_int, argv: *mut *mut wchar_t) -> c_int; + pub fn Py_BytesMain(argc: c_int, argv: *mut *mut c_char) -> c_int; + + #[cfg_attr( + Py_3_11, + deprecated(note = "Deprecated since Python 3.11. Use `PyConfig.program_name` instead.") + )] + pub fn Py_SetProgramName(arg1: *const wchar_t); + #[cfg(not(Py_3_15))] + #[cfg_attr(PyPy, link_name = "PyPy_GetProgramName")] + #[cfg_attr( + Py_3_13, + deprecated(note = "Deprecated since Python 3.13. Use `sys.executable` instead.") + )] + pub fn Py_GetProgramName() -> *mut wchar_t; + + #[cfg_attr( + Py_3_11, + deprecated(note = "Deprecated since Python 3.11. Use `PyConfig.home` instead.") + )] + pub fn Py_SetPythonHome(arg1: *const wchar_t); + #[cfg(not(Py_3_15))] + #[cfg_attr( + Py_3_13, + deprecated( + note = "Deprecated since Python 3.13. Use `PyConfig.home` or the value of the `PYTHONHOME` environment variable instead." + ) + )] + pub fn Py_GetPythonHome() -> *mut wchar_t; + #[cfg(not(Py_3_15))] + #[cfg_attr( + Py_3_13, + deprecated(note = "Deprecated since Python 3.13. Use `sys.executable` instead.") + )] + pub fn Py_GetProgramFullPath() -> *mut wchar_t; + #[cfg(not(Py_3_15))] + #[cfg_attr( + Py_3_13, + deprecated(note = "Deprecated since Python 3.13. Use `sys.prefix` instead.") + )] + pub fn Py_GetPrefix() -> *mut wchar_t; + #[cfg(not(Py_3_15))] + #[cfg_attr( + Py_3_13, + deprecated(note = "Deprecated since Python 3.13. Use `sys.exec_prefix` instead.") + )] + pub fn Py_GetExecPrefix() -> *mut wchar_t; + #[cfg(not(Py_3_15))] + #[cfg_attr( + Py_3_13, + deprecated(note = "Deprecated since Python 3.13. Use `sys.path` instead.") + )] + pub fn Py_GetPath() -> *mut wchar_t; + #[cfg(not(Py_3_13))] + #[cfg_attr( + Py_3_11, + deprecated(note = "Deprecated since Python 3.11. Use `sys.path` instead.") + )] + pub fn Py_SetPath(arg1: *const wchar_t); + + // skipped _Py_CheckPython3 + + #[cfg_attr(PyPy, link_name = "PyPy_GetVersion")] + pub fn Py_GetVersion() -> *const c_char; + pub fn Py_GetPlatform() -> *const c_char; + pub fn Py_GetCopyright() -> *const c_char; + pub fn Py_GetCompiler() -> *const c_char; + pub fn Py_GetBuildInfo() -> *const c_char; +} + +type PyOS_sighandler_t = unsafe extern "C" fn(arg1: c_int); + +extern_libpython! { + pub fn PyOS_getsig(arg1: c_int) -> PyOS_sighandler_t; + pub fn PyOS_setsig(arg1: c_int, arg2: PyOS_sighandler_t) -> PyOS_sighandler_t; + + #[cfg(Py_3_11)] + pub static Py_Version: core::ffi::c_ulong; + + #[cfg(Py_3_13)] + pub fn Py_IsFinalizing() -> c_int; +} diff --git a/vendor/pyo3-ffi/src/pymem.rs b/vendor/pyo3-ffi/src/pymem.rs new file mode 100644 index 0000000..45e57ef --- /dev/null +++ b/vendor/pyo3-ffi/src/pymem.rs @@ -0,0 +1,13 @@ +use core::ffi::c_void; +use libc::size_t; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyMem_Malloc")] + pub fn PyMem_Malloc(size: size_t) -> *mut c_void; + #[cfg_attr(PyPy, link_name = "PyPyMem_Calloc")] + pub fn PyMem_Calloc(nelem: size_t, elsize: size_t) -> *mut c_void; + #[cfg_attr(PyPy, link_name = "PyPyMem_Realloc")] + pub fn PyMem_Realloc(ptr: *mut c_void, new_size: size_t) -> *mut c_void; + #[cfg_attr(PyPy, link_name = "PyPyMem_Free")] + pub fn PyMem_Free(ptr: *mut c_void); +} diff --git a/vendor/pyo3-ffi/src/pyport.rs b/vendor/pyo3-ffi/src/pyport.rs new file mode 100644 index 0000000..db10236 --- /dev/null +++ b/vendor/pyo3-ffi/src/pyport.rs @@ -0,0 +1,30 @@ +// NB libc does not define this constant on all platforms, so we hard code it +// like CPython does. +// https://github.com/python/cpython/blob/d8b9011702443bb57579f8834f3effe58e290dfc/Include/pyport.h#L372 +pub const INT_MAX: core::ffi::c_int = 2147483647; + +pub type PY_UINT32_T = u32; +pub type PY_UINT64_T = u64; + +pub type PY_INT32_T = i32; +pub type PY_INT64_T = i64; + +pub type Py_uintptr_t = ::libc::uintptr_t; +pub type Py_intptr_t = ::libc::intptr_t; +pub type Py_ssize_t = ::libc::ssize_t; + +pub type Py_hash_t = Py_ssize_t; +pub type Py_uhash_t = ::libc::size_t; + +pub const PY_SSIZE_T_MIN: Py_ssize_t = Py_ssize_t::MIN; +pub const PY_SSIZE_T_MAX: Py_ssize_t = Py_ssize_t::MAX; + +#[cfg(target_endian = "big")] +pub const PY_BIG_ENDIAN: usize = 1; +#[cfg(target_endian = "big")] +pub const PY_LITTLE_ENDIAN: usize = 0; + +#[cfg(target_endian = "little")] +pub const PY_BIG_ENDIAN: usize = 0; +#[cfg(target_endian = "little")] +pub const PY_LITTLE_ENDIAN: usize = 1; diff --git a/vendor/pyo3-ffi/src/pystate.rs b/vendor/pyo3-ffi/src/pystate.rs new file mode 100644 index 0000000..776c302 --- /dev/null +++ b/vendor/pyo3-ffi/src/pystate.rs @@ -0,0 +1,138 @@ +use crate::moduleobject::PyModuleDef; +use crate::object::PyObject; +use crate::pytypedefs::{PyInterpreterState, PyThreadState}; +use core::ffi::c_int; + +#[cfg(any(all(Py_3_9, not(Py_LIMITED_API)), Py_3_10))] +#[cfg(not(PyPy))] +use crate::PyFrameObject; + +#[cfg(not(PyPy))] +use core::ffi::c_long; + +pub const MAX_CO_EXTRA_USERS: c_int = 255; + +extern_libpython! { + #[cfg(not(PyPy))] + pub fn PyInterpreterState_New() -> *mut PyInterpreterState; + #[cfg(not(PyPy))] + pub fn PyInterpreterState_Clear(arg1: *mut PyInterpreterState); + #[cfg(not(PyPy))] + pub fn PyInterpreterState_Delete(arg1: *mut PyInterpreterState); + + #[cfg(all(Py_3_9, not(PyPy)))] + pub fn PyInterpreterState_Get() -> *mut PyInterpreterState; + + #[cfg(not(PyPy))] + pub fn PyInterpreterState_GetDict(arg1: *mut PyInterpreterState) -> *mut PyObject; + + #[cfg(not(PyPy))] + pub fn PyInterpreterState_GetID(arg1: *mut PyInterpreterState) -> i64; + + #[cfg_attr(PyPy, link_name = "PyPyState_AddModule")] + pub fn PyState_AddModule(arg1: *mut PyObject, arg2: *mut PyModuleDef) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyState_RemoveModule")] + pub fn PyState_RemoveModule(arg1: *mut PyModuleDef) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPyState_FindModule")] + pub fn PyState_FindModule(arg1: *mut PyModuleDef) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyThreadState_New")] + pub fn PyThreadState_New(arg1: *mut PyInterpreterState) -> *mut PyThreadState; + #[cfg_attr(PyPy, link_name = "PyPyThreadState_Clear")] + pub fn PyThreadState_Clear(arg1: *mut PyThreadState); + #[cfg_attr(PyPy, link_name = "PyPyThreadState_Delete")] + pub fn PyThreadState_Delete(arg1: *mut PyThreadState); + + #[cfg_attr(PyPy, link_name = "PyPyThreadState_Get")] + pub fn PyThreadState_Get() -> *mut PyThreadState; +} + +#[inline] +pub unsafe fn PyThreadState_GET() -> *mut PyThreadState { + PyThreadState_Get() +} + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyThreadState_Swap")] + pub fn PyThreadState_Swap(arg1: *mut PyThreadState) -> *mut PyThreadState; + #[cfg_attr(PyPy, link_name = "PyPyThreadState_GetDict")] + pub fn PyThreadState_GetDict() -> *mut PyObject; + #[cfg(not(PyPy))] + pub fn PyThreadState_SetAsyncExc(arg1: c_long, arg2: *mut PyObject) -> c_int; + + #[cfg(any(all(Py_3_9, not(Py_LIMITED_API)), Py_3_10))] + #[cfg(not(PyPy))] + pub fn PyThreadState_GetInterpreter(arg1: *mut PyThreadState) -> *mut PyInterpreterState; + #[cfg(any(all(Py_3_9, not(Py_LIMITED_API)), Py_3_10))] + #[cfg(not(PyPy))] + pub fn PyThreadState_GetFrame(arg1: *mut PyThreadState) -> *mut PyFrameObject; + #[cfg(any(all(Py_3_9, not(Py_LIMITED_API)), Py_3_10))] + #[cfg(not(PyPy))] + pub fn PyThreadState_GetID(arg1: *mut PyThreadState) -> i64; +} + +#[repr(C)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum PyGILState_STATE { + PyGILState_LOCKED, + PyGILState_UNLOCKED, +} + +// The PyGILState_Ensure function will call pthread_exit during interpreter shutdown, +// which causes undefined behavior. Redirect to the "safe" version that hangs instead, +// as Python 3.14 does. +// +// See https://github.com/rust-lang/rust/issues/135929 + +// C-unwind only supported (and necessary) since 1.71. Python 3.14+ does not do +// pthread_exit from PyGILState_Ensure (https://github.com/python/cpython/issues/87135). +mod raw { + #[cfg(not(any(Py_3_14, target_arch = "wasm32")))] + extern_libpython! { "C-unwind" { + #[cfg_attr(PyPy, link_name = "PyPyGILState_Ensure")] + pub fn PyGILState_Ensure() -> super::PyGILState_STATE; + }} + + #[cfg(any(Py_3_14, target_arch = "wasm32"))] + extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyGILState_Ensure")] + pub fn PyGILState_Ensure() -> super::PyGILState_STATE; + } +} + +#[cfg(not(any(Py_3_14, target_arch = "wasm32")))] +pub unsafe extern "C" fn PyGILState_Ensure() -> PyGILState_STATE { + let guard = crate::impl_::HangThread; + // If `PyGILState_Ensure` calls `pthread_exit`, which it does on Python < 3.14 + // when the interpreter is shutting down, this will cause a forced unwind. + // doing a forced unwind through a function with a Rust destructor is unspecified + // behavior. + // + // However, currently it runs the destructor, which will cause the thread to + // hang as it should. + // + // And if we don't catch the unwinding here, then one of our callers probably has a destructor, + // so it's unspecified behavior anyway, and on many configurations causes the process to abort. + // + // The alternative is for pyo3 to contain custom C or C++ code that catches the `pthread_exit`, + // but that's also annoying from a portability point of view. + // + // On Windows, `PyGILState_Ensure` calls `_endthreadex` instead, which AFAICT can't be caught + // and therefore will cause unsafety if there are pinned objects on the stack. AFAICT there's + // nothing we can do it other than waiting for Python 3.14 or not using Windows. At least, + // if there is nothing pinned on the stack, it won't cause the process to crash. + let ret: PyGILState_STATE = raw::PyGILState_Ensure(); + core::mem::forget(guard); + ret +} + +#[cfg(any(Py_3_14, target_arch = "wasm32"))] +pub use self::raw::PyGILState_Ensure; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyGILState_Release")] + pub fn PyGILState_Release(arg1: PyGILState_STATE); + #[cfg(not(PyPy))] + pub fn PyGILState_GetThisThreadState() -> *mut PyThreadState; +} diff --git a/vendor/pyo3-ffi/src/pystrtod.rs b/vendor/pyo3-ffi/src/pystrtod.rs new file mode 100644 index 0000000..43ac27b --- /dev/null +++ b/vendor/pyo3-ffi/src/pystrtod.rs @@ -0,0 +1,32 @@ +use crate::object::PyObject; +use core::ffi::{c_char, c_double, c_int}; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyOS_string_to_double")] + pub fn PyOS_string_to_double( + str: *const c_char, + endptr: *mut *mut c_char, + overflow_exception: *mut PyObject, + ) -> c_double; + #[cfg_attr(PyPy, link_name = "PyPyOS_double_to_string")] + pub fn PyOS_double_to_string( + val: c_double, + format_code: c_char, + precision: c_int, + flags: c_int, + _type: *mut c_int, + ) -> *mut c_char; +} + +// skipped non-limited _Py_string_to_number_with_underscores +// skipped non-limited _Py_parse_inf_or_nan + +/* PyOS_double_to_string's "flags" parameter can be set to 0 or more of: */ +pub const Py_DTSF_SIGN: c_int = 0x01; /* always add the sign */ +pub const Py_DTSF_ADD_DOT_0: c_int = 0x02; /* if the result is an integer add ".0" */ +pub const Py_DTSF_ALT: c_int = 0x04; /* "alternate" formatting. it's format_code specific */ + +/* PyOS_double_to_string's "type", if non-NULL, will be set to one of: */ +pub const Py_DTST_FINITE: c_int = 0; +pub const Py_DTST_INFINITE: c_int = 1; +pub const Py_DTST_NAN: c_int = 2; diff --git a/vendor/pyo3-ffi/src/pythonrun.rs b/vendor/pyo3-ffi/src/pythonrun.rs new file mode 100644 index 0000000..91c12a1 --- /dev/null +++ b/vendor/pyo3-ffi/src/pythonrun.rs @@ -0,0 +1,88 @@ +use crate::object::*; +#[cfg(any(Py_LIMITED_API, not(Py_3_10), PyPy, GraalPy))] +use core::ffi::c_char; +use core::ffi::c_int; +#[cfg(not(any(PyPy, Py_LIMITED_API, Py_3_10)))] +use libc::FILE; + +extern_libpython! { + #[cfg(any(all(Py_LIMITED_API, not(PyPy)), GraalPy))] + pub fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyErr_Print")] + pub fn PyErr_Print(); + #[cfg_attr(PyPy, link_name = "PyPyErr_PrintEx")] + pub fn PyErr_PrintEx(arg1: c_int); + #[cfg_attr(PyPy, link_name = "PyPyErr_Display")] + pub fn PyErr_Display(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject); + + #[cfg(Py_3_12)] + pub fn PyErr_DisplayException(exc: *mut PyObject); +} + +#[inline] +#[cfg(PyPy)] +pub unsafe fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject { + // PyPy's implementation of Py_CompileString always forwards to Py_CompileStringFlags; this + // is only available in the non-limited API and has a real definition for all versions in + // the cpython/ subdirectory. + #[cfg(Py_LIMITED_API)] + extern_libpython! { + #[link_name = "PyPy_CompileStringFlags"] + pub fn Py_CompileStringFlags( + string: *const c_char, + p: *const c_char, + s: c_int, + f: *mut core::ffi::c_void, // Actually *mut Py_CompilerFlags in the real definition + ) -> *mut PyObject; + } + #[cfg(not(Py_LIMITED_API))] + use crate::Py_CompileStringFlags; + + Py_CompileStringFlags(string, p, s, core::ptr::null_mut()) +} + +// skipped PyOS_InputHook + +pub const PYOS_STACK_MARGIN: c_int = 2048; + +// skipped PyOS_CheckStack under Microsoft C + +#[cfg(not(any(PyPy, Py_LIMITED_API, Py_3_10)))] +opaque_struct!(pub _mod); + +#[cfg(not(any(PyPy, Py_3_10)))] +opaque_struct!(pub symtable); +#[cfg(not(any(PyPy, Py_3_10)))] +opaque_struct!(pub _node); + +#[cfg(not(any(PyPy, Py_LIMITED_API, Py_3_10)))] +#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] +#[inline] +pub unsafe fn PyParser_SimpleParseString(s: *const c_char, b: c_int) -> *mut _node { + #[allow(deprecated)] + crate::PyParser_SimpleParseStringFlags(s, b, 0) +} + +#[cfg(not(any(PyPy, Py_LIMITED_API, Py_3_10)))] +#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] +#[inline] +pub unsafe fn PyParser_SimpleParseFile(fp: *mut FILE, s: *const c_char, b: c_int) -> *mut _node { + #[allow(deprecated)] + crate::PyParser_SimpleParseFileFlags(fp, s, b, 0) +} + +extern_libpython! { + #[cfg(not(any(PyPy, Py_3_10)))] + pub fn Py_SymtableString( + str: *const c_char, + filename: *const c_char, + start: c_int, + ) -> *mut symtable; + #[cfg(not(any(PyPy, Py_LIMITED_API, Py_3_10)))] + pub fn Py_SymtableStringObject( + str: *const c_char, + filename: *mut PyObject, + start: c_int, + ) -> *mut symtable; +} diff --git a/vendor/pyo3-ffi/src/pytypedefs.rs b/vendor/pyo3-ffi/src/pytypedefs.rs new file mode 100644 index 0000000..419b752 --- /dev/null +++ b/vendor/pyo3-ffi/src/pytypedefs.rs @@ -0,0 +1,26 @@ +// NB: unlike C, we do not need to forward declare structs in Rust. +// So we only define opaque structs for those which do not have public structure. +// +// Some of these structs defined below only for the opaque PyObject ABI +// (e.g. all(Py_GIL_DISABLED, Py_LIMITED_API)) since we need to define +// the structs but can't know their layout + +// PyModuleDef_Slot +// PyMethodDef +// PyGetSetDef +// PyMemberDef + +// PyLongObject +opaque_struct!(pub PyCodeObject); +opaque_struct!(pub PyFrameObject); + +opaque_struct!(pub PyThreadState); +opaque_struct!(pub PyInterpreterState); +#[cfg(all(Py_LIMITED_API, Py_GIL_DISABLED))] +opaque_struct!(pub PyModuleDef); +#[cfg(Py_LIMITED_API)] +opaque_struct!(pub PyTypeObject); +#[cfg(all(Py_LIMITED_API, Py_GIL_DISABLED))] +opaque_struct!(pub PyObject); +#[cfg(all(Py_LIMITED_API, Py_GIL_DISABLED))] +opaque_struct!(pub PyVarObject); diff --git a/vendor/pyo3-ffi/src/rangeobject.rs b/vendor/pyo3-ffi/src/rangeobject.rs new file mode 100644 index 0000000..ffecd07 --- /dev/null +++ b/vendor/pyo3-ffi/src/rangeobject.rs @@ -0,0 +1,21 @@ +use crate::object::*; +use core::ffi::c_int; + +extern_libpython! { + #[cfg(not(RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyRange_Type")] + pub static mut PyRange_Type: PyTypeObject; + #[cfg(not(RustPython))] + pub static mut PyRangeIter_Type: PyTypeObject; + #[cfg(not(RustPython))] + pub static mut PyLongRangeIter_Type: PyTypeObject; + + #[cfg(RustPython)] + pub fn PyRange_Check(op: *mut PyObject) -> c_int; +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyRange_Check(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyRange_Type) +} diff --git a/vendor/pyo3-ffi/src/refcount.rs b/vendor/pyo3-ffi/src/refcount.rs new file mode 100644 index 0000000..4da1096 --- /dev/null +++ b/vendor/pyo3-ffi/src/refcount.rs @@ -0,0 +1,372 @@ +use crate::pyport::Py_ssize_t; +use crate::PyObject; +#[cfg(all(not(Py_LIMITED_API), py_sys_config = "Py_REF_DEBUG"))] +use core::ffi::c_char; +#[cfg(any(Py_3_12, all(py_sys_config = "Py_REF_DEBUG", not(Py_LIMITED_API))))] +use core::ffi::c_int; +#[cfg(all(Py_3_14, any(not(Py_GIL_DISABLED), target_pointer_width = "32")))] +use core::ffi::c_long; +#[cfg(any(Py_GIL_DISABLED, all(Py_3_12, not(Py_3_14))))] +use core::ffi::c_uint; +#[cfg(all(Py_3_14, not(Py_GIL_DISABLED)))] +use core::ffi::c_ulong; +use core::ptr; +#[cfg(all(Py_GIL_DISABLED, not(Py_LIMITED_API)))] +use core::sync::atomic::Ordering::Relaxed; + +#[cfg(all(Py_3_14, not(Py_3_15)))] +const _Py_STATICALLY_ALLOCATED_FLAG: c_int = 1 << 7; +#[cfg(Py_3_15)] +pub(crate) const _Py_STATICALLY_ALLOCATED_FLAG: c_int = 1 << 2; + +#[cfg(all(Py_3_12, not(Py_3_14)))] +const _Py_IMMORTAL_REFCNT: Py_ssize_t = { + if cfg!(target_pointer_width = "64") { + c_uint::MAX as Py_ssize_t + } else { + // for 32-bit systems, use the lower 30 bits (see comment in CPython's object.h) + (c_uint::MAX >> 2) as Py_ssize_t + } +}; + +// comments in Python.h about the choices for these constants + +#[cfg(all(Py_3_14, not(Py_GIL_DISABLED)))] +const _Py_IMMORTAL_INITIAL_REFCNT: Py_ssize_t = { + if cfg!(target_pointer_width = "64") { + ((3 as c_ulong) << (30 as c_ulong)) as Py_ssize_t + } else { + ((5 as c_long) << (28 as c_long)) as Py_ssize_t + } +}; + +#[cfg(all(Py_3_14, not(Py_GIL_DISABLED)))] +const _Py_STATIC_IMMORTAL_INITIAL_REFCNT: Py_ssize_t = { + if cfg!(target_pointer_width = "64") { + _Py_IMMORTAL_INITIAL_REFCNT + | ((_Py_STATICALLY_ALLOCATED_FLAG as Py_ssize_t) << (32 as Py_ssize_t)) + } else { + ((7 as c_long) << (28 as c_long)) as Py_ssize_t + } +}; + +#[cfg(all(Py_3_14, target_pointer_width = "32"))] +const _Py_IMMORTAL_MINIMUM_REFCNT: Py_ssize_t = ((1 as c_long) << (30 as c_long)) as Py_ssize_t; + +#[cfg(all(Py_3_14, target_pointer_width = "32"))] +const _Py_STATIC_IMMORTAL_MINIMUM_REFCNT: Py_ssize_t = + ((6 as c_long) << (28 as c_long)) as Py_ssize_t; + +#[cfg(all(Py_3_14, Py_GIL_DISABLED))] +const _Py_IMMORTAL_INITIAL_REFCNT: Py_ssize_t = c_uint::MAX as Py_ssize_t; + +#[cfg(Py_GIL_DISABLED)] +pub(crate) const _Py_IMMORTAL_REFCNT_LOCAL: u32 = u32::MAX; + +#[cfg(Py_GIL_DISABLED)] +const _Py_REF_SHARED_SHIFT: isize = 2; +// skipped private _Py_REF_SHARED_FLAG_MASK + +// skipped private _Py_REF_SHARED_INIT +// skipped private _Py_REF_MAYBE_WEAKREF +// skipped private _Py_REF_QUEUED +// skipped private _Py_REF_MERGED + +// skipped private _Py_REF_SHARED + +extern_libpython! { + #[cfg(all(Py_3_14, Py_LIMITED_API))] + pub fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t; +} + +#[cfg(not(all(Py_3_14, Py_LIMITED_API)))] +#[inline] +pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t { + #[cfg(Py_GIL_DISABLED)] + { + let local = (*ob).ob_ref_local.load(Relaxed); + if local == _Py_IMMORTAL_REFCNT_LOCAL { + #[cfg(not(Py_3_14))] + return _Py_IMMORTAL_REFCNT; + #[cfg(Py_3_14)] + return _Py_IMMORTAL_INITIAL_REFCNT; + } + let shared = (*ob).ob_ref_shared.load(Relaxed); + local as Py_ssize_t + Py_ssize_t::from(shared >> _Py_REF_SHARED_SHIFT) + } + + #[cfg(all(Py_LIMITED_API, Py_3_14))] + { + Py_REFCNT(ob) + } + + #[cfg(all(not(Py_GIL_DISABLED), not(all(Py_LIMITED_API, Py_3_14)), Py_3_12))] + { + (*ob).ob_refcnt.ob_refcnt + } + + #[cfg(all(not(Py_GIL_DISABLED), not(Py_3_12), not(GraalPy)))] + { + (*ob).ob_refcnt + } + + #[cfg(all(not(Py_GIL_DISABLED), not(Py_3_12), GraalPy))] + { + _Py_REFCNT(ob) + } +} + +#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))] +#[cfg(Py_3_12)] +#[inline(always)] +unsafe fn _Py_IsImmortal(op: *mut PyObject) -> c_int { + #[cfg(all(target_pointer_width = "64", not(Py_GIL_DISABLED)))] + { + (((*op).ob_refcnt.ob_refcnt as crate::PY_INT32_T) < 0) as c_int + } + + #[cfg(all(target_pointer_width = "32", not(Py_GIL_DISABLED)))] + { + #[cfg(not(Py_3_14))] + { + ((*op).ob_refcnt.ob_refcnt == _Py_IMMORTAL_REFCNT) as c_int + } + + #[cfg(Py_3_14)] + { + ((*op).ob_refcnt.ob_refcnt >= _Py_IMMORTAL_MINIMUM_REFCNT) as c_int + } + } + + #[cfg(Py_GIL_DISABLED)] + { + ((*op).ob_ref_local.load(Relaxed) == _Py_IMMORTAL_REFCNT_LOCAL) as c_int + } +} + +// skipped _Py_IsStaticImmortal + +// TODO: Py_SET_REFCNT + +extern_libpython! { + #[cfg(all(py_sys_config = "Py_REF_DEBUG", not(Py_LIMITED_API)))] + fn _Py_NegativeRefcount(filename: *const c_char, lineno: c_int, op: *mut PyObject); + #[cfg(all(Py_3_12, py_sys_config = "Py_REF_DEBUG", not(Py_LIMITED_API)))] + fn _Py_INCREF_IncRefTotal(); + #[cfg(all(Py_3_12, py_sys_config = "Py_REF_DEBUG", not(Py_LIMITED_API)))] + fn _Py_DECREF_DecRefTotal(); + + #[cfg_attr(PyPy, link_name = "_PyPy_Dealloc")] + fn _Py_Dealloc(arg1: *mut PyObject); + + #[cfg_attr(PyPy, link_name = "PyPy_IncRef")] + #[cfg_attr(GraalPy, link_name = "_Py_IncRef")] + pub fn Py_IncRef(o: *mut PyObject); + #[cfg_attr(PyPy, link_name = "PyPy_DecRef")] + #[cfg_attr(GraalPy, link_name = "_Py_DecRef")] + pub fn Py_DecRef(o: *mut PyObject); + + #[cfg(all(Py_3_10, not(PyPy)))] + fn _Py_IncRef(o: *mut PyObject); + #[cfg(all(Py_3_10, not(PyPy)))] + fn _Py_DecRef(o: *mut PyObject); + + #[cfg(GraalPy)] + fn _Py_REFCNT(arg1: *const PyObject) -> Py_ssize_t; +} + +#[inline(always)] +pub unsafe fn Py_INCREF(op: *mut PyObject) { + // On limited API, the free-threaded build, or with refcount debugging, let the interpreter do refcounting + // TODO: reimplement the logic in the header in the free-threaded build, for a little bit of performance. + #[cfg(any( + Py_GIL_DISABLED, + Py_LIMITED_API, + py_sys_config = "Py_REF_DEBUG", + GraalPy + ))] + { + // _Py_IncRef was added to the ABI in 3.10; skips null checks + #[cfg(all(Py_3_10, not(PyPy)))] + { + _Py_IncRef(op); + } + + #[cfg(any(not(Py_3_10), PyPy))] + { + Py_IncRef(op); + } + } + + // version-specific builds are allowed to directly manipulate the reference count + #[cfg(not(any( + Py_GIL_DISABLED, + Py_LIMITED_API, + py_sys_config = "Py_REF_DEBUG", + GraalPy + )))] + { + #[cfg(all(Py_3_14, target_pointer_width = "64"))] + { + let cur_refcnt = (*op).ob_refcnt.ob_refcnt; + if (cur_refcnt as i32) < 0 { + return; + } + (*op).ob_refcnt.ob_refcnt = cur_refcnt.wrapping_add(1); + } + + #[cfg(all(Py_3_12, not(Py_3_14), target_pointer_width = "64"))] + { + let cur_refcnt = (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN]; + let new_refcnt = cur_refcnt.wrapping_add(1); + if new_refcnt == 0 { + return; + } + (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN] = new_refcnt; + } + + #[cfg(all(Py_3_12, target_pointer_width = "32"))] + { + if _Py_IsImmortal(op) != 0 { + return; + } + (*op).ob_refcnt.ob_refcnt += 1 + } + + #[cfg(not(Py_3_12))] + { + (*op).ob_refcnt += 1 + } + + // Skipped _Py_INCREF_STAT_INC - if anyone wants this, please file an issue + // or submit a PR supporting Py_STATS build option and pystats.h + } +} + +// skipped _Py_DecRefShared +// skipped _Py_DecRefSharedDebug +// skipped _Py_MergeZeroLocalRefcount + +#[inline(always)] +#[cfg_attr( + all(py_sys_config = "Py_REF_DEBUG", Py_3_12, not(Py_LIMITED_API)), + track_caller +)] +pub unsafe fn Py_DECREF(op: *mut PyObject) { + // On limited API, the free-threaded build, or with refcount debugging, let the interpreter do refcounting + // On 3.12+ we implement refcount debugging to get better assertion locations on negative refcounts + // TODO: reimplement the logic in the header in the free-threaded build, for a little bit of performance. + #[cfg(any( + Py_GIL_DISABLED, + Py_LIMITED_API, + all(py_sys_config = "Py_REF_DEBUG", not(Py_3_12)), + GraalPy + ))] + { + // _Py_DecRef was added to the ABI in 3.10; skips null checks + #[cfg(all(Py_3_10, not(PyPy)))] + { + _Py_DecRef(op); + } + + #[cfg(any(not(Py_3_10), PyPy))] + { + Py_DecRef(op); + } + } + + #[cfg(not(any( + Py_GIL_DISABLED, + Py_LIMITED_API, + all(py_sys_config = "Py_REF_DEBUG", not(Py_3_12)), + GraalPy + )))] + { + #[cfg(Py_3_12)] + if _Py_IsImmortal(op) != 0 { + return; + } + + // Skipped _Py_DECREF_STAT_INC - if anyone needs this, please file an issue + // or submit a PR supporting Py_STATS build option and pystats.h + + #[cfg(py_sys_config = "Py_REF_DEBUG")] + _Py_DECREF_DecRefTotal(); + + #[cfg(Py_3_12)] + { + (*op).ob_refcnt.ob_refcnt -= 1; + + #[cfg(py_sys_config = "Py_REF_DEBUG")] + if (*op).ob_refcnt.ob_refcnt < 0 { + let location = core::panic::Location::caller(); + let filename = alloc::ffi::CString::new(location.file()).unwrap(); + _Py_NegativeRefcount(filename.as_ptr(), location.line() as i32, op); + } + + if (*op).ob_refcnt.ob_refcnt == 0 { + _Py_Dealloc(op); + } + } + + #[cfg(not(Py_3_12))] + { + (*op).ob_refcnt -= 1; + + if (*op).ob_refcnt == 0 { + _Py_Dealloc(op); + } + } + } +} + +#[inline] +pub unsafe fn Py_CLEAR(op: *mut *mut PyObject) { + let tmp = *op; + if !tmp.is_null() { + *op = ptr::null_mut(); + Py_DECREF(tmp); + } +} + +#[inline] +pub unsafe fn Py_XINCREF(op: *mut PyObject) { + if !op.is_null() { + Py_INCREF(op) + } +} + +#[inline] +pub unsafe fn Py_XDECREF(op: *mut PyObject) { + if !op.is_null() { + Py_DECREF(op) + } +} + +extern_libpython! { + #[cfg(all(Py_3_10, Py_LIMITED_API, not(PyPy)))] + #[cfg_attr(docsrs, doc(cfg(Py_3_10)))] + pub fn Py_NewRef(obj: *mut PyObject) -> *mut PyObject; + #[cfg(all(Py_3_10, Py_LIMITED_API, not(PyPy)))] + #[cfg_attr(docsrs, doc(cfg(Py_3_10)))] + pub fn Py_XNewRef(obj: *mut PyObject) -> *mut PyObject; +} + +// macro _Py_NewRef not public; reimplemented directly inside Py_NewRef here +// macro _Py_XNewRef not public; reimplemented directly inside Py_XNewRef here + +#[cfg(all(Py_3_10, any(not(Py_LIMITED_API), PyPy)))] +#[cfg_attr(docsrs, doc(cfg(Py_3_10)))] +#[inline] +pub unsafe fn Py_NewRef(obj: *mut PyObject) -> *mut PyObject { + Py_INCREF(obj); + obj +} + +#[cfg(all(Py_3_10, any(not(Py_LIMITED_API), PyPy)))] +#[cfg_attr(docsrs, doc(cfg(Py_3_10)))] +#[inline] +pub unsafe fn Py_XNewRef(obj: *mut PyObject) -> *mut PyObject { + Py_XINCREF(obj); + obj +} diff --git a/vendor/pyo3-ffi/src/setobject.rs b/vendor/pyo3-ffi/src/setobject.rs new file mode 100644 index 0000000..505b50d --- /dev/null +++ b/vendor/pyo3-ffi/src/setobject.rs @@ -0,0 +1,94 @@ +use crate::object::*; +use crate::pyport::Py_ssize_t; +use core::ffi::c_int; + +#[cfg(not(RustPython))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPySet_Type")] + pub static mut PySet_Type: PyTypeObject; + #[cfg_attr(PyPy, link_name = "PyPyFrozenSet_Type")] + pub static mut PyFrozenSet_Type: PyTypeObject; + pub static mut PySetIter_Type: PyTypeObject; +} + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPySet_New")] + pub fn PySet_New(arg1: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyFrozenSet_New")] + pub fn PyFrozenSet_New(arg1: *mut PyObject) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPySet_Add")] + pub fn PySet_Add(set: *mut PyObject, key: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPySet_Clear")] + pub fn PySet_Clear(set: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPySet_Contains")] + pub fn PySet_Contains(anyset: *mut PyObject, key: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPySet_Discard")] + pub fn PySet_Discard(set: *mut PyObject, key: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPySet_Pop")] + pub fn PySet_Pop(set: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPySet_Size")] + pub fn PySet_Size(anyset: *mut PyObject) -> Py_ssize_t; + + #[cfg(any(PyPy, RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyFrozenSet_CheckExact")] + pub fn PyFrozenSet_CheckExact(ob: *mut PyObject) -> c_int; + + #[cfg(any(PyPy, RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyFrozenSet_Check")] + pub fn PyFrozenSet_Check(ob: *mut PyObject) -> c_int; + + #[cfg(any(PyPy, RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyAnySet_CheckExact")] + pub fn PyAnySet_CheckExact(ob: *mut PyObject) -> c_int; + + #[cfg(RustPython)] + pub fn PyAnySet_Check(ob: *mut PyObject) -> c_int; + + #[cfg(RustPython)] + pub fn PySet_CheckExact(op: *mut PyObject) -> c_int; + + #[cfg(any(PyPy, RustPython))] + #[cfg_attr(PyPy, link_name = "PyPySet_Check")] + pub fn PySet_Check(ob: *mut PyObject) -> c_int; +} + +#[inline] +#[cfg(not(any(PyPy, GraalPy, RustPython)))] +pub unsafe fn PyFrozenSet_CheckExact(ob: *mut PyObject) -> c_int { + (Py_TYPE(ob) == &raw mut PyFrozenSet_Type) as c_int +} + +#[inline] +#[cfg(not(any(PyPy, RustPython)))] +pub unsafe fn PyFrozenSet_Check(ob: *mut PyObject) -> c_int { + (Py_TYPE(ob) == &raw mut PyFrozenSet_Type + || PyType_IsSubtype(Py_TYPE(ob), &raw mut PyFrozenSet_Type) != 0) as c_int +} + +#[inline] +#[cfg(not(any(PyPy, RustPython)))] +pub unsafe fn PyAnySet_CheckExact(ob: *mut PyObject) -> c_int { + (Py_TYPE(ob) == &raw mut PySet_Type || Py_TYPE(ob) == &raw mut PyFrozenSet_Type) as c_int +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyAnySet_Check(ob: *mut PyObject) -> c_int { + (PyAnySet_CheckExact(ob) != 0 + || PyType_IsSubtype(Py_TYPE(ob), &raw mut PySet_Type) != 0 + || PyType_IsSubtype(Py_TYPE(ob), &raw mut PyFrozenSet_Type) != 0) as c_int +} + +#[inline] +#[cfg(all(Py_3_10, not(RustPython)))] +pub unsafe fn PySet_CheckExact(op: *mut PyObject) -> c_int { + crate::Py_IS_TYPE(op, &raw mut PySet_Type) +} + +#[inline] +#[cfg(not(any(PyPy, RustPython)))] +pub unsafe fn PySet_Check(ob: *mut PyObject) -> c_int { + (Py_TYPE(ob) == &raw mut PySet_Type || PyType_IsSubtype(Py_TYPE(ob), &raw mut PySet_Type) != 0) + as c_int +} diff --git a/vendor/pyo3-ffi/src/sliceobject.rs b/vendor/pyo3-ffi/src/sliceobject.rs new file mode 100644 index 0000000..175a65f --- /dev/null +++ b/vendor/pyo3-ffi/src/sliceobject.rs @@ -0,0 +1,109 @@ +use crate::object::*; +use crate::pyport::Py_ssize_t; +use core::ffi::c_int; + +extern_libpython! { + #[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))] + #[cfg_attr(PyPy, link_name = "_PyPy_EllipsisObject")] + static mut _Py_EllipsisObject: PyObject; + + #[cfg(GraalPy)] + static mut _Py_EllipsisObjectReference: *mut PyObject; +} + +#[inline] +pub unsafe fn Py_Ellipsis() -> *mut PyObject { + #[cfg(all(not(GraalPy), all(Py_3_13, Py_LIMITED_API)))] + return Py_GetConstantBorrowed(Py_CONSTANT_ELLIPSIS); + + #[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))] + return &raw mut _Py_EllipsisObject; + + #[cfg(GraalPy)] + return _Py_EllipsisObjectReference; +} + +#[cfg(not(Py_LIMITED_API))] +#[repr(C)] +pub struct PySliceObject { + pub ob_base: PyObject, + #[cfg(not(GraalPy))] + pub start: *mut PyObject, + #[cfg(not(GraalPy))] + pub stop: *mut PyObject, + #[cfg(not(GraalPy))] + pub step: *mut PyObject, +} + +#[cfg(not(RustPython))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPySlice_Type")] + pub static mut PySlice_Type: PyTypeObject; + pub static mut PyEllipsis_Type: PyTypeObject; +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PySlice_Check(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PySlice_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PySlice_Check(op: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPySlice_New")] + pub fn PySlice_New( + start: *mut PyObject, + stop: *mut PyObject, + step: *mut PyObject, + ) -> *mut PyObject; + + // skipped non-limited _PySlice_FromIndices + // skipped non-limited _PySlice_GetLongIndices + + #[cfg_attr(PyPy, link_name = "PyPySlice_GetIndices")] + pub fn PySlice_GetIndices( + r: *mut PyObject, + length: Py_ssize_t, + start: *mut Py_ssize_t, + stop: *mut Py_ssize_t, + step: *mut Py_ssize_t, + ) -> c_int; +} + +#[inline] +pub unsafe fn PySlice_GetIndicesEx( + slice: *mut PyObject, + length: Py_ssize_t, + start: *mut Py_ssize_t, + stop: *mut Py_ssize_t, + step: *mut Py_ssize_t, + slicelength: *mut Py_ssize_t, +) -> c_int { + if PySlice_Unpack(slice, start, stop, step) < 0 { + *slicelength = 0; + -1 + } else { + *slicelength = PySlice_AdjustIndices(length, start, stop, *step); + 0 + } +} + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPySlice_Unpack")] + pub fn PySlice_Unpack( + slice: *mut PyObject, + start: *mut Py_ssize_t, + stop: *mut Py_ssize_t, + step: *mut Py_ssize_t, + ) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPySlice_AdjustIndices")] + pub fn PySlice_AdjustIndices( + length: Py_ssize_t, + start: *mut Py_ssize_t, + stop: *mut Py_ssize_t, + step: Py_ssize_t, + ) -> Py_ssize_t; +} diff --git a/vendor/pyo3-ffi/src/slots.rs b/vendor/pyo3-ffi/src/slots.rs new file mode 100644 index 0000000..f11a330 --- /dev/null +++ b/vendor/pyo3-ffi/src/slots.rs @@ -0,0 +1,151 @@ +#[cfg(Py_3_15)] +use crate::Py_ssize_t; +#[cfg(Py_3_15)] +use core::ffi::{c_int, c_void}; + +#[cfg(Py_3_15)] +pub type _Py_funcptr_t = unsafe extern "C" fn(); + +#[derive(Copy, Clone)] +#[repr(C)] +#[cfg(Py_3_15)] +pub union _anon_union_32b { + pub sl_reserved: u32, +} + +#[derive(Copy, Clone)] +#[repr(C)] +#[cfg(Py_3_15)] +pub union _anon_union_64b { + pub sl_ptr: *mut c_void, + pub sl_func: Option<_Py_funcptr_t>, + pub sl_size: Py_ssize_t, + pub sl_int64: i64, + pub sl_uint64: u64, +} + +#[derive(Copy, Clone)] +#[repr(C)] +#[cfg(Py_3_15)] +pub struct PySlot { + pub sl_id: u16, + pub sl_flags: u16, + pub anon1: _anon_union_32b, + pub anon2: _anon_union_64b, +} + +#[cfg(Py_3_15)] +pub const PySlot_OPTIONAL: u16 = 0x01; +#[cfg(Py_3_15)] +pub const PySlot_STATIC: u16 = 0x02; +#[cfg(Py_3_15)] +pub const PySlot_INTPTR: u16 = 0x04; +#[cfg(Py_3_15)] +pub const Py_slot_invalid: u16 = 0xffff; + +// The slot IDs are integer constants in the C headers and don't have +// explicit types. Legacy slot IDs are c integers but PySlot IDs are +// u16s. We use this to convert from c_int to u16 safely, without using +// `as`. The panic should only be possible if there is a programming +// error somewhere leading to a slot ID outside the range of u16. If +// TryInto becomes possible in const contexts we could use that instead. +#[cfg(Py_3_15)] +const fn safe_cast_c_int_to_u16(val: c_int) -> u16 { + if val >= 0 && val <= u16::MAX as c_int { + val as u16 + } else { + panic!("Slot ID out of range for u16"); + } +} + +#[cfg(Py_3_15)] +pub const fn PySlot_DATA(NAME: c_int, VALUE: *mut c_void) -> PySlot { + PySlot { + sl_id: safe_cast_c_int_to_u16(NAME), + sl_flags: PySlot_INTPTR, + anon1: _anon_union_32b { sl_reserved: 0 }, + anon2: _anon_union_64b { sl_ptr: VALUE }, + } +} + +#[expect(clippy::incompatible_msrv, reason = "guarded by cfg(const_is_null)")] +#[cfg(Py_3_15)] +pub const unsafe fn PySlot_FUNC(NAME: c_int, VALUE: *mut c_void) -> PySlot { + #[cfg(const_is_null)] + assert!(!VALUE.is_null(), "value may not be null"); + PySlot { + sl_id: safe_cast_c_int_to_u16(NAME), + sl_flags: 0, + anon1: _anon_union_32b { sl_reserved: 0 }, + anon2: _anon_union_64b { + // SAFETY: caller should have provided a valid pointer to function + sl_func: Some(unsafe { core::mem::transmute::<*mut c_void, _Py_funcptr_t>(VALUE) }), + }, + } +} + +#[cfg(Py_3_15)] +pub const fn PySlot_SIZE(NAME: c_int, VALUE: Py_ssize_t) -> PySlot { + PySlot { + sl_id: safe_cast_c_int_to_u16(NAME), + sl_flags: 0, + anon1: _anon_union_32b { sl_reserved: 0 }, + anon2: _anon_union_64b { sl_size: VALUE }, + } +} + +#[cfg(Py_3_15)] +pub const fn PySlot_INT64(NAME: c_int, VALUE: i64) -> PySlot { + PySlot { + sl_id: safe_cast_c_int_to_u16(NAME), + sl_flags: 0, + anon1: _anon_union_32b { sl_reserved: 0 }, + anon2: _anon_union_64b { sl_int64: VALUE }, + } +} + +#[cfg(Py_3_15)] +pub const fn PySlot_UINT64(NAME: c_int, VALUE: u64) -> PySlot { + PySlot { + sl_id: safe_cast_c_int_to_u16(NAME), + sl_flags: 0, + anon1: _anon_union_32b { sl_reserved: 0 }, + anon2: _anon_union_64b { sl_uint64: VALUE }, + } +} + +#[cfg(Py_3_15)] +pub const fn PySlot_STATIC_DATA(NAME: c_int, VALUE: *mut c_void) -> PySlot { + PySlot { + sl_id: safe_cast_c_int_to_u16(NAME), + sl_flags: PySlot_STATIC, + anon1: _anon_union_32b { sl_reserved: 0 }, + anon2: _anon_union_64b { sl_ptr: VALUE }, + } +} + +#[cfg(Py_3_15)] +pub const fn PySlot_PTR(NAME: c_int, VALUE: *mut c_void) -> PySlot { + PySlot { + sl_id: safe_cast_c_int_to_u16(NAME), + sl_flags: PySlot_INTPTR, + anon1: _anon_union_32b { sl_reserved: 0 }, + anon2: _anon_union_64b { sl_ptr: VALUE }, + } +} + +#[cfg(Py_3_15)] +pub const fn PySlot_PTR_STATIC(NAME: c_int, VALUE: *mut c_void) -> PySlot { + PySlot { + sl_id: safe_cast_c_int_to_u16(NAME), + sl_flags: PySlot_INTPTR | PySlot_STATIC, + anon1: _anon_union_32b { sl_reserved: 0 }, + anon2: _anon_union_64b { sl_ptr: VALUE }, + } +} + +#[cfg(Py_3_15)] +pub const fn PySlot_END() -> PySlot { + // SAFETY: the interpreter expects a zeroed slot to mark the end of the slot array + unsafe { core::mem::zeroed() } +} diff --git a/vendor/pyo3-ffi/src/slots_generated.rs b/vendor/pyo3-ffi/src/slots_generated.rs new file mode 100644 index 0000000..ef46e39 --- /dev/null +++ b/vendor/pyo3-ffi/src/slots_generated.rs @@ -0,0 +1,138 @@ +use core::ffi::c_int; + +#[allow(unused_variables)] +const fn _Py_SLOT_COMPAT_VALUE(OLD: c_int, NEW: c_int) -> c_int { + if cfg!(Py_3_15) { + NEW + } else { + OLD + } +} + +#[cfg(Py_3_15)] +pub const Py_slot_end: c_int = 0; +pub const Py_mp_subscript: c_int = 5; +pub const Py_nb_absolute: c_int = 6; +pub const Py_nb_add: c_int = 7; +pub const Py_nb_and: c_int = 8; +pub const Py_nb_bool: c_int = 9; +pub const Py_nb_divmod: c_int = 10; +pub const Py_nb_float: c_int = 11; +pub const Py_nb_floor_divide: c_int = 12; +pub const Py_nb_index: c_int = 13; +pub const Py_nb_inplace_add: c_int = 14; +pub const Py_nb_inplace_and: c_int = 15; +pub const Py_nb_inplace_floor_divide: c_int = 16; +pub const Py_nb_inplace_lshift: c_int = 17; +pub const Py_nb_inplace_multiply: c_int = 18; +pub const Py_nb_inplace_or: c_int = 19; +pub const Py_nb_inplace_power: c_int = 20; +pub const Py_nb_inplace_remainder: c_int = 21; +pub const Py_nb_inplace_rshift: c_int = 22; +pub const Py_nb_inplace_subtract: c_int = 23; +pub const Py_nb_inplace_true_divide: c_int = 24; +pub const Py_nb_inplace_xor: c_int = 25; +pub const Py_nb_int: c_int = 26; +pub const Py_nb_invert: c_int = 27; +pub const Py_nb_lshift: c_int = 28; +pub const Py_nb_multiply: c_int = 29; +pub const Py_nb_negative: c_int = 30; +pub const Py_nb_or: c_int = 31; +pub const Py_nb_positive: c_int = 32; +pub const Py_nb_power: c_int = 33; +pub const Py_nb_remainder: c_int = 34; +pub const Py_nb_rshift: c_int = 35; +pub const Py_nb_subtract: c_int = 36; +pub const Py_nb_true_divide: c_int = 37; +pub const Py_nb_xor: c_int = 38; +pub const Py_sq_ass_item: c_int = 39; +pub const Py_sq_concat: c_int = 40; +pub const Py_sq_contains: c_int = 41; +pub const Py_sq_inplace_concat: c_int = 42; +pub const Py_sq_inplace_repeat: c_int = 43; +pub const Py_sq_item: c_int = 44; +pub const Py_sq_length: c_int = 45; +pub const Py_sq_repeat: c_int = 46; +pub const Py_tp_alloc: c_int = 47; +pub const Py_tp_base: c_int = 48; +pub const Py_tp_bases: c_int = 49; +pub const Py_tp_call: c_int = 50; +pub const Py_tp_clear: c_int = 51; +pub const Py_tp_dealloc: c_int = 52; +pub const Py_tp_del: c_int = 53; +pub const Py_tp_descr_get: c_int = 54; +pub const Py_tp_descr_set: c_int = 55; +pub const Py_tp_doc: c_int = 56; +pub const Py_tp_getattr: c_int = 57; +pub const Py_tp_getattro: c_int = 58; +pub const Py_tp_hash: c_int = 59; +pub const Py_tp_init: c_int = 60; +pub const Py_tp_is_gc: c_int = 61; +pub const Py_tp_iter: c_int = 62; +pub const Py_tp_iternext: c_int = 63; +pub const Py_tp_methods: c_int = 64; +pub const Py_tp_new: c_int = 65; +pub const Py_tp_repr: c_int = 66; +pub const Py_tp_richcompare: c_int = 67; +pub const Py_tp_setattr: c_int = 68; +pub const Py_tp_setattro: c_int = 69; +pub const Py_tp_str: c_int = 70; +pub const Py_tp_traverse: c_int = 71; +pub const Py_tp_members: c_int = 72; +pub const Py_tp_getset: c_int = 73; +pub const Py_tp_free: c_int = 74; +pub const Py_nb_matrix_multiply: c_int = 75; +pub const Py_nb_inplace_matrix_multiply: c_int = 76; +pub const Py_am_await: c_int = 77; +pub const Py_am_aiter: c_int = 78; +pub const Py_am_anext: c_int = 79; +pub const Py_tp_finalize: c_int = 80; +pub const Py_am_send: c_int = 81; +pub const Py_tp_vectorcall: c_int = 82; +pub const Py_tp_token: c_int = 83; +pub const Py_mod_create: c_int = _Py_SLOT_COMPAT_VALUE(1, 84); +pub const Py_mod_exec: c_int = _Py_SLOT_COMPAT_VALUE(2, 85); +pub const Py_mod_multiple_interpreters: c_int = _Py_SLOT_COMPAT_VALUE(3, 86); +pub const Py_mod_gil: c_int = _Py_SLOT_COMPAT_VALUE(4, 87); +pub const Py_bf_getbuffer: c_int = _Py_SLOT_COMPAT_VALUE(1, 88); +pub const Py_bf_releasebuffer: c_int = _Py_SLOT_COMPAT_VALUE(2, 89); +pub const Py_mp_ass_subscript: c_int = _Py_SLOT_COMPAT_VALUE(3, 90); +pub const Py_mp_length: c_int = _Py_SLOT_COMPAT_VALUE(4, 91); +#[cfg(Py_3_15)] +pub const Py_slot_subslots: c_int = 92; +#[cfg(Py_3_15)] +pub const Py_tp_slots: c_int = 93; +#[cfg(Py_3_15)] +pub const Py_mod_slots: c_int = 94; +#[cfg(Py_3_15)] +pub const Py_tp_name: c_int = 95; +#[cfg(Py_3_15)] +pub const Py_tp_basicsize: c_int = 96; +#[cfg(Py_3_15)] +pub const Py_tp_extra_basicsize: c_int = 97; +#[cfg(Py_3_15)] +pub const Py_tp_itemsize: c_int = 98; +#[cfg(Py_3_15)] +pub const Py_tp_flags: c_int = 99; +#[cfg(Py_3_15)] +pub const Py_mod_name: c_int = 100; +#[cfg(Py_3_15)] +pub const Py_mod_doc: c_int = 101; +#[cfg(Py_3_15)] +pub const Py_mod_state_size: c_int = 102; +#[cfg(Py_3_15)] +pub const Py_mod_methods: c_int = 103; +#[cfg(Py_3_15)] +pub const Py_mod_state_traverse: c_int = 104; +#[cfg(Py_3_15)] +pub const Py_mod_state_clear: c_int = 105; +#[cfg(Py_3_15)] +pub const Py_mod_state_free: c_int = 106; +#[cfg(Py_3_15)] +pub const Py_tp_metaclass: c_int = 107; +#[cfg(Py_3_15)] +pub const Py_tp_module: c_int = 108; +#[cfg(Py_3_15)] +pub const Py_mod_abi: c_int = 109; +#[cfg(Py_3_15)] +pub const Py_mod_token: c_int = 110; diff --git a/vendor/pyo3-ffi/src/structmember.rs b/vendor/pyo3-ffi/src/structmember.rs new file mode 100644 index 0000000..7b29482 --- /dev/null +++ b/vendor/pyo3-ffi/src/structmember.rs @@ -0,0 +1,33 @@ +use core::ffi::c_int; + +pub use crate::PyMemberDef; + +#[allow(deprecated)] +pub use crate::_Py_T_OBJECT as T_OBJECT; +pub use crate::Py_T_BOOL as T_BOOL; +pub use crate::Py_T_BYTE as T_BYTE; +pub use crate::Py_T_CHAR as T_CHAR; +pub use crate::Py_T_DOUBLE as T_DOUBLE; +pub use crate::Py_T_FLOAT as T_FLOAT; +pub use crate::Py_T_INT as T_INT; +pub use crate::Py_T_LONG as T_LONG; +pub use crate::Py_T_LONGLONG as T_LONGLONG; +pub use crate::Py_T_OBJECT_EX as T_OBJECT_EX; +pub use crate::Py_T_SHORT as T_SHORT; +pub use crate::Py_T_STRING as T_STRING; +pub use crate::Py_T_STRING_INPLACE as T_STRING_INPLACE; +pub use crate::Py_T_UBYTE as T_UBYTE; +pub use crate::Py_T_UINT as T_UINT; +pub use crate::Py_T_ULONG as T_ULONG; +pub use crate::Py_T_ULONGLONG as T_ULONGLONG; +pub use crate::Py_T_USHORT as T_USHORT; + +#[allow(deprecated)] +pub use crate::_Py_T_NONE as T_NONE; +pub use crate::Py_T_PYSSIZET as T_PYSSIZET; + +/* Flags */ +pub use crate::Py_READONLY as READONLY; +pub const READ_RESTRICTED: c_int = 2; +pub const PY_WRITE_RESTRICTED: c_int = 4; +pub const RESTRICTED: c_int = READ_RESTRICTED | PY_WRITE_RESTRICTED; diff --git a/vendor/pyo3-ffi/src/structseq.rs b/vendor/pyo3-ffi/src/structseq.rs new file mode 100644 index 0000000..7a1a700 --- /dev/null +++ b/vendor/pyo3-ffi/src/structseq.rs @@ -0,0 +1,66 @@ +use crate::object::{PyObject, PyTypeObject}; +#[cfg(not(PyPy))] +use crate::pyport::Py_ssize_t; +use core::ffi::{c_char, c_int}; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyStructSequence_Field { + pub name: *const c_char, + pub doc: *const c_char, +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyStructSequence_Desc { + pub name: *const c_char, + pub doc: *const c_char, + pub fields: *mut PyStructSequence_Field, + pub n_in_sequence: c_int, +} + +extern_libpython! { + #[cfg(any(Py_3_11, all(Py_3_9, not(Py_LIMITED_API))))] + pub static PyStructSequence_UnnamedField: *const c_char; +} + +extern_libpython! { + #[cfg(not(Py_LIMITED_API))] + #[cfg_attr(PyPy, link_name = "PyPyStructSequence_InitType")] + pub fn PyStructSequence_InitType(_type: *mut PyTypeObject, desc: *mut PyStructSequence_Desc); + + #[cfg(not(Py_LIMITED_API))] + #[cfg_attr(PyPy, link_name = "PyPyStructSequence_InitType2")] + pub fn PyStructSequence_InitType2( + _type: *mut PyTypeObject, + desc: *mut PyStructSequence_Desc, + ) -> c_int; + + #[cfg(not(PyPy))] + pub fn PyStructSequence_NewType(desc: *mut PyStructSequence_Desc) -> *mut PyTypeObject; + #[cfg_attr(PyPy, link_name = "PyPyStructSequence_New")] + pub fn PyStructSequence_New(_type: *mut PyTypeObject) -> *mut PyObject; +} + +#[cfg(not(Py_LIMITED_API))] +pub type PyStructSequence = crate::PyTupleObject; + +#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))] +#[inline] +pub unsafe fn PyStructSequence_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) { + crate::PyTuple_SET_ITEM(op, i, v) +} + +#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))] +#[inline] +pub unsafe fn PyStructSequence_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject { + crate::PyTuple_GET_ITEM(op, i) +} + +extern_libpython! { + #[cfg(not(PyPy))] + pub fn PyStructSequence_SetItem(arg1: *mut PyObject, arg2: Py_ssize_t, arg3: *mut PyObject); + + #[cfg(not(PyPy))] + pub fn PyStructSequence_GetItem(arg1: *mut PyObject, arg2: Py_ssize_t) -> *mut PyObject; +} diff --git a/vendor/pyo3-ffi/src/sysmodule.rs b/vendor/pyo3-ffi/src/sysmodule.rs new file mode 100644 index 0000000..d5c2beb --- /dev/null +++ b/vendor/pyo3-ffi/src/sysmodule.rs @@ -0,0 +1,51 @@ +use crate::object::PyObject; +use core::ffi::{c_char, c_int}; +use libc::wchar_t; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPySys_GetObject")] + pub fn PySys_GetObject(arg1: *const c_char) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPySys_SetObject")] + pub fn PySys_SetObject(arg1: *const c_char, arg2: *mut PyObject) -> c_int; + + #[cfg_attr( + Py_3_11, + deprecated( + note = "Deprecated in Python 3.11, use `PyConfig.argv` and `PyConfig.parse_argv` instead" + ) + )] + pub fn PySys_SetArgv(arg1: c_int, arg2: *mut *mut wchar_t); + #[cfg_attr( + Py_3_11, + deprecated( + note = "Deprecated in Python 3.11, use `PyConfig.argv` and `PyConfig.parse_argv` instead" + ) + )] + pub fn PySys_SetArgvEx(arg1: c_int, arg2: *mut *mut wchar_t, arg3: c_int); + pub fn PySys_SetPath(arg1: *const wchar_t); + + #[cfg_attr(PyPy, link_name = "PyPySys_WriteStdout")] + pub fn PySys_WriteStdout(format: *const c_char, ...); + #[cfg_attr(PyPy, link_name = "PyPySys_WriteStderr")] + pub fn PySys_WriteStderr(format: *const c_char, ...); + pub fn PySys_FormatStdout(format: *const c_char, ...); + pub fn PySys_FormatStderr(format: *const c_char, ...); + + #[cfg(not(Py_3_15))] + #[cfg_attr( + Py_3_13, + deprecated( + note = "Deprecated since Python 3.13. Clear sys.warnoptions and warnings.filters instead." + ) + )] + pub fn PySys_ResetWarnOptions(); + #[cfg_attr(Py_3_11, deprecated(note = "Python 3.11"))] + pub fn PySys_AddWarnOption(arg1: *const wchar_t); + #[cfg_attr(Py_3_11, deprecated(note = "Python 3.11"))] + pub fn PySys_AddWarnOptionUnicode(arg1: *mut PyObject); + #[cfg_attr(Py_3_11, deprecated(note = "Python 3.11"))] + pub fn PySys_HasWarnOptions() -> c_int; + + pub fn PySys_AddXOption(arg1: *const wchar_t); + pub fn PySys_GetXOptions() -> *mut PyObject; +} diff --git a/vendor/pyo3-ffi/src/traceback.rs b/vendor/pyo3-ffi/src/traceback.rs new file mode 100644 index 0000000..9cfb11d --- /dev/null +++ b/vendor/pyo3-ffi/src/traceback.rs @@ -0,0 +1,23 @@ +use crate::object::*; +use core::ffi::c_int; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyTraceBack_Here")] + pub fn PyTraceBack_Here(arg1: *mut crate::PyFrameObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyTraceBack_Print")] + pub fn PyTraceBack_Print(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int; + + #[cfg(not(RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyTraceBack_Type")] + pub static mut PyTraceBack_Type: PyTypeObject; + + #[cfg(any(PyPy, RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyTraceBack_Check")] + pub fn PyTraceBack_Check(op: *mut PyObject) -> c_int; +} + +#[inline] +#[cfg(not(any(PyPy, RustPython)))] +pub unsafe fn PyTraceBack_Check(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyTraceBack_Type) +} diff --git a/vendor/pyo3-ffi/src/tupleobject.rs b/vendor/pyo3-ffi/src/tupleobject.rs new file mode 100644 index 0000000..e415eab --- /dev/null +++ b/vendor/pyo3-ffi/src/tupleobject.rs @@ -0,0 +1,50 @@ +use crate::object::*; +use crate::pyport::Py_ssize_t; +use core::ffi::c_int; + +#[cfg(not(RustPython))] +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyTuple_Type")] + pub static mut PyTuple_Type: PyTypeObject; + pub static mut PyTupleIter_Type: PyTypeObject; +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyTuple_Check(op: *mut PyObject) -> c_int { + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS) +} + +#[inline] +#[cfg(not(RustPython))] +pub unsafe fn PyTuple_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyTuple_Type) +} + +extern_libpython! { + #[cfg(RustPython)] + pub fn PyTuple_Check(op: *mut PyObject) -> c_int; + #[cfg(RustPython)] + pub fn PyTuple_CheckExact(op: *mut PyObject) -> c_int; + + #[cfg_attr(PyPy, link_name = "PyPyTuple_New")] + pub fn PyTuple_New(size: Py_ssize_t) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyTuple_Size")] + pub fn PyTuple_Size(arg1: *mut PyObject) -> Py_ssize_t; + #[cfg_attr(PyPy, link_name = "PyPyTuple_GetItem")] + pub fn PyTuple_GetItem(arg1: *mut PyObject, arg2: Py_ssize_t) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyTuple_SetItem")] + pub fn PyTuple_SetItem(arg1: *mut PyObject, arg2: Py_ssize_t, arg3: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyTuple_GetSlice")] + pub fn PyTuple_GetSlice( + arg1: *mut PyObject, + arg2: Py_ssize_t, + arg3: Py_ssize_t, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyTuple_Pack")] + pub fn PyTuple_Pack(arg1: Py_ssize_t, ...) -> *mut PyObject; + #[cfg(any(all(Py_3_15, not(Py_LIMITED_API)), RustPython))] + pub fn PyTuple_FromArray(array: *const *mut PyObject, size: Py_ssize_t) -> *mut PyObject; + #[cfg(not(Py_3_9))] + pub fn PyTuple_ClearFreeList() -> c_int; +} diff --git a/vendor/pyo3-ffi/src/unicodeobject.rs b/vendor/pyo3-ffi/src/unicodeobject.rs new file mode 100644 index 0000000..07dab31 --- /dev/null +++ b/vendor/pyo3-ffi/src/unicodeobject.rs @@ -0,0 +1,368 @@ +use crate::object::*; +use crate::pyport::Py_ssize_t; +use core::ffi::{c_char, c_int, c_void}; +use libc::wchar_t; + +pub type Py_UCS4 = u32; +pub type Py_UCS2 = u16; +pub type Py_UCS1 = u8; + +extern_libpython! { + #[cfg(not(RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyUnicode_Type")] + pub static mut PyUnicode_Type: PyTypeObject; + #[cfg(not(RustPython))] + pub static mut PyUnicodeIter_Type: PyTypeObject; + + #[cfg(any(PyPy, RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyUnicode_Check")] + pub fn PyUnicode_Check(op: *mut PyObject) -> c_int; + + #[cfg(any(PyPy, RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyUnicode_CheckExact")] + pub fn PyUnicode_CheckExact(op: *mut PyObject) -> c_int; +} + +#[inline] +#[cfg(not(any(PyPy, RustPython)))] +pub unsafe fn PyUnicode_Check(op: *mut PyObject) -> c_int { + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) +} + +#[inline] +#[cfg(not(any(PyPy, RustPython)))] +pub unsafe fn PyUnicode_CheckExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut PyUnicode_Type) +} + +pub const Py_UNICODE_REPLACEMENT_CHARACTER: Py_UCS4 = 0xFFFD; + +extern_libpython! { + + #[cfg_attr(PyPy, link_name = "PyPyUnicode_FromStringAndSize")] + pub fn PyUnicode_FromStringAndSize(u: *const c_char, size: Py_ssize_t) -> *mut PyObject; + pub fn PyUnicode_FromString(u: *const c_char) -> *mut PyObject; + + pub fn PyUnicode_Substring( + str: *mut PyObject, + start: Py_ssize_t, + end: Py_ssize_t, + ) -> *mut PyObject; + pub fn PyUnicode_AsUCS4( + unicode: *mut PyObject, + buffer: *mut Py_UCS4, + buflen: Py_ssize_t, + copy_null: c_int, + ) -> *mut Py_UCS4; + pub fn PyUnicode_AsUCS4Copy(unicode: *mut PyObject) -> *mut Py_UCS4; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_GetLength")] + pub fn PyUnicode_GetLength(unicode: *mut PyObject) -> Py_ssize_t; + #[cfg(not(Py_3_12))] + #[deprecated(note = "Removed in Python 3.12")] + #[cfg_attr(PyPy, link_name = "PyPyUnicode_GetSize")] + pub fn PyUnicode_GetSize(unicode: *mut PyObject) -> Py_ssize_t; + pub fn PyUnicode_ReadChar(unicode: *mut PyObject, index: Py_ssize_t) -> Py_UCS4; + pub fn PyUnicode_WriteChar( + unicode: *mut PyObject, + index: Py_ssize_t, + character: Py_UCS4, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_Resize")] + pub fn PyUnicode_Resize(unicode: *mut *mut PyObject, length: Py_ssize_t) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_FromEncodedObject")] + pub fn PyUnicode_FromEncodedObject( + obj: *mut PyObject, + encoding: *const c_char, + errors: *const c_char, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_FromObject")] + pub fn PyUnicode_FromObject(obj: *mut PyObject) -> *mut PyObject; + // #[cfg_attr(PyPy, link_name = "PyPyUnicode_FromFormatV")] + // pub fn PyUnicode_FromFormatV(format: *const c_char, vargs: va_list) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_FromFormat")] + pub fn PyUnicode_FromFormat(format: *const c_char, ...) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_InternInPlace")] + pub fn PyUnicode_InternInPlace(arg1: *mut *mut PyObject); + #[cfg(not(Py_3_12))] + #[cfg_attr(Py_3_10, deprecated(note = "Python 3.10"))] + pub fn PyUnicode_InternImmortal(arg1: *mut *mut PyObject); + #[cfg_attr(PyPy, link_name = "PyPyUnicode_InternFromString")] + pub fn PyUnicode_InternFromString(u: *const c_char) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_FromWideChar")] + pub fn PyUnicode_FromWideChar(w: *const wchar_t, size: Py_ssize_t) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_AsWideChar")] + pub fn PyUnicode_AsWideChar( + unicode: *mut PyObject, + w: *mut wchar_t, + size: Py_ssize_t, + ) -> Py_ssize_t; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_AsWideCharString")] + pub fn PyUnicode_AsWideCharString( + unicode: *mut PyObject, + size: *mut Py_ssize_t, + ) -> *mut wchar_t; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_FromOrdinal")] + pub fn PyUnicode_FromOrdinal(ordinal: c_int) -> *mut PyObject; + #[cfg(not(Py_3_9))] + pub fn PyUnicode_ClearFreeList() -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_GetDefaultEncoding")] + pub fn PyUnicode_GetDefaultEncoding() -> *const c_char; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_Decode")] + pub fn PyUnicode_Decode( + s: *const c_char, + size: Py_ssize_t, + encoding: *const c_char, + errors: *const c_char, + ) -> *mut PyObject; + #[cfg(not(Py_3_15))] + #[deprecated(note = "use PyCodec_Decode() instead")] + pub fn PyUnicode_AsDecodedObject( + unicode: *mut PyObject, + encoding: *const c_char, + errors: *const c_char, + ) -> *mut PyObject; + #[cfg(not(Py_3_15))] + #[deprecated(note = "use PyCodec_Decode() instead")] + pub fn PyUnicode_AsDecodedUnicode( + unicode: *mut PyObject, + encoding: *const c_char, + errors: *const c_char, + ) -> *mut PyObject; + #[cfg(not(Py_3_15))] + #[deprecated(note = "use PyCodec_Encode() instead")] + #[cfg_attr(PyPy, link_name = "PyPyUnicode_AsEncodedObject")] + pub fn PyUnicode_AsEncodedObject( + unicode: *mut PyObject, + encoding: *const c_char, + errors: *const c_char, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_AsEncodedString")] + pub fn PyUnicode_AsEncodedString( + unicode: *mut PyObject, + encoding: *const c_char, + errors: *const c_char, + ) -> *mut PyObject; + #[cfg(not(Py_3_15))] + #[deprecated(note = "use PyCodec_Encode() instead")] + pub fn PyUnicode_AsEncodedUnicode( + unicode: *mut PyObject, + encoding: *const c_char, + errors: *const c_char, + ) -> *mut PyObject; + pub fn PyUnicode_BuildEncodingMap(string: *mut PyObject) -> *mut PyObject; + pub fn PyUnicode_DecodeUTF7( + string: *const c_char, + length: Py_ssize_t, + errors: *const c_char, + ) -> *mut PyObject; + pub fn PyUnicode_DecodeUTF7Stateful( + string: *const c_char, + length: Py_ssize_t, + errors: *const c_char, + consumed: *mut Py_ssize_t, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeUTF8")] + pub fn PyUnicode_DecodeUTF8( + string: *const c_char, + length: Py_ssize_t, + errors: *const c_char, + ) -> *mut PyObject; + pub fn PyUnicode_DecodeUTF8Stateful( + string: *const c_char, + length: Py_ssize_t, + errors: *const c_char, + consumed: *mut Py_ssize_t, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF8String")] + pub fn PyUnicode_AsUTF8String(unicode: *mut PyObject) -> *mut PyObject; + #[cfg(any(Py_3_10, not(Py_LIMITED_API)))] + #[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF8AndSize")] + pub fn PyUnicode_AsUTF8AndSize(unicode: *mut PyObject, size: *mut Py_ssize_t) -> *const c_char; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeUTF32")] + pub fn PyUnicode_DecodeUTF32( + string: *const c_char, + length: Py_ssize_t, + errors: *const c_char, + byteorder: *mut c_int, + ) -> *mut PyObject; + pub fn PyUnicode_DecodeUTF32Stateful( + string: *const c_char, + length: Py_ssize_t, + errors: *const c_char, + byteorder: *mut c_int, + consumed: *mut Py_ssize_t, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF32String")] + pub fn PyUnicode_AsUTF32String(unicode: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeUTF16")] + pub fn PyUnicode_DecodeUTF16( + string: *const c_char, + length: Py_ssize_t, + errors: *const c_char, + byteorder: *mut c_int, + ) -> *mut PyObject; + pub fn PyUnicode_DecodeUTF16Stateful( + string: *const c_char, + length: Py_ssize_t, + errors: *const c_char, + byteorder: *mut c_int, + consumed: *mut Py_ssize_t, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF16String")] + pub fn PyUnicode_AsUTF16String(unicode: *mut PyObject) -> *mut PyObject; + pub fn PyUnicode_DecodeUnicodeEscape( + string: *const c_char, + length: Py_ssize_t, + errors: *const c_char, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUnicodeEscapeString")] + pub fn PyUnicode_AsUnicodeEscapeString(unicode: *mut PyObject) -> *mut PyObject; + pub fn PyUnicode_DecodeRawUnicodeEscape( + string: *const c_char, + length: Py_ssize_t, + errors: *const c_char, + ) -> *mut PyObject; + pub fn PyUnicode_AsRawUnicodeEscapeString(unicode: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeLatin1")] + pub fn PyUnicode_DecodeLatin1( + string: *const c_char, + length: Py_ssize_t, + errors: *const c_char, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_AsLatin1String")] + pub fn PyUnicode_AsLatin1String(unicode: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeASCII")] + pub fn PyUnicode_DecodeASCII( + string: *const c_char, + length: Py_ssize_t, + errors: *const c_char, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_AsASCIIString")] + pub fn PyUnicode_AsASCIIString(unicode: *mut PyObject) -> *mut PyObject; + pub fn PyUnicode_DecodeCharmap( + string: *const c_char, + length: Py_ssize_t, + mapping: *mut PyObject, + errors: *const c_char, + ) -> *mut PyObject; + pub fn PyUnicode_AsCharmapString( + unicode: *mut PyObject, + mapping: *mut PyObject, + ) -> *mut PyObject; + // skipped PyUnicode_DecodeMBCS + // skipped PyUnicode_DecodeMBCSStateful + // skipped PyUnicode_DecodeCodePageStateful + // skipped PyUnicode_AsMBCSString + // skipped PyUnicode_EncodeCodePage + pub fn PyUnicode_DecodeLocaleAndSize( + str: *const c_char, + len: Py_ssize_t, + errors: *const c_char, + ) -> *mut PyObject; + pub fn PyUnicode_DecodeLocale(str: *const c_char, errors: *const c_char) -> *mut PyObject; + pub fn PyUnicode_EncodeLocale(unicode: *mut PyObject, errors: *const c_char) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_FSConverter")] + pub fn PyUnicode_FSConverter(arg1: *mut PyObject, arg2: *mut c_void) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_FSDecoder")] + pub fn PyUnicode_FSDecoder(arg1: *mut PyObject, arg2: *mut c_void) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeFSDefault")] + pub fn PyUnicode_DecodeFSDefault(s: *const c_char) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeFSDefaultAndSize")] + pub fn PyUnicode_DecodeFSDefaultAndSize(s: *const c_char, size: Py_ssize_t) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_EncodeFSDefault")] + pub fn PyUnicode_EncodeFSDefault(unicode: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_Concat")] + pub fn PyUnicode_Concat(left: *mut PyObject, right: *mut PyObject) -> *mut PyObject; + pub fn PyUnicode_Append(pleft: *mut *mut PyObject, right: *mut PyObject); + pub fn PyUnicode_AppendAndDel(pleft: *mut *mut PyObject, right: *mut PyObject); + #[cfg_attr(PyPy, link_name = "PyPyUnicode_Split")] + pub fn PyUnicode_Split( + s: *mut PyObject, + sep: *mut PyObject, + maxsplit: Py_ssize_t, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_Splitlines")] + pub fn PyUnicode_Splitlines(s: *mut PyObject, keepends: c_int) -> *mut PyObject; + pub fn PyUnicode_Partition(s: *mut PyObject, sep: *mut PyObject) -> *mut PyObject; + pub fn PyUnicode_RPartition(s: *mut PyObject, sep: *mut PyObject) -> *mut PyObject; + pub fn PyUnicode_RSplit( + s: *mut PyObject, + sep: *mut PyObject, + maxsplit: Py_ssize_t, + ) -> *mut PyObject; + pub fn PyUnicode_Translate( + str: *mut PyObject, + table: *mut PyObject, + errors: *const c_char, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_Join")] + pub fn PyUnicode_Join(separator: *mut PyObject, seq: *mut PyObject) -> *mut PyObject; +} + +#[cfg(PyPy)] +type TailmatchResult = c_int; + +#[cfg(not(PyPy))] +type TailmatchResult = Py_ssize_t; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyUnicode_Tailmatch")] + pub fn PyUnicode_Tailmatch( + str: *mut PyObject, + substr: *mut PyObject, + start: Py_ssize_t, + end: Py_ssize_t, + direction: c_int, + ) -> TailmatchResult; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_Find")] + pub fn PyUnicode_Find( + str: *mut PyObject, + substr: *mut PyObject, + start: Py_ssize_t, + end: Py_ssize_t, + direction: c_int, + ) -> Py_ssize_t; + pub fn PyUnicode_FindChar( + str: *mut PyObject, + ch: Py_UCS4, + start: Py_ssize_t, + end: Py_ssize_t, + direction: c_int, + ) -> Py_ssize_t; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_Count")] + pub fn PyUnicode_Count( + str: *mut PyObject, + substr: *mut PyObject, + start: Py_ssize_t, + end: Py_ssize_t, + ) -> Py_ssize_t; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_Replace")] + pub fn PyUnicode_Replace( + str: *mut PyObject, + substr: *mut PyObject, + replstr: *mut PyObject, + maxcount: Py_ssize_t, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_Compare")] + pub fn PyUnicode_Compare(left: *mut PyObject, right: *mut PyObject) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_CompareWithASCIIString")] + pub fn PyUnicode_CompareWithASCIIString(left: *mut PyObject, right: *const c_char) -> c_int; + #[cfg(Py_3_13)] + pub fn PyUnicode_EqualToUTF8(unicode: *mut PyObject, string: *const c_char) -> c_int; + #[cfg(Py_3_13)] + pub fn PyUnicode_EqualToUTF8AndSize( + unicode: *mut PyObject, + string: *const c_char, + size: Py_ssize_t, + ) -> c_int; + // skipped PyUnicode_Equal + pub fn PyUnicode_RichCompare( + left: *mut PyObject, + right: *mut PyObject, + op: c_int, + ) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyUnicode_Format")] + pub fn PyUnicode_Format(format: *mut PyObject, args: *mut PyObject) -> *mut PyObject; + pub fn PyUnicode_Contains(container: *mut PyObject, element: *mut PyObject) -> c_int; + pub fn PyUnicode_IsIdentifier(s: *mut PyObject) -> c_int; +} diff --git a/vendor/pyo3-ffi/src/warnings.rs b/vendor/pyo3-ffi/src/warnings.rs new file mode 100644 index 0000000..4277c4d --- /dev/null +++ b/vendor/pyo3-ffi/src/warnings.rs @@ -0,0 +1,34 @@ +use crate::object::PyObject; +use crate::pyport::Py_ssize_t; +use core::ffi::{c_char, c_int}; + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyErr_WarnEx")] + pub fn PyErr_WarnEx( + category: *mut PyObject, + message: *const c_char, + stack_level: Py_ssize_t, + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyErr_WarnFormat")] + pub fn PyErr_WarnFormat( + category: *mut PyObject, + stack_level: Py_ssize_t, + format: *const c_char, + ... + ) -> c_int; + pub fn PyErr_ResourceWarning( + source: *mut PyObject, + stack_level: Py_ssize_t, + format: *const c_char, + ... + ) -> c_int; + #[cfg_attr(PyPy, link_name = "PyPyErr_WarnExplicit")] + pub fn PyErr_WarnExplicit( + category: *mut PyObject, + message: *const c_char, + filename: *const c_char, + lineno: c_int, + module: *const c_char, + registry: *mut PyObject, + ) -> c_int; +} diff --git a/vendor/pyo3-ffi/src/weakrefobject.rs b/vendor/pyo3-ffi/src/weakrefobject.rs new file mode 100644 index 0000000..84b9412 --- /dev/null +++ b/vendor/pyo3-ffi/src/weakrefobject.rs @@ -0,0 +1,73 @@ +use crate::object::*; +use core::ffi::c_int; + +#[cfg(all(not(PyPy), Py_LIMITED_API, not(GraalPy)))] +opaque_struct!(pub PyWeakReference); + +#[cfg(all(not(PyPy), not(Py_LIMITED_API), not(GraalPy)))] +pub use crate::_PyWeakReference as PyWeakReference; + +extern_libpython! { + // TODO: PyO3 is depending on this symbol in `reference.rs`, we should change this and + // remove the export as this is a private symbol. + #[cfg(not(RustPython))] + pub static mut _PyWeakref_RefType: PyTypeObject; + #[cfg(not(RustPython))] + static mut _PyWeakref_ProxyType: PyTypeObject; + #[cfg(not(RustPython))] + static mut _PyWeakref_CallableProxyType: PyTypeObject; + + #[cfg(any(PyPy, RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyWeakref_CheckRef")] + pub fn PyWeakref_CheckRef(op: *mut PyObject) -> c_int; + + #[cfg(any(PyPy, RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyWeakref_CheckRefExact")] + pub fn PyWeakref_CheckRefExact(op: *mut PyObject) -> c_int; + + #[cfg(any(PyPy, RustPython))] + #[cfg_attr(PyPy, link_name = "PyPyWeakref_CheckProxy")] + pub fn PyWeakref_CheckProxy(op: *mut PyObject) -> c_int; +} + +#[inline] +#[cfg(not(any(PyPy, RustPython)))] +#[cfg(not(RustPython))] +pub unsafe fn PyWeakref_CheckRef(op: *mut PyObject) -> c_int { + PyObject_TypeCheck(op, &raw mut _PyWeakref_RefType) +} + +#[inline] +#[cfg(not(any(PyPy, RustPython)))] +pub unsafe fn PyWeakref_CheckRefExact(op: *mut PyObject) -> c_int { + Py_IS_TYPE(op, &raw mut _PyWeakref_RefType) +} + +#[inline] +#[cfg(not(any(PyPy, RustPython)))] +pub unsafe fn PyWeakref_CheckProxy(op: *mut PyObject) -> c_int { + (Py_IS_TYPE(op, &raw mut _PyWeakref_ProxyType) > 0 + || Py_IS_TYPE(op, &raw mut _PyWeakref_CallableProxyType) > 0) as c_int +} + +#[inline] +pub unsafe fn PyWeakref_Check(op: *mut PyObject) -> c_int { + (PyWeakref_CheckRef(op) != 0 || PyWeakref_CheckProxy(op) != 0) as c_int +} + +extern_libpython! { + #[cfg_attr(PyPy, link_name = "PyPyWeakref_NewRef")] + pub fn PyWeakref_NewRef(ob: *mut PyObject, callback: *mut PyObject) -> *mut PyObject; + #[cfg_attr(PyPy, link_name = "PyPyWeakref_NewProxy")] + pub fn PyWeakref_NewProxy(ob: *mut PyObject, callback: *mut PyObject) -> *mut PyObject; + #[cfg(not(Py_3_15))] + #[cfg_attr(PyPy, link_name = "PyPyWeakref_GetObject")] + #[cfg_attr( + Py_3_13, + deprecated(note = "deprecated since Python 3.13. Use `PyWeakref_GetRef` instead.") + )] + pub fn PyWeakref_GetObject(reference: *mut PyObject) -> *mut PyObject; + #[cfg(Py_3_13)] + #[cfg_attr(PyPy, link_name = "PyPyWeakref_GetRef")] + pub fn PyWeakref_GetRef(reference: *mut PyObject, pobj: *mut *mut PyObject) -> c_int; +} diff --git a/vendor/pyo3-macros-backend/.cargo-checksum.json b/vendor/pyo3-macros-backend/.cargo-checksum.json new file mode 100644 index 0000000..12776e9 --- /dev/null +++ b/vendor/pyo3-macros-backend/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo_vcs_info.json":"0e1142e078c836d3fc899bac603093f62ed68865ca83470570104176e5351d4c","Cargo.lock":"71cc767bf9534b42c58032ab23525bb98f2e7fd7d733a4ee38ed5fa3eb7e5e8f","Cargo.toml":"a965cadd857e44658af0673a7e7402a266de9fbbfdbc12beff0fcf58c40375ef","Cargo.toml.orig":"2d85e4cf389597ee7e3d0661c5d3a4dbec08fef4f9327ac841f75a5683575833","LICENSE-APACHE":"32c76dbe0e73d79100d5ece77c158399f2e2541bc5c78548a4ba45c1cb53c5c9","LICENSE-MIT":"afcbe3b2e6b37172b5a9ca869ee4c0b8cdc09316e5d4384864154482c33e5af6","src/attributes.rs":"153b8b3c48279c4ce58aef6f7a75fe0bc404721b183026df2ec87020f8845b0d","src/combine_errors.rs":"e4fd8dc4ad4ce70810012c88379ca31eb064c713ef1a0c7705d1c16699b38b74","src/derive_attributes.rs":"07ae0ba3230060c5dd82628d514bc03d6e9b5f9e804127553d1e3d9b856eb9b9","src/frompyobject.rs":"3c76c8388e9a82382859d7653977eb98ec4ff453efaec323eead3812a7a9d9c4","src/intopyobject.rs":"9a370047b655d21033cbaaeb8961d28708744b5dd74dc29f3a43bbabf6f5b7cc","src/introspection.rs":"3d4903dcd69dc3b98c64714a7ca1ecc4870b354d9a30b512e3cfc17c2af1daa2","src/konst.rs":"00ff9f22898cd65b20d9069fb4454a246ee7f2fa458a6b967f33e03942ca5d10","src/lib.rs":"1aaec987df980bbba136ed55cefcb0d9035155c0b819ca02f695915c56456e9f","src/method.rs":"efb72df7fb00e34af90a64fa2d5f3f74b2ecb795209935cb8ba5c12ea0b62575","src/module.rs":"8717fd425d3ef6e3844d2f67c3eab3d265fab88c99b921615da381cafa959894","src/params.rs":"cab1d681390152ded6c5871e47fc54eac7bf457cd6a5772e271cb745664b00f4","src/py_expr.rs":"f49abc226659d650cb717c640222d85d7166c54c48373ed85d3c280b6a3d254e","src/pyclass.rs":"75ac0fe8947af3702a6e9c76c1b33725721a7ebc802a6b53dfd0b770a3776250","src/pyfunction.rs":"b5b808017500010fc3f2d751c482ae3fa8244559ad2a6518c9cd9f3cb96f0a92","src/pyfunction/signature.rs":"6f353506a230df30448ba5c288dd4abd83b2c8c96edbbd727c225c678702185f","src/pyimpl.rs":"5f41adfa9b291444dfe4c21c35db97f9a7c4853d1c8a68fa94a033e05216934b","src/pymethod.rs":"9ac954eb95ba17d64615a760cae1329fb0b4468813f721f8eee8890b8759ae2c","src/quotes.rs":"95d11e4a4e4742be4caefa8a69762080b53a9f10d8255cfedab23bd5912cf194","src/utils.rs":"b3ab1888bc6e2169176ef4f3cc1fee38ad51a232f8c9071f9a2090622ceb70e6"},"package":"571575aa3749fa6216757dd47d2a3e7ef360f329a40f0666a9fbd14889024952"} \ No newline at end of file diff --git a/vendor/pyo3-macros-backend/.cargo_vcs_info.json b/vendor/pyo3-macros-backend/.cargo_vcs_info.json new file mode 100644 index 0000000..87f0093 --- /dev/null +++ b/vendor/pyo3-macros-backend/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "a70d17f898df41b3d1632ee987f624f5222d8d39" + }, + "path_in_vcs": "pyo3-macros-backend" +} \ No newline at end of file diff --git a/vendor/pyo3-macros-backend/Cargo.lock b/vendor/pyo3-macros-backend/Cargo.lock new file mode 100644 index 0000000..9039744 --- /dev/null +++ b/vendor/pyo3-macros-backend/Cargo.lock @@ -0,0 +1,54 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pyo3-macros-backend" +version = "0.29.2" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" diff --git a/vendor/pyo3-macros-backend/Cargo.toml b/vendor/pyo3-macros-backend/Cargo.toml new file mode 100644 index 0000000..f58275f --- /dev/null +++ b/vendor/pyo3-macros-backend/Cargo.toml @@ -0,0 +1,111 @@ +# 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.83" +name = "pyo3-macros-backend" +version = "0.29.2" +authors = ["PyO3 Project and Contributors "] +build = false +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Code generation for PyO3 package" +homepage = "https://github.com/pyo3/pyo3" +readme = false +keywords = [ + "pyo3", + "python", + "cpython", + "ffi", +] +categories = [ + "api-bindings", + "development-tools::ffi", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/pyo3/pyo3" + +[features] +experimental-async = [] +experimental-inspect = [] + +[lib] +name = "pyo3_macros_backend" +path = "src/lib.rs" + +[dependencies.heck] +version = "0.5" + +[dependencies.proc-macro2] +version = "1.0.60" +default-features = false + +[dependencies.quote] +version = "1.0.37" +default-features = false + +[dependencies.syn] +version = "2.0.59" +features = [ + "derive", + "parsing", + "printing", + "clone-impls", + "full", + "extra-traits", + "visit-mut", +] +default-features = false + +[lints.clippy] +checked_conversions = "warn" +dbg_macro = "warn" +explicit_into_iter_loop = "warn" +explicit_iter_loop = "warn" +filter_map_next = "warn" +flat_map_option = "warn" +let_unit_value = "warn" +manual_assert = "warn" +manual_ok_or = "warn" +todo = "warn" +undocumented_unsafe_blocks = "warn" +unnecessary_wraps = "warn" +used_underscore_binding = "warn" +useless_transmute = "warn" + +[lints.rust] +elided_lifetimes_in_paths = "warn" +invalid_doc_attributes = "warn" +rust_2021_prelude_collisions = "warn" +unsafe_op_in_unsafe_fn = "warn" +unused_lifetimes = "warn" + +[lints.rust.rust_2018_idioms] +level = "warn" +priority = -1 + +[lints.rust.unexpected_cfgs] +level = "warn" +priority = 0 +check-cfg = [ + "cfg(pyo3_disable_reference_pool)", + "cfg(pyo3_leak_on_drop_without_reference_pool)", + "cfg(pyo3_use_raw_dylib)", + 'cfg(pyo3_dll, values("python3", "python3_d", "python3t", "python3t_d", "python38", "python38_d", "python39", "python39_d", "python310", "python310_d", "python311", "python311_d", "python312", "python312_d", "python313", "python313_d", "python313t", "python313t_d", "python314", "python314_d", "python314t", "python314t_d", "python315", "python315_d", "python315t", "python315t_d", "python316", "python316_d", "python316t", "python316t_d", "libpypy3.11-c"))', +] + +[lints.rustdoc] +bare_urls = "warn" +broken_intra_doc_links = "warn" diff --git a/vendor/pyo3-macros-backend/Cargo.toml.orig b/vendor/pyo3-macros-backend/Cargo.toml.orig new file mode 100644 index 0000000..3d4b66a --- /dev/null +++ b/vendor/pyo3-macros-backend/Cargo.toml.orig @@ -0,0 +1,33 @@ +[package] +name = "pyo3-macros-backend" +version = "0.29.2" +description = "Code generation for PyO3 package" +authors = ["PyO3 Project and Contributors "] +keywords = ["pyo3", "python", "cpython", "ffi"] +homepage = "https://github.com/pyo3/pyo3" +repository = "https://github.com/pyo3/pyo3" +categories = ["api-bindings", "development-tools::ffi"] +license = "MIT OR Apache-2.0" +edition = "2021" +rust-version.workspace = true + +# Note: we use default-features = false for proc-macro related crates +# not to depend on proc-macro itself. +# See https://github.com/PyO3/pyo3/pull/810 for more. +[dependencies] +heck = "0.5" +proc-macro2 = { version = "1.0.60", default-features = false } +quote = { version = "1.0.37", default-features = false } + +[dependencies.syn] +# 2.0.59 for `LitCStr` +version = "2.0.59" +default-features = false +features = ["derive", "parsing", "printing", "clone-impls", "full", "extra-traits", "visit-mut"] + +[lints] +workspace = true + +[features] +experimental-async = [] +experimental-inspect = [] diff --git a/vendor/pyo3-macros-backend/LICENSE-APACHE b/vendor/pyo3-macros-backend/LICENSE-APACHE new file mode 100644 index 0000000..72207b8 --- /dev/null +++ b/vendor/pyo3-macros-backend/LICENSE-APACHE @@ -0,0 +1,178 @@ +Copyright (c) 2017-present PyO3 Project and Contributors. https://github.com/PyO3 + + 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/pyo3-macros-backend/LICENSE-MIT b/vendor/pyo3-macros-backend/LICENSE-MIT new file mode 100644 index 0000000..cd0ad00 --- /dev/null +++ b/vendor/pyo3-macros-backend/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2023-present PyO3 Project and Contributors. https://github.com/PyO3 + +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/pyo3-macros-backend/src/attributes.rs b/vendor/pyo3-macros-backend/src/attributes.rs new file mode 100644 index 0000000..9894c46 --- /dev/null +++ b/vendor/pyo3-macros-backend/src/attributes.rs @@ -0,0 +1,450 @@ +use proc_macro2::TokenStream; +use quote::{quote, ToTokens}; +use syn::parse::Parser; +use syn::{ + ext::IdentExt, + parse::{Parse, ParseStream}, + punctuated::Punctuated, + spanned::Spanned, + token::Comma, + Attribute, Expr, ExprPath, Ident, Index, LitBool, LitStr, Member, Path, Result, Token, +}; + +use crate::combine_errors::CombineErrors; + +pub mod kw { + syn::custom_keyword!(annotation); + syn::custom_keyword!(attribute); + syn::custom_keyword!(cancel_handle); + syn::custom_keyword!(constructor); + syn::custom_keyword!(dict); + syn::custom_keyword!(eq); + syn::custom_keyword!(eq_int); + syn::custom_keyword!(extends); + syn::custom_keyword!(freelist); + syn::custom_keyword!(from_py_with); + syn::custom_keyword!(frozen); + syn::custom_keyword!(get); + syn::custom_keyword!(get_all); + syn::custom_keyword!(hash); + syn::custom_keyword!(into_py_with); + syn::custom_keyword!(item); + syn::custom_keyword!(immutable_type); + syn::custom_keyword!(from_item_all); + syn::custom_keyword!(mapping); + syn::custom_keyword!(module); + syn::custom_keyword!(name); + syn::custom_keyword!(ord); + syn::custom_keyword!(pass_module); + syn::custom_keyword!(rename_all); + syn::custom_keyword!(sequence); + syn::custom_keyword!(set); + syn::custom_keyword!(set_all); + syn::custom_keyword!(new); + syn::custom_keyword!(signature); + syn::custom_keyword!(str); + syn::custom_keyword!(subclass); + syn::custom_keyword!(submodule); + syn::custom_keyword!(text_signature); + syn::custom_keyword!(transparent); + syn::custom_keyword!(unsendable); + syn::custom_keyword!(weakref); + syn::custom_keyword!(generic); + syn::custom_keyword!(gil_used); + syn::custom_keyword!(warn); + syn::custom_keyword!(message); + syn::custom_keyword!(category); + syn::custom_keyword!(from_py_object); + syn::custom_keyword!(skip_from_py_object); +} + +fn take_int(read: &mut &str, tracker: &mut usize) -> String { + let mut int = String::new(); + for (i, ch) in read.char_indices() { + match ch { + '0'..='9' => { + *tracker += 1; + int.push(ch) + } + _ => { + *read = &read[i..]; + break; + } + } + } + int +} + +fn take_ident(read: &mut &str, tracker: &mut usize) -> Ident { + let mut ident = String::new(); + if read.starts_with("r#") { + ident.push_str("r#"); + *tracker += 2; + *read = &read[2..]; + } + for (i, ch) in read.char_indices() { + match ch { + 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' => { + *tracker += 1; + ident.push(ch) + } + _ => { + *read = &read[i..]; + break; + } + } + } + Ident::parse_any.parse_str(&ident).unwrap() +} + +// shorthand parsing logic inspiration taken from https://github.com/dtolnay/thiserror/blob/master/impl/src/fmt.rs +fn parse_shorthand_format(fmt: LitStr) -> Result<(LitStr, Vec)> { + let span = fmt.span(); + let token = fmt.token(); + let value = fmt.value(); + let mut read = value.as_str(); + let mut out = String::new(); + let mut members = Vec::new(); + let mut tracker = 1; + while let Some(brace) = read.find('{') { + tracker += brace; + out += &read[..brace + 1]; + read = &read[brace + 1..]; + if read.starts_with('{') { + out.push('{'); + read = &read[1..]; + tracker += 2; + continue; + } + let next = match read.chars().next() { + Some(next) => next, + None => break, + }; + tracker += 1; + let member = match next { + '0'..='9' => { + let start = tracker; + let index = take_int(&mut read, &mut tracker).parse::().unwrap(); + let end = tracker; + let subspan = token.subspan(start..end).unwrap_or(span); + let idx = Index { + index, + span: subspan, + }; + Member::Unnamed(idx) + } + 'a'..='z' | 'A'..='Z' | '_' => { + let start = tracker; + let mut ident = take_ident(&mut read, &mut tracker); + let end = tracker; + let subspan = token.subspan(start..end).unwrap_or(span); + ident.set_span(subspan); + Member::Named(ident) + } + '}' | ':' => { + let start = tracker; + tracker += 1; + let end = tracker; + let subspan = token.subspan(start..end).unwrap_or(span); + // we found a closing bracket or formatting ':' without finding a member, we assume the user wants the instance formatted here + bail_spanned!(subspan.span() => "No member found, you must provide a named or positionally specified member.") + } + _ => continue, + }; + members.push(member); + } + out += read; + Ok((LitStr::new(&out, span), members)) +} + +#[derive(Clone, Debug)] +pub struct StringFormatter { + pub fmt: LitStr, + pub args: Vec, +} + +impl Parse for crate::attributes::StringFormatter { + fn parse(input: ParseStream<'_>) -> Result { + let (fmt, args) = parse_shorthand_format(input.parse()?)?; + Ok(Self { fmt, args }) + } +} + +impl ToTokens for crate::attributes::StringFormatter { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.fmt.to_tokens(tokens); + tokens.extend(quote! {self.args}) + } +} + +#[derive(Clone, Debug)] +pub struct KeywordAttribute { + pub kw: K, + pub value: V, +} + +#[derive(Clone, Debug)] +pub struct OptionalKeywordAttribute { + pub kw: K, + pub value: Option, +} + +/// A helper type which parses the inner type via a literal string +/// e.g. `LitStrValue` -> parses "some::path" in quotes. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct LitStrValue(pub T); + +impl Parse for LitStrValue { + fn parse(input: ParseStream<'_>) -> Result { + let lit_str: LitStr = input.parse()?; + lit_str.parse().map(LitStrValue) + } +} + +impl ToTokens for LitStrValue { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.0.to_tokens(tokens) + } +} + +/// A helper type which parses a name via a literal string +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct NameLitStr(pub Ident); + +impl Parse for NameLitStr { + fn parse(input: ParseStream<'_>) -> Result { + let string_literal: LitStr = input.parse()?; + if let Ok(ident) = string_literal.parse_with(Ident::parse_any) { + Ok(NameLitStr(ident)) + } else { + bail_spanned!(string_literal.span() => "expected a single identifier in double quotes") + } + } +} + +impl ToTokens for NameLitStr { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.0.to_tokens(tokens) + } +} + +/// Available renaming rules +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum RenamingRule { + CamelCase, + KebabCase, + Lowercase, + PascalCase, + ScreamingKebabCase, + ScreamingSnakeCase, + SnakeCase, + Uppercase, +} + +/// A helper type which parses a renaming rule via a literal string +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct RenamingRuleLitStr { + pub lit: LitStr, + pub rule: RenamingRule, +} + +impl Parse for RenamingRuleLitStr { + fn parse(input: ParseStream<'_>) -> Result { + let string_literal: LitStr = input.parse()?; + let rule = match string_literal.value().as_ref() { + "camelCase" => RenamingRule::CamelCase, + "kebab-case" => RenamingRule::KebabCase, + "lowercase" => RenamingRule::Lowercase, + "PascalCase" => RenamingRule::PascalCase, + "SCREAMING-KEBAB-CASE" => RenamingRule::ScreamingKebabCase, + "SCREAMING_SNAKE_CASE" => RenamingRule::ScreamingSnakeCase, + "snake_case" => RenamingRule::SnakeCase, + "UPPERCASE" => RenamingRule::Uppercase, + _ => { + bail_spanned!(string_literal.span() => "expected a valid renaming rule, possible values are: \"camelCase\", \"kebab-case\", \"lowercase\", \"PascalCase\", \"SCREAMING-KEBAB-CASE\", \"SCREAMING_SNAKE_CASE\", \"snake_case\", \"UPPERCASE\"") + } + }; + Ok(Self { + lit: string_literal, + rule, + }) + } +} + +impl ToTokens for RenamingRuleLitStr { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.lit.to_tokens(tokens) + } +} + +/// Text signature can be either a literal string or opt-in/out +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum TextSignatureAttributeValue { + Str(LitStr), + // `None` ident to disable automatic text signature generation + Disabled(Ident), +} + +impl Parse for TextSignatureAttributeValue { + fn parse(input: ParseStream<'_>) -> Result { + if let Ok(lit_str) = input.parse::() { + return Ok(TextSignatureAttributeValue::Str(lit_str)); + } + + let err_span = match input.parse::() { + Ok(ident) if ident == "None" => { + return Ok(TextSignatureAttributeValue::Disabled(ident)); + } + Ok(other_ident) => other_ident.span(), + Err(e) => e.span(), + }; + + Err(err_spanned!(err_span => "expected a string literal or `None`")) + } +} + +impl ToTokens for TextSignatureAttributeValue { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + TextSignatureAttributeValue::Str(s) => s.to_tokens(tokens), + TextSignatureAttributeValue::Disabled(b) => b.to_tokens(tokens), + } + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum NewImplTypeAttributeValue { + FromFields, + // Future variant for 'default' should go here +} + +impl Parse for NewImplTypeAttributeValue { + fn parse(input: ParseStream<'_>) -> Result { + let string_literal: LitStr = input.parse()?; + if string_literal.value().as_str() == "from_fields" { + Ok(NewImplTypeAttributeValue::FromFields) + } else { + bail_spanned!(string_literal.span() => "expected \"from_fields\"") + } + } +} + +impl ToTokens for NewImplTypeAttributeValue { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + NewImplTypeAttributeValue::FromFields => { + tokens.extend(quote! { "from_fields" }); + } + } + } +} + +pub type ExtendsAttribute = KeywordAttribute; +pub type FreelistAttribute = KeywordAttribute>; +pub type ModuleAttribute = KeywordAttribute; +pub type NameAttribute = KeywordAttribute; +pub type RenameAllAttribute = KeywordAttribute; +pub type StrFormatterAttribute = OptionalKeywordAttribute; +pub type TextSignatureAttribute = KeywordAttribute; +pub type NewImplTypeAttribute = KeywordAttribute; +pub type SubmoduleAttribute = kw::submodule; +pub type GILUsedAttribute = KeywordAttribute; + +impl Parse for KeywordAttribute { + fn parse(input: ParseStream<'_>) -> Result { + let kw: K = input.parse()?; + let _: Token![=] = input.parse()?; + let value = input.parse()?; + Ok(KeywordAttribute { kw, value }) + } +} + +impl ToTokens for KeywordAttribute { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.kw.to_tokens(tokens); + Token![=](self.kw.span()).to_tokens(tokens); + self.value.to_tokens(tokens); + } +} + +impl Parse for OptionalKeywordAttribute { + fn parse(input: ParseStream<'_>) -> Result { + let kw: K = input.parse()?; + let value = match input.parse::() { + Ok(_) => Some(input.parse()?), + Err(_) => None, + }; + Ok(OptionalKeywordAttribute { kw, value }) + } +} + +impl ToTokens for OptionalKeywordAttribute { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.kw.to_tokens(tokens); + if self.value.is_some() { + Token![=](self.kw.span()).to_tokens(tokens); + self.value.to_tokens(tokens); + } + } +} + +pub type FromPyWithAttribute = KeywordAttribute; +pub type IntoPyWithAttribute = KeywordAttribute; + +pub type DefaultAttribute = OptionalKeywordAttribute; + +/// For specifying the path to the pyo3 crate. +pub type CrateAttribute = KeywordAttribute>; + +pub fn get_pyo3_options(attr: &syn::Attribute) -> Result>> { + if attr.path().is_ident("pyo3") { + attr.parse_args_with(Punctuated::parse_terminated).map(Some) + } else { + Ok(None) + } +} + +/// Takes attributes from an attribute vector. +/// +/// For each attribute in `attrs`, `extractor` is called. If `extractor` returns `Ok(true)`, then +/// the attribute will be removed from the vector. +/// +/// This is similar to `Vec::retain` except the closure is fallible and the condition is reversed. +/// (In `retain`, returning `true` keeps the element, here it removes it.) +pub fn take_attributes( + attrs: &mut Vec, + mut extractor: impl FnMut(&Attribute) -> Result, +) -> Result<()> { + *attrs = attrs + .drain(..) + .filter_map(|attr| { + extractor(&attr) + .map(move |attribute_handled| if attribute_handled { None } else { Some(attr) }) + .transpose() + }) + .collect::>()?; + Ok(()) +} + +pub fn take_pyo3_options(attrs: &mut Vec) -> Result> { + let mut out = Vec::new(); + + take_attributes(attrs, |attr| match get_pyo3_options(attr) { + Ok(result) => { + if let Some(options) = result { + out.extend(options.into_iter().map(|a| Ok(a))); + Ok(true) + } else { + Ok(false) + } + } + Err(err) => { + out.push(Err(err)); + Ok(true) + } + })?; + + let out: Vec = out.into_iter().try_combine_syn_errors()?; + + Ok(out) +} diff --git a/vendor/pyo3-macros-backend/src/combine_errors.rs b/vendor/pyo3-macros-backend/src/combine_errors.rs new file mode 100644 index 0000000..235831a --- /dev/null +++ b/vendor/pyo3-macros-backend/src/combine_errors.rs @@ -0,0 +1,36 @@ +pub(crate) trait CombineErrors: Iterator { + type Ok; + fn try_combine_syn_errors(self) -> syn::Result>; +} + +impl CombineErrors for I +where + I: Iterator>, +{ + type Ok = T; + + fn try_combine_syn_errors(self) -> syn::Result> { + let mut oks: Vec = Vec::new(); + let mut errors: Vec = Vec::new(); + + for res in self { + match res { + Ok(val) => oks.push(val), + Err(e) => errors.push(e), + } + } + + let mut err_iter = errors.into_iter(); + let mut err = match err_iter.next() { + // There are no errors + None => return Ok(oks), + Some(e) => e, + }; + + for e in err_iter { + err.combine(e); + } + + Err(err) + } +} diff --git a/vendor/pyo3-macros-backend/src/derive_attributes.rs b/vendor/pyo3-macros-backend/src/derive_attributes.rs new file mode 100644 index 0000000..6ec78e1 --- /dev/null +++ b/vendor/pyo3-macros-backend/src/derive_attributes.rs @@ -0,0 +1,217 @@ +use crate::attributes::{ + self, get_pyo3_options, CrateAttribute, DefaultAttribute, FromPyWithAttribute, + IntoPyWithAttribute, RenameAllAttribute, +}; +use proc_macro2::Span; +use syn::parse::{Parse, ParseStream}; +use syn::spanned::Spanned; +use syn::{parenthesized, Attribute, LitStr, Result, Token}; + +/// Attributes for deriving `FromPyObject`/`IntoPyObject` scoped on containers. +pub enum ContainerAttribute { + /// Treat the Container as a Wrapper, operate directly on its field + Transparent(attributes::kw::transparent), + /// Force every field to be extracted from item of source Python object. + ItemAll(attributes::kw::from_item_all), + /// Change the name of an enum variant in the generated error message. + ErrorAnnotation(LitStr), + /// Change the path for the pyo3 crate + Crate(CrateAttribute), + /// Converts the field idents according to the [RenamingRule](attributes::RenamingRule) before extraction + RenameAll(RenameAllAttribute), +} + +impl Parse for ContainerAttribute { + fn parse(input: ParseStream<'_>) -> Result { + let lookahead = input.lookahead1(); + if lookahead.peek(attributes::kw::transparent) { + let kw: attributes::kw::transparent = input.parse()?; + Ok(ContainerAttribute::Transparent(kw)) + } else if lookahead.peek(attributes::kw::from_item_all) { + let kw: attributes::kw::from_item_all = input.parse()?; + Ok(ContainerAttribute::ItemAll(kw)) + } else if lookahead.peek(attributes::kw::annotation) { + let _: attributes::kw::annotation = input.parse()?; + let _: Token![=] = input.parse()?; + input.parse().map(ContainerAttribute::ErrorAnnotation) + } else if lookahead.peek(Token![crate]) { + input.parse().map(ContainerAttribute::Crate) + } else if lookahead.peek(attributes::kw::rename_all) { + input.parse().map(ContainerAttribute::RenameAll) + } else { + Err(lookahead.error()) + } + } +} + +#[derive(Default, Clone)] +pub struct ContainerAttributes { + /// Treat the Container as a Wrapper, operate directly on its field + pub transparent: Option, + /// Force every field to be extracted from item of source Python object. + pub from_item_all: Option, + /// Change the name of an enum variant in the generated error message. + pub annotation: Option, + /// Change the path for the pyo3 crate + pub krate: Option, + /// Converts the field idents according to the [RenamingRule](attributes::RenamingRule) before extraction + pub rename_all: Option, +} + +impl ContainerAttributes { + pub fn from_attrs(attrs: &[Attribute]) -> Result { + let mut options = ContainerAttributes::default(); + + for attr in attrs { + if let Some(pyo3_attrs) = get_pyo3_options(attr)? { + pyo3_attrs + .into_iter() + .try_for_each(|opt| options.set_option(opt))?; + } + } + Ok(options) + } + + fn set_option(&mut self, option: ContainerAttribute) -> syn::Result<()> { + macro_rules! set_option { + ($key:ident) => { + { + ensure_spanned!( + self.$key.is_none(), + $key.span() => concat!("`", stringify!($key), "` may only be specified once") + ); + self.$key = Some($key); + } + }; + } + + match option { + ContainerAttribute::Transparent(transparent) => set_option!(transparent), + ContainerAttribute::ItemAll(from_item_all) => set_option!(from_item_all), + ContainerAttribute::ErrorAnnotation(annotation) => set_option!(annotation), + ContainerAttribute::Crate(krate) => set_option!(krate), + ContainerAttribute::RenameAll(rename_all) => set_option!(rename_all), + } + Ok(()) + } +} + +#[derive(Clone, Debug)] +pub enum FieldGetter { + GetItem(attributes::kw::item, Option), + GetAttr(attributes::kw::attribute, Option), +} + +impl FieldGetter { + pub fn span(&self) -> Span { + match self { + FieldGetter::GetItem(item, _) => item.span, + FieldGetter::GetAttr(attribute, _) => attribute.span, + } + } +} + +pub enum FieldAttribute { + Getter(FieldGetter), + FromPyWith(FromPyWithAttribute), + IntoPyWith(IntoPyWithAttribute), + Default(DefaultAttribute), +} + +impl Parse for FieldAttribute { + fn parse(input: ParseStream<'_>) -> Result { + let lookahead = input.lookahead1(); + if lookahead.peek(attributes::kw::attribute) { + let attr_kw: attributes::kw::attribute = input.parse()?; + if input.peek(syn::token::Paren) { + let content; + let _ = parenthesized!(content in input); + let attr_name: LitStr = content.parse()?; + if !content.is_empty() { + return Err(content.error( + "expected at most one argument: `attribute` or `attribute(\"name\")`", + )); + } + ensure_spanned!( + !attr_name.value().is_empty(), + attr_name.span() => "attribute name cannot be empty" + ); + Ok(Self::Getter(FieldGetter::GetAttr(attr_kw, Some(attr_name)))) + } else { + Ok(Self::Getter(FieldGetter::GetAttr(attr_kw, None))) + } + } else if lookahead.peek(attributes::kw::item) { + let item_kw: attributes::kw::item = input.parse()?; + if input.peek(syn::token::Paren) { + let content; + let _ = parenthesized!(content in input); + let key = content.parse()?; + if !content.is_empty() { + return Err( + content.error("expected at most one argument: `item` or `item(key)`") + ); + } + Ok(Self::Getter(FieldGetter::GetItem(item_kw, Some(key)))) + } else { + Ok(Self::Getter(FieldGetter::GetItem(item_kw, None))) + } + } else if lookahead.peek(attributes::kw::from_py_with) { + input.parse().map(Self::FromPyWith) + } else if lookahead.peek(attributes::kw::into_py_with) { + input.parse().map(FieldAttribute::IntoPyWith) + } else if lookahead.peek(Token![default]) { + input.parse().map(Self::Default) + } else { + Err(lookahead.error()) + } + } +} + +#[derive(Clone, Debug, Default)] +pub struct FieldAttributes { + pub getter: Option, + pub from_py_with: Option, + pub into_py_with: Option, + pub default: Option, +} + +impl FieldAttributes { + /// Extract the field attributes. + pub fn from_attrs(attrs: &[Attribute]) -> Result { + let mut options = FieldAttributes::default(); + + for attr in attrs { + if let Some(pyo3_attrs) = get_pyo3_options(attr)? { + pyo3_attrs + .into_iter() + .try_for_each(|opt| options.set_option(opt))?; + } + } + Ok(options) + } + + fn set_option(&mut self, option: FieldAttribute) -> syn::Result<()> { + macro_rules! set_option { + ($key:ident) => { + set_option!($key, concat!("`", stringify!($key), "` may only be specified once")) + }; + ($key:ident, $msg: expr) => {{ + ensure_spanned!( + self.$key.is_none(), + $key.span() => $msg + ); + self.$key = Some($key); + }} + } + + match option { + FieldAttribute::Getter(getter) => { + set_option!(getter, "only one of `attribute` or `item` can be provided") + } + FieldAttribute::FromPyWith(from_py_with) => set_option!(from_py_with), + FieldAttribute::IntoPyWith(into_py_with) => set_option!(into_py_with), + FieldAttribute::Default(default) => set_option!(default), + } + Ok(()) + } +} diff --git a/vendor/pyo3-macros-backend/src/frompyobject.rs b/vendor/pyo3-macros-backend/src/frompyobject.rs new file mode 100644 index 0000000..8260fd9 --- /dev/null +++ b/vendor/pyo3-macros-backend/src/frompyobject.rs @@ -0,0 +1,598 @@ +use crate::attributes::{DefaultAttribute, FromPyWithAttribute, RenamingRule}; +use crate::derive_attributes::{ContainerAttributes, FieldAttributes, FieldGetter}; +#[cfg(feature = "experimental-inspect")] +use crate::py_expr::PyExpr; +use crate::utils::{self, Ctx}; +use proc_macro2::TokenStream; +use quote::{format_ident, quote, quote_spanned, ToTokens}; +use syn::{ + ext::IdentExt, parse_quote, punctuated::Punctuated, spanned::Spanned, DataEnum, DeriveInput, + Fields, Ident, Result, Token, +}; + +/// Describes derivation input of an enum. +struct Enum<'a> { + enum_ident: &'a Ident, + variants: Vec>, +} + +impl<'a> Enum<'a> { + /// Construct a new enum representation. + /// + /// `data_enum` is the `syn` representation of the input enum, `ident` is the + /// `Identifier` of the enum. + fn new( + data_enum: &'a DataEnum, + ident: &'a Ident, + options: ContainerAttributes, + ) -> Result { + ensure_spanned!( + !data_enum.variants.is_empty(), + ident.span() => "cannot derive FromPyObject for empty enum" + ); + let variants = data_enum + .variants + .iter() + .map(|variant| { + let mut variant_options = ContainerAttributes::from_attrs(&variant.attrs)?; + if let Some(rename_all) = &options.rename_all { + ensure_spanned!( + variant_options.rename_all.is_none(), + variant_options.rename_all.span() => "Useless variant `rename_all` - enum is already annotated with `rename_all" + ); + variant_options.rename_all = Some(rename_all.clone()); + + } + let var_ident = &variant.ident; + Container::new( + &variant.fields, + parse_quote!(#ident::#var_ident), + variant_options, + ) + }) + .collect::>>()?; + + Ok(Enum { + enum_ident: ident, + variants, + }) + } + + /// Build derivation body for enums. + fn build(&self, ctx: &Ctx) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + let mut var_extracts = Vec::new(); + let mut variant_names = Vec::new(); + let mut error_names = Vec::new(); + + for var in &self.variants { + let struct_derive = var.build(ctx); + let ext = quote!({ + let maybe_ret = || -> #pyo3_path::PyResult { + #struct_derive + }(); + + match maybe_ret { + ok @ ::std::result::Result::Ok(_) => return ok, + ::std::result::Result::Err(err) => err + } + }); + + var_extracts.push(ext); + variant_names.push(var.path.segments.last().unwrap().ident.to_string()); + error_names.push(&var.err_name); + } + let ty_name = self.enum_ident.to_string(); + quote!( + let errors = [ + #(#var_extracts),* + ]; + ::std::result::Result::Err( + #pyo3_path::impl_::frompyobject::failed_to_extract_enum( + obj.py(), + #ty_name, + &[#(#variant_names),*], + &[#(#error_names),*], + &errors + ) + ) + ) + } + + #[cfg(feature = "experimental-inspect")] + fn input_type(&self) -> PyExpr { + self.variants + .iter() + .map(|var| var.input_type()) + .reduce(PyExpr::union) + .expect("Empty enum") + } +} + +struct NamedStructField<'a> { + ident: &'a syn::Ident, + getter: Option, + from_py_with: Option, + default: Option, + ty: &'a syn::Type, +} + +struct TupleStructField { + from_py_with: Option, + ty: syn::Type, +} + +/// Container Style +/// +/// Covers Structs, Tuplestructs and corresponding Newtypes. +enum ContainerType<'a> { + /// Struct Container, e.g. `struct Foo { a: String }` + /// + /// Variant contains the list of field identifiers and the corresponding extraction call. + Struct(Vec>), + /// Newtype struct container, e.g. `#[transparent] struct Foo { a: String }` + /// + /// The field specified by the identifier is extracted directly from the object. + #[cfg_attr(not(feature = "experimental-inspect"), allow(unused))] + StructNewtype(&'a syn::Ident, Option, &'a syn::Type), + /// Tuple struct, e.g. `struct Foo(String)`. + /// + /// Variant contains a list of conversion methods for each of the fields that are directly + /// extracted from the tuple. + Tuple(Vec), + /// Tuple newtype, e.g. `#[transparent] struct Foo(String)` + /// + /// The wrapped field is directly extracted from the object. + #[cfg_attr(not(feature = "experimental-inspect"), allow(unused))] + TupleNewtype(Option, Box), +} + +/// Data container +/// +/// Either describes a struct or an enum variant. +struct Container<'a> { + path: syn::Path, + ty: ContainerType<'a>, + err_name: String, + rename_rule: Option, +} + +impl<'a> Container<'a> { + /// Construct a container based on fields, identifier and attributes. + /// + /// Fails if the variant has no fields or incompatible attributes. + fn new(fields: &'a Fields, path: syn::Path, options: ContainerAttributes) -> Result { + let style = match fields { + Fields::Unnamed(unnamed) if !unnamed.unnamed.is_empty() => { + ensure_spanned!( + options.rename_all.is_none(), + options.rename_all.span() => "`rename_all` is useless on tuple structs and variants." + ); + let mut tuple_fields = unnamed + .unnamed + .iter() + .map(|field| { + let attrs = FieldAttributes::from_attrs(&field.attrs)?; + ensure_spanned!( + attrs.getter.is_none(), + field.span() => "`getter` is not permitted on tuple struct elements." + ); + ensure_spanned!( + attrs.default.is_none(), + field.span() => "`default` is not permitted on tuple struct elements." + ); + Ok(TupleStructField { + from_py_with: attrs.from_py_with, + ty: field.ty.clone(), + }) + }) + .collect::>>()?; + + if tuple_fields.len() == 1 { + // Always treat a 1-length tuple struct as "transparent", even without the + // explicit annotation. + let field = tuple_fields.pop().unwrap(); + ContainerType::TupleNewtype(field.from_py_with, Box::new(field.ty)) + } else if options.transparent.is_some() { + bail_spanned!( + fields.span() => "transparent structs and variants can only have 1 field" + ); + } else { + ContainerType::Tuple(tuple_fields) + } + } + Fields::Named(named) if !named.named.is_empty() => { + let mut struct_fields = named + .named + .iter() + .map(|field| { + let ident = field + .ident + .as_ref() + .expect("Named fields should have identifiers"); + let mut attrs = FieldAttributes::from_attrs(&field.attrs)?; + + if let Some(ref from_item_all) = options.from_item_all { + if let Some(replaced) = attrs.getter.replace(FieldGetter::GetItem(parse_quote!(item), None)) + { + match replaced { + FieldGetter::GetItem(item, Some(item_name)) => { + attrs.getter = Some(FieldGetter::GetItem(item, Some(item_name))); + } + FieldGetter::GetItem(_, None) => bail_spanned!(from_item_all.span() => "Useless `item` - the struct is already annotated with `from_item_all`"), + FieldGetter::GetAttr(_, _) => bail_spanned!( + from_item_all.span() => "The struct is already annotated with `from_item_all`, `attribute` is not allowed" + ), + } + } + } + + Ok(NamedStructField { + ident, + getter: attrs.getter, + from_py_with: attrs.from_py_with, + default: attrs.default, + ty: &field.ty, + }) + }) + .collect::>>()?; + if struct_fields.iter().all(|field| field.default.is_some()) { + bail_spanned!( + fields.span() => "cannot derive FromPyObject for structs and variants with only default values" + ) + } else if options.transparent.is_some() { + ensure_spanned!( + struct_fields.len() == 1, + fields.span() => "transparent structs and variants can only have 1 field" + ); + ensure_spanned!( + options.rename_all.is_none(), + options.rename_all.span() => "`rename_all` is not permitted on `transparent` structs and variants" + ); + let field = struct_fields.pop().unwrap(); + ensure_spanned!( + field.getter.is_none(), + field.ident.span() => "`transparent` structs may not have a `getter` for the inner field" + ); + ContainerType::StructNewtype(field.ident, field.from_py_with, field.ty) + } else { + ContainerType::Struct(struct_fields) + } + } + _ => bail_spanned!( + fields.span() => "cannot derive FromPyObject for empty structs and variants" + ), + }; + let err_name = options.annotation.map_or_else( + || path.segments.last().unwrap().ident.to_string(), + |lit_str| lit_str.value(), + ); + + let v = Container { + path, + ty: style, + err_name, + rename_rule: options.rename_all.map(|v| v.value.rule), + }; + Ok(v) + } + + fn name(&self) -> String { + let mut value = String::new(); + for segment in &self.path.segments { + if !value.is_empty() { + value.push_str("::"); + } + value.push_str(&segment.ident.to_string()); + } + value + } + + /// Build derivation body for a struct. + fn build(&self, ctx: &Ctx) -> TokenStream { + match &self.ty { + ContainerType::StructNewtype(ident, from_py_with, _) => { + self.build_newtype_struct(Some(ident), from_py_with, ctx) + } + ContainerType::TupleNewtype(from_py_with, _) => { + self.build_newtype_struct(None, from_py_with, ctx) + } + ContainerType::Tuple(tups) => self.build_tuple_struct(tups, ctx), + ContainerType::Struct(tups) => self.build_struct(tups, ctx), + } + } + + fn build_newtype_struct( + &self, + field_ident: Option<&Ident>, + from_py_with: &Option, + ctx: &Ctx, + ) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + let self_ty = &self.path; + let struct_name = self.name(); + if let Some(ident) = field_ident { + let field_name = ident.to_string(); + if let Some(FromPyWithAttribute { + kw, + value: expr_path, + }) = from_py_with + { + let extractor = quote_spanned! { kw.span => + { let from_py_with: fn(_) -> _ = #expr_path; from_py_with } + }; + quote! { + Ok(#self_ty { + #ident: #pyo3_path::impl_::frompyobject::extract_struct_field_with(#extractor, obj, #struct_name, #field_name)? + }) + } + } else { + quote! { + Ok(#self_ty { + #ident: #pyo3_path::impl_::frompyobject::extract_struct_field(obj, #struct_name, #field_name)? + }) + } + } + } else if let Some(FromPyWithAttribute { + kw, + value: expr_path, + }) = from_py_with + { + let extractor = quote_spanned! { kw.span => + { let from_py_with: fn(_) -> _ = #expr_path; from_py_with } + }; + quote! { + #pyo3_path::impl_::frompyobject::extract_tuple_struct_field_with(#extractor, obj, #struct_name, 0).map(#self_ty) + } + } else { + quote! { + #pyo3_path::impl_::frompyobject::extract_tuple_struct_field(obj, #struct_name, 0).map(#self_ty) + } + } + } + + fn build_tuple_struct(&self, struct_fields: &[TupleStructField], ctx: &Ctx) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + let self_ty = &self.path; + let struct_name = &self.name(); + let field_idents: Vec<_> = (0..struct_fields.len()) + .map(|i| format_ident!("arg{}", i)) + .collect(); + let fields = struct_fields.iter().zip(&field_idents).enumerate().map(|(index, (field, ident))| { + if let Some(FromPyWithAttribute { + kw, + value: expr_path, .. + }) = &field.from_py_with { + let extractor = quote_spanned! { kw.span => + { let from_py_with: fn(_) -> _ = #expr_path; from_py_with } + }; + quote! { + #pyo3_path::impl_::frompyobject::extract_tuple_struct_field_with(#extractor, &#ident, #struct_name, #index)? + } + } else { + quote!{ + #pyo3_path::impl_::frompyobject::extract_tuple_struct_field(&#ident, #struct_name, #index)? + }} + }); + + quote!( + match #pyo3_path::types::PyAnyMethods::extract(obj) { + ::std::result::Result::Ok((#(#field_idents),*)) => ::std::result::Result::Ok(#self_ty(#(#fields),*)), + ::std::result::Result::Err(err) => ::std::result::Result::Err(err), + } + ) + } + + fn build_struct(&self, struct_fields: &[NamedStructField<'_>], ctx: &Ctx) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + let self_ty = &self.path; + let struct_name = self.name(); + let mut fields: Punctuated = Punctuated::new(); + for field in struct_fields { + let ident = field.ident; + let field_name = ident.unraw().to_string(); + let getter = match field + .getter + .as_ref() + .unwrap_or(&FieldGetter::GetAttr(parse_quote!(attribute), None)) + { + FieldGetter::GetAttr(_, Some(name)) => { + quote!(#pyo3_path::types::PyAnyMethods::getattr(obj, #pyo3_path::intern!(obj.py(), #name))) + } + FieldGetter::GetAttr(_, None) => { + let name = self + .rename_rule + .map(|rule| utils::apply_renaming_rule(rule, &field_name)); + let name = name.as_deref().unwrap_or(&field_name); + quote!(#pyo3_path::types::PyAnyMethods::getattr(obj, #pyo3_path::intern!(obj.py(), #name))) + } + FieldGetter::GetItem(_, Some(syn::Lit::Str(key))) => { + quote!(#pyo3_path::types::PyAnyMethods::get_item(obj, #pyo3_path::intern!(obj.py(), #key))) + } + FieldGetter::GetItem(_, Some(key)) => { + quote!(#pyo3_path::types::PyAnyMethods::get_item(obj, #key)) + } + FieldGetter::GetItem(_, None) => { + let name = self + .rename_rule + .map(|rule| utils::apply_renaming_rule(rule, &field_name)); + let name = name.as_deref().unwrap_or(&field_name); + quote!(#pyo3_path::types::PyAnyMethods::get_item(obj, #pyo3_path::intern!(obj.py(), #name))) + } + }; + let extractor = if let Some(FromPyWithAttribute { + kw, + value: expr_path, + }) = &field.from_py_with + { + let extractor = quote_spanned! { kw.span => + { let from_py_with: fn(_) -> _ = #expr_path; from_py_with } + }; + quote! (#pyo3_path::impl_::frompyobject::extract_struct_field_with(#extractor, &#getter?, #struct_name, #field_name)?) + } else { + quote!(#pyo3_path::impl_::frompyobject::extract_struct_field(&value, #struct_name, #field_name)?) + }; + let extracted = if let Some(default) = &field.default { + let default_expr = if let Some(default_expr) = &default.value { + default_expr.to_token_stream() + } else { + quote!(::std::default::Default::default()) + }; + quote!(if let ::std::result::Result::Ok(value) = #getter { + #extractor + } else { + #default_expr + }) + } else { + quote!({ + let value = #getter?; + #extractor + }) + }; + + fields.push(quote!(#ident: #extracted)); + } + + quote!(::std::result::Result::Ok(#self_ty{#fields})) + } + + #[cfg(feature = "experimental-inspect")] + fn input_type(&self) -> PyExpr { + match &self.ty { + ContainerType::StructNewtype(_, from_py_with, ty) => { + Self::field_input_type(from_py_with, ty) + } + ContainerType::TupleNewtype(from_py_with, ty) => { + Self::field_input_type(from_py_with, ty) + } + ContainerType::Tuple(tups) => PyExpr::subscript( + PyExpr::builtin("tuple"), + PyExpr::tuple(tups.iter().map(|TupleStructField { from_py_with, ty }| { + Self::field_input_type(from_py_with, ty) + })), + ), + ContainerType::Struct(_) => { + // TODO: implement using a Protocol? + PyExpr::module_attr("_typeshed", "Incomplete") + } + } + } + + #[cfg(feature = "experimental-inspect")] + fn field_input_type(from_py_with: &Option, ty: &syn::Type) -> PyExpr { + if from_py_with.is_some() { + // We don't know what from_py_with is doing + PyExpr::module_attr("_typeshed", "Incomplete") + } else { + PyExpr::from_from_py_object(ty.clone(), None) + } + } +} + +fn verify_and_get_lifetime(generics: &syn::Generics) -> Result> { + let mut lifetimes = generics.lifetimes(); + let lifetime = lifetimes.next(); + ensure_spanned!( + lifetimes.next().is_none(), + generics.span() => "FromPyObject can be derived with at most one lifetime parameter" + ); + Ok(lifetime) +} + +/// Derive FromPyObject for enums and structs. +/// +/// * Max 1 lifetime specifier, will be tied to `FromPyObject`'s specifier +/// * At least one field, in case of `#[transparent]`, exactly one field +/// * At least one variant for enums. +/// * Fields of input structs and enums must implement `FromPyObject` or be annotated with `from_py_with` +/// * Derivation for structs with generic fields like `struct Foo(T)` +/// adds `T: FromPyObject` on the derived implementation. +pub fn build_derive_from_pyobject(tokens: &DeriveInput) -> Result { + let options = ContainerAttributes::from_attrs(&tokens.attrs)?; + let ctx = &Ctx::new(&options.krate, None); + let Ctx { pyo3_path, .. } = &ctx; + + let (_, ty_generics, _) = tokens.generics.split_for_impl(); + let mut trait_generics = tokens.generics.clone(); + let lt_param = if let Some(lt) = verify_and_get_lifetime(&trait_generics)? { + lt.clone() + } else { + trait_generics.params.push(parse_quote!('py)); + parse_quote!('py) + }; + let (impl_generics, _, where_clause) = trait_generics.split_for_impl(); + + let mut where_clause = where_clause.cloned().unwrap_or_else(|| parse_quote!(where)); + for param in trait_generics.type_params() { + let gen_ident = ¶m.ident; + where_clause + .predicates + .push(parse_quote!(#gen_ident: #pyo3_path::conversion::FromPyObjectOwned<#lt_param>)) + } + + let derives = match &tokens.data { + syn::Data::Enum(en) => { + if options.transparent.is_some() || options.annotation.is_some() { + bail_spanned!(tokens.span() => "`transparent` or `annotation` is not supported \ + at top level for enums"); + } + let en = Enum::new(en, &tokens.ident, options.clone())?; + en.build(ctx) + } + syn::Data::Struct(st) => { + if let Some(lit_str) = &options.annotation { + bail_spanned!(lit_str.span() => "`annotation` is unsupported for structs"); + } + let ident = &tokens.ident; + let st = Container::new(&st.fields, parse_quote!(#ident), options.clone())?; + st.build(ctx) + } + syn::Data::Union(_) => bail_spanned!( + tokens.span() => "#[derive(FromPyObject)] is not supported for unions" + ), + }; + + #[cfg(feature = "experimental-inspect")] + let input_type = { + let pyo3_crate_path = &ctx.pyo3_path; + let input_type = if tokens + .generics + .params + .iter() + .all(|p| matches!(p, syn::GenericParam::Lifetime(_))) + { + match &tokens.data { + syn::Data::Enum(en) => Enum::new(en, &tokens.ident, options)?.input_type(), + syn::Data::Struct(st) => { + let ident = &tokens.ident; + Container::new(&st.fields, parse_quote!(#ident), options.clone())?.input_type() + } + syn::Data::Union(_) => { + // Not supported at this point + PyExpr::module_attr("_typeshed", "Incomplete") + } + } + } else { + // We don't know how to deal with generic parameters + // Blocked by https://github.com/rust-lang/rust/issues/76560 + PyExpr::module_attr("_typeshed", "Incomplete") + } + .to_introspection_token_stream(pyo3_crate_path); + quote! { const INPUT_TYPE: #pyo3_crate_path::inspect::PyStaticExpr = #input_type; } + }; + #[cfg(not(feature = "experimental-inspect"))] + let input_type = quote! {}; + + let ident = &tokens.ident; + Ok(quote!( + #[automatically_derived] + impl #impl_generics #pyo3_path::FromPyObject<'_, #lt_param> for #ident #ty_generics #where_clause { + type Error = #pyo3_path::PyErr; + fn extract(obj: #pyo3_path::Borrowed<'_, #lt_param, #pyo3_path::PyAny>) -> ::std::result::Result { + let obj: &#pyo3_path::Bound<'_, _> = &*obj; + #derives + } + #input_type + } + )) +} diff --git a/vendor/pyo3-macros-backend/src/intopyobject.rs b/vendor/pyo3-macros-backend/src/intopyobject.rs new file mode 100644 index 0000000..a4e557e --- /dev/null +++ b/vendor/pyo3-macros-backend/src/intopyobject.rs @@ -0,0 +1,622 @@ +use crate::attributes::{IntoPyWithAttribute, RenamingRule}; +use crate::derive_attributes::{ContainerAttributes, FieldAttributes}; +#[cfg(feature = "experimental-inspect")] +use crate::py_expr::PyExpr; +use crate::utils::{self, Ctx}; +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote, quote_spanned, ToTokens}; +use syn::ext::IdentExt; +use syn::spanned::Spanned as _; +use syn::{parse_quote, DataEnum, DeriveInput, Fields, Ident, Index, Result}; + +struct ItemOption(Option); + +enum IntoPyObjectTypes { + Transparent(syn::Type), + Opaque { + target: TokenStream, + output: TokenStream, + error: TokenStream, + }, +} + +struct IntoPyObjectImpl { + types: IntoPyObjectTypes, + body: TokenStream, +} + +struct NamedStructField<'a> { + ident: &'a syn::Ident, + field: &'a syn::Field, + item: Option, + into_py_with: Option, +} + +struct TupleStructField<'a> { + field: &'a syn::Field, + into_py_with: Option, +} + +/// Container Style +/// +/// Covers Structs, Tuplestructs and corresponding Newtypes. +enum ContainerType<'a> { + /// Struct Container, e.g. `struct Foo { a: String }` + /// + /// Variant contains the list of field identifiers and the corresponding extraction call. + Struct(Vec>), + /// Newtype struct container, e.g. `#[transparent] struct Foo { a: String }` + /// + /// The field specified by the identifier is extracted directly from the object. + StructNewtype(&'a syn::Field), + /// Tuple struct, e.g. `struct Foo(String)`. + /// + /// Variant contains a list of conversion methods for each of the fields that are directly + /// extracted from the tuple. + Tuple(Vec>), + /// Tuple newtype, e.g. `#[transparent] struct Foo(String)` + /// + /// The wrapped field is directly extracted from the object. + TupleNewtype(&'a syn::Field), +} + +/// Data container +/// +/// Either describes a struct or an enum variant. +struct Container<'a, const REF: bool> { + path: syn::Path, + receiver: Option, + ty: ContainerType<'a>, + rename_rule: Option, +} + +/// Construct a container based on fields, identifier and attributes. +impl<'a, const REF: bool> Container<'a, REF> { + /// + /// Fails if the variant has no fields or incompatible attributes. + fn new( + receiver: Option, + fields: &'a Fields, + path: syn::Path, + options: ContainerAttributes, + ) -> Result { + let style = match fields { + Fields::Unnamed(unnamed) if !unnamed.unnamed.is_empty() => { + ensure_spanned!( + options.rename_all.is_none(), + options.rename_all.span() => "`rename_all` is useless on tuple structs and variants." + ); + let mut tuple_fields = unnamed + .unnamed + .iter() + .map(|field| { + let attrs = FieldAttributes::from_attrs(&field.attrs)?; + ensure_spanned!( + attrs.getter.is_none(), + attrs.getter.unwrap().span() => "`item` and `attribute` are not permitted on tuple struct elements." + ); + Ok(TupleStructField { + field, + into_py_with: attrs.into_py_with, + }) + }) + .collect::>>()?; + if tuple_fields.len() == 1 { + // Always treat a 1-length tuple struct as "transparent", even without the + // explicit annotation. + let TupleStructField { + field, + into_py_with, + } = tuple_fields.pop().unwrap(); + ensure_spanned!( + into_py_with.is_none(), + into_py_with.span() => "`into_py_with` is not permitted on `transparent` structs" + ); + ContainerType::TupleNewtype(field) + } else if options.transparent.is_some() { + bail_spanned!( + fields.span() => "transparent structs and variants can only have 1 field" + ); + } else { + ContainerType::Tuple(tuple_fields) + } + } + Fields::Named(named) if !named.named.is_empty() => { + if options.transparent.is_some() { + ensure_spanned!( + named.named.iter().count() == 1, + fields.span() => "transparent structs and variants can only have 1 field" + ); + + let field = named.named.iter().next().unwrap(); + let attrs = FieldAttributes::from_attrs(&field.attrs)?; + ensure_spanned!( + attrs.getter.is_none(), + attrs.getter.unwrap().span() => "`transparent` structs may not have `item` nor `attribute` for the inner field" + ); + ensure_spanned!( + options.rename_all.is_none(), + options.rename_all.span() => "`rename_all` is not permitted on `transparent` structs and variants" + ); + ensure_spanned!( + attrs.into_py_with.is_none(), + attrs.into_py_with.span() => "`into_py_with` is not permitted on `transparent` structs or variants" + ); + ContainerType::StructNewtype(field) + } else { + let struct_fields = named + .named + .iter() + .map(|field| { + let ident = field + .ident + .as_ref() + .expect("Named fields should have identifiers"); + + let attrs = FieldAttributes::from_attrs(&field.attrs)?; + + Ok(NamedStructField { + ident, + field, + item: attrs.getter.and_then(|getter| match getter { + crate::derive_attributes::FieldGetter::GetItem(_, lit) => { + Some(ItemOption(lit)) + } + crate::derive_attributes::FieldGetter::GetAttr(_, _) => None, + }), + into_py_with: attrs.into_py_with, + }) + }) + .collect::>>()?; + ContainerType::Struct(struct_fields) + } + } + _ => bail_spanned!( + fields.span() => "cannot derive `IntoPyObject` for empty structs" + ), + }; + + let v = Container { + path, + receiver, + ty: style, + rename_rule: options.rename_all.map(|v| v.value.rule), + }; + Ok(v) + } + + fn match_pattern(&self) -> TokenStream { + let path = &self.path; + let pattern = match &self.ty { + ContainerType::Struct(fields) => fields + .iter() + .enumerate() + .map(|(i, f)| { + let ident = f.ident; + let new_ident = format_ident!("arg{i}"); + quote! {#ident: #new_ident,} + }) + .collect::(), + ContainerType::StructNewtype(field) => { + let ident = field.ident.as_ref().unwrap(); + quote!(#ident: arg0) + } + ContainerType::Tuple(fields) => { + let i = (0..fields.len()).map(Index::from); + let idents = (0..fields.len()).map(|i| format_ident!("arg{i}")); + quote! { #(#i: #idents,)* } + } + ContainerType::TupleNewtype(_) => quote!(0: arg0), + }; + + quote! { #path{ #pattern } } + } + + /// Build derivation body for a struct. + fn build(&self, ctx: &Ctx) -> IntoPyObjectImpl { + match &self.ty { + ContainerType::StructNewtype(field) | ContainerType::TupleNewtype(field) => { + self.build_newtype_struct(field, ctx) + } + ContainerType::Tuple(fields) => self.build_tuple_struct(fields, ctx), + ContainerType::Struct(fields) => self.build_struct(fields, ctx), + } + } + + fn build_newtype_struct(&self, field: &syn::Field, ctx: &Ctx) -> IntoPyObjectImpl { + let Ctx { pyo3_path, .. } = ctx; + let ty = &field.ty; + + let unpack = self + .receiver + .as_ref() + .map(|i| { + let pattern = self.match_pattern(); + quote! { let #pattern = #i;} + }) + .unwrap_or_default(); + + IntoPyObjectImpl { + types: IntoPyObjectTypes::Transparent(ty.clone()), + body: quote_spanned! { ty.span() => + #unpack + #pyo3_path::conversion::IntoPyObject::into_pyobject(arg0, py) + }, + } + } + + fn build_struct(&self, fields: &[NamedStructField<'_>], ctx: &Ctx) -> IntoPyObjectImpl { + let Ctx { pyo3_path, .. } = ctx; + + let unpack = self + .receiver + .as_ref() + .map(|i| { + let pattern = self.match_pattern(); + quote! { let #pattern = #i;} + }) + .unwrap_or_default(); + + let setter = fields + .iter() + .enumerate() + .map(|(i, f)| { + let key = f + .item + .as_ref() + .and_then(|item| item.0.as_ref()) + .map(|item| item.into_token_stream()) + .unwrap_or_else(|| { + let name = f.ident.unraw().to_string(); + self.rename_rule.map(|rule| utils::apply_renaming_rule(rule, &name)).unwrap_or(name).into_token_stream() + }); + let value = Ident::new(&format!("arg{i}"), f.field.ty.span()); + + if let Some(expr_path) = f.into_py_with.as_ref().map(|i|&i.value) { + let cow = if REF { + quote!(::std::borrow::Cow::Borrowed(#value)) + } else { + quote!(::std::borrow::Cow::Owned(#value)) + }; + quote! { + let into_py_with: fn(::std::borrow::Cow<'_, _>, #pyo3_path::Python<'py>) -> #pyo3_path::PyResult<#pyo3_path::Bound<'py, #pyo3_path::PyAny>> = #expr_path; + #pyo3_path::types::PyDictMethods::set_item(&dict, #key, into_py_with(#cow, py)?)?; + } + } else { + quote! { + #pyo3_path::types::PyDictMethods::set_item(&dict, #key, #value)?; + } + } + }) + .collect::(); + + IntoPyObjectImpl { + types: IntoPyObjectTypes::Opaque { + target: quote!(#pyo3_path::types::PyDict), + output: quote!(#pyo3_path::Bound<'py, Self::Target>), + error: quote!(#pyo3_path::PyErr), + }, + body: quote! { + #unpack + let dict = #pyo3_path::types::PyDict::new(py); + #setter + ::std::result::Result::Ok::<_, Self::Error>(dict) + }, + } + } + + fn build_tuple_struct(&self, fields: &[TupleStructField<'_>], ctx: &Ctx) -> IntoPyObjectImpl { + let Ctx { pyo3_path, .. } = ctx; + + let unpack = self + .receiver + .as_ref() + .map(|i| { + let pattern = self.match_pattern(); + quote! { let #pattern = #i;} + }) + .unwrap_or_default(); + + let setter = fields + .iter() + .enumerate() + .map(|(i, f)| { + let ty = &f.field.ty; + let value = Ident::new(&format!("arg{i}"), f.field.ty.span()); + + if let Some(expr_path) = f.into_py_with.as_ref().map(|i|&i.value) { + let cow = if REF { + quote!(::std::borrow::Cow::Borrowed(#value)) + } else { + quote!(::std::borrow::Cow::Owned(#value)) + }; + quote_spanned! { ty.span() => + { + let into_py_with: fn(::std::borrow::Cow<'_, _>, #pyo3_path::Python<'py>) -> #pyo3_path::PyResult<#pyo3_path::Bound<'py, #pyo3_path::PyAny>> = #expr_path; + into_py_with(#cow, py)? + }, + } + } else { + quote_spanned! { ty.span() => + #pyo3_path::conversion::IntoPyObject::into_pyobject(#value, py) + .map(#pyo3_path::BoundObject::into_any) + .map(#pyo3_path::BoundObject::into_bound)?, + } + } + }) + .collect::(); + + IntoPyObjectImpl { + types: IntoPyObjectTypes::Opaque { + target: quote!(#pyo3_path::types::PyTuple), + output: quote!(#pyo3_path::Bound<'py, Self::Target>), + error: quote!(#pyo3_path::PyErr), + }, + body: quote! { + #unpack + #pyo3_path::types::PyTuple::new(py, [#setter]) + }, + } + } + + #[cfg(feature = "experimental-inspect")] + fn output_type(&self) -> PyExpr { + match &self.ty { + ContainerType::StructNewtype(field) | ContainerType::TupleNewtype(field) => { + Self::field_output_type(&None, &field.ty) + } + ContainerType::Tuple(tups) => PyExpr::subscript( + PyExpr::builtin("tuple"), + PyExpr::tuple(tups.iter().map( + |TupleStructField { + into_py_with, + field, + }| { Self::field_output_type(into_py_with, &field.ty) }, + )), + ), + ContainerType::Struct(_) => { + // TODO: implement using a Protocol? + PyExpr::module_attr("_typeshed", "Incomplete") + } + } + } + + #[cfg(feature = "experimental-inspect")] + fn field_output_type(into_py_with: &Option, ty: &syn::Type) -> PyExpr { + if into_py_with.is_some() { + // We don't know what into_py_with is doing + PyExpr::module_attr("_typeshed", "Incomplete") + } else { + PyExpr::from_into_py_object(ty.clone(), None) + } + } +} + +/// Describes derivation input of an enum. +struct Enum<'a, const REF: bool> { + variants: Vec>, +} + +impl<'a, const REF: bool> Enum<'a, REF> { + /// Construct a new enum representation. + /// + /// `data_enum` is the `syn` representation of the input enum, `ident` is the + /// `Identifier` of the enum. + fn new(data_enum: &'a DataEnum, ident: &'a Ident) -> Result { + ensure_spanned!( + !data_enum.variants.is_empty(), + ident.span() => "cannot derive `IntoPyObject` for empty enum" + ); + let variants = data_enum + .variants + .iter() + .map(|variant| { + let attrs = ContainerAttributes::from_attrs(&variant.attrs)?; + let var_ident = &variant.ident; + + ensure_spanned!( + !variant.fields.is_empty(), + variant.ident.span() => "cannot derive `IntoPyObject` for empty variants" + ); + + Container::new( + None, + &variant.fields, + parse_quote!(#ident::#var_ident), + attrs, + ) + }) + .collect::>>()?; + + Ok(Enum { variants }) + } + + /// Build derivation body for enums. + fn build(&self, ctx: &Ctx) -> IntoPyObjectImpl { + let Ctx { pyo3_path, .. } = ctx; + + let variants = self + .variants + .iter() + .map(|v| { + let IntoPyObjectImpl { body, .. } = v.build(ctx); + let pattern = v.match_pattern(); + quote! { + #pattern => { + {#body} + .map(#pyo3_path::BoundObject::into_any) + .map(#pyo3_path::BoundObject::into_bound) + .map_err(::std::convert::Into::<#pyo3_path::PyErr>::into) + } + } + }) + .collect::(); + + IntoPyObjectImpl { + types: IntoPyObjectTypes::Opaque { + target: quote!(#pyo3_path::types::PyAny), + output: quote!(#pyo3_path::Bound<'py, >::Target>), + error: quote!(#pyo3_path::PyErr), + }, + body: quote! { + match self { + #variants + } + }, + } + } + + #[cfg(feature = "experimental-inspect")] + fn output_type(&self) -> PyExpr { + self.variants + .iter() + .map(|var| var.output_type()) + .reduce(PyExpr::union) + .expect("Empty enum") + } +} + +// if there is a `'py` lifetime, we treat it as the `Python<'py>` lifetime +fn verify_and_get_lifetime(generics: &syn::Generics) -> Option<&syn::LifetimeParam> { + let mut lifetimes = generics.lifetimes(); + lifetimes.find(|l| l.lifetime.ident == "py") +} + +pub fn build_derive_into_pyobject(tokens: &DeriveInput) -> Result { + let options = ContainerAttributes::from_attrs(&tokens.attrs)?; + let ctx = &Ctx::new(&options.krate, None); + let Ctx { pyo3_path, .. } = &ctx; + + let (_, ty_generics, _) = tokens.generics.split_for_impl(); + let mut trait_generics = tokens.generics.clone(); + if REF { + trait_generics.params.push(parse_quote!('_a)); + } + let lt_param = if let Some(lt) = verify_and_get_lifetime(&trait_generics) { + lt.clone() + } else { + trait_generics.params.push(parse_quote!('py)); + parse_quote!('py) + }; + let (impl_generics, _, where_clause) = trait_generics.split_for_impl(); + + let mut where_clause = where_clause.cloned().unwrap_or_else(|| parse_quote!(where)); + for param in trait_generics.type_params() { + let gen_ident = ¶m.ident; + where_clause.predicates.push(if REF { + parse_quote!(&'_a #gen_ident: #pyo3_path::conversion::IntoPyObject<'py>) + } else { + parse_quote!(#gen_ident: #pyo3_path::conversion::IntoPyObject<'py>) + }) + } + + let IntoPyObjectImpl { types, body } = match &tokens.data { + syn::Data::Enum(en) => { + if options.transparent.is_some() { + bail_spanned!(tokens.span() => "`transparent` is not supported at top level for enums"); + } + if let Some(rename_all) = options.rename_all { + bail_spanned!(rename_all.span() => "`rename_all` is not supported at top level for enums"); + } + let en = Enum::::new(en, &tokens.ident)?; + en.build(ctx) + } + syn::Data::Struct(st) => { + let ident = &tokens.ident; + let st = Container::::new( + Some(Ident::new("self", Span::call_site())), + &st.fields, + parse_quote!(#ident), + options.clone(), + )?; + st.build(ctx) + } + syn::Data::Union(_) => bail_spanned!( + tokens.span() => "#[derive(`IntoPyObject`)] is not supported for unions" + ), + }; + + let (target, output, error) = match types { + IntoPyObjectTypes::Transparent(ty) => { + if REF { + ( + quote! { <&'_a #ty as #pyo3_path::IntoPyObject<'py>>::Target }, + quote! { <&'_a #ty as #pyo3_path::IntoPyObject<'py>>::Output }, + quote! { <&'_a #ty as #pyo3_path::IntoPyObject<'py>>::Error }, + ) + } else { + ( + quote! { <#ty as #pyo3_path::IntoPyObject<'py>>::Target }, + quote! { <#ty as #pyo3_path::IntoPyObject<'py>>::Output }, + quote! { <#ty as #pyo3_path::IntoPyObject<'py>>::Error }, + ) + } + } + IntoPyObjectTypes::Opaque { + target, + output, + error, + } => (target, output, error), + }; + + let ident = &tokens.ident; + let ident = if REF { + quote! { &'_a #ident} + } else { + quote! { #ident } + }; + + #[cfg(feature = "experimental-inspect")] + let output_type = { + let pyo3_crate_path = &ctx.pyo3_path; + let output_type = if tokens + .generics + .params + .iter() + .all(|p| matches!(p, syn::GenericParam::Lifetime(_))) + { + match &tokens.data { + syn::Data::Enum(en) => Enum::::new(en, &tokens.ident)?.output_type(), + syn::Data::Struct(st) => { + let ident = &tokens.ident; + Container::::new( + Some(Ident::new("self", Span::call_site())), + &st.fields, + parse_quote!(#ident), + options, + )? + .output_type() + } + syn::Data::Union(_) => { + // Not supported at this point + PyExpr::module_attr("_typeshed", "Incomplete") + } + } + } else { + // We don't know how to deal with generic parameters + // Blocked by https://github.com/rust-lang/rust/issues/76560 + PyExpr::module_attr("_typeshed", "Incomplete") + } + .to_introspection_token_stream(pyo3_crate_path); + quote! { const OUTPUT_TYPE: #pyo3_path::inspect::PyStaticExpr = #output_type; } + }; + #[cfg(not(feature = "experimental-inspect"))] + let output_type = quote! {}; + + Ok(quote!( + #[automatically_derived] + impl #impl_generics #pyo3_path::conversion::IntoPyObject<#lt_param> for #ident #ty_generics #where_clause { + type Target = #target; + type Output = #output; + type Error = #error; + #output_type + + fn into_pyobject(self, py: #pyo3_path::Python<#lt_param>) -> ::std::result::Result< + >::Output, + >::Error, + > { + #body + } + } + )) +} diff --git a/vendor/pyo3-macros-backend/src/introspection.rs b/vendor/pyo3-macros-backend/src/introspection.rs new file mode 100644 index 0000000..05422d9 --- /dev/null +++ b/vendor/pyo3-macros-backend/src/introspection.rs @@ -0,0 +1,641 @@ +//! Generates introspection data i.e. JSON strings in the .pyo3i0 section. +//! +//! There is a JSON per PyO3 proc macro (pyclass, pymodule, pyfunction...). +//! +//! These JSON blobs can refer to each others via the _PYO3_INTROSPECTION_ID constants +//! providing unique ids for each element. +//! +//! The JSON blobs format must be synchronized with the `pyo3_introspection::introspection.rs::Chunk` +//! type that is used to parse them. + +use crate::method::{FnArg, RegularArg}; +use crate::py_expr::PyExpr; +use crate::pyfunction::FunctionSignature; +use crate::utils::{PyO3CratePath, PythonDoc, StrOrExpr}; +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote, ToTokens}; +use std::borrow::Cow; +use std::collections::hash_map::DefaultHasher; +use std::collections::BTreeMap; +use std::fmt::Write; +use std::hash::{Hash, Hasher}; +use std::mem::take; +use std::sync::atomic::{AtomicUsize, Ordering}; +use syn::{Attribute, Ident, Type, TypePath}; + +static GLOBAL_COUNTER_FOR_UNIQUE_NAMES: AtomicUsize = AtomicUsize::new(0); + +pub fn module_introspection_code<'a>( + pyo3_crate_path: &PyO3CratePath, + name: &str, + members: impl IntoIterator, + members_cfg_attrs: impl IntoIterator>, + doc: Option<&PythonDoc>, + incomplete: bool, +) -> TokenStream { + let mut desc = BTreeMap::from([ + ("type", IntrospectionNode::String("module".into())), + ("id", IntrospectionNode::IntrospectionId(None)), + ("name", IntrospectionNode::String(name.into())), + ( + "members", + IntrospectionNode::List( + members + .into_iter() + .zip(members_cfg_attrs) + .map(|(member, attributes)| AttributedIntrospectionNode { + node: IntrospectionNode::IntrospectionId(Some(ident_to_type(member))), + attributes, + }) + .collect(), + ), + ), + ("incomplete", IntrospectionNode::Bool(incomplete)), + ]); + if let Some(doc) = doc { + desc.insert("doc", IntrospectionNode::Doc(doc)); + } + IntrospectionNode::Map(desc).emit(pyo3_crate_path) +} + +pub fn class_introspection_code( + pyo3_crate_path: &PyO3CratePath, + ident: &Ident, + name: &str, + extends: Option, + is_final: bool, + parent: Option<&Type>, + doc: Option<&PythonDoc>, +) -> TokenStream { + let mut desc = BTreeMap::from([ + ("type", IntrospectionNode::String("class".into())), + ( + "id", + IntrospectionNode::IntrospectionId(Some(ident_to_type(ident))), + ), + ("name", IntrospectionNode::String(name.into())), + ]); + if let Some(extends) = extends { + desc.insert("bases", IntrospectionNode::List(vec![extends.into()])); + } + if is_final { + desc.insert( + "decorators", + IntrospectionNode::List(vec![PyExpr::module_attr("typing", "final").into()]), + ); + } + if let Some(parent) = parent { + desc.insert( + "parent", + IntrospectionNode::IntrospectionId(Some(Cow::Borrowed(parent))), + ); + } + if let Some(doc) = &doc { + desc.insert("doc", IntrospectionNode::Doc(doc)); + } + IntrospectionNode::Map(desc).emit(pyo3_crate_path) +} + +#[expect(clippy::too_many_arguments)] +pub fn function_introspection_code( + pyo3_crate_path: &PyO3CratePath, + ident: Option<&Ident>, + name: &str, + signature: &FunctionSignature<'_>, + first_argument: Option<&'static str>, + returns: PyExpr, + decorators: impl IntoIterator, + is_async: bool, + is_returning_not_implemented_on_extraction_error: bool, + doc: Option<&PythonDoc>, + parent: Option<&Type>, +) -> TokenStream { + let mut desc = BTreeMap::from([ + ("type", IntrospectionNode::String("function".into())), + ("name", IntrospectionNode::String(name.into())), + ( + "arguments", + arguments_introspection_data( + signature, + first_argument, + is_returning_not_implemented_on_extraction_error, + parent, + ), + ), + ( + "returns", + if let Some((_, returns)) = signature + .attribute + .as_ref() + .and_then(|attribute| attribute.value.returns.as_ref()) + { + returns.as_type_hint().into() + } else { + returns.into() + }, + ), + ]); + if is_async { + desc.insert("async", IntrospectionNode::Bool(true)); + } + if let Some(ident) = ident { + desc.insert( + "id", + IntrospectionNode::IntrospectionId(Some(ident_to_type(ident))), + ); + } + let decorators = decorators.into_iter().map(|d| d.into()).collect::>(); + if !decorators.is_empty() { + desc.insert("decorators", IntrospectionNode::List(decorators)); + } + if let Some(doc) = doc { + desc.insert("doc", IntrospectionNode::Doc(doc)); + } + if let Some(parent) = parent { + desc.insert( + "parent", + IntrospectionNode::IntrospectionId(Some(Cow::Borrowed(parent))), + ); + } + IntrospectionNode::Map(desc).emit(pyo3_crate_path) +} + +pub fn attribute_introspection_code( + pyo3_crate_path: &PyO3CratePath, + parent: Option<&Type>, + name: String, + value: PyExpr, + rust_type: Type, + doc: Option<&PythonDoc>, + is_final: bool, +) -> TokenStream { + let mut desc = BTreeMap::from([ + ("type", IntrospectionNode::String("attribute".into())), + ("name", IntrospectionNode::String(name.into())), + ( + "parent", + IntrospectionNode::IntrospectionId(parent.map(Cow::Borrowed)), + ), + ]); + if value == PyExpr::ellipsis() { + // We need to set a type, but not need to set the value to ..., all attributes have a value + desc.insert( + "annotation", + if is_final { + PyExpr::subscript( + PyExpr::module_attr("typing", "Final"), + PyExpr::from_return_type(rust_type, parent), + ) + .into() + } else { + PyExpr::from_return_type(rust_type, parent).into() + }, + ); + } else { + desc.insert( + "annotation", + if is_final { + // Type checkers can infer the type from the value because it's typing.Literal[value] + // So, following stubs best practices, we only write typing.Final and not + // typing.Final[typing.literal[value]] + PyExpr::module_attr("typing", "Final") + } else { + PyExpr::from_return_type(rust_type, parent) + } + .into(), + ); + desc.insert("value", value.into()); + } + if let Some(doc) = doc { + desc.insert("doc", IntrospectionNode::Doc(doc)); + } + IntrospectionNode::Map(desc).emit(pyo3_crate_path) +} + +fn arguments_introspection_data<'a>( + signature: &'a FunctionSignature<'a>, + first_argument: Option<&'a str>, + is_returning_not_implemented_on_extraction_error: bool, + class_type: Option<&Type>, +) -> IntrospectionNode<'a> { + let mut argument_desc = signature.arguments.iter().filter(|arg| { + matches!( + arg, + FnArg::Regular(_) | FnArg::VarArgs(_) | FnArg::KwArgs(_) + ) + }); + + let mut posonlyargs = Vec::new(); + let mut args = Vec::new(); + let mut vararg = None; + let mut kwonlyargs = Vec::new(); + let mut kwarg = None; + + if let Some(first_argument) = first_argument { + posonlyargs.push( + IntrospectionNode::Map( + [("name", IntrospectionNode::String(first_argument.into()))].into(), + ) + .into(), + ); + } + + for (i, param) in signature + .python_signature + .positional_parameters + .iter() + .enumerate() + { + let arg_desc = if let Some(FnArg::Regular(arg_desc)) = argument_desc.next() { + arg_desc + } else { + panic!("Less arguments than in python signature"); + }; + let arg = argument_introspection_data( + param, + arg_desc, + is_returning_not_implemented_on_extraction_error, + class_type, + ); + if i < signature.python_signature.positional_only_parameters { + posonlyargs.push(arg); + } else { + args.push(arg) + } + } + + if let Some(param) = &signature.python_signature.varargs { + let Some(FnArg::VarArgs(arg_desc)) = argument_desc.next() else { + panic!("Fewer arguments than in python signature"); + }; + let mut params = BTreeMap::from([("name", IntrospectionNode::String(param.into()))]); + if let Some(annotation) = &arg_desc.annotation { + params.insert("annotation", annotation.clone().into()); + } + vararg = Some(IntrospectionNode::Map(params)); + } + + for (param, _) in &signature.python_signature.keyword_only_parameters { + let Some(FnArg::Regular(arg_desc)) = argument_desc.next() else { + panic!("Less arguments than in python signature"); + }; + kwonlyargs.push(argument_introspection_data( + param, + arg_desc, + is_returning_not_implemented_on_extraction_error, + class_type, + )); + } + + if let Some(param) = &signature.python_signature.kwargs { + let Some(FnArg::KwArgs(arg_desc)) = argument_desc.next() else { + panic!("Less arguments than in python signature"); + }; + let mut params = BTreeMap::from([("name", IntrospectionNode::String(param.into()))]); + if let Some(annotation) = &arg_desc.annotation { + params.insert("annotation", annotation.clone().into()); + } + kwarg = Some(IntrospectionNode::Map(params)); + } + + let mut map = BTreeMap::new(); + if !posonlyargs.is_empty() { + map.insert("posonlyargs", IntrospectionNode::List(posonlyargs)); + } + if !args.is_empty() { + map.insert("args", IntrospectionNode::List(args)); + } + if let Some(vararg) = vararg { + map.insert("vararg", vararg); + } + if !kwonlyargs.is_empty() { + map.insert("kwonlyargs", IntrospectionNode::List(kwonlyargs)); + } + if let Some(kwarg) = kwarg { + map.insert("kwarg", kwarg); + } + IntrospectionNode::Map(map) +} + +fn argument_introspection_data<'a>( + name: &'a str, + desc: &'a RegularArg<'_>, + is_returning_not_implemented_on_extraction_error: bool, + class_type: Option<&Type>, +) -> AttributedIntrospectionNode<'a> { + let mut params: BTreeMap<_, _> = [("name", IntrospectionNode::String(name.into()))].into(); + if let Some(expr) = &desc.default_value { + params.insert("default", PyExpr::constant_from_expression(expr).into()); + } + + if is_returning_not_implemented_on_extraction_error { + // all inputs are allowed, we use `object` + params.insert("annotation", PyExpr::builtin("object").into()); + } else if let Some(annotation) = &desc.annotation { + params.insert("annotation", annotation.clone().into()); + } else if desc.from_py_with.is_none() { + // If from_py_with is set we don't know anything on the input type + params.insert( + "annotation", + PyExpr::from_argument_type(desc.ty.clone(), class_type).into(), + ); + } + IntrospectionNode::Map(params).into() +} + +enum IntrospectionNode<'a> { + String(Cow<'a, str>), + Bool(bool), + IntrospectionId(Option>), + TypeHint(Cow<'a, PyExpr>), + Doc(&'a PythonDoc), + Map(BTreeMap<&'static str, IntrospectionNode<'a>>), + List(Vec>), +} + +impl IntrospectionNode<'_> { + fn emit(self, pyo3_crate_path: &PyO3CratePath) -> TokenStream { + let mut content = ConcatenationBuilder::default(); + self.add_to_serialization(&mut content, pyo3_crate_path); + content.into_static( + pyo3_crate_path, + format_ident!("PYO3_INTROSPECTION_1_{}", unique_element_id()), + ) + } + + fn add_to_serialization( + self, + content: &mut ConcatenationBuilder, + pyo3_crate_path: &PyO3CratePath, + ) { + match self { + Self::String(string) => { + content.push_str_to_escape(&string); + } + Self::Bool(value) => content.push_str(if value { "true" } else { "false" }), + Self::IntrospectionId(ident) => { + content.push_str("\""); + content.push_tokens(if let Some(ident) = ident { + quote! { #ident::_PYO3_INTROSPECTION_ID.as_bytes() } + } else { + quote! { _PYO3_INTROSPECTION_ID.as_bytes() } + }); + content.push_str("\""); + } + Self::TypeHint(hint) => { + content.push_tokens(serialize_type_hint( + hint.to_introspection_token_stream(pyo3_crate_path), + pyo3_crate_path, + )); + } + Self::Doc(doc) => { + content.push_str("\""); + for part in &doc.parts { + match part { + StrOrExpr::Str {value, ..} => content.push_str(&escape_json_string(value)), + StrOrExpr::Expr(value) => content.push_tokens(quote! {{ + const DOC: &str = #value; + const DOC_LEN: usize = #pyo3_crate_path::impl_::introspection::escaped_json_string_len(&DOC); + const DOC_SER: [u8; DOC_LEN] = { + let mut result: [u8; DOC_LEN] = [0; DOC_LEN]; + #pyo3_crate_path::impl_::introspection::escape_json_string(&DOC, &mut result); + result + }; + &DOC_SER + }}), + } + } + content.push_str("\""); + } + Self::Map(map) => { + content.push_str("{"); + for (i, (key, value)) in map.into_iter().enumerate() { + if i > 0 { + content.push_str(","); + } + content.push_str_to_escape(key); + content.push_str(":"); + value.add_to_serialization(content, pyo3_crate_path); + } + content.push_str("}"); + } + Self::List(list) => { + content.push_str("["); + if list.iter().all(|element| element.attributes.is_empty()) { + for (i, element) in list.into_iter().enumerate() { + if i > 0 { + content.push_str(","); + } + element.node.add_to_serialization(content, pyo3_crate_path); + } + } else { + // A `,` must only be written if at least one of the elements before the one + // it precedes is compiled in, so we gate it behind an `any(..)` of their + // `cfg`s on top of the element's own. This needs no special case: `any()` is + // false, so the first element gets no separator, and `all()` is true, so an + // element without `cfg` makes every later separator unconditional. + let mut preceding = Vec::new(); + for AttributedIntrospectionNode { node, attributes } in list { + content.push_tokens( + quote! { #[cfg(any(#(#preceding),*))] #(#attributes)* ",".as_bytes() }, + ); + let cfgs = attributes + .iter() + .filter_map(|attribute| attribute.meta.require_list().ok()) + .map(|cfg| &cfg.tokens); + preceding.push(quote! { all(#(#cfgs),*) }); + // We serialize the element to easily gate it behind the attributes + let mut nested_builder = ConcatenationBuilder::default(); + node.add_to_serialization(&mut nested_builder, pyo3_crate_path); + let nested_content = nested_builder.into_token_stream(pyo3_crate_path); + content.push_tokens(quote! { #(#attributes)* #nested_content }); + } + } + content.push_str("]"); + } + } + } +} + +impl From for IntrospectionNode<'static> { + fn from(element: PyExpr) -> Self { + Self::TypeHint(Cow::Owned(element)) + } +} + +fn serialize_type_hint(hint: TokenStream, pyo3_crate_path: &PyO3CratePath) -> TokenStream { + quote! {{ + const TYPE_HINT: #pyo3_crate_path::inspect::PyStaticExpr = #hint; + const TYPE_HINT_LEN: usize = #pyo3_crate_path::inspect::serialized_len_for_introspection(&TYPE_HINT); + const TYPE_HINT_SER: [u8; TYPE_HINT_LEN] = { + let mut result: [u8; TYPE_HINT_LEN] = [0; TYPE_HINT_LEN]; + #pyo3_crate_path::inspect::serialize_for_introspection(&TYPE_HINT, &mut result); + result + }; + &TYPE_HINT_SER + }} +} + +struct AttributedIntrospectionNode<'a> { + node: IntrospectionNode<'a>, + attributes: &'a [Attribute], +} + +impl<'a> From> for AttributedIntrospectionNode<'a> { + fn from(node: IntrospectionNode<'a>) -> Self { + Self { + node, + attributes: &[], + } + } +} + +impl<'a> From for AttributedIntrospectionNode<'a> { + fn from(node: PyExpr) -> Self { + IntrospectionNode::from(node).into() + } +} + +#[derive(Default)] +pub struct ConcatenationBuilder { + elements: Vec, + current_string: String, +} + +impl ConcatenationBuilder { + pub fn push_tokens(&mut self, token_stream: TokenStream) { + if !self.current_string.is_empty() { + self.elements.push(ConcatenationBuilderElement::String(take( + &mut self.current_string, + ))); + } + self.elements + .push(ConcatenationBuilderElement::TokenStream(token_stream)); + } + + pub fn push_str(&mut self, value: &str) { + self.current_string.push_str(value); + } + + fn push_str_to_escape(&mut self, value: &str) { + self.current_string.push('"'); + for c in value.chars() { + match c { + '\\' => self.current_string.push_str("\\\\"), + '"' => self.current_string.push_str("\\\""), + c => { + if c < char::from(32) { + panic!("ASCII chars below 32 are not allowed") + } else { + self.current_string.push(c); + } + } + } + } + self.current_string.push('"'); + } + + pub fn into_token_stream(self, pyo3_crate_path: &PyO3CratePath) -> TokenStream { + let mut elements = self.elements; + if !self.current_string.is_empty() { + elements.push(ConcatenationBuilderElement::String(self.current_string)); + } + + if let [ConcatenationBuilderElement::String(string)] = elements.as_slice() { + // We avoid the const_concat! macro if there is only a single string + return quote! { #string.as_bytes() }; + } + + quote! { + { + const PIECES: &[&[u8]] = &[#(#elements , )*]; + &#pyo3_crate_path::impl_::concat::combine_to_array::<{ + #pyo3_crate_path::impl_::concat::combined_len(PIECES) + }>(PIECES) + } + } + } + + fn into_static(self, pyo3_crate_path: &PyO3CratePath, ident: Ident) -> TokenStream { + let mut elements = self.elements; + if !self.current_string.is_empty() { + elements.push(ConcatenationBuilderElement::String(self.current_string)); + } + + // #[no_mangle] is required to make sure some linkers like Linux ones do not mangle the section name too. + quote! { + const _: () = { + const PIECES: &[&[u8]] = &[#(#elements , )*]; + const PIECES_LEN: usize = #pyo3_crate_path::impl_::concat::combined_len(PIECES); + #[used] + #[no_mangle] + static #ident: #pyo3_crate_path::impl_::introspection::SerializedIntrospectionFragment = #pyo3_crate_path::impl_::introspection::SerializedIntrospectionFragment { + length: PIECES_LEN as u32, + fragment: #pyo3_crate_path::impl_::concat::combine_to_array::(PIECES) + }; + }; + } + } +} + +enum ConcatenationBuilderElement { + String(String), + TokenStream(TokenStream), +} + +impl ToTokens for ConcatenationBuilderElement { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + Self::String(s) => quote! { #s.as_bytes() }.to_tokens(tokens), + Self::TokenStream(ts) => ts.to_tokens(tokens), + } + } +} + +/// Generates a new unique identifier for linking introspection objects together +pub fn introspection_id_const() -> TokenStream { + let id = unique_element_id().to_string(); + quote! { + #[doc(hidden)] + pub const _PYO3_INTROSPECTION_ID: &'static str = #id; + } +} + +pub fn unique_element_id() -> u64 { + let mut hasher = DefaultHasher::new(); + format!("{:?}", Span::call_site()).hash(&mut hasher); // Distinguishes between call sites + GLOBAL_COUNTER_FOR_UNIQUE_NAMES + .fetch_add(1, Ordering::Relaxed) + .hash(&mut hasher); // If there are multiple elements in the same call site + hasher.finish() +} + +fn ident_to_type(ident: &Ident) -> Cow<'static, Type> { + Cow::Owned( + TypePath { + path: ident.clone().into(), + qself: None, + } + .into(), + ) +} + +fn escape_json_string(value: &str) -> String { + let mut output = String::with_capacity(value.len()); + for c in value.chars() { + match c { + '\\' => output.push_str("\\\\"), + '"' => output.push_str("\\\""), + '\x08' => output.push_str("\\b"), + '\x0C' => output.push_str("\\f"), + '\n' => output.push_str("\\n"), + '\r' => output.push_str("\\r"), + '\t' => output.push_str("\\t"), + c @ '\0'..='\x1F' => { + write!(output, "\\u{:0>4x}", u32::from(c)).unwrap(); + } + c => output.push(c), + } + } + output +} diff --git a/vendor/pyo3-macros-backend/src/konst.rs b/vendor/pyo3-macros-backend/src/konst.rs new file mode 100644 index 0000000..aab082c --- /dev/null +++ b/vendor/pyo3-macros-backend/src/konst.rs @@ -0,0 +1,101 @@ +use std::borrow::Cow; +use std::ffi::CString; + +use crate::attributes::{self, get_pyo3_options, take_attributes, NameAttribute}; +#[cfg(feature = "experimental-inspect")] +use crate::utils::PythonDoc; +use proc_macro2::{Ident, Span}; +use syn::LitCStr; +use syn::{ + ext::IdentExt, + parse::{Parse, ParseStream}, + spanned::Spanned, + Result, +}; + +pub struct ConstSpec { + pub rust_ident: Ident, + pub attributes: ConstAttributes, + #[cfg(feature = "experimental-inspect")] + pub expr: Option, + #[cfg(feature = "experimental-inspect")] + pub ty: syn::Type, + #[cfg(feature = "experimental-inspect")] + pub doc: Option, +} + +impl ConstSpec { + pub fn python_name(&self) -> Cow<'_, Ident> { + if let Some(name) = &self.attributes.name { + Cow::Borrowed(&name.value.0) + } else { + Cow::Owned(self.rust_ident.unraw()) + } + } + + /// Null-terminated Python name + pub fn null_terminated_python_name(&self) -> LitCStr { + let name = self.python_name().to_string(); + LitCStr::new(&CString::new(name).unwrap(), Span::call_site()) + } +} + +pub struct ConstAttributes { + pub is_class_attr: bool, + pub name: Option, +} + +pub enum PyO3ConstAttribute { + Name(NameAttribute), +} + +impl Parse for PyO3ConstAttribute { + fn parse(input: ParseStream<'_>) -> Result { + let lookahead = input.lookahead1(); + if lookahead.peek(attributes::kw::name) { + input.parse().map(PyO3ConstAttribute::Name) + } else { + Err(lookahead.error()) + } + } +} + +impl ConstAttributes { + pub fn from_attrs(attrs: &mut Vec) -> syn::Result { + let mut attributes = ConstAttributes { + is_class_attr: false, + name: None, + }; + + take_attributes(attrs, |attr| { + if attr.path().is_ident("classattr") { + ensure_spanned!( + matches!(attr.meta, syn::Meta::Path(..)), + attr.span() => "`#[classattr]` does not take any arguments" + ); + attributes.is_class_attr = true; + Ok(true) + } else if let Some(pyo3_attributes) = get_pyo3_options(attr)? { + for pyo3_attr in pyo3_attributes { + match pyo3_attr { + PyO3ConstAttribute::Name(name) => attributes.set_name(name)?, + } + } + Ok(true) + } else { + Ok(false) + } + })?; + + Ok(attributes) + } + + fn set_name(&mut self, name: NameAttribute) -> Result<()> { + ensure_spanned!( + self.name.is_none(), + name.span() => "`name` may only be specified once" + ); + self.name = Some(name); + Ok(()) + } +} diff --git a/vendor/pyo3-macros-backend/src/lib.rs b/vendor/pyo3-macros-backend/src/lib.rs new file mode 100644 index 0000000..a90fa73 --- /dev/null +++ b/vendor/pyo3-macros-backend/src/lib.rs @@ -0,0 +1,36 @@ +//! This crate contains the implementation of the proc macro attributes + +#![warn(elided_lifetimes_in_paths, unused_lifetimes)] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![recursion_limit = "1024"] + +// Listed first so that macros in this module are available in the rest of the crate. +#[macro_use] +mod utils; + +mod attributes; +mod combine_errors; +mod derive_attributes; +mod frompyobject; +mod intopyobject; +#[cfg(feature = "experimental-inspect")] +mod introspection; +mod konst; +mod method; +mod module; +mod params; +#[cfg(feature = "experimental-inspect")] +mod py_expr; +mod pyclass; +mod pyfunction; +mod pyimpl; +mod pymethod; +mod quotes; + +pub use frompyobject::build_derive_from_pyobject; +pub use intopyobject::build_derive_into_pyobject; +pub use module::{pymodule_function_impl, pymodule_module_impl, PyModuleOptions}; +pub use pyclass::{build_py_class, build_py_enum, PyClassArgs}; +pub use pyfunction::{build_py_function, PyFunctionOptions}; +pub use pyimpl::{build_py_methods, PyClassMethodsType}; +pub use utils::get_doc; diff --git a/vendor/pyo3-macros-backend/src/method.rs b/vendor/pyo3-macros-backend/src/method.rs new file mode 100644 index 0000000..c40be23 --- /dev/null +++ b/vendor/pyo3-macros-backend/src/method.rs @@ -0,0 +1,1305 @@ +use std::borrow::Cow; +use std::ffi::CString; +use std::fmt::Display; + +use proc_macro2::{Span, TokenStream}; +use quote::{quote, quote_spanned, ToTokens}; +use syn::LitCStr; +use syn::{ext::IdentExt, spanned::Spanned, Ident, Result}; + +use crate::params::is_forwarded_args; +#[cfg(feature = "experimental-inspect")] +use crate::py_expr::PyExpr; +use crate::pyfunction::{PyFunctionWarning, WarningFactory}; +use crate::utils::Ctx; +use crate::{ + attributes::{FromPyWithAttribute, TextSignatureAttribute, TextSignatureAttributeValue}, + params::{impl_arg_params, Holders}, + pyfunction::{ + FunctionSignature, PyFunctionArgPyO3Attributes, PyFunctionOptions, SignatureAttribute, + }, + quotes, + utils::{self, PythonDoc}, +}; + +#[derive(Clone, Debug)] +pub struct RegularArg<'a> { + pub name: Cow<'a, syn::Ident>, + pub ty: &'a syn::Type, + pub from_py_with: Option>, + pub default_value: Option>, + pub option_wrapped_type: Option<&'a syn::Type>, + #[cfg(feature = "experimental-inspect")] + pub annotation: Option, +} + +/// Pythons *args argument +#[derive(Clone, Debug)] +pub struct VarargsArg<'a> { + pub name: Cow<'a, syn::Ident>, + pub ty: &'a syn::Type, + #[cfg(feature = "experimental-inspect")] + pub annotation: Option, +} + +/// Pythons **kwarg argument +#[derive(Clone, Debug)] +pub struct KwargsArg<'a> { + pub name: Cow<'a, syn::Ident>, + pub ty: &'a syn::Type, + #[cfg(feature = "experimental-inspect")] + pub annotation: Option, +} + +#[derive(Clone, Debug)] +pub struct CancelHandleArg<'a> { + pub name: &'a syn::Ident, + pub ty: &'a syn::Type, +} + +#[derive(Clone, Debug)] +pub struct PyArg<'a> { + pub name: &'a syn::Ident, + pub ty: &'a syn::Type, +} + +#[derive(Clone, Debug)] +pub enum FnArg<'a> { + Regular(RegularArg<'a>), + VarArgs(VarargsArg<'a>), + KwArgs(KwargsArg<'a>), + Py(PyArg<'a>), + CancelHandle(CancelHandleArg<'a>), +} + +impl<'a> FnArg<'a> { + pub fn name(&self) -> &syn::Ident { + match self { + FnArg::Regular(RegularArg { name, .. }) => name, + FnArg::VarArgs(VarargsArg { name, .. }) => name, + FnArg::KwArgs(KwargsArg { name, .. }) => name, + FnArg::Py(PyArg { name, .. }) => name, + FnArg::CancelHandle(CancelHandleArg { name, .. }) => name, + } + } + + pub fn ty(&self) -> &'a syn::Type { + match self { + FnArg::Regular(RegularArg { ty, .. }) => ty, + FnArg::VarArgs(VarargsArg { ty, .. }) => ty, + FnArg::KwArgs(KwargsArg { ty, .. }) => ty, + FnArg::Py(PyArg { ty, .. }) => ty, + FnArg::CancelHandle(CancelHandleArg { ty, .. }) => ty, + } + } + + #[expect( + clippy::wrong_self_convention, + reason = "called `from_` but not a constructor" + )] + pub fn from_py_with(&self) -> Option<&FromPyWithAttribute> { + if let FnArg::Regular(RegularArg { from_py_with, .. }) = self { + from_py_with.as_deref() + } else { + None + } + } + + pub fn to_varargs_mut(&mut self) -> Result<&mut Self> { + if let Self::Regular(RegularArg { + name, + ty, + option_wrapped_type: None, + #[cfg(feature = "experimental-inspect")] + annotation, + .. + }) = self + { + *self = Self::VarArgs(VarargsArg { + name: name.clone(), + ty, + #[cfg(feature = "experimental-inspect")] + annotation: annotation.clone(), + }); + Ok(self) + } else { + bail_spanned!(self.name().span() => "args cannot be optional") + } + } + + pub fn to_kwargs_mut(&mut self) -> Result<&mut Self> { + if let Self::Regular(RegularArg { + name, + ty, + option_wrapped_type: Some(..), + #[cfg(feature = "experimental-inspect")] + annotation, + .. + }) = self + { + *self = Self::KwArgs(KwargsArg { + name: name.clone(), + ty, + #[cfg(feature = "experimental-inspect")] + annotation: annotation.clone(), + }); + Ok(self) + } else { + bail_spanned!(self.name().span() => "kwargs must be Option<_>") + } + } + + /// Transforms a rust fn arg parsed with syn into a method::FnArg + pub fn parse(arg: &'a mut syn::FnArg) -> Result { + match arg { + syn::FnArg::Receiver(recv) => { + bail_spanned!(recv.span() => "unexpected receiver") + } // checked in parse_fn_type + syn::FnArg::Typed(cap) => { + if let syn::Type::ImplTrait(_) = &*cap.ty { + bail_spanned!(cap.ty.span() => IMPL_TRAIT_ERR); + } + + let PyFunctionArgPyO3Attributes { + from_py_with, + cancel_handle, + } = PyFunctionArgPyO3Attributes::from_attrs(&mut cap.attrs)?; + let ident = match &*cap.pat { + syn::Pat::Ident(syn::PatIdent { ident, .. }) => ident, + other => return Err(handle_argument_error(other)), + }; + + if utils::is_python(&cap.ty) { + return Ok(Self::Py(PyArg { + name: ident, + ty: &cap.ty, + })); + } + + if cancel_handle.is_some() { + // `PyFunctionArgPyO3Attributes::from_attrs` validates that + // only compatible attributes are specified, either + // `cancel_handle` or `from_py_with`, duplicates and any + // combination of the two are already rejected. + return Ok(Self::CancelHandle(CancelHandleArg { + name: ident, + ty: &cap.ty, + })); + } + + Ok(Self::Regular(RegularArg { + name: Cow::Borrowed(ident), + ty: &cap.ty, + from_py_with: from_py_with.map(Box::new), + default_value: None, + option_wrapped_type: utils::option_type_argument(&cap.ty), + #[cfg(feature = "experimental-inspect")] + annotation: None, + })) + } + } + } +} + +fn handle_argument_error(pat: &syn::Pat) -> syn::Error { + let span = pat.span(); + let msg = match pat { + syn::Pat::Wild(_) => "wildcard argument names are not supported", + syn::Pat::Struct(_) + | syn::Pat::Tuple(_) + | syn::Pat::TupleStruct(_) + | syn::Pat::Slice(_) => "destructuring in arguments is not supported", + _ => "unsupported argument", + }; + syn::Error::new(span, msg) +} + +/// Represents what kind of a function a pyfunction or pymethod is +#[derive(Clone, Debug)] +pub enum FnType { + /// Represents a pymethod annotated with `#[getter]` + Getter(SelfType), + /// Represents a pymethod annotated with `#[setter]` + Setter(SelfType), + /// Represents a pymethod annotated with `#[deleter]` + Deleter(SelfType), + /// Represents a regular pymethod + Fn(SelfType), + /// Represents a pymethod annotated with `#[classmethod]`, like a `@classmethod` + FnClass(Span), + /// Represents a pyfunction or a pymethod annotated with `#[staticmethod]`, like a `@staticmethod` + FnStatic, + /// Represents a pyfunction annotated with `#[pyo3(pass_module)] + FnModule(Span), + /// Represents a pymethod or associated constant annotated with `#[classattr]` + ClassAttribute, +} + +#[derive(Clone, Copy, Debug)] +pub(crate) enum ClassMethodReceiver { + Class, + Instance, +} + +impl FnType { + pub fn skip_first_rust_argument_in_python_signature(&self) -> bool { + match self { + FnType::Getter(_) + | FnType::Setter(_) + | FnType::Deleter(_) + | FnType::Fn(_) + | FnType::FnClass(_) + | FnType::FnModule(_) => true, + FnType::FnStatic | FnType::ClassAttribute => false, + } + } + + pub fn signature_attribute_allowed(&self) -> bool { + match self { + FnType::Fn(_) | FnType::FnStatic | FnType::FnClass(_) | FnType::FnModule(_) => true, + // Getter, Setter and Deleter and ClassAttribute all have fixed signatures (either take 0 or 1 + // arguments) so cannot have a `signature = (...)` attribute. + FnType::Getter(_) | FnType::Setter(_) | FnType::Deleter(_) | FnType::ClassAttribute => { + false + } + } + } + + pub fn self_arg( + &self, + cls: Option<&syn::Type>, + error_mode: ExtractErrorMode, + self_conversion: SelfConversionPolicy, + class_method_receiver: ClassMethodReceiver, + holders: &mut Holders, + ctx: &Ctx, + ) -> Option { + let Ctx { pyo3_path, .. } = ctx; + match self { + FnType::Getter(st) | FnType::Setter(st) | FnType::Deleter(st) | FnType::Fn(st) => { + Some(st.receiver( + cls.expect("no class given for Fn with a \"self\" receiver"), + error_mode, + self_conversion, + holders, + ctx, + )) + } + FnType::FnClass(span) => { + let py = syn::Ident::new("py", Span::call_site()); + let slf: Ident = syn::Ident::new("_slf", Span::call_site()); + let pyo3_path = pyo3_path.to_tokens_spanned(*span); + let class_method_receiver = match class_method_receiver { + ClassMethodReceiver::Class => quote! { #slf.cast() }, + ClassMethodReceiver::Instance => { + let type_check = match self_conversion.0 { + SelfConversionPolicyInner::Trusted => quote! {}, + SelfConversionPolicyInner::Checked => { + let cls = cls.expect("no class given for a class method"); + let type_check = error_mode.handle_error( + quote_spanned! { *span => + #pyo3_path::Bound::ref_from_ptr(#py, &#slf).cast::<#cls>() + }, + ctx, + ); + quote! { #type_check; } + } + }; + quote! {{ + #type_check + #pyo3_path::ffi::Py_TYPE(#slf).cast() + }} + } + }; + let ret = quote_spanned! { *span => + #[allow(clippy::useless_conversion, reason = "#[classmethod] accepts anything which implements `From<&Bound>`")] + ::std::convert::Into::into( + #pyo3_path::Bound::ref_from_ptr(#py, &#class_method_receiver) + .cast_unchecked::<#pyo3_path::types::PyType>() + ) + }; + Some(quote! { unsafe { #ret } }) + } + FnType::FnModule(span) => { + let py = syn::Ident::new("py", Span::call_site()); + let slf: Ident = syn::Ident::new("_slf", Span::call_site()); + let pyo3_path = pyo3_path.to_tokens_spanned(*span); + let ret = quote_spanned! { *span => + #[allow(clippy::useless_conversion, reason = "`pass_module` accepts anything which implements `From<&Bound>`")] + ::std::convert::Into::into( + #pyo3_path::Bound::ref_from_ptr(#py, &#slf.cast()) + .cast_unchecked::<#pyo3_path::types::PyModule>() + ) + }; + Some(quote! { unsafe { #ret } }) + } + FnType::FnStatic | FnType::ClassAttribute => None, + } + } +} + +#[derive(Clone, Debug)] +pub enum SelfType { + Receiver { + mutable: bool, + non_null: bool, + span: Span, + }, + TryFromBoundRef { + span: Span, + non_null: bool, + }, +} + +#[derive(Clone, Copy, Debug)] +enum SelfConversionPolicyInner { + /// The receiver's type is guaranteed by CPython's slot/method dispatch contract. + /// Used for all extension-type method and slot entrypoints. + Trusted, + /// The receiver's type is verified at runtime. Used for number-protocol + /// binary operator fragments where the CPython dispatch contract does not + /// guarantee the receiver type. + Checked, +} + +/// Receiver conversion policy for extension-type method wrappers. +/// +/// Controls whether the `self` receiver is validated with a runtime type check +/// (`Checked`) or treated as trusted and cast directly without checking +/// (`Trusted`). +/// +/// # Invariant +/// +/// The `Trusted` path is valid due to CPython's slot/method receiver contract: +/// when CPython dispatches a method call on an extension type — whether through +/// a type slot or through `tp_methods` — the receiver is guaranteed to be an +/// instance of the owning type (or a compatible subtype). For `tp_methods` +/// entries, CPython's method-wrapper descriptor enforces this before the C +/// function is reached. +/// +/// `Checked` should be used in cases where that guarantee does not hold: +/// - Number-protocol binary operator fragments (`__add__`, `__radd__`, …, +/// `__pow__`, `__rpow__`): CPython combines the forward and reflected +/// fragments into a single `nb_add`/`nb_power` slot, and the runtime helper +/// may call the reflected fragment with the operands swapped, meaning `_slf` +/// can arrive with a non-class type. The existing +/// `ExtractErrorMode::NotImplemented` behavior on type mismatch is preserved +/// by using `Checked` for those fragments. +#[derive(Clone, Copy, Debug)] +pub struct SelfConversionPolicy(SelfConversionPolicyInner); + +impl SelfConversionPolicy { + pub const fn checked() -> Self { + Self(SelfConversionPolicyInner::Checked) + } + + // Using the trusted conversion incorrectly can lead to incorrect runtime + // behavior and memory safety issues, so this is marked `unsafe` and usage + // should be justified by the caller. + pub const unsafe fn trusted() -> Self { + Self(SelfConversionPolicyInner::Trusted) + } +} + +#[derive(Clone, Copy)] +pub enum ExtractErrorMode { + NotImplemented, + Raise, +} + +impl ExtractErrorMode { + pub fn handle_error(self, extract: TokenStream, ctx: &Ctx) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + match self { + ExtractErrorMode::Raise => quote! { #extract? }, + ExtractErrorMode::NotImplemented => quote! { + match #extract { + ::std::result::Result::Ok(value) => value, + ::std::result::Result::Err(_) => { return #pyo3_path::impl_::callback::convert(py, py.NotImplemented()); }, + } + }, + } + } +} + +impl SelfType { + pub fn receiver( + &self, + cls: &syn::Type, + error_mode: ExtractErrorMode, + self_conversion: SelfConversionPolicy, + holders: &mut Holders, + ctx: &Ctx, + ) -> TokenStream { + // Due to use of quote_spanned in this function, need to bind these idents to the + // main macro callsite. + let py = syn::Ident::new("py", Span::call_site()); + let slf = syn::Ident::new("_slf", Span::call_site()); + let Ctx { pyo3_path, .. } = ctx; + match self { + SelfType::Receiver { + span, + mutable, + non_null, + } => { + let cast_fn = if *non_null { + quote!(cast_non_null_function_argument) + } else { + quote!(cast_function_argument) + }; + let arg = + quote! { unsafe { #pyo3_path::impl_::extract_argument::#cast_fn(#py, #slf) } }; + let holder = holders.push_holder(*span); + let pyo3_path = pyo3_path.to_tokens_spanned(*span); + match self_conversion.0 { + SelfConversionPolicyInner::Trusted => { + let method = if *mutable { + syn::Ident::new("extract_pyclass_ref_mut_trusted", *span) + } else { + syn::Ident::new("extract_pyclass_ref_trusted", *span) + }; + // Safety: slot wrappers are only installed on the extension type itself. + // CPython's slot dispatch contract ensures the receiver is an instance + // of the correct type before invoking the slot. + // + // The trailing `?` exists because if the extraction fails here it represents + // a genuine type error, should not fall back to e.g. `ExtractErrorMode::NotImplemented`. + quote! { + unsafe { #pyo3_path::impl_::extract_argument::#method::<#cls>( + #arg, + &mut #holder, + ) }? + } + } + SelfConversionPolicyInner::Checked => { + let method = if *mutable { + syn::Ident::new("extract_pyclass_ref_mut", *span) + } else { + syn::Ident::new("extract_pyclass_ref", *span) + }; + error_mode.handle_error( + quote_spanned! { *span => + #pyo3_path::impl_::extract_argument::#method::<#cls>( + #arg, + &mut #holder, + ) + }, + ctx, + ) + } + } + } + SelfType::TryFromBoundRef { span, non_null } => { + let bound_ref = if *non_null { + quote! { unsafe { #pyo3_path::Bound::ref_from_non_null(#py, &#slf) } } + } else { + quote! { unsafe { #pyo3_path::Bound::ref_from_ptr(#py, &#slf) } } + }; + let pyo3_path = pyo3_path.to_tokens_spanned(*span); + let receiver = match self_conversion.0 { + SelfConversionPolicyInner::Trusted => { + // Safety: slot wrappers are only installed on the extension type + // itself. CPython's slot dispatch contract ensures the receiver is + // an instance of the correct type (or a compatible subtype) before + // invoking the slot. + // + // The wrapping `Ok(...?)` here is because an error here should not + // be treated by e.g. `ExtractErrorMode::NotImplemented` as falling + // back to the default, but instead a genuine type error. + quote! { + unsafe { + #pyo3_path::PyResult::Ok( + #pyo3_path::impl_::extract_argument::cast_bound_ref_trusted::<#cls>(#bound_ref)? + ) + } + } + } + SelfConversionPolicyInner::Checked => { + quote_spanned! { *span => + #bound_ref.cast::<#cls>() + .map_err(::std::convert::Into::<#pyo3_path::PyErr>::into) + } + } + }; + error_mode.handle_error( + quote_spanned! { *span => + #receiver + .and_then( + #[allow( + clippy::unnecessary_fallible_conversions, + clippy::useless_conversion, + reason = "anything implementing `TryFrom<&Bound>` is permitted" + )] + |bound| ::std::convert::TryFrom::try_from(bound).map_err(::std::convert::Into::into) + ) + + }, + ctx + ) + } + } + } +} + +/// Determines which CPython calling convention a given FnSpec uses. +#[derive(Clone, Debug, Copy)] +pub enum CallingConvention { + Noargs, // METH_NOARGS + Varargs, // METH_VARARGS | METH_KEYWORDS + Fastcall, // METH_FASTCALL | METH_KEYWORDS +} + +impl CallingConvention { + /// Determine default calling convention from an argument signature. + /// + /// Different other slots (tp_call, tp_new) can have other requirements + /// and are set manually (see `parse_fn_type` below). + pub fn from_signature(signature: &FunctionSignature<'_>) -> Self { + if signature.python_signature.has_no_args() { + Self::Noargs + } else if signature.python_signature.kwargs.is_none() { + Self::Fastcall + } else { + Self::Varargs + } + } +} + +#[derive(Clone)] +pub struct FnSpec<'a> { + pub tp: FnType, + // Rust function name + pub name: &'a syn::Ident, + // Wrapped python name. This should not have any leading r#. + // r# can be removed by syn::ext::IdentExt::unraw() + pub python_name: syn::Ident, + pub signature: FunctionSignature<'a>, + pub text_signature: Option, + pub asyncness: Option, + pub unsafety: Option, + pub warnings: Vec, + #[cfg_attr(not(feature = "experimental-inspect"), expect(dead_code))] + pub output: syn::ReturnType, +} + +pub fn parse_method_receiver(arg: &syn::FnArg, non_null: bool) -> Result { + match arg { + syn::FnArg::Receiver( + recv @ syn::Receiver { + reference: None, .. + }, + ) => { + bail_spanned!(recv.span() => RECEIVER_BY_VALUE_ERR); + } + syn::FnArg::Receiver(recv @ syn::Receiver { mutability, .. }) => Ok(SelfType::Receiver { + mutable: mutability.is_some(), + span: recv.span(), + non_null, + }), + syn::FnArg::Typed(syn::PatType { ty, .. }) => { + if let syn::Type::ImplTrait(_) = &**ty { + bail_spanned!(ty.span() => IMPL_TRAIT_ERR); + } + Ok(SelfType::TryFromBoundRef { + span: ty.span(), + non_null, + }) + } + } +} + +impl<'a> FnSpec<'a> { + /// Parser function signature and function attributes + pub fn parse( + // Signature is mutable to remove the `Python` argument. + sig: &'a mut syn::Signature, + meth_attrs: &mut Vec, + options: PyFunctionOptions, + ) -> Result> { + let PyFunctionOptions { + text_signature, + name, + signature, + warnings, + .. + } = options; + + let mut python_name = name.map(|name| name.value.0); + + let fn_type = Self::parse_fn_type(sig, meth_attrs, &mut python_name)?; + ensure_signatures_on_valid_method(&fn_type, signature.as_ref(), text_signature.as_ref())?; + + let name = &sig.ident; + let python_name = python_name.as_ref().unwrap_or(name).unraw(); + + let arguments: Vec<_> = sig + .inputs + .iter_mut() + .skip(if fn_type.skip_first_rust_argument_in_python_signature() { + 1 + } else { + 0 + }) + .map(FnArg::parse) + .collect::>()?; + + let signature = if let Some(signature) = signature { + FunctionSignature::from_arguments_and_attribute(arguments, signature)? + } else { + FunctionSignature::from_arguments(arguments) + }; + + Ok(FnSpec { + tp: fn_type, + name, + python_name, + signature, + text_signature, + asyncness: sig.asyncness, + unsafety: sig.unsafety, + warnings, + output: sig.output.clone(), + }) + } + + pub fn null_terminated_python_name(&self) -> LitCStr { + let name = self.python_name.to_string(); + let name = CString::new(name).unwrap(); + LitCStr::new(&name, self.python_name.span()) + } + + fn parse_fn_type( + sig: &syn::Signature, + meth_attrs: &mut Vec, + python_name: &mut Option, + ) -> Result { + let mut method_attributes = parse_method_attributes(meth_attrs)?; + let receiver_non_null = method_attributes.iter().any(|attr| { + matches!( + attr, + MethodTypeAttribute::Getter(_, _) + | MethodTypeAttribute::Setter(_, _) + | MethodTypeAttribute::Deleter(_, _) + ) + }); + + let name = &sig.ident; + let parse_receiver = |msg: &'static str| { + let first_arg = sig + .inputs + .first() + .ok_or_else(|| err_spanned!(sig.span() => msg))?; + parse_method_receiver(first_arg, receiver_non_null) + }; + + // strip get_ or set_ + let strip_fn_name = |prefix: &'static str| { + name.unraw() + .to_string() + .strip_prefix(prefix) + .map(|stripped| syn::Ident::new(stripped, name.span())) + }; + + let mut set_name_to_new = || { + if let Some(name) = &python_name { + bail_spanned!(name.span() => "`name` not allowed with `#[new]`"); + } + *python_name = Some(syn::Ident::new("__new__", Span::call_site())); + Ok(()) + }; + + let fn_type = match method_attributes.as_mut_slice() { + [] => FnType::Fn(parse_receiver( + "static method needs #[staticmethod] attribute", + )?), + [MethodTypeAttribute::StaticMethod(_)] => FnType::FnStatic, + [MethodTypeAttribute::ClassAttribute(_)] => FnType::ClassAttribute, + [MethodTypeAttribute::New(_)] => { + set_name_to_new()?; + FnType::FnStatic + } + [MethodTypeAttribute::New(_), MethodTypeAttribute::ClassMethod(span)] + | [MethodTypeAttribute::ClassMethod(span), MethodTypeAttribute::New(_)] => { + set_name_to_new()?; + FnType::FnClass(*span) + } + [MethodTypeAttribute::ClassMethod(_)] => { + // Add a helpful hint if the classmethod doesn't look like a classmethod + let span = match sig.inputs.first() { + // Don't actually bother checking the type of the first argument, the compiler + // will error on incorrect type. + Some(syn::FnArg::Typed(first_arg)) => first_arg.ty.span(), + Some(syn::FnArg::Receiver(_)) | None => bail_spanned!( + sig.paren_token.span.join() => "Expected `&Bound` or `Py` as the first argument to `#[classmethod]`" + ), + }; + FnType::FnClass(span) + } + [MethodTypeAttribute::Getter(_, name)] => { + if let Some(name) = name.take() { + ensure_spanned!( + python_name.replace(name).is_none(), + python_name.span() => "`name` may only be specified once" + ); + } else if python_name.is_none() { + // Strip off "get_" prefix if needed + *python_name = strip_fn_name("get_"); + } + + FnType::Getter(parse_receiver("expected receiver for `#[getter]`")?) + } + [MethodTypeAttribute::Setter(_, name)] => { + if let Some(name) = name.take() { + ensure_spanned!( + python_name.replace(name).is_none(), + python_name.span() => "`name` may only be specified once" + ); + } else if python_name.is_none() { + // Strip off "set_" prefix if needed + *python_name = strip_fn_name("set_"); + } + + FnType::Setter(parse_receiver("expected receiver for `#[setter]`")?) + } + [MethodTypeAttribute::Deleter(_, name)] => { + if let Some(name) = name.take() { + ensure_spanned!( + python_name.replace(name).is_none(), + python_name.span() => "`name` may only be specified once" + ); + } else if python_name.is_none() { + // Strip off "delete_" prefix if needed + *python_name = strip_fn_name("delete_"); + } + + FnType::Deleter(parse_receiver("expected receiver for `#[deleter]`")?) + } + [first, rest @ .., last] => { + // Join as many of the spans together as possible + let span = rest + .iter() + .fold(first.span(), |s, next| s.join(next.span()).unwrap_or(s)); + let span = span.join(last.span()).unwrap_or(span); + // List all the attributes in the error message + let mut msg = format!("`{first}` may not be combined with"); + let mut is_first = true; + for attr in &*rest { + msg.push_str(&format!(" `{attr}`")); + if is_first { + is_first = false; + } else { + msg.push(','); + } + } + if !rest.is_empty() { + msg.push_str(" and"); + } + msg.push_str(&format!(" `{last}`")); + bail_spanned!(span => msg) + } + }; + Ok(fn_type) + } + + /// Return a C wrapper function for this signature. + pub fn get_wrapper_function( + &self, + ident: &proc_macro2::Ident, + cls: Option<&syn::Type>, + convention: CallingConvention, + self_conversion: SelfConversionPolicy, + class_method_receiver: ClassMethodReceiver, + ctx: &Ctx, + ) -> Result { + let Ctx { + pyo3_path, + output_span, + } = ctx; + let mut cancel_handle_iter = self + .signature + .arguments + .iter() + .filter(|arg| matches!(arg, FnArg::CancelHandle(..))); + let cancel_handle = cancel_handle_iter.next(); + if let Some(FnArg::CancelHandle(CancelHandleArg { name, .. })) = cancel_handle { + ensure_spanned!(self.asyncness.is_some(), name.span() => "`cancel_handle` attribute can only be used with `async fn`"); + if let Some(FnArg::CancelHandle(CancelHandleArg { name, .. })) = + cancel_handle_iter.next() + { + bail_spanned!(name.span() => "`cancel_handle` may only be specified once"); + } + } + + let rust_call = |args: Vec, mut holders: Holders| { + let self_arg = self.tp.self_arg( + cls, + ExtractErrorMode::Raise, + self_conversion, + class_method_receiver, + &mut holders, + ctx, + ); + let init_holders = holders.init_holders(ctx); + + // We must assign the output_span to the return value of the call, + // but *not* of the call itself otherwise the spans get really weird + let ret_ident = Ident::new("ret", *output_span); + + if self.asyncness.is_some() { + // For async functions, we need to build up a coroutine object to return from the initial function call. + // + // Extraction of the call signature (positional & keyword arguments) happens as part of the initial function + // call. The Python objects are then moved into the Rust future that will be executed when the coroutine is + // awaited. + // + // The argument extraction from Python objects to Rust values then happens inside the future, this allows + // things like extraction to `&MyClass` which needs a holder (for the class guard) to work properly inside + // async code. + // + // It *might* be possible in the future to do the extraction before the coroutine is created, but that would require + // changing argument extraction code to first create holders and then read the values from them later. + let (throw_callback, init_throw_callback) = if cancel_handle.is_some() { + ( + quote! { Some(__throw_callback) }, + Some( + quote! { let __cancel_handle = #pyo3_path::coroutine::CancelHandle::new(); + let __throw_callback = __cancel_handle.throw_callback(); }, + ), + ) + } else { + (quote! { None }, None) + }; + let python_name = &self.python_name; + let qualname_prefix = match cls { + Some(cls) => quote!(Some(<#cls as #pyo3_path::PyClass>::NAME)), + None => quote!(None), + }; + // copy self arg into async block + // slf_py will create the owned value to store in the future + // slf_ptr recreates the raw pointer temporarily when building the future + let (slf_py, slf_ptr) = if self_arg.is_some() { + ( + Some( + quote! { let _slf = #pyo3_path::Borrowed::from_ptr(py, _slf).to_owned().unbind(); }, + ), + Some(quote! { let _slf = _slf.as_ptr(); }), + ) + } else { + (None, None) + }; + // copy extracted arguments into async block + // output_py will create the owned arguments to store in the future + // output_args recreates the borrowed objects temporarily when building the future + let (output_py, output_args) = if !matches!(convention, CallingConvention::Noargs) + && !is_forwarded_args(&self.signature) + { + ( + Some(quote! { + let output = output.map(|o| o.map(Py::from)); + }), + Some(quote! { + let output = output.each_ref().map(|o| o.as_ref().map(|obj| obj.bind_borrowed(assume_attached.py()))); + }), + ) + } else { + (None, None) + }; + // if *args / **kwargs are present, treat the `Bound<'_, PyTuple>` / `Option>` similarly + let (varargs_py, varargs_ptr) = if self.signature.python_signature.varargs.is_some() + { + ( + Some(quote! { + let _args = _args.to_owned().unbind(); + }), + Some(quote! { + let _args = _args.bind_borrowed(assume_attached.py()); + }), + ) + } else { + (None, None) + }; + let (kwargs_py, kwargs_ptr) = if self.signature.python_signature.kwargs.is_some() { + ( + Some(quote! { + let _kwargs = _kwargs.map(|k| k.to_owned().unbind()); + }), + Some(quote! { + let _kwargs = _kwargs.as_ref().map(|k| k.bind_borrowed(assume_attached.py())); + }), + ) + } else { + (None, None) + }; + let args = self_arg.into_iter().chain(args); + let ok_wrap = quotes::ok_wrap(ret_ident.to_token_stream(), ctx); + quote! { + { + let coroutine = { + #slf_py + #output_py + #varargs_py + #kwargs_py + #init_throw_callback + #pyo3_path::impl_::coroutine::new_coroutine( + #pyo3_path::intern!(py, stringify!(#python_name)), + #qualname_prefix, + #throw_callback, + async move { + // SAFETY: attached when future is polled (see `Coroutine::poll`) + let assume_attached = unsafe { #pyo3_path::impl_::coroutine::AssumeAttachedInCoroutine::new() }; + #init_holders + let future = { + let py = assume_attached.py(); + #slf_ptr + #output_args + #varargs_ptr + #kwargs_ptr + function(#(#args),*) + }; + let #ret_ident = future.await; + let #ret_ident = #ok_wrap; + #pyo3_path::impl_::wrap::converter(&#ret_ident).map_into_pyobject(assume_attached.py(), #ret_ident) + }, + ) + }; + #pyo3_path::Py::new(py, coroutine).map(#pyo3_path::Py::into_ptr) + } + } + } else { + let args = self_arg.into_iter().chain(args); + let return_conversion = quotes::map_result_into_ptr( + quotes::ok_wrap(ret_ident.to_token_stream(), ctx), + ctx, + ); + quote! { + { + #init_holders + let #ret_ident = function(#(#args),*); + #return_conversion + } + } + } + }; + + let func_name = &self.name; + let rust_name = if let Some(cls) = cls { + quote!(#cls::#func_name) + } else { + quote!(#func_name) + }; + + let warnings = self.warnings.build_py_warning(ctx); + let mut holders = Holders::new(); + + Ok(match convention { + CallingConvention::Noargs => { + let args = self + .signature + .arguments + .iter() + .map(|arg| match arg { + FnArg::Py(arg) => { + let span = Span::call_site().located_at(arg.ty.span()); + quote_spanned!( span => py) + } + FnArg::CancelHandle(arg) => { + let span = Span::call_site().located_at(arg.ty.span()); + quote_spanned!(span => __cancel_handle) + } + _ => unreachable!("`CallingConvention::Noargs` should not contain any arguments (reaching Python) except for `self`, which is handled below."), + }) + .collect(); + let call = rust_call(args, holders); + quote! { + unsafe fn #ident<'py>( + py: #pyo3_path::Python<'py>, + _slf: *mut #pyo3_path::ffi::PyObject, + ) -> #pyo3_path::PyResult<*mut #pyo3_path::ffi::PyObject> { + let function = #rust_name; // Shadow the function name to avoid #3017 + #warnings + let result = #call; + result + } + } + } + CallingConvention::Fastcall => { + let (arg_convert, args) = impl_arg_params(self, cls, true, &mut holders, ctx); + let call = rust_call(args, holders); + + quote! { + #pyo3_path::impl_::pymethods::maybe_define_fastcall_function_with_keywords!( + #ident, py, _slf, _args, _nargs, _kwargs, { + let function = #rust_name; // Shadow the function name to avoid #3017 + #arg_convert + #warnings + let result = #call; + result + } + ); + } + } + CallingConvention::Varargs => { + let (arg_convert, args) = impl_arg_params(self, cls, false, &mut holders, ctx); + let call = rust_call(args, holders); + + quote! { + unsafe fn #ident<'py>( + py: #pyo3_path::Python<'py>, + _slf: *mut #pyo3_path::ffi::PyObject, + _args: *mut #pyo3_path::ffi::PyObject, + _kwargs: *mut #pyo3_path::ffi::PyObject + ) -> #pyo3_path::PyResult<*mut #pyo3_path::ffi::PyObject> { + let function = #rust_name; // Shadow the function name to avoid #3017 + #arg_convert + #warnings + let result = #call; + result + } + } + } + }) + } + + /// Return a `PyMethodDef` constructor for this function, matching the selected + /// calling convention. + pub fn get_methoddef( + &self, + wrapper: impl ToTokens, + doc: Option<&PythonDoc>, + convention: CallingConvention, + ctx: &Ctx, + ) -> Result { + let Ctx { pyo3_path, .. } = ctx; + let python_name = self.null_terminated_python_name(); + let flags = match self.tp { + FnType::FnClass(_) => quote! { .flags(#pyo3_path::ffi::METH_CLASS) }, + FnType::FnStatic => quote! { .flags(#pyo3_path::ffi::METH_STATIC) }, + _ => quote! {}, + }; + let trampoline = match convention { + CallingConvention::Noargs => Ident::new("noargs", Span::call_site()), + CallingConvention::Fastcall => { + Ident::new("maybe_fastcall_cfunction_with_keywords", Span::call_site()) + } + CallingConvention::Varargs => Ident::new("cfunction_with_keywords", Span::call_site()), + }; + let doc = if let Some(doc) = doc { + doc.to_cstr_stream(ctx)? + } else { + c"".to_token_stream() + }; + Ok(quote! { + #pyo3_path::impl_::pymethods::PyMethodDef::#trampoline( + #python_name, + #pyo3_path::impl_::trampoline::get_trampoline_function!(#trampoline, #wrapper), + #doc, + ) #flags + }) + } + + /// Forwards to [utils::get_doc] with the text signature of this spec. + pub fn get_doc(&self, attrs: &[syn::Attribute]) -> Option { + let text_signature = self + .text_signature_call_signature() + .map(|sig| format!("{}{}", self.python_name, sig)); + utils::get_doc(attrs, text_signature) + } + + /// Creates the parenthesised arguments list for `__text_signature__` snippet based on this spec's signature + /// and/or attributes. Prepend the callable name to make a complete `__text_signature__`. + pub fn text_signature_call_signature(&self) -> Option { + let self_argument = match &self.tp { + // Getters / Setters / deleter / ClassAttribute are not callables on the Python side + FnType::Getter(_) | FnType::Setter(_) | FnType::Deleter(_) | FnType::ClassAttribute => { + return None + } + FnType::Fn(_) => Some("self"), + FnType::FnModule(_) => Some("module"), + FnType::FnClass(_) => Some("cls"), + FnType::FnStatic => None, + }; + + match self.text_signature.as_ref().map(|attr| &attr.value) { + Some(TextSignatureAttributeValue::Str(s)) => Some(s.value()), + None => Some(self.signature.text_signature(self_argument)), + Some(TextSignatureAttributeValue::Disabled(_)) => None, + } + } +} + +enum MethodTypeAttribute { + New(Span), + ClassMethod(Span), + StaticMethod(Span), + Getter(Span, Option), + Setter(Span, Option), + Deleter(Span, Option), + ClassAttribute(Span), +} + +impl MethodTypeAttribute { + fn span(&self) -> Span { + match self { + MethodTypeAttribute::New(span) + | MethodTypeAttribute::ClassMethod(span) + | MethodTypeAttribute::StaticMethod(span) + | MethodTypeAttribute::Getter(span, _) + | MethodTypeAttribute::Setter(span, _) + | MethodTypeAttribute::Deleter(span, _) + | MethodTypeAttribute::ClassAttribute(span) => *span, + } + } + + /// Attempts to parse a method type attribute. + /// + /// If the attribute does not match one of the attribute names, returns `Ok(None)`. + /// + /// Otherwise will either return a parse error or the attribute. + fn parse_if_matching_attribute(attr: &syn::Attribute) -> Result> { + fn ensure_no_arguments(meta: &syn::Meta, ident: &str) -> syn::Result<()> { + match meta { + syn::Meta::Path(_) => Ok(()), + syn::Meta::List(l) => bail_spanned!( + l.span() => format!( + "`#[{ident}]` does not take any arguments\n= help: did you mean `#[{ident}] #[pyo3({meta})]`?", + ident = ident, + meta = l.tokens, + ) + ), + syn::Meta::NameValue(nv) => { + bail_spanned!(nv.eq_token.span() => format!( + "`#[{}]` does not take any arguments\n= note: this was previously accepted and ignored", + ident + )) + } + } + } + + fn extract_name(meta: &syn::Meta, ident: &str) -> Result> { + match meta { + syn::Meta::Path(_) => Ok(None), + syn::Meta::NameValue(nv) => bail_spanned!( + nv.eq_token.span() => format!("expected `#[{}(name)]` to set the name", ident) + ), + syn::Meta::List(l) => { + if let Ok(name) = l.parse_args::() { + Ok(Some(name)) + } else if let Ok(name) = l.parse_args::() { + name.parse().map(Some) + } else { + bail_spanned!(l.tokens.span() => "expected ident or string literal for property name"); + } + } + } + } + + let meta = &attr.meta; + let path = meta.path(); + + if path.is_ident("new") { + ensure_no_arguments(meta, "new")?; + Ok(Some(MethodTypeAttribute::New(path.span()))) + } else if path.is_ident("classmethod") { + ensure_no_arguments(meta, "classmethod")?; + Ok(Some(MethodTypeAttribute::ClassMethod(path.span()))) + } else if path.is_ident("staticmethod") { + ensure_no_arguments(meta, "staticmethod")?; + Ok(Some(MethodTypeAttribute::StaticMethod(path.span()))) + } else if path.is_ident("classattr") { + ensure_no_arguments(meta, "classattr")?; + Ok(Some(MethodTypeAttribute::ClassAttribute(path.span()))) + } else if path.is_ident("getter") { + let name = extract_name(meta, "getter")?; + Ok(Some(MethodTypeAttribute::Getter(path.span(), name))) + } else if path.is_ident("setter") { + let name = extract_name(meta, "setter")?; + Ok(Some(MethodTypeAttribute::Setter(path.span(), name))) + } else if path.is_ident("deleter") { + let name = extract_name(meta, "deleter")?; + Ok(Some(MethodTypeAttribute::Deleter(path.span(), name))) + } else { + Ok(None) + } + } +} + +impl Display for MethodTypeAttribute { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(match self { + MethodTypeAttribute::New(_) => "#[new]", + MethodTypeAttribute::ClassMethod(_) => "#[classmethod]", + MethodTypeAttribute::StaticMethod(_) => "#[staticmethod]", + MethodTypeAttribute::Getter(_, _) => "#[getter]", + MethodTypeAttribute::Setter(_, _) => "#[setter]", + MethodTypeAttribute::Deleter(_, _) => "#[deleter]", + MethodTypeAttribute::ClassAttribute(_) => "#[classattr]", + }) + } +} + +fn parse_method_attributes(attrs: &mut Vec) -> Result> { + let mut new_attrs = Vec::new(); + let mut found_attrs = Vec::new(); + + for attr in attrs.drain(..) { + match MethodTypeAttribute::parse_if_matching_attribute(&attr)? { + Some(attr) => found_attrs.push(attr), + None => new_attrs.push(attr), + } + } + + *attrs = new_attrs; + + Ok(found_attrs) +} + +const IMPL_TRAIT_ERR: &str = "Python functions cannot have `impl Trait` arguments"; +const RECEIVER_BY_VALUE_ERR: &str = + "Python objects are shared, so 'self' cannot be moved out of the Python interpreter. +Try `&self`, `&mut self, `slf: PyClassGuard<'_, Self>` or `slf: PyClassGuardMut<'_, Self>`."; + +fn ensure_signatures_on_valid_method( + fn_type: &FnType, + signature: Option<&SignatureAttribute>, + text_signature: Option<&TextSignatureAttribute>, +) -> syn::Result<()> { + if let Some(signature) = signature { + match fn_type { + FnType::Getter(_) => { + debug_assert!(!fn_type.signature_attribute_allowed()); + bail_spanned!(signature.kw.span() => "`signature` not allowed with `getter`") + } + FnType::Setter(_) => { + debug_assert!(!fn_type.signature_attribute_allowed()); + bail_spanned!(signature.kw.span() => "`signature` not allowed with `setter`") + } + FnType::Deleter(_) => { + debug_assert!(!fn_type.signature_attribute_allowed()); + bail_spanned!(signature.kw.span() => "`signature` not allowed with `deleter`") + } + FnType::ClassAttribute => { + debug_assert!(!fn_type.signature_attribute_allowed()); + bail_spanned!(signature.kw.span() => "`signature` not allowed with `classattr`") + } + _ => debug_assert!(fn_type.signature_attribute_allowed()), + } + } + if let Some(text_signature) = text_signature { + match fn_type { + FnType::Getter(_) => { + bail_spanned!(text_signature.kw.span() => "`text_signature` not allowed with `getter`") + } + FnType::Setter(_) => { + bail_spanned!(text_signature.kw.span() => "`text_signature` not allowed with `setter`") + } + FnType::Deleter(_) => { + bail_spanned!(text_signature.kw.span() => "`text_signature` not allowed with `deleter`") + } + FnType::ClassAttribute => { + bail_spanned!(text_signature.kw.span() => "`text_signature` not allowed with `classattr`") + } + _ => {} + } + } + Ok(()) +} diff --git a/vendor/pyo3-macros-backend/src/module.rs b/vendor/pyo3-macros-backend/src/module.rs new file mode 100644 index 0000000..9e3f795 --- /dev/null +++ b/vendor/pyo3-macros-backend/src/module.rs @@ -0,0 +1,743 @@ +//! Code generation for the function that initializes a python module and adds classes and function. + +#[cfg(feature = "experimental-inspect")] +use crate::introspection::{ + attribute_introspection_code, introspection_id_const, module_introspection_code, +}; +#[cfg(feature = "experimental-inspect")] +use crate::py_expr::PyExpr; +use crate::{ + attributes::{ + self, kw, take_attributes, take_pyo3_options, CrateAttribute, GILUsedAttribute, + ModuleAttribute, NameAttribute, SubmoduleAttribute, + }, + combine_errors::CombineErrors, + get_doc, + pyclass::PyClassPyO3Option, + pyfunction::{impl_wrap_pyfunction, PyFunctionOptions}, + utils::{has_attribute, has_attribute_with_namespace, Ctx, IdentOrStr, PythonDoc}, +}; +use proc_macro2::{Span, TokenStream}; +use quote::{quote, ToTokens}; +use std::ffi::CString; +use syn::LitCStr; +use syn::{ + ext::IdentExt, + parse::{Parse, ParseStream}, + parse_quote, parse_quote_spanned, + punctuated::Punctuated, + spanned::Spanned, + token::Comma, + Item, Meta, Path, Result, +}; + +#[derive(Default)] +pub struct PyModuleOptions { + krate: Option, + name: Option, + module: Option, + submodule: Option, + gil_used: Option, +} + +impl Parse for PyModuleOptions { + fn parse(input: ParseStream<'_>) -> syn::Result { + let mut options: PyModuleOptions = Default::default(); + + options.add_attributes( + Punctuated::::parse_terminated(input)?, + )?; + + Ok(options) + } +} + +impl PyModuleOptions { + fn take_pyo3_options(&mut self, attrs: &mut Vec) -> Result<()> { + self.add_attributes(take_pyo3_options(attrs)?) + } + + fn add_attributes( + &mut self, + attrs: impl IntoIterator, + ) -> Result<()> { + macro_rules! set_option { + ($key:ident $(, $extra:literal)?) => { + { + ensure_spanned!( + self.$key.is_none(), + $key.span() => concat!("`", stringify!($key), "` may only be specified once" $(, $extra)?) + ); + self.$key = Some($key); + } + }; + } + attrs + .into_iter() + .map(|attr| { + match attr { + PyModulePyO3Option::Crate(krate) => set_option!(krate), + PyModulePyO3Option::Name(name) => set_option!(name), + PyModulePyO3Option::Module(module) => set_option!(module), + PyModulePyO3Option::Submodule(submodule) => set_option!( + submodule, + " (it is implicitly always specified for nested modules)" + ), + PyModulePyO3Option::GILUsed(gil_used) => { + set_option!(gil_used) + } + } + + Ok(()) + }) + .try_combine_syn_errors()?; + Ok(()) + } +} + +pub fn pymodule_module_impl( + module: &mut syn::ItemMod, + mut options: PyModuleOptions, +) -> Result { + let syn::ItemMod { + attrs, + vis, + unsafety: _, + ident, + mod_token, + content, + semi: _, + } = module; + let items = if let Some((_, items)) = content { + items + } else { + bail_spanned!(mod_token.span() => "`#[pymodule]` can only be used on inline modules") + }; + options.take_pyo3_options(attrs)?; + let ctx = &Ctx::new(&options.krate, None); + let Ctx { pyo3_path, .. } = ctx; + let doc = get_doc(attrs, None); + let name = options + .name + .map_or_else(|| ident.unraw(), |name| name.value.0); + let full_name = if let Some(module) = &options.module { + format!("{}.{}", module.value.value(), name) + } else { + name.to_string() + }; + + let mut module_items = Vec::new(); + let mut module_items_cfg_attrs = Vec::new(); + #[cfg(feature = "experimental-inspect")] + let mut introspection_chunks = Vec::new(); + #[cfg(not(feature = "experimental-inspect"))] + let introspection_chunks = Vec::::new(); + + fn extract_use_items( + source: &syn::UseTree, + cfg_attrs: &[syn::Attribute], + target_items: &mut Vec, + target_cfg_attrs: &mut Vec>, + ) -> Result<()> { + match source { + syn::UseTree::Name(name) => { + target_items.push(name.ident.clone()); + target_cfg_attrs.push(cfg_attrs.to_vec()); + } + syn::UseTree::Path(path) => { + extract_use_items(&path.tree, cfg_attrs, target_items, target_cfg_attrs)? + } + syn::UseTree::Group(group) => { + for tree in &group.items { + extract_use_items(tree, cfg_attrs, target_items, target_cfg_attrs)? + } + } + syn::UseTree::Glob(glob) => { + bail_spanned!(glob.span() => "#[pymodule] cannot import glob statements") + } + syn::UseTree::Rename(rename) => { + target_items.push(rename.rename.clone()); + target_cfg_attrs.push(cfg_attrs.to_vec()); + } + } + Ok(()) + } + + let mut pymodule_init = None; + let mut module_consts = Vec::new(); + let mut module_consts_cfg_attrs = Vec::new(); + + let _: Vec<()> = (*items).iter_mut().map(|item|{ + match item { + Item::Use(item_use) => { + let is_pymodule_export = + find_and_remove_attribute(&mut item_use.attrs, "pymodule_export"); + if is_pymodule_export { + let cfg_attrs = get_cfg_attributes(&item_use.attrs); + extract_use_items( + &item_use.tree, + &cfg_attrs, + &mut module_items, + &mut module_items_cfg_attrs, + )?; + } + } + Item::Fn(item_fn) => { + ensure_spanned!( + !has_attribute(&item_fn.attrs, "pymodule_export"), + item.span() => "`#[pymodule_export]` may only be used on `use` or `const` statements" + ); + let is_pymodule_init = + find_and_remove_attribute(&mut item_fn.attrs, "pymodule_init"); + let ident = &item_fn.sig.ident; + if is_pymodule_init { + ensure_spanned!( + !has_attribute(&item_fn.attrs, "pyfunction"), + item_fn.span() => "`#[pyfunction]` cannot be used alongside `#[pymodule_init]`" + ); + ensure_spanned!(pymodule_init.is_none(), item_fn.span() => "only one `#[pymodule_init]` may be specified"); + pymodule_init = Some(quote! { #ident(module)?; }); + } else if has_attribute(&item_fn.attrs, "pyfunction") + || has_attribute_with_namespace( + &item_fn.attrs, + Some(pyo3_path), + &["pyfunction"], + ) + || has_attribute_with_namespace( + &item_fn.attrs, + Some(pyo3_path), + &["prelude", "pyfunction"], + ) + { + module_items.push(ident.clone()); + module_items_cfg_attrs.push(get_cfg_attributes(&item_fn.attrs)); + } + } + Item::Struct(item_struct) => { + ensure_spanned!( + !has_attribute(&item_struct.attrs, "pymodule_export"), + item.span() => "`#[pymodule_export]` may only be used on `use` or `const` statements" + ); + if has_attribute(&item_struct.attrs, "pyclass") + || has_attribute_with_namespace( + &item_struct.attrs, + Some(pyo3_path), + &["pyclass"], + ) + || has_attribute_with_namespace( + &item_struct.attrs, + Some(pyo3_path), + &["prelude", "pyclass"], + ) + { + module_items.push(item_struct.ident.clone()); + module_items_cfg_attrs.push(get_cfg_attributes(&item_struct.attrs)); + if !has_pyo3_module_declared::( + &item_struct.attrs, + "pyclass", + |option| matches!(option, PyClassPyO3Option::Module(_)), + )? { + set_module_attribute(&mut item_struct.attrs, &full_name); + } + } + } + Item::Enum(item_enum) => { + ensure_spanned!( + !has_attribute(&item_enum.attrs, "pymodule_export"), + item.span() => "`#[pymodule_export]` may only be used on `use` or `const` statements" + ); + if has_attribute(&item_enum.attrs, "pyclass") + || has_attribute_with_namespace(&item_enum.attrs, Some(pyo3_path), &["pyclass"]) + || has_attribute_with_namespace( + &item_enum.attrs, + Some(pyo3_path), + &["prelude", "pyclass"], + ) + { + module_items.push(item_enum.ident.clone()); + module_items_cfg_attrs.push(get_cfg_attributes(&item_enum.attrs)); + if !has_pyo3_module_declared::( + &item_enum.attrs, + "pyclass", + |option| matches!(option, PyClassPyO3Option::Module(_)), + )? { + set_module_attribute(&mut item_enum.attrs, &full_name); + } + } + } + Item::Mod(item_mod) => { + ensure_spanned!( + !has_attribute(&item_mod.attrs, "pymodule_export"), + item.span() => "`#[pymodule_export]` may only be used on `use` or `const` statements" + ); + if has_attribute(&item_mod.attrs, "pymodule") + || has_attribute_with_namespace(&item_mod.attrs, Some(pyo3_path), &["pymodule"]) + || has_attribute_with_namespace( + &item_mod.attrs, + Some(pyo3_path), + &["prelude", "pymodule"], + ) + { + module_items.push(item_mod.ident.clone()); + module_items_cfg_attrs.push(get_cfg_attributes(&item_mod.attrs)); + if !has_pyo3_module_declared::( + &item_mod.attrs, + "pymodule", + |option| matches!(option, PyModulePyO3Option::Module(_)), + )? { + set_module_attribute(&mut item_mod.attrs, &full_name); + } + item_mod + .attrs + .push(parse_quote_spanned!(item_mod.mod_token.span()=> #[pyo3(submodule)])); + } + } + Item::ForeignMod(item) => { + ensure_spanned!( + !has_attribute(&item.attrs, "pymodule_export"), + item.span() => "`#[pymodule_export]` may only be used on `use` or `const` statements" + ); + } + Item::Trait(item) => { + ensure_spanned!( + !has_attribute(&item.attrs, "pymodule_export"), + item.span() => "`#[pymodule_export]` may only be used on `use` or `const` statements" + ); + } + Item::Const(item) => { + if !find_and_remove_attribute(&mut item.attrs, "pymodule_export") { + return Ok(()); + } + module_consts.push(item.ident.clone()); + module_consts_cfg_attrs.push(get_cfg_attributes(&item.attrs)); + #[cfg(feature = "experimental-inspect")] + { + let cfg_attrs = get_cfg_attributes(&item.attrs); + let chunk = attribute_introspection_code( + pyo3_path, + None, + item.ident.unraw().to_string(), + PyExpr::constant_from_expression(&item.expr), + (*item.ty).clone(), + get_doc(&item.attrs, None).as_ref(), + true, + ); + introspection_chunks.push(quote! { + #(#cfg_attrs)* + #chunk + }); + } + } + Item::Static(item) => { + ensure_spanned!( + !has_attribute(&item.attrs, "pymodule_export"), + item.span() => "`#[pymodule_export]` may only be used on `use` or `const` statements" + ); + } + Item::Macro(item) => { + ensure_spanned!( + !has_attribute(&item.attrs, "pymodule_export"), + item.span() => "`#[pymodule_export]` may only be used on `use` or `const` statements" + ); + } + Item::ExternCrate(item) => { + ensure_spanned!( + !has_attribute(&item.attrs, "pymodule_export"), + item.span() => "`#[pymodule_export]` may only be used on `use` or `const` statements" + ); + } + Item::Impl(item) => { + ensure_spanned!( + !has_attribute(&item.attrs, "pymodule_export"), + item.span() => "`#[pymodule_export]` may only be used on `use` or `const` statements" + ); + } + Item::TraitAlias(item) => { + ensure_spanned!( + !has_attribute(&item.attrs, "pymodule_export"), + item.span() => "`#[pymodule_export]` may only be used on `use` or `const` statements" + ); + } + Item::Type(item) => { + ensure_spanned!( + !has_attribute(&item.attrs, "pymodule_export"), + item.span() => "`#[pymodule_export]` may only be used on `use` or `const` statements" + ); + } + Item::Union(item) => { + ensure_spanned!( + !has_attribute(&item.attrs, "pymodule_export"), + item.span() => "`#[pymodule_export]` may only be used on `use` or `const` statements" + ); + } + _ => (), + } + Ok(()) + }).try_combine_syn_errors()?; + + #[cfg(feature = "experimental-inspect")] + let introspection = module_introspection_code( + pyo3_path, + &name.to_string(), + &module_items, + &module_items_cfg_attrs, + doc.as_ref(), + pymodule_init.is_some(), + ); + #[cfg(not(feature = "experimental-inspect"))] + let introspection = quote! {}; + #[cfg(feature = "experimental-inspect")] + let introspection_id = introspection_id_const(); + #[cfg(not(feature = "experimental-inspect"))] + let introspection_id = quote! {}; + + let gil_used = options.gil_used.is_some_and(|op| op.value.value); + + let initialization = module_initialization( + &full_name, + &name, + ctx, + quote! { __pyo3_pymodule }, + options.submodule.is_some(), + gil_used, + doc.as_ref(), + )?; + + let module_consts_names = module_consts.iter().map(|i| i.unraw().to_string()); + + Ok(quote!( + #(#attrs)* + #vis #mod_token #ident { + #(#items)* + + #initialization + #introspection + #introspection_id + #(#introspection_chunks)* + + fn __pyo3_pymodule(module: &#pyo3_path::Bound<'_, #pyo3_path::types::PyModule>) -> #pyo3_path::PyResult<()> { + use #pyo3_path::impl_::pymodule::PyAddToModule; + #( + #(#module_items_cfg_attrs)* + #module_items::_PYO3_DEF.add_to_module(module)?; + )* + + #( + #(#module_consts_cfg_attrs)* + #pyo3_path::types::PyModuleMethods::add(module, #module_consts_names, #module_consts)?; + )* + + #pymodule_init + ::std::result::Result::Ok(()) + } + } + )) +} + +/// Generates the function that is called by the python interpreter to initialize the native +/// module +pub fn pymodule_function_impl( + function: &mut syn::ItemFn, + mut options: PyModuleOptions, +) -> Result { + options.take_pyo3_options(&mut function.attrs)?; + process_functions_in_module(&options, function)?; + let ctx = &Ctx::new(&options.krate, None); + let Ctx { pyo3_path, .. } = ctx; + let ident = &function.sig.ident; + let name = options + .name + .map_or_else(|| ident.unraw(), |name| name.value.0); + let vis = &function.vis; + let doc = get_doc(&function.attrs, None); + + let gil_used = options.gil_used.is_some_and(|op| op.value.value); + + let initialization = module_initialization( + &name.to_string(), + &name, + ctx, + quote! { ModuleExec::__pyo3_module_exec }, + false, + gil_used, + doc.as_ref(), + )?; + + #[cfg(feature = "experimental-inspect")] + let introspection = module_introspection_code( + pyo3_path, + &name.unraw().to_string(), + &[], + &[], + doc.as_ref(), + true, + ); + #[cfg(not(feature = "experimental-inspect"))] + let introspection = quote! {}; + #[cfg(feature = "experimental-inspect")] + let introspection_id = introspection_id_const(); + #[cfg(not(feature = "experimental-inspect"))] + let introspection_id = quote! {}; + + // Module function called with optional Python<'_> marker as first arg, followed by the module. + let mut module_args = Vec::new(); + if function.sig.inputs.len() == 2 { + module_args.push(quote!(module.py())); + } + module_args.push(quote!(::std::convert::Into::into(module))); + + Ok(quote! { + #[doc(hidden)] + #vis mod #ident { + #initialization + #introspection + #introspection_id + } + + // Generate the definition inside an anonymous function in the same scope as the original function - + // this avoids complications around the fact that the generated module has a different scope + // (and `super` doesn't always refer to the outer scope, e.g. if the `#[pymodule] is + // inside a function body) + #[allow(unknown_lints, non_local_definitions)] + impl #ident::ModuleExec { + fn __pyo3_module_exec(module: &#pyo3_path::Bound<'_, #pyo3_path::types::PyModule>) -> #pyo3_path::PyResult<()> { + #ident(#(#module_args),*) + } + } + }) +} + +fn module_initialization( + full_name: &str, + name: &syn::Ident, + ctx: &Ctx, + module_exec: TokenStream, + is_submodule: bool, + gil_used: bool, + doc: Option<&PythonDoc>, +) -> Result { + let Ctx { pyo3_path, .. } = ctx; + let pyinit_symbol = format!("PyInit_{name}"); + let pymodexport_symbol = format!("PyModExport_{name}"); + let pyo3_name = LitCStr::new(&CString::new(full_name).unwrap(), Span::call_site()); + let doc = if let Some(doc) = doc { + doc.to_cstr_stream(ctx)? + } else { + c"".into_token_stream() + }; + + let mut result = quote! { + #[doc(hidden)] + pub static __PYO3_NAME: &'static ::std::ffi::CStr = #pyo3_name; + + // This structure exists for `fn` modules declared within `fn` bodies, where due to the hidden + // module (used for importing) the `fn` to initialize the module cannot be seen from the #module_def + // declaration just below. + #[doc(hidden)] + pub(super) struct ModuleExec; + + #[doc(hidden)] + pub static _PYO3_DEF: #pyo3_path::impl_::pymodule::ModuleDef = { + use #pyo3_path::impl_::pymodule as impl_; + + unsafe extern "C" fn __pyo3_module_exec(module: *mut #pyo3_path::ffi::PyObject) -> ::std::ffi::c_int { + #pyo3_path::impl_::trampoline::module_exec(module, #module_exec) + } + + static DOC: &'static ::std::ffi::CStr = #doc; + static SLOTS: impl_::PrimaryModuleSlots = impl_::PyModuleSlotsBuilder::new() + .with_mod_exec(__pyo3_module_exec) + .with_abi_info() + .with_gil_used(#gil_used) + .with_name(__PYO3_NAME) + .with_doc(DOC) + .build(); + static SECONDARY_SLOTS: impl_::SecondaryModuleSlots = impl_::secondary_slots(&SLOTS); + + // Since the macros need to be written agnostic to the Python version + // we need to explicitly pass the name and docstring for PyModuleDef + // initialization. + impl_::ModuleDef::new(__PYO3_NAME, DOC, &SLOTS, &SECONDARY_SLOTS) + }; + }; + if !is_submodule { + result.extend(quote! { + // We want to define only one or the other of these initialization functions + // so we implement them in macros to allow the version gating to live there + + // Defines the `PyInit_` entry point used by Python 3.14 and older. + #pyo3_path::__pyo3_pyinit!(#pyinit_symbol, _PYO3_DEF); + + // Defines the `PyModExport_` entry point used by Python 3.15 and newer. + #pyo3_path::__pyo3_pymodexport!(#pymodexport_symbol, _PYO3_DEF); + }); + } + Ok(result) +} + +/// Finds and takes care of the #[pyfn(...)] in `#[pymodule]` +fn process_functions_in_module(options: &PyModuleOptions, func: &mut syn::ItemFn) -> Result<()> { + let ctx = &Ctx::new(&options.krate, None); + let Ctx { pyo3_path, .. } = ctx; + let mut stmts: Vec = Vec::new(); + + for mut stmt in func.block.stmts.drain(..) { + if let syn::Stmt::Item(Item::Fn(func)) = &mut stmt { + if let Some((pyfn_span, pyfn_args)) = get_pyfn_attr(&mut func.attrs)? { + let module_name = pyfn_args.modname; + let wrapped_function = impl_wrap_pyfunction(func, pyfn_args.options)?; + let name = &func.sig.ident; + let statements: Vec = syn::parse_quote_spanned! { + pyfn_span => + #wrapped_function + { + use #pyo3_path::types::PyModuleMethods; + #module_name.add_function(#pyo3_path::wrap_pyfunction!(#name, #module_name.as_borrowed())?)?; + #[deprecated(note = "`pyfn` will be removed in a future PyO3 version, use declarative `#[pymodule]` with `mod` instead")] + #[allow(dead_code)] + const PYFN_ATTRIBUTE: () = (); + const _: () = PYFN_ATTRIBUTE; + } + }; + stmts.extend(statements); + } + }; + stmts.push(stmt); + } + + func.block.stmts = stmts; + Ok(()) +} + +pub struct PyFnArgs { + modname: Path, + options: PyFunctionOptions, +} + +impl Parse for PyFnArgs { + fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result { + let modname = input.parse().map_err( + |e| err_spanned!(e.span() => "expected module as first argument to #[pyfn()]"), + )?; + + if input.is_empty() { + return Ok(Self { + modname, + options: Default::default(), + }); + } + + let _: Comma = input.parse()?; + + Ok(Self { + modname, + options: input.parse()?, + }) + } +} + +/// Extracts the data from the #[pyfn(...)] attribute of a function +fn get_pyfn_attr(attrs: &mut Vec) -> syn::Result> { + let mut pyfn_args: Option<(Span, PyFnArgs)> = None; + + take_attributes(attrs, |attr| { + if attr.path().is_ident("pyfn") { + ensure_spanned!( + pyfn_args.is_none(), + attr.span() => "`#[pyfn] may only be specified once" + ); + pyfn_args = Some((attr.path().span(), attr.parse_args()?)); + Ok(true) + } else { + Ok(false) + } + })?; + + if let Some((_, pyfn_args)) = &mut pyfn_args { + pyfn_args + .options + .add_attributes(take_pyo3_options(attrs)?)?; + } + + Ok(pyfn_args) +} + +fn get_cfg_attributes(attrs: &[syn::Attribute]) -> Vec { + attrs + .iter() + .filter(|attr| attr.path().is_ident("cfg")) + .cloned() + .collect() +} + +fn find_and_remove_attribute(attrs: &mut Vec, ident: &str) -> bool { + let mut found = false; + attrs.retain(|attr| { + if attr.path().is_ident(ident) { + found = true; + false + } else { + true + } + }); + found +} + +impl PartialEq for IdentOrStr<'_> { + fn eq(&self, other: &syn::Ident) -> bool { + match self { + IdentOrStr::Str(s) => other == s, + IdentOrStr::Ident(i) => other == i, + } + } +} + +fn set_module_attribute(attrs: &mut Vec, module_name: &str) { + attrs.push(parse_quote!(#[pyo3(module = #module_name)])); +} + +fn has_pyo3_module_declared( + attrs: &[syn::Attribute], + root_attribute_name: &str, + is_module_option: impl Fn(&T) -> bool + Copy, +) -> Result { + for attr in attrs { + if (attr.path().is_ident("pyo3") || attr.path().is_ident(root_attribute_name)) + && matches!(attr.meta, Meta::List(_)) + { + for option in &attr.parse_args_with(Punctuated::::parse_terminated)? { + if is_module_option(option) { + return Ok(true); + } + } + } + } + Ok(false) +} + +enum PyModulePyO3Option { + Submodule(SubmoduleAttribute), + Crate(CrateAttribute), + Name(NameAttribute), + Module(ModuleAttribute), + GILUsed(GILUsedAttribute), +} + +impl Parse for PyModulePyO3Option { + fn parse(input: ParseStream<'_>) -> Result { + let lookahead = input.lookahead1(); + if lookahead.peek(attributes::kw::name) { + input.parse().map(PyModulePyO3Option::Name) + } else if lookahead.peek(syn::Token![crate]) { + input.parse().map(PyModulePyO3Option::Crate) + } else if lookahead.peek(attributes::kw::module) { + input.parse().map(PyModulePyO3Option::Module) + } else if lookahead.peek(attributes::kw::submodule) { + input.parse().map(PyModulePyO3Option::Submodule) + } else if lookahead.peek(attributes::kw::gil_used) { + input.parse().map(PyModulePyO3Option::GILUsed) + } else { + Err(lookahead.error()) + } + } +} diff --git a/vendor/pyo3-macros-backend/src/params.rs b/vendor/pyo3-macros-backend/src/params.rs new file mode 100644 index 0000000..305cf06 --- /dev/null +++ b/vendor/pyo3-macros-backend/src/params.rs @@ -0,0 +1,318 @@ +use crate::utils::Ctx; +use crate::{ + attributes::FromPyWithAttribute, + method::{FnArg, FnSpec, RegularArg}, + pyfunction::FunctionSignature, + quotes::some_wrap, +}; +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote, quote_spanned}; +use syn::spanned::Spanned; + +pub struct Holders { + holders: Vec, +} + +impl Holders { + pub fn new() -> Self { + Holders { + holders: Vec::new(), + } + } + + pub fn push_holder(&mut self, span: Span) -> syn::Ident { + let holder = syn::Ident::new(&format!("holder_{}", self.holders.len()), span); + self.holders.push(holder.clone()); + holder + } + + pub fn init_holders(&self, ctx: &Ctx) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + let holders = &self.holders; + quote! { + #[allow(clippy::let_unit_value, reason = "many holders are just `()`")] + #(let mut #holders = #pyo3_path::impl_::extract_argument::FunctionArgumentHolder::INIT;)* + } + } +} + +/// Return true if the argument list is simply (*args, **kwds). +pub fn is_forwarded_args(signature: &FunctionSignature<'_>) -> bool { + matches!( + signature.arguments.as_slice(), + [FnArg::VarArgs(..), FnArg::KwArgs(..),] + ) +} + +pub fn impl_arg_params( + spec: &FnSpec<'_>, + self_: Option<&syn::Type>, + fastcall: bool, + holders: &mut Holders, + ctx: &Ctx, +) -> (TokenStream, Vec) { + let args_array = syn::Ident::new("output", Span::call_site()); + let Ctx { pyo3_path, .. } = ctx; + + let from_py_with = spec + .signature + .arguments + .iter() + .enumerate() + .filter_map(|(i, arg)| { + let from_py_with = &arg.from_py_with()?.value; + let from_py_with_holder = format_ident!("from_py_with_{}", i); + Some(quote_spanned! { from_py_with.span() => + let #from_py_with_holder = #from_py_with; + }) + }) + .collect::(); + + if !fastcall && is_forwarded_args(&spec.signature) { + // In the varargs convention, we can just pass though if the signature + // is (*args, **kwds). + let arg_convert = spec + .signature + .arguments + .iter() + .enumerate() + .map(|(i, arg)| impl_arg_param(arg, i, &mut 0, holders, ctx)) + .collect(); + return ( + quote! { + let _args = unsafe { #pyo3_path::impl_::extract_argument::cast_function_argument(py, _args) }; + let _kwargs = unsafe { #pyo3_path::impl_::extract_argument::cast_optional_function_argument(py, _kwargs) }; + #from_py_with + }, + arg_convert, + ); + }; + + let positional_parameter_names = &spec.signature.python_signature.positional_parameters; + let positional_only_parameters = &spec.signature.python_signature.positional_only_parameters; + let required_positional_parameters = spec + .signature + .python_signature + .required_positional_parameters(); + let keyword_only_parameters = spec + .signature + .python_signature + .keyword_only_parameters + .iter() + .map(|(name, default_value)| { + let required = default_value.is_none(); + quote! { + #pyo3_path::impl_::extract_argument::KeywordOnlyParameterDescription { + name: #name, + required: #required, + } + } + }); + + let num_params = positional_parameter_names.len() + keyword_only_parameters.len(); + + let mut option_pos = 0usize; + let param_conversion = spec + .signature + .arguments + .iter() + .enumerate() + .map(|(i, arg)| impl_arg_param(arg, i, &mut option_pos, holders, ctx)) + .collect(); + + let args_handler = if spec.signature.python_signature.varargs.is_some() { + quote! { #pyo3_path::impl_::extract_argument::TupleVarargs } + } else { + quote! { #pyo3_path::impl_::extract_argument::NoVarargs } + }; + let kwargs_handler = if spec.signature.python_signature.kwargs.is_some() { + quote! { #pyo3_path::impl_::extract_argument::DictVarkeywords } + } else { + quote! { #pyo3_path::impl_::extract_argument::NoVarkeywords } + }; + + let cls_name = if let Some(cls) = self_ { + quote! { ::std::option::Option::Some(<#cls as #pyo3_path::PyClass>::NAME) } + } else { + quote! { ::std::option::Option::None } + }; + let python_name = &spec.python_name; + + let extract_expression = if fastcall { + quote! { + #pyo3_path::impl_::pymethods::maybe_extract_arguments_fastcall!( + DESCRIPTION, + py, + _args, + _nargs, + _kwargs, + #args_array, + #args_handler, + #kwargs_handler + )? + } + } else { + quote! { + DESCRIPTION.extract_arguments_tuple_dict::<#args_handler, #kwargs_handler>( + py, + _args, + _kwargs, + &mut #args_array + )? + } + }; + + // create array of arguments, and then parse + ( + quote! { + const DESCRIPTION: #pyo3_path::impl_::extract_argument::FunctionDescription = #pyo3_path::impl_::extract_argument::FunctionDescription { + cls_name: #cls_name, + func_name: stringify!(#python_name), + positional_parameter_names: &[#(#positional_parameter_names),*], + positional_only_parameters: #positional_only_parameters, + required_positional_parameters: #required_positional_parameters, + keyword_only_parameters: &[#(#keyword_only_parameters),*], + }; + let mut #args_array = [::std::option::Option::None; #num_params]; + let (_args, _kwargs) = #extract_expression; + #from_py_with + }, + param_conversion, + ) +} + +fn impl_arg_param( + arg: &FnArg<'_>, + pos: usize, + option_pos: &mut usize, + holders: &mut Holders, + ctx: &Ctx, +) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + let args_array = syn::Ident::new("output", Span::call_site()); + + match arg { + FnArg::Regular(arg) => { + let from_py_with = format_ident!("from_py_with_{}", pos); + let arg_value = quote!(#args_array[#option_pos]); + *option_pos += 1; + impl_regular_arg_param(arg, from_py_with, arg_value, holders, ctx) + } + FnArg::VarArgs(arg) => { + let span = Span::call_site().located_at(arg.ty.span()); + let holder = holders.push_holder(span); + let name_str = arg.name.to_string(); + quote_spanned! { span => + #pyo3_path::impl_::extract_argument::extract_argument( + _args.as_any().as_borrowed(), + &mut #holder, + #name_str + )? + } + } + FnArg::KwArgs(arg) => { + let span = Span::call_site().located_at(arg.ty.span()); + let holder = holders.push_holder(span); + let name_str = arg.name.to_string(); + quote_spanned! { span => + #pyo3_path::impl_::extract_argument::extract_argument_with_default( + _kwargs.as_ref().map(|d| d.as_any().as_borrowed()), + &mut #holder, + #name_str, + || ::std::option::Option::None + )? + } + } + FnArg::Py(arg) => { + let span = Span::call_site().located_at(arg.ty.span()); + quote_spanned! { span => py } + } + FnArg::CancelHandle(arg) => { + let span = Span::call_site().located_at(arg.ty.span()); + quote_spanned! { span => __cancel_handle } + } + } +} + +/// Re option_pos: The option slice doesn't contain the py: Python argument, so the argument +/// index and the index in option diverge when using py: Python +pub(crate) fn impl_regular_arg_param( + arg: &RegularArg<'_>, + from_py_with: syn::Ident, + arg_value: TokenStream, // expected type: Option<&'a Bound<'py, PyAny>> + holders: &mut Holders, + ctx: &Ctx, +) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + let pyo3_path = pyo3_path.to_tokens_spanned(arg.ty.span()); + + // Use this macro inside this function, to ensure that all code generated here is associated + // with the function argument + let use_probe = quote! { + #[allow(unused_imports, reason = "`Probe` trait used on negative case only")] + use #pyo3_path::impl_::pyclass::Probe as _; + }; + macro_rules! quote_arg_span { + ($($tokens:tt)*) => { quote_spanned!(arg.ty.span() => { #use_probe $($tokens)* }) } + } + + let name_str = arg.name.to_string(); + let mut default = arg.default_value.as_ref().map(|expr| quote!(#expr)); + + // Option arguments have special treatment: the default should be specified _without_ the + // Some() wrapper. Maybe this should be changed in future?! + if arg.option_wrapped_type.is_some() { + default = default.map(|tokens| some_wrap(tokens, ctx)); + } + + if let Some(FromPyWithAttribute { kw, .. }) = &arg.from_py_with.as_deref() { + let extractor = quote_spanned! { kw.span => + { let from_py_with: fn(_) -> _ = #from_py_with; from_py_with } + }; + if let Some(default) = default { + quote_arg_span! { + #pyo3_path::impl_::extract_argument::from_py_with_with_default( + #arg_value.as_deref(), + #name_str, + #extractor, + #[allow(clippy::redundant_closure, reason = "wrapping user-provided default expression")] + { + || #default + } + )? + } + } else { + let unwrap = quote! {unsafe { #pyo3_path::impl_::extract_argument::unwrap_required_argument_bound(#arg_value.as_deref()) }}; + quote_arg_span! { + #pyo3_path::impl_::extract_argument::from_py_with( + #unwrap, + #name_str, + #extractor, + )? + } + } + } else if let Some(default) = default { + let holder = holders.push_holder(arg.ty.span()); + quote_arg_span! { + #pyo3_path::impl_::extract_argument::extract_argument_with_default( + #arg_value, + &mut #holder, + #name_str, + #[allow(clippy::redundant_closure, reason = "wrapping user-provided default expression")] + { + || #default + } + )? + } + } else { + let holder = holders.push_holder(arg.ty.span()); + let unwrap = quote! { unsafe { #pyo3_path::impl_::extract_argument::unwrap_required_argument(#arg_value) } }; + quote_arg_span! { + #pyo3_path::impl_::extract_argument::extract_argument( + #unwrap, + &mut #holder, + #name_str + )? + } + } +} diff --git a/vendor/pyo3-macros-backend/src/py_expr.rs b/vendor/pyo3-macros-backend/src/py_expr.rs new file mode 100644 index 0000000..893addc --- /dev/null +++ b/vendor/pyo3-macros-backend/src/py_expr.rs @@ -0,0 +1,322 @@ +//! Define a data structure for Python type hints, mixing static data from macros and call to Pyo3 constants. + +use crate::utils::PyO3CratePath; +use proc_macro2::TokenStream; +use quote::quote; +use std::borrow::Cow; +use syn::visit_mut::{visit_type_mut, VisitMut}; +use syn::{Expr, ExprLit, ExprPath, Lit, Type}; + +/// A Python expression +/// +/// Please do not construct directly but use the constructor methods that normalize the expression +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum PyExpr { + /// The Python type hint of a FromPyObject implementation + FromPyObjectType(Type), + /// The Python type hint of a IntoPyObject implementation + IntoPyObjectType(Type), + /// The Python type hint of a IntoPyObject implementation on the ref type or the base type + IntoPyObjectMaybeRefType(Type), + /// The Python type matching the given Rust type given as a function argument + ArgumentType(Type), + /// The Python type matching the given Rust type given as a function returned value + ReturnType(Type), + /// The Python type matching the given Rust type + Type(Type), + /// A name + Name { id: Cow<'static, str> }, + /// An attribute `value.attr` + Attribute { + value: Box, + attr: Cow<'static, str>, + }, + /// A binary operator + BinOp { + left: Box, + op: PyOperator, + right: Box, + }, + /// A tuple + Tuple { elts: Vec }, + /// A subscript `value[slice]` + Subscript { value: Box, slice: Box }, + /// A constant + Constant(PyConstant), +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum PyOperator { + /// `|` operator + BitOr, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum PyConstant { + /// None + None, + /// The `True` and `False` booleans + Bool(bool), + /// `int` value written in base 10 ([+-]?[0-9]+) + Int(String), + /// `float` value written in base-10 ([+-]?[0-9]*(.[0-9]*)*([eE])[0-9]*), not including Inf and NaN + Float(String), + /// `str` value unescaped and without quotes + Str(String), + /// `...` + Ellipsis, +} + +impl PyExpr { + /// Build from a builtins name like `str` + pub fn builtin(name: impl Into>) -> Self { + Self::Name { id: name.into() } + } + + /// Build from a module and a name like `collections.abc` and `Sequence` + pub fn module_attr( + module: impl Into>, + name: impl Into>, + ) -> Self { + Self::attribute(Self::Name { id: module.into() }, name) + } + + /// The type hint of a `FromPyObject` implementation as a function argument + /// + /// If self_type is set, self_type will replace Self in the given type + pub fn from_from_py_object(t: Type, self_type: Option<&Type>) -> Self { + Self::FromPyObjectType(clean_type(t, self_type)) + } + + /// The type hint of a `IntoPyObject` implementation as a function argument + /// + /// If self_type is set, self_type will replace Self in the given type + pub fn from_into_py_object(t: Type, self_type: Option<&Type>) -> Self { + Self::IntoPyObjectType(clean_type(t, self_type)) + } + + /// The type hint of a `IntoPyObject` implementation used by a field getter + /// + /// If self_type is set, self_type will replace Self in the given type + pub fn from_into_py_object_maybe_ref(t: Type, self_type: Option<&Type>) -> Self { + Self::IntoPyObjectMaybeRefType(clean_type(t, self_type)) + } + + /// The type hint of the Rust type used as a function argument + /// + /// If self_type is set, self_type will replace Self in the given type + pub fn from_argument_type(t: Type, self_type: Option<&Type>) -> Self { + Self::ArgumentType(clean_type(t, self_type)) + } + + /// The type hint of the Rust type used as a function output type + /// + /// If self_type is set, self_type will replace Self in the given type + pub fn from_return_type(t: Type, self_type: Option<&Type>) -> Self { + Self::ReturnType(clean_type(t, self_type)) + } + + /// The type hint of the Rust type `PyTypeCheck` trait. + /// + /// If self_type is set, self_type will replace Self in the given type + pub fn from_type(t: Type, self_type: Option<&Type>) -> Self { + Self::Type(clean_type(t, self_type)) + } + + /// An attribute of a given value: `value.attr` + pub fn attribute(value: Self, attr: impl Into>) -> Self { + Self::Attribute { + value: Box::new(value), + attr: attr.into(), + } + } + + /// Build the union of the different element + pub fn union(left: Self, right: Self) -> Self { + Self::BinOp { + left: Box::new(left), + op: PyOperator::BitOr, + right: Box::new(right), + } + } + + /// Build the subscripted type value[slice] + pub fn subscript(value: Self, slice: Self) -> Self { + Self::Subscript { + value: Box::new(value), + slice: Box::new(slice), + } + } + + /// Build a tuple + pub fn tuple(elts: impl IntoIterator) -> Self { + Self::Tuple { + elts: elts.into_iter().collect(), + } + } + + pub fn constant_from_expression(expr: &Expr) -> Self { + Self::Constant(match expr { + Expr::Lit(ExprLit { lit, .. }) => match lit { + Lit::Str(s) => PyConstant::Str(s.value()), + Lit::Char(c) => PyConstant::Str(c.value().into()), + Lit::Int(i) => PyConstant::Int(i.base10_digits().into()), + Lit::Float(f) => PyConstant::Float(f.base10_digits().into()), + Lit::Bool(b) => PyConstant::Bool(b.value()), + _ => PyConstant::Ellipsis, // TODO: implement ByteStr and CStr + }, + Expr::Path(ExprPath { qself, path, .. }) + if qself.is_none() && path.is_ident("None") => + { + PyConstant::None + } + _ => PyConstant::Ellipsis, + }) + } + + pub fn str_constant(value: impl Into) -> Self { + Self::Constant(PyConstant::Str(value.into())) + } + + /// `...` + pub fn ellipsis() -> Self { + Self::Constant(PyConstant::Ellipsis) + } + + /// `None` + pub fn none() -> Self { + Self::Constant(PyConstant::None) + } + + pub fn to_introspection_token_stream(&self, pyo3_crate_path: &PyO3CratePath) -> TokenStream { + match self { + Self::FromPyObjectType(t) => { + quote! { <#t as #pyo3_crate_path::FromPyObject<'_, '_>>::INPUT_TYPE } + } + Self::IntoPyObjectType(t) => { + quote! { <#t as #pyo3_crate_path::IntoPyObject<'_>>::OUTPUT_TYPE } + } + Self::IntoPyObjectMaybeRefType(t) => { + quote! {{ + #[allow(unused_imports)] + use #pyo3_crate_path::impl_::pyclass::Probe as _; + <#t as #pyo3_crate_path::impl_::introspection::PyIntoPyObjectMaybeRefType<{ + #pyo3_crate_path::impl_::pyclass::IsIntoPyObjectRef::<#t>::VALUE + }>>::OUTPUT_TYPE + }} + } + Self::ArgumentType(t) => { + quote! { + <#t as #pyo3_crate_path::impl_::extract_argument::PyFunctionArgument< + { + #[allow(unused_imports, reason = "`Probe` trait used on negative case only")] + use #pyo3_crate_path::impl_::pyclass::Probe as _; + #pyo3_crate_path::impl_::pyclass::IsFromPyObject::<#t>::VALUE + } + >>::INPUT_TYPE + } + } + Self::ReturnType(t) => { + quote! {{ + #[allow(unused_imports)] + use #pyo3_crate_path::impl_::pyclass::Probe as _; + const TYPE: #pyo3_crate_path::inspect::PyStaticExpr = if #pyo3_crate_path::impl_::pyclass::IsReturningEmptyTuple::<#t>::VALUE { + <#pyo3_crate_path::types::PyNone as #pyo3_crate_path::type_object::PyTypeInfo>::TYPE_HINT + } else { + <#t as #pyo3_crate_path::impl_::introspection::PyReturnType>::OUTPUT_TYPE + }; + TYPE + }} + } + Self::Type(t) => { + quote! { <#t as #pyo3_crate_path::type_object::PyTypeCheck>::TYPE_HINT } + } + Self::Name { id } => { + quote! { #pyo3_crate_path::inspect::PyStaticExpr::Name { id: #id } } + } + Self::Attribute { value, attr } => { + let value = value.to_introspection_token_stream(pyo3_crate_path); + quote! { #pyo3_crate_path::inspect::PyStaticExpr::Attribute { value: &#value, attr: #attr } } + } + Self::BinOp { left, op, right } => { + let left = left.to_introspection_token_stream(pyo3_crate_path); + let op = match op { + PyOperator::BitOr => quote!(#pyo3_crate_path::inspect::PyStaticOperator::BitOr), + }; + let right = right.to_introspection_token_stream(pyo3_crate_path); + quote! { + #pyo3_crate_path::inspect::PyStaticExpr::BinOp { + left: &#left, + op: #op, + right: &#right, + } + } + } + Self::Subscript { value, slice } => { + let value = value.to_introspection_token_stream(pyo3_crate_path); + let slice = slice.to_introspection_token_stream(pyo3_crate_path); + quote! { #pyo3_crate_path::inspect::PyStaticExpr::Subscript { value: &#value, slice: &#slice } } + } + Self::Tuple { elts } => { + let elts = elts + .iter() + .map(|e| e.to_introspection_token_stream(pyo3_crate_path)); + quote! { #pyo3_crate_path::inspect::PyStaticExpr::Tuple { elts: &[#(#elts),*] } } + } + Self::Constant(c) => match c { + PyConstant::None => { + quote! { #pyo3_crate_path::inspect::PyStaticExpr::Constant { value: #pyo3_crate_path::inspect::PyStaticConstant::None } } + } + PyConstant::Bool(v) => { + quote! { #pyo3_crate_path::inspect::PyStaticExpr::Constant { value: #pyo3_crate_path::inspect::PyStaticConstant::Bool(#v) } } + } + PyConstant::Int(v) => { + quote! { #pyo3_crate_path::inspect::PyStaticExpr::Constant { value: #pyo3_crate_path::inspect::PyStaticConstant::Int(#v) } } + } + PyConstant::Float(v) => { + quote! { #pyo3_crate_path::inspect::PyStaticExpr::Constant { value: #pyo3_crate_path::inspect::PyStaticConstant::Float(#v) } } + } + PyConstant::Str(v) => { + quote! { #pyo3_crate_path::inspect::PyStaticExpr::Constant { value: #pyo3_crate_path::inspect::PyStaticConstant::Str(#v) } } + } + PyConstant::Ellipsis => { + quote! { #pyo3_crate_path::inspect::PyStaticExpr::Constant { value: #pyo3_crate_path::inspect::PyStaticConstant::Ellipsis } } + } + }, + } + } +} + +fn clean_type(mut t: Type, self_type: Option<&Type>) -> Type { + if let Some(self_type) = self_type { + replace_self(&mut t, self_type); + } + crate::utils::elide_lifetimes(&mut t); + t +} + +// Replace Self in types with the given type +fn replace_self(ty: &mut Type, self_target: &Type) { + struct SelfReplacementVisitor<'a> { + self_target: &'a Type, + } + + impl VisitMut for SelfReplacementVisitor<'_> { + fn visit_type_mut(&mut self, ty: &mut Type) { + if let Type::Path(type_path) = ty { + if type_path.qself.is_none() + && type_path.path.segments.len() == 1 + && type_path.path.segments[0].ident == "Self" + && type_path.path.segments[0].arguments.is_empty() + { + // It is Self + *ty = self.self_target.clone(); + return; + } + } + visit_type_mut(self, ty); + } + } + + SelfReplacementVisitor { self_target }.visit_type_mut(ty); +} diff --git a/vendor/pyo3-macros-backend/src/pyclass.rs b/vendor/pyo3-macros-backend/src/pyclass.rs new file mode 100644 index 0000000..a9c55ca --- /dev/null +++ b/vendor/pyo3-macros-backend/src/pyclass.rs @@ -0,0 +1,3249 @@ +use std::borrow::Cow; +use std::fmt::Debug; + +use proc_macro2::{Ident, Span, TokenStream}; +use quote::{format_ident, quote, quote_spanned, ToTokens}; +use syn::ext::IdentExt; +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::{parse_quote, parse_quote_spanned, spanned::Spanned, ImplItemFn, Result, Token}; + +use crate::attributes::kw::frozen; +use crate::attributes::{ + self, kw, take_pyo3_options, CrateAttribute, ExtendsAttribute, FreelistAttribute, + ModuleAttribute, NameAttribute, NameLitStr, NewImplTypeAttribute, NewImplTypeAttributeValue, + RenameAllAttribute, StrFormatterAttribute, +}; +use crate::combine_errors::CombineErrors; +#[cfg(feature = "experimental-inspect")] +use crate::introspection::{ + attribute_introspection_code, class_introspection_code, function_introspection_code, + introspection_id_const, +}; +use crate::konst::{ConstAttributes, ConstSpec}; +use crate::method::{FnArg, FnSpec, PyArg, RegularArg}; +#[cfg(feature = "experimental-inspect")] +use crate::py_expr::PyExpr; +use crate::pyfunction::{ConstructorAttribute, FunctionSignature}; +#[cfg(feature = "experimental-inspect")] +use crate::pyimpl::method_introspection_code; +use crate::pyimpl::{gen_py_const, get_cfg_attributes, PyClassMethodsType}; +#[cfg(feature = "experimental-inspect")] +use crate::pymethod::field_python_name; +use crate::pymethod::{ + impl_py_class_attribute, impl_py_getter_def, impl_py_setter_def, MethodAndMethodDef, + MethodAndSlotDef, PropertyType, SlotDef, __GETITEM__, __HASH__, __INT__, __LEN__, __NEW__, + __REPR__, __RICHCMP__, __STR__, +}; +use crate::utils::{self, apply_renaming_rule, get_doc, locate_tokens_at, Ctx, PythonDoc}; +use crate::PyFunctionOptions; + +/// If the class is derived from a Rust `struct` or `enum`. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum PyClassKind { + Struct, + Enum, +} + +/// The parsed arguments of the pyclass macro +#[derive(Clone)] +pub struct PyClassArgs { + pub class_kind: PyClassKind, + pub options: PyClassPyO3Options, +} + +impl PyClassArgs { + fn parse(input: ParseStream<'_>, kind: PyClassKind) -> Result { + Ok(PyClassArgs { + class_kind: kind, + options: PyClassPyO3Options::parse(input)?, + }) + } + + pub fn parse_struct_args(input: ParseStream<'_>) -> syn::Result { + Self::parse(input, PyClassKind::Struct) + } + + pub fn parse_enum_args(input: ParseStream<'_>) -> syn::Result { + Self::parse(input, PyClassKind::Enum) + } +} + +#[derive(Clone, Default)] +pub struct PyClassPyO3Options { + pub krate: Option, + pub dict: Option, + pub eq: Option, + pub eq_int: Option, + pub extends: Option, + pub get_all: Option, + pub freelist: Option, + pub frozen: Option, + pub hash: Option, + pub immutable_type: Option, + pub mapping: Option, + pub module: Option, + pub name: Option, + pub ord: Option, + pub rename_all: Option, + pub sequence: Option, + pub set_all: Option, + pub new: Option, + pub str: Option, + pub subclass: Option, + pub unsendable: Option, + pub weakref: Option, + pub generic: Option, + pub from_py_object: Option, + pub skip_from_py_object: Option, +} + +pub enum PyClassPyO3Option { + Crate(CrateAttribute), + Dict(kw::dict), + Eq(kw::eq), + EqInt(kw::eq_int), + Extends(ExtendsAttribute), + Freelist(FreelistAttribute), + Frozen(kw::frozen), + GetAll(kw::get_all), + Hash(kw::hash), + ImmutableType(kw::immutable_type), + Mapping(kw::mapping), + Module(ModuleAttribute), + Name(NameAttribute), + Ord(kw::ord), + RenameAll(RenameAllAttribute), + Sequence(kw::sequence), + SetAll(kw::set_all), + New(NewImplTypeAttribute), + Str(StrFormatterAttribute), + Subclass(kw::subclass), + Unsendable(kw::unsendable), + Weakref(kw::weakref), + Generic(kw::generic), + FromPyObject(kw::from_py_object), + SkipFromPyObject(kw::skip_from_py_object), +} + +impl Parse for PyClassPyO3Option { + fn parse(input: ParseStream<'_>) -> Result { + let lookahead = input.lookahead1(); + if lookahead.peek(Token![crate]) { + input.parse().map(PyClassPyO3Option::Crate) + } else if lookahead.peek(kw::dict) { + input.parse().map(PyClassPyO3Option::Dict) + } else if lookahead.peek(kw::eq) { + input.parse().map(PyClassPyO3Option::Eq) + } else if lookahead.peek(kw::eq_int) { + input.parse().map(PyClassPyO3Option::EqInt) + } else if lookahead.peek(kw::extends) { + input.parse().map(PyClassPyO3Option::Extends) + } else if lookahead.peek(attributes::kw::freelist) { + input.parse().map(PyClassPyO3Option::Freelist) + } else if lookahead.peek(attributes::kw::frozen) { + input.parse().map(PyClassPyO3Option::Frozen) + } else if lookahead.peek(attributes::kw::get_all) { + input.parse().map(PyClassPyO3Option::GetAll) + } else if lookahead.peek(attributes::kw::hash) { + input.parse().map(PyClassPyO3Option::Hash) + } else if lookahead.peek(attributes::kw::immutable_type) { + input.parse().map(PyClassPyO3Option::ImmutableType) + } else if lookahead.peek(attributes::kw::mapping) { + input.parse().map(PyClassPyO3Option::Mapping) + } else if lookahead.peek(attributes::kw::module) { + input.parse().map(PyClassPyO3Option::Module) + } else if lookahead.peek(kw::name) { + input.parse().map(PyClassPyO3Option::Name) + } else if lookahead.peek(attributes::kw::ord) { + input.parse().map(PyClassPyO3Option::Ord) + } else if lookahead.peek(kw::rename_all) { + input.parse().map(PyClassPyO3Option::RenameAll) + } else if lookahead.peek(attributes::kw::sequence) { + input.parse().map(PyClassPyO3Option::Sequence) + } else if lookahead.peek(attributes::kw::set_all) { + input.parse().map(PyClassPyO3Option::SetAll) + } else if lookahead.peek(attributes::kw::new) { + input.parse().map(PyClassPyO3Option::New) + } else if lookahead.peek(attributes::kw::str) { + input.parse().map(PyClassPyO3Option::Str) + } else if lookahead.peek(attributes::kw::subclass) { + input.parse().map(PyClassPyO3Option::Subclass) + } else if lookahead.peek(attributes::kw::unsendable) { + input.parse().map(PyClassPyO3Option::Unsendable) + } else if lookahead.peek(attributes::kw::weakref) { + input.parse().map(PyClassPyO3Option::Weakref) + } else if lookahead.peek(attributes::kw::generic) { + input.parse().map(PyClassPyO3Option::Generic) + } else if lookahead.peek(attributes::kw::from_py_object) { + input.parse().map(PyClassPyO3Option::FromPyObject) + } else if lookahead.peek(attributes::kw::skip_from_py_object) { + input.parse().map(PyClassPyO3Option::SkipFromPyObject) + } else { + Err(lookahead.error()) + } + } +} + +impl Parse for PyClassPyO3Options { + fn parse(input: ParseStream<'_>) -> syn::Result { + let mut options: PyClassPyO3Options = Default::default(); + + for option in Punctuated::::parse_terminated(input)? { + options.set_option(option)?; + } + + Ok(options) + } +} + +impl PyClassPyO3Options { + pub fn take_pyo3_options(&mut self, attrs: &mut Vec) -> syn::Result<()> { + take_pyo3_options(attrs)? + .into_iter() + .try_for_each(|option| self.set_option(option)) + } + + fn set_option(&mut self, option: PyClassPyO3Option) -> syn::Result<()> { + macro_rules! set_option { + ($key:ident) => { + { + ensure_spanned!( + self.$key.is_none(), + $key.span() => concat!("`", stringify!($key), "` may only be specified once") + ); + self.$key = Some($key); + } + }; + } + + match option { + PyClassPyO3Option::Crate(krate) => set_option!(krate), + PyClassPyO3Option::Dict(dict) => set_option!(dict), + PyClassPyO3Option::Eq(eq) => set_option!(eq), + PyClassPyO3Option::EqInt(eq_int) => set_option!(eq_int), + PyClassPyO3Option::Extends(extends) => set_option!(extends), + PyClassPyO3Option::Freelist(freelist) => set_option!(freelist), + PyClassPyO3Option::Frozen(frozen) => set_option!(frozen), + PyClassPyO3Option::GetAll(get_all) => set_option!(get_all), + PyClassPyO3Option::ImmutableType(immutable_type) => { + set_option!(immutable_type) + } + PyClassPyO3Option::Hash(hash) => set_option!(hash), + PyClassPyO3Option::Mapping(mapping) => set_option!(mapping), + PyClassPyO3Option::Module(module) => set_option!(module), + PyClassPyO3Option::Name(name) => set_option!(name), + PyClassPyO3Option::Ord(ord) => set_option!(ord), + PyClassPyO3Option::RenameAll(rename_all) => set_option!(rename_all), + PyClassPyO3Option::Sequence(sequence) => set_option!(sequence), + PyClassPyO3Option::SetAll(set_all) => set_option!(set_all), + PyClassPyO3Option::New(new) => set_option!(new), + PyClassPyO3Option::Str(str) => set_option!(str), + PyClassPyO3Option::Subclass(subclass) => set_option!(subclass), + PyClassPyO3Option::Unsendable(unsendable) => set_option!(unsendable), + PyClassPyO3Option::Weakref(weakref) => set_option!(weakref), + PyClassPyO3Option::Generic(generic) => set_option!(generic), + PyClassPyO3Option::SkipFromPyObject(skip_from_py_object) => { + ensure_spanned!( + self.from_py_object.is_none(), + skip_from_py_object.span() => "`skip_from_py_object` and `from_py_object` are mutually exclusive" + ); + set_option!(skip_from_py_object) + } + PyClassPyO3Option::FromPyObject(from_py_object) => { + ensure_spanned!( + self.skip_from_py_object.is_none(), + from_py_object.span() => "`skip_from_py_object` and `from_py_object` are mutually exclusive" + ); + set_option!(from_py_object) + } + } + Ok(()) + } +} + +pub fn build_py_class( + class: &mut syn::ItemStruct, + mut args: PyClassArgs, + methods_type: PyClassMethodsType, +) -> syn::Result { + args.options.take_pyo3_options(&mut class.attrs)?; + + let ctx = &Ctx::new(&args.options.krate, None); + let doc = utils::get_doc(&class.attrs, None); + + if let Some(lt) = class.generics.lifetimes().next() { + bail_spanned!( + lt.span() => concat!( + "#[pyclass] cannot have lifetime parameters. For an explanation, see \ + https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#no-lifetime-parameters" + ) + ); + } + + ensure_spanned!( + class.generics.params.is_empty(), + class.generics.span() => concat!( + "#[pyclass] cannot have generic parameters. For an explanation, see \ + https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#no-generic-parameters" + ) + ); + + let mut field_options: Vec<(&syn::Field, FieldPyO3Options)> = match &mut class.fields { + syn::Fields::Named(fields) => fields + .named + .iter_mut() + .map( + |field| match FieldPyO3Options::take_pyo3_options(&mut field.attrs) { + Ok(options) => Ok((&*field, options)), + Err(e) => Err(e), + }, + ) + .collect::>(), + syn::Fields::Unnamed(fields) => fields + .unnamed + .iter_mut() + .map( + |field| match FieldPyO3Options::take_pyo3_options(&mut field.attrs) { + Ok(options) => Ok((&*field, options)), + Err(e) => Err(e), + }, + ) + .collect::>(), + syn::Fields::Unit => { + let mut results = Vec::new(); + + if let Some(attr) = args.options.set_all { + results.push(Err(syn::Error::new_spanned(attr, UNIT_SET))); + }; + if let Some(attr) = args.options.get_all { + results.push(Err(syn::Error::new_spanned(attr, UNIT_GET))); + }; + + results + } + } + .into_iter() + .try_combine_syn_errors()?; + + if let Some(attr) = args.options.get_all { + for (_, FieldPyO3Options { get, .. }) in &mut field_options { + if let Some(old_get) = get.replace(Annotated::Struct(attr)) { + return Err(syn::Error::new(old_get.span(), DUPE_GET)); + } + } + } + + if let Some(attr) = args.options.set_all { + for (_, FieldPyO3Options { set, .. }) in &mut field_options { + if let Some(old_set) = set.replace(Annotated::Struct(attr)) { + return Err(syn::Error::new(old_set.span(), DUPE_SET)); + } + } + } + + impl_class(&class.ident, &args, doc, field_options, methods_type, ctx) +} + +enum Annotated { + Field(X), + Struct(Y), +} + +impl Annotated { + fn span(&self) -> Span { + match self { + Self::Field(x) => x.span(), + Self::Struct(y) => y.span(), + } + } +} + +/// `#[pyo3()]` options for pyclass fields +struct FieldPyO3Options { + get: Option>, + set: Option>, + name: Option, +} + +enum FieldPyO3Option { + Get(attributes::kw::get), + Set(attributes::kw::set), + Name(NameAttribute), +} + +impl Parse for FieldPyO3Option { + fn parse(input: ParseStream<'_>) -> Result { + let lookahead = input.lookahead1(); + if lookahead.peek(attributes::kw::get) { + input.parse().map(FieldPyO3Option::Get) + } else if lookahead.peek(attributes::kw::set) { + input.parse().map(FieldPyO3Option::Set) + } else if lookahead.peek(attributes::kw::name) { + input.parse().map(FieldPyO3Option::Name) + } else { + Err(lookahead.error()) + } + } +} + +impl FieldPyO3Options { + fn take_pyo3_options(attrs: &mut Vec) -> Result { + let mut options = FieldPyO3Options { + get: None, + set: None, + name: None, + }; + + for option in take_pyo3_options(attrs)? { + match option { + FieldPyO3Option::Get(kw) => { + if options.get.replace(Annotated::Field(kw)).is_some() { + return Err(syn::Error::new(kw.span(), UNIQUE_GET)); + } + } + FieldPyO3Option::Set(kw) => { + if options.set.replace(Annotated::Field(kw)).is_some() { + return Err(syn::Error::new(kw.span(), UNIQUE_SET)); + } + } + FieldPyO3Option::Name(name) => { + if options.name.replace(name).is_some() { + return Err(syn::Error::new(options.name.span(), UNIQUE_NAME)); + } + } + } + } + + Ok(options) + } +} + +fn get_class_python_name<'a>(cls: &'a Ident, args: &'a PyClassArgs) -> Cow<'a, Ident> { + args.options + .name + .as_ref() + .map(|name_attr| Cow::Borrowed(&name_attr.value.0)) + .unwrap_or_else(|| Cow::Owned(cls.unraw())) +} + +#[cfg(feature = "experimental-inspect")] +fn get_class_type_hint(cls: &Ident, args: &PyClassArgs, ctx: &Ctx) -> TokenStream { + let pyo3_path = &ctx.pyo3_path; + let name = get_class_python_name(cls, args).to_string(); + if let Some(module) = &args.options.module { + let module = module.value.value(); + quote! { + #pyo3_path::inspect::PyStaticExpr::PyClass(#pyo3_path::inspect::PyClassNameStaticExpr::new( + &#pyo3_path::inspect::PyStaticExpr::Attribute { + value: &#pyo3_path::inspect::PyStaticExpr::Name { + id: #module + }, + attr: #name + }, + Self::_PYO3_INTROSPECTION_ID + )) + } + } else { + quote! { + #pyo3_path::inspect::PyStaticExpr::PyClass(#pyo3_path::inspect::PyClassNameStaticExpr::new( + &#pyo3_path::inspect::PyStaticExpr::Name { + id: #name + }, + Self::_PYO3_INTROSPECTION_ID + )) + } + } +} + +fn impl_class( + cls: &Ident, + args: &PyClassArgs, + doc: Option, + field_options: Vec<(&syn::Field, FieldPyO3Options)>, + methods_type: PyClassMethodsType, + ctx: &Ctx, +) -> Result { + let Ctx { pyo3_path, .. } = ctx; + let pytypeinfo_impl = impl_pytypeinfo(cls, args, ctx); + + if let Some(str) = &args.options.str { + if str.value.is_some() { + // check if any renaming is present + let no_naming_conflict = field_options.iter().all(|x| x.1.name.is_none()) + & args.options.name.is_none() + & args.options.rename_all.is_none(); + ensure_spanned!(no_naming_conflict, str.value.span() => "The format string syntax is incompatible with any renaming via `name` or `rename_all`"); + } + } + + let (default_new, default_new_slot) = pyclass_new_impl( + &args.options, + &syn::parse_quote!(#cls), + field_options.iter().map(|(f, _)| f), + ctx, + )?; + + let mut default_methods = descriptors_to_items( + cls, + args.options.rename_all.as_ref(), + args.options.frozen, + field_options, + ctx, + )?; + + let (default_class_getitem, default_class_getitem_method) = + pyclass_class_getitem(&args.options, &syn::parse_quote!(#cls), ctx)?; + + if let Some(default_class_getitem_method) = default_class_getitem_method { + default_methods.push(default_class_getitem_method); + } + + let (default_str, default_str_slot) = + implement_pyclass_str(&args.options, &syn::parse_quote!(#cls), ctx); + + let (default_richcmp, default_richcmp_slot) = + pyclass_richcmp(&args.options, &syn::parse_quote!(#cls), ctx)?; + + let (default_hash, default_hash_slot) = + pyclass_hash(&args.options, &syn::parse_quote!(#cls), ctx)?; + + let mut slots = Vec::new(); + slots.extend(default_richcmp_slot); + slots.extend(default_hash_slot); + slots.extend(default_str_slot); + slots.extend(default_new_slot); + + let mut impl_builder = + PyClassImplsBuilder::new(cls, cls, args, methods_type, default_methods, slots); + if let Some(doc) = doc { + impl_builder = impl_builder.doc(doc); + } + let py_class_impl: TokenStream = [ + impl_builder.impl_pyclass(ctx), + impl_builder.impl_into_py(ctx), + impl_builder.impl_pyclassimpl(ctx)?, + impl_builder.impl_add_to_module(ctx), + impl_builder.impl_freelist(ctx), + impl_builder.impl_introspection(ctx, None), + ] + .into_iter() + .collect(); + + Ok(quote! { + impl #pyo3_path::types::DerefToPyAny for #cls {} + + #pytypeinfo_impl + + #py_class_impl + + #[doc(hidden)] + #[allow(non_snake_case)] + impl #cls { + #default_richcmp + #default_hash + #default_str + #default_new + #default_class_getitem + } + }) +} + +enum PyClassEnum<'a> { + Simple(PyClassSimpleEnum<'a>), + Complex(PyClassComplexEnum<'a>), +} + +impl<'a> PyClassEnum<'a> { + fn new(enum_: &'a mut syn::ItemEnum) -> syn::Result { + let has_only_unit_variants = enum_ + .variants + .iter() + .all(|variant| matches!(variant.fields, syn::Fields::Unit)); + + Ok(if has_only_unit_variants { + let simple_enum = PyClassSimpleEnum::new(enum_)?; + Self::Simple(simple_enum) + } else { + let complex_enum = PyClassComplexEnum::new(enum_)?; + Self::Complex(complex_enum) + }) + } +} + +pub fn build_py_enum( + enum_: &mut syn::ItemEnum, + mut args: PyClassArgs, + method_type: PyClassMethodsType, +) -> syn::Result { + args.options.take_pyo3_options(&mut enum_.attrs)?; + + let ctx = &Ctx::new(&args.options.krate, None); + if let Some(extends) = &args.options.extends { + bail_spanned!(extends.span() => "enums can't extend from other classes"); + } else if let Some(subclass) = &args.options.subclass { + bail_spanned!(subclass.span() => "enums can't be inherited by other classes"); + } else if enum_.variants.is_empty() { + bail_spanned!(enum_.brace_token.span.join() => "#[pyclass] can't be used on enums without any variants"); + } + + if let Some(generic) = &args.options.generic { + bail_spanned!(generic.span() => "enums do not support #[pyclass(generic)]"); + } + + let doc = utils::get_doc(&enum_.attrs, None); + let enum_ = PyClassEnum::new(enum_)?; + impl_enum(enum_, &args, doc, method_type, ctx) +} + +struct PyClassSimpleEnum<'a> { + ident: &'a syn::Ident, + // The underlying #[repr] of the enum, used to implement __int__ and __richcmp__. + // This matters when the underlying representation may not fit in `isize`. + repr_type: syn::Ident, + variants: Vec>, +} + +impl<'a> PyClassSimpleEnum<'a> { + fn new(enum_: &'a mut syn::ItemEnum) -> syn::Result { + fn is_numeric_type(t: &syn::Ident) -> bool { + [ + "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "u128", "i128", "usize", + "isize", + ] + .iter() + .any(|&s| t == s) + } + + fn extract_unit_variant_data( + variant: &mut syn::Variant, + ) -> syn::Result> { + use syn::Fields; + let ident = match &variant.fields { + Fields::Unit => &variant.ident, + _ => bail_spanned!(variant.span() => "Must be a unit variant."), + }; + let options = EnumVariantPyO3Options::take_pyo3_options(&mut variant.attrs)?; + Ok(PyClassEnumUnitVariant { + ident, + options, + attrs: variant.attrs.clone(), + }) + } + + let ident = &enum_.ident; + + // According to the [reference](https://doc.rust-lang.org/reference/items/enumerations.html), + // "Under the default representation, the specified discriminant is interpreted as an isize + // value", so `isize` should be enough by default. + let mut repr_type = syn::Ident::new("isize", proc_macro2::Span::call_site()); + if let Some(attr) = enum_.attrs.iter().find(|attr| attr.path().is_ident("repr")) { + let args = + attr.parse_args_with(Punctuated::::parse_terminated)?; + if let Some(ident) = args + .into_iter() + .filter_map(|ts| syn::parse2::(ts).ok()) + .find(is_numeric_type) + { + repr_type = ident; + } + } + + let variants: Vec<_> = enum_ + .variants + .iter_mut() + .map(extract_unit_variant_data) + .collect::>()?; + Ok(Self { + ident, + repr_type, + variants, + }) + } +} + +struct PyClassComplexEnum<'a> { + ident: &'a syn::Ident, + variants: Vec>, +} + +impl<'a> PyClassComplexEnum<'a> { + fn new(enum_: &'a mut syn::ItemEnum) -> syn::Result { + let witness = enum_ + .variants + .iter() + .find(|variant| !matches!(variant.fields, syn::Fields::Unit)) + .expect("complex enum has a non-unit variant") + .ident + .to_owned(); + + let extract_variant_data = + |variant: &'a mut syn::Variant| -> syn::Result> { + use syn::Fields; + let ident = &variant.ident; + let options = EnumVariantPyO3Options::take_pyo3_options(&mut variant.attrs)?; + + let variant = match &variant.fields { + Fields::Unit => { + bail_spanned!(variant.span() => format!( + "Unit variant `{ident}` is not yet supported in a complex enum\n\ + = help: change to an empty tuple variant instead: `{ident}()`\n\ + = note: the enum is complex because of non-unit variant `{witness}`", + ident=ident, witness=witness)) + } + Fields::Named(fields) => { + let fields = fields + .named + .iter() + .map(|field| PyClassEnumVariantNamedField { + ident: field.ident.as_ref().expect("named field has an identifier"), + ty: &field.ty, + attrs: &field.attrs, + span: field.span(), + }) + .collect(); + + PyClassEnumVariant::Struct(PyClassEnumStructVariant { + ident, + fields, + options, + attrs: variant.attrs.clone(), + }) + } + Fields::Unnamed(types) => { + let fields = types + .unnamed + .iter() + .map(|field| PyClassEnumVariantUnnamedField { + ty: &field.ty, + span: field.span(), + attrs: &field.attrs, + }) + .collect(); + + PyClassEnumVariant::Tuple(PyClassEnumTupleVariant { + ident, + fields, + options, + attrs: variant.attrs.clone(), + }) + } + }; + + Ok(variant) + }; + + let ident = &enum_.ident; + + let variants: Vec<_> = enum_ + .variants + .iter_mut() + .map(extract_variant_data) + .collect::>()?; + + Ok(Self { ident, variants }) + } +} + +enum PyClassEnumVariant<'a> { + // TODO(mkovaxx): Unit(PyClassEnumUnitVariant<'a>), + Struct(PyClassEnumStructVariant<'a>), + Tuple(PyClassEnumTupleVariant<'a>), +} + +trait EnumVariant { + fn get_ident(&self) -> &syn::Ident; + fn get_options(&self) -> &EnumVariantPyO3Options; + fn get_attrs(&self) -> &[syn::Attribute]; + + fn get_python_name(&self, args: &PyClassArgs) -> Cow<'_, syn::Ident> { + self.get_options() + .name + .as_ref() + .map(|name_attr| Cow::Borrowed(&name_attr.value.0)) + .unwrap_or_else(|| { + let name = self.get_ident().unraw(); + if let Some(attr) = &args.options.rename_all { + let new_name = apply_renaming_rule(attr.value.rule, &name.to_string()); + Cow::Owned(Ident::new(&new_name, Span::call_site())) + } else { + Cow::Owned(name) + } + }) + } +} + +impl EnumVariant for PyClassEnumVariant<'_> { + fn get_ident(&self) -> &syn::Ident { + match self { + Self::Struct(struct_variant) => struct_variant.ident, + Self::Tuple(tuple_variant) => tuple_variant.ident, + } + } + + fn get_options(&self) -> &EnumVariantPyO3Options { + match self { + Self::Struct(struct_variant) => &struct_variant.options, + Self::Tuple(tuple_variant) => &tuple_variant.options, + } + } + + fn get_attrs(&self) -> &[syn::Attribute] { + match self { + Self::Struct(struct_variant) => &struct_variant.attrs, + Self::Tuple(tuple_variant) => &tuple_variant.attrs, + } + } +} + +/// A unit variant has no fields +struct PyClassEnumUnitVariant<'a> { + ident: &'a syn::Ident, + options: EnumVariantPyO3Options, + attrs: Vec, +} + +impl EnumVariant for PyClassEnumUnitVariant<'_> { + fn get_ident(&self) -> &syn::Ident { + self.ident + } + + fn get_options(&self) -> &EnumVariantPyO3Options { + &self.options + } + + fn get_attrs(&self) -> &[syn::Attribute] { + &self.attrs + } +} + +/// A struct variant has named fields +struct PyClassEnumStructVariant<'a> { + ident: &'a syn::Ident, + fields: Vec>, + options: EnumVariantPyO3Options, + attrs: Vec, +} + +impl PyClassEnumStructVariant<'_> { + fn python_name(&self) -> Cow<'_, syn::Ident> { + self.options + .name + .as_ref() + .map(|name_attr| Cow::Borrowed(&name_attr.value.0)) + .unwrap_or_else(|| Cow::Owned(self.ident.unraw())) + } +} + +struct PyClassEnumTupleVariant<'a> { + ident: &'a syn::Ident, + fields: Vec>, + options: EnumVariantPyO3Options, + attrs: Vec, +} + +impl PyClassEnumTupleVariant<'_> { + fn python_name(&self) -> Cow<'_, syn::Ident> { + self.options + .name + .as_ref() + .map(|name_attr| Cow::Borrowed(&name_attr.value.0)) + .unwrap_or_else(|| Cow::Owned(self.ident.unraw())) + } +} + +struct PyClassEnumVariantNamedField<'a> { + ident: &'a syn::Ident, + ty: &'a syn::Type, + attrs: &'a [syn::Attribute], + span: Span, +} + +struct PyClassEnumVariantUnnamedField<'a> { + ty: &'a syn::Type, + attrs: &'a [syn::Attribute], + span: Span, +} + +/// `#[pyo3()]` options for pyclass enum variants +#[derive(Clone, Default)] +struct EnumVariantPyO3Options { + name: Option, + constructor: Option, +} + +enum EnumVariantPyO3Option { + Name(NameAttribute), + Constructor(ConstructorAttribute), +} + +impl Parse for EnumVariantPyO3Option { + fn parse(input: ParseStream<'_>) -> Result { + let lookahead = input.lookahead1(); + if lookahead.peek(attributes::kw::name) { + input.parse().map(EnumVariantPyO3Option::Name) + } else if lookahead.peek(attributes::kw::constructor) { + input.parse().map(EnumVariantPyO3Option::Constructor) + } else { + Err(lookahead.error()) + } + } +} + +impl EnumVariantPyO3Options { + fn take_pyo3_options(attrs: &mut Vec) -> Result { + let mut options = EnumVariantPyO3Options::default(); + + take_pyo3_options(attrs)? + .into_iter() + .try_for_each(|option| options.set_option(option))?; + + Ok(options) + } + + fn set_option(&mut self, option: EnumVariantPyO3Option) -> syn::Result<()> { + macro_rules! set_option { + ($key:ident) => { + { + ensure_spanned!( + self.$key.is_none(), + $key.span() => concat!("`", stringify!($key), "` may only be specified once") + ); + self.$key = Some($key); + } + }; + } + + match option { + EnumVariantPyO3Option::Constructor(constructor) => set_option!(constructor), + EnumVariantPyO3Option::Name(name) => set_option!(name), + } + Ok(()) + } +} + +// todo(remove this dead code allowance once __repr__ is implemented +#[allow(dead_code)] +pub enum PyFmtName { + Str, + Repr, +} + +fn implement_py_formatting( + ty: &syn::Type, + ctx: &Ctx, + option: &StrFormatterAttribute, +) -> (ImplItemFn, MethodAndSlotDef) { + let mut fmt_impl = match &option.value { + Some(opt) => { + let fmt = &opt.fmt; + let args = &opt + .args + .iter() + .map(|member| quote! {self.#member}) + .collect::>(); + let fmt_impl: ImplItemFn = syn::parse_quote! { + fn __pyo3__generated____str__(&self) -> ::std::string::String { + ::std::format!(#fmt, #(#args, )*) + } + }; + fmt_impl + } + None => { + let fmt_impl: syn::ImplItemFn = syn::parse_quote! { + fn __pyo3__generated____str__(&self) -> ::std::string::String { + ::std::format!("{}", &self) + } + }; + fmt_impl + } + }; + let fmt_slot = generate_protocol_slot( + ty, + &mut fmt_impl, + &__STR__, + "__str__", + #[cfg(feature = "experimental-inspect")] + FunctionIntrospectionData { + names: &["__str__"], + arguments: Vec::new(), + returns: parse_quote! { ::std::string::String }, + is_returning_not_implemented_on_extraction_error: false, + }, + ctx, + ) + .unwrap(); + (fmt_impl, fmt_slot) +} + +fn implement_pyclass_str( + options: &PyClassPyO3Options, + ty: &syn::Type, + ctx: &Ctx, +) -> (Option, Option) { + match &options.str { + Some(option) => { + let (default_str, default_str_slot) = implement_py_formatting(ty, ctx, option); + (Some(default_str), Some(default_str_slot)) + } + _ => (None, None), + } +} + +fn impl_enum( + enum_: PyClassEnum<'_>, + args: &PyClassArgs, + doc: Option, + methods_type: PyClassMethodsType, + ctx: &Ctx, +) -> Result { + if let Some(str_fmt) = &args.options.str { + ensure_spanned!(str_fmt.value.is_none(), str_fmt.value.span() => "The format string syntax cannot be used with enums") + } + + match enum_ { + PyClassEnum::Simple(simple_enum) => { + impl_simple_enum(simple_enum, args, doc, methods_type, ctx) + } + PyClassEnum::Complex(complex_enum) => { + impl_complex_enum(complex_enum, args, doc, methods_type, ctx) + } + } +} + +fn impl_simple_enum( + simple_enum: PyClassSimpleEnum<'_>, + args: &PyClassArgs, + doc: Option, + methods_type: PyClassMethodsType, + ctx: &Ctx, +) -> Result { + let Ctx { pyo3_path, .. } = ctx; + let cls = simple_enum.ident; + let ty: syn::Type = syn::parse_quote!(#cls); + let variants = simple_enum.variants; + let pytypeinfo = impl_pytypeinfo(cls, args, ctx); + + for variant in &variants { + ensure_spanned!(variant.options.constructor.is_none(), variant.options.constructor.span() => "`constructor` can't be used on a simple enum variant"); + } + + let variant_cfg_check = generate_cfg_check(&variants, cls); + + let (default_repr, default_repr_slot) = { + let variants_repr = variants.iter().map(|variant| { + let variant_name = variant.ident; + let cfg_attrs = get_cfg_attributes(&variant.attrs); + // Assuming all variants are unit variants because they are the only type we support. + let repr = format!( + "{}.{}", + get_class_python_name(cls, args), + variant.get_python_name(args), + ); + quote! { #(#cfg_attrs)* #cls::#variant_name => #repr, } + }); + let mut repr_impl: syn::ImplItemFn = syn::parse_quote! { + fn __pyo3__repr__(&self) -> &'static str { + match *self { + #(#variants_repr)* + } + } + }; + let repr_slot = generate_default_protocol_slot( + &ty, + &mut repr_impl, + &__REPR__, + #[cfg(feature = "experimental-inspect")] + FunctionIntrospectionData { + names: &["__repr__"], + arguments: Vec::new(), + returns: parse_quote! { &'static str }, + is_returning_not_implemented_on_extraction_error: false, + }, + ctx, + )?; + (repr_impl, repr_slot) + }; + + let (default_str, default_str_slot) = implement_pyclass_str(&args.options, &ty, ctx); + + let repr_type = &simple_enum.repr_type; + + let (default_int, default_int_slot) = { + // This implementation allows us to convert &T to #repr_type without implementing `Copy` + let variants_to_int = variants.iter().map(|variant| { + let variant_name = variant.ident; + let cfg_attrs = get_cfg_attributes(&variant.attrs); + quote! { #(#cfg_attrs)* #cls::#variant_name => #cls::#variant_name as #repr_type, } + }); + let mut int_impl: syn::ImplItemFn = syn::parse_quote! { + fn __pyo3__int__(&self) -> #repr_type { + match *self { + #(#variants_to_int)* + } + } + }; + let int_slot = generate_default_protocol_slot( + &ty, + &mut int_impl, + &__INT__, + #[cfg(feature = "experimental-inspect")] + FunctionIntrospectionData { + names: &["__int__"], + arguments: Vec::new(), + returns: parse_quote!(#repr_type), + is_returning_not_implemented_on_extraction_error: false, + }, + ctx, + )?; + (int_impl, int_slot) + }; + + let (default_richcmp, default_richcmp_slot) = + pyclass_richcmp_simple_enum(&args.options, &ty, repr_type, ctx)?; + let (default_hash, default_hash_slot) = pyclass_hash(&args.options, &ty, ctx)?; + + let mut default_slots = vec![default_repr_slot, default_int_slot]; + default_slots.extend(default_richcmp_slot); + default_slots.extend(default_hash_slot); + default_slots.extend(default_str_slot); + + let mut impl_builder = PyClassImplsBuilder::new( + cls, + cls, + args, + methods_type, + simple_enum_default_methods( + cls, + variants + .iter() + .map(|v| (v.ident, v.get_python_name(args), v.attrs.as_slice())), + ctx, + ), + default_slots, + ); + if let Some(doc) = doc { + impl_builder = impl_builder.doc(doc); + } + + let enum_into_pyobject_impl = { + let output_type = get_conversion_type_hint(ctx, &format_ident!("OUTPUT_TYPE"), cls); + + let num = variants.len(); + let i = (0..num).map(proc_macro2::Literal::usize_unsuffixed); + let variant_idents = variants.iter().map(|v| v.ident); + let cfgs = variants.iter().map(|v| get_cfg_attributes(&v.attrs)); + quote! { + impl<'py> #pyo3_path::conversion::IntoPyObject<'py> for #cls { + type Target = Self; + type Output = #pyo3_path::Bound<'py, >::Target>; + type Error = #pyo3_path::PyErr; + #output_type + + fn into_pyobject(self, py: #pyo3_path::Python<'py>) -> ::std::result::Result< + >::Output, + >::Error, + > { + // TODO(icxolu): switch this to lookup the variants on the type object, once that is immutable + static SINGLETON: [#pyo3_path::sync::PyOnceLock<#pyo3_path::Py<#cls>>; #num] = + [const { #pyo3_path::sync::PyOnceLock::<#pyo3_path::Py<#cls>>::new() }; #num]; + let idx: usize = match self { + #( + #(#cfgs)* + Self::#variant_idents => #i, + )* + }; + #[allow(unreachable_code)] // May happen if all variants are disabled by cfg attributes + { + // Ensure that the type object is initialized before we attempt to initialize any of the singleton instances, + // to avoid deadlocking. + ::lazy_type_object().get_or_try_init(py)?; + SINGLETON[idx].get_or_try_init(py, || { + #pyo3_path::Py::new(py, self) + }).map(|obj| ::std::clone::Clone::clone(obj.bind(py))) + } + } + } + } + }; + + let pyclass_impls: TokenStream = [ + impl_builder.impl_pyclass(ctx), + enum_into_pyobject_impl, + impl_builder.impl_pyclassimpl(ctx)?, + impl_builder.impl_add_to_module(ctx), + impl_builder.impl_freelist(ctx), + impl_builder.impl_introspection(ctx, None), + ] + .into_iter() + .collect(); + + Ok(quote! { + #variant_cfg_check + + #pytypeinfo + + #pyclass_impls + + #[doc(hidden)] + #[allow(non_snake_case)] + impl #cls { + #default_repr + #default_int + #default_richcmp + #default_hash + #default_str + } + }) +} + +fn impl_complex_enum( + complex_enum: PyClassComplexEnum<'_>, + args: &PyClassArgs, + doc: Option, + methods_type: PyClassMethodsType, + ctx: &Ctx, +) -> Result { + let Ctx { pyo3_path, .. } = ctx; + let cls = complex_enum.ident; + let ty: syn::Type = syn::parse_quote!(#cls); + + // Need to rig the enum PyClass options + let args = { + let mut rigged_args = args.clone(); + // Needs to be frozen to disallow `&mut self` methods, which could break a runtime invariant + rigged_args.options.frozen = parse_quote!(frozen); + // Needs to be subclassable by the variant PyClasses + rigged_args.options.subclass = parse_quote!(subclass); + rigged_args + }; + + let ctx = &Ctx::new(&args.options.krate, None); + let cls = complex_enum.ident; + let variants = complex_enum.variants; + let pytypeinfo = impl_pytypeinfo(cls, &args, ctx); + + let (default_richcmp, default_richcmp_slot) = pyclass_richcmp(&args.options, &ty, ctx)?; + let (default_hash, default_hash_slot) = pyclass_hash(&args.options, &ty, ctx)?; + + let (default_str, default_str_slot) = implement_pyclass_str(&args.options, &ty, ctx); + + let mut default_slots = vec![]; + default_slots.extend(default_richcmp_slot); + default_slots.extend(default_hash_slot); + default_slots.extend(default_str_slot); + + let mut impl_builder = PyClassImplsBuilder::new( + cls, + cls, + &args, + methods_type, + complex_enum_default_methods( + cls, + variants + .iter() + .map(|v| (v.get_ident(), v.get_python_name(&args), v.get_attrs())), + ctx, + ), + default_slots, + ); + if let Some(doc) = doc { + impl_builder = impl_builder.doc(doc); + } + + let enum_into_pyobject_impl = { + let match_arms = variants + .iter() + .map(|variant| { + let variant_ident = variant.get_ident(); + let variant_cls = gen_complex_enum_variant_class_ident(cls, variant.get_ident()); + quote! { + #cls::#variant_ident { .. } => { + let pyclass_init = <#pyo3_path::PyClassInitializer as ::std::convert::From>::from(self).add_subclass(#variant_cls); + unsafe { #pyo3_path::Bound::new(py, pyclass_init).map(|b| b.cast_into_unchecked()) } + } + } + }); + let output_type = get_conversion_type_hint(ctx, &format_ident!("OUTPUT_TYPE"), cls); + quote! { + impl<'py> #pyo3_path::conversion::IntoPyObject<'py> for #cls { + type Target = Self; + type Output = #pyo3_path::Bound<'py, >::Target>; + type Error = #pyo3_path::PyErr; + #output_type + + fn into_pyobject(self, py: #pyo3_path::Python<'py>) -> ::std::result::Result< + ::Output, + ::Error, + > { + match self { + #(#match_arms)* + } + } + } + } + }; + + let pyclass_impls: TokenStream = [ + impl_builder.impl_pyclass(ctx), + enum_into_pyobject_impl, + impl_builder.impl_pyclassimpl(ctx)?, + impl_builder.impl_add_to_module(ctx), + impl_builder.impl_freelist(ctx), + impl_builder.impl_introspection(ctx, None), + ] + .into_iter() + .collect(); + + let mut variant_cls_zsts = vec![]; + let mut variant_cls_pytypeinfos = vec![]; + let mut variant_cls_pyclass_impls = vec![]; + let mut variant_cls_impls = vec![]; + for variant in variants { + let variant_name = variant.get_ident().clone(); + let variant_cls = gen_complex_enum_variant_class_ident(cls, &variant_name); + + let variant_cls_zst = quote! { + #[doc(hidden)] + #[allow(non_camel_case_types)] + struct #variant_cls; + }; + variant_cls_zsts.push(variant_cls_zst); + + let variant_args = PyClassArgs { + class_kind: PyClassKind::Struct, + // TODO(mkovaxx): propagate variant.options + options: { + let mut rigged_options: PyClassPyO3Options = parse_quote!(extends = #cls, frozen); + // If a specific module was given to the base class, use it for all variants. + rigged_options.module.clone_from(&args.options.module); + rigged_options + }, + }; + + let variant_cls_pytypeinfo = impl_pytypeinfo(&variant_cls, &variant_args, ctx); + variant_cls_pytypeinfos.push(variant_cls_pytypeinfo); + + let (variant_cls_impl, field_getters, mut slots) = + impl_complex_enum_variant_cls(cls, &args, &variant, ctx)?; + variant_cls_impls.push(variant_cls_impl); + + let variant_doc = get_doc(variant.get_attrs(), None); + let variant_new = complex_enum_variant_new(cls, variant, ctx)?; + slots.push(variant_new); + + let mut impl_builder = PyClassImplsBuilder::new( + &variant_cls, + &variant_name, + &variant_args, + methods_type, + field_getters, + slots, + ); + if let Some(doc) = variant_doc { + impl_builder = impl_builder.doc(doc); + } + + let pyclass_impl: TokenStream = [ + impl_builder.impl_pyclass(ctx), + impl_builder.impl_into_py(ctx), + impl_builder.impl_pyclassimpl(ctx)?, + impl_builder.impl_add_to_module(ctx), + impl_builder.impl_freelist(ctx), + impl_builder.impl_introspection(ctx, Some(cls)), + ] + .into_iter() + .collect(); + + variant_cls_pyclass_impls.push(pyclass_impl); + } + + Ok(quote! { + #pytypeinfo + + #pyclass_impls + + #[doc(hidden)] + #[allow(non_snake_case)] + impl #cls { + #default_richcmp + #default_hash + #default_str + } + + #(#variant_cls_zsts)* + + #(#variant_cls_pytypeinfos)* + + #(#variant_cls_pyclass_impls)* + + #(#variant_cls_impls)* + }) +} + +fn impl_complex_enum_variant_cls( + enum_name: &syn::Ident, + args: &PyClassArgs, + variant: &PyClassEnumVariant<'_>, + ctx: &Ctx, +) -> Result<(TokenStream, Vec, Vec)> { + match variant { + PyClassEnumVariant::Struct(struct_variant) => { + impl_complex_enum_struct_variant_cls(enum_name, args, struct_variant, ctx) + } + PyClassEnumVariant::Tuple(tuple_variant) => { + impl_complex_enum_tuple_variant_cls(enum_name, args, tuple_variant, ctx) + } + } +} + +fn impl_complex_enum_variant_match_args( + ctx @ Ctx { pyo3_path, .. }: &Ctx, + variant_cls_type: &syn::Type, + field_names: &[Ident], +) -> syn::Result<(MethodAndMethodDef, syn::ImplItemFn)> { + let ident = format_ident!("__match_args__"); + let field_names_unraw = field_names.iter().map(|name| name.unraw()); + let mut match_args_impl: syn::ImplItemFn = { + parse_quote! { + #[classattr] + fn #ident(py: #pyo3_path::Python<'_>) -> #pyo3_path::PyResult<#pyo3_path::Bound<'_, #pyo3_path::types::PyTuple>> { + #pyo3_path::types::PyTuple::new::<&str, _>(py, [ + #(stringify!(#field_names_unraw),)* + ]) + } + } + }; + + let spec = FnSpec::parse( + &mut match_args_impl.sig, + &mut match_args_impl.attrs, + Default::default(), + )?; + #[cfg_attr(not(feature = "experimental-inspect"), allow(unused_mut))] + let mut variant_match_args = impl_py_class_attribute(variant_cls_type, &spec, ctx)?; + #[cfg(feature = "experimental-inspect")] + variant_match_args.add_introspection(attribute_introspection_code( + pyo3_path, + Some(variant_cls_type), + "__match_args__".into(), + PyExpr::tuple( + field_names + .iter() + .map(|name| PyExpr::str_constant(name.unraw().to_string())), + ), + syn::Type::Tuple(syn::TypeTuple { + paren_token: syn::token::Paren::default(), + elems: field_names + .iter() + .map(|_| { + let t: syn::Type = parse_quote!(&'static str); + t + }) + .collect(), + }), + None, + true, + )); + Ok((variant_match_args, match_args_impl)) +} + +fn impl_complex_enum_struct_variant_cls( + enum_name: &syn::Ident, + args: &PyClassArgs, + variant: &PyClassEnumStructVariant<'_>, + ctx: &Ctx, +) -> Result<(TokenStream, Vec, Vec)> { + let Ctx { pyo3_path, .. } = ctx; + let variant_ident = &variant.ident; + let variant_cls = gen_complex_enum_variant_class_ident(enum_name, variant.ident); + let variant_cls_type = parse_quote!(#variant_cls); + + let mut field_names: Vec = vec![]; + let mut fields_with_types: Vec = vec![]; + let mut field_getters = vec![]; + let mut field_getter_impls: Vec = vec![]; + for field in &variant.fields { + let field_name = field.ident; + let field_type = field.ty; + let field_with_type = quote! { #field_name: #field_type }; + + let field_getter = complex_enum_variant_field_getter( + &variant_cls_type, + field_name, + field_type, + field.attrs, + field.span, + ctx, + )?; + + let field_getter_impl = quote! { + fn #field_name(slf: #pyo3_path::PyClassGuard<'_, Self>, py: #pyo3_path::Python<'_>) -> #pyo3_path::PyResult<#pyo3_path::Py<#pyo3_path::PyAny>> { + #[allow(unused_imports)] + use #pyo3_path::impl_::pyclass::Probe as _; + match &*slf.into_super() { + #enum_name::#variant_ident { #field_name, .. } => + #pyo3_path::impl_::pyclass::ConvertField::< + { #pyo3_path::impl_::pyclass::IsIntoPyObjectRef::<#field_type>::VALUE } + >::convert_field::<#field_type>(#field_name, py), + _ => ::core::unreachable!("Wrong complex enum variant found in variant wrapper PyClass"), + } + } + }; + + field_names.push(field_name.clone()); + fields_with_types.push(field_with_type); + field_getters.push(field_getter); + field_getter_impls.push(field_getter_impl); + } + + let (qualname, qualname_impl) = impl_complex_enum_variant_qualname( + &get_class_python_name(enum_name, args), + &variant.python_name(), + &variant_cls_type, + ctx, + )?; + + field_getters.push(qualname); + + let (variant_match_args, match_args_const_impl) = + impl_complex_enum_variant_match_args(ctx, &variant_cls_type, &field_names)?; + + field_getters.push(variant_match_args); + + let cls_impl = quote! { + #[doc(hidden)] + #[allow(non_snake_case)] + impl #variant_cls { + #[allow(clippy::too_many_arguments)] + fn __pymethod_constructor__(py: #pyo3_path::Python<'_>, #(#fields_with_types,)*) -> #pyo3_path::PyClassInitializer<#variant_cls> { + let base_value = #enum_name::#variant_ident { #(#field_names,)* }; + <#pyo3_path::PyClassInitializer<#enum_name> as ::std::convert::From<#enum_name>>::from(base_value).add_subclass(#variant_cls) + } + + #match_args_const_impl + + #qualname_impl + + #(#field_getter_impls)* + } + }; + + Ok((cls_impl, field_getters, Vec::new())) +} + +fn impl_complex_enum_tuple_variant_field_getters( + ctx: &Ctx, + variant: &PyClassEnumTupleVariant<'_>, + enum_name: &syn::Ident, + variant_cls_type: &syn::Type, + variant_ident: &&Ident, + field_names: &mut Vec, + fields_types: &mut Vec, +) -> Result<(Vec, Vec)> { + let Ctx { pyo3_path, .. } = ctx; + + let mut field_getters = vec![]; + let mut field_getter_impls = vec![]; + + for (index, field) in variant.fields.iter().enumerate() { + let field_name = format_ident!("_{}", index); + let field_type = field.ty; + + let field_getter = complex_enum_variant_field_getter( + variant_cls_type, + &field_name, + field_type, + field.attrs, + field.span, + ctx, + )?; + + // Generate the match arms needed to destructure the tuple and access the specific field + let field_access_tokens: Vec<_> = (0..variant.fields.len()) + .map(|i| { + if i == index { + quote! { val } + } else { + quote! { _ } + } + }) + .collect(); + let field_getter_impl: syn::ImplItemFn = parse_quote! { + fn #field_name(slf: #pyo3_path::PyClassGuard<'_, Self>, py: #pyo3_path::Python<'_>) -> #pyo3_path::PyResult<#pyo3_path::Py<#pyo3_path::PyAny>> { + #[allow(unused_imports)] + use #pyo3_path::impl_::pyclass::Probe as _; + match &*slf.into_super() { + #enum_name::#variant_ident ( #(#field_access_tokens), *) => + #pyo3_path::impl_::pyclass::ConvertField::< + { #pyo3_path::impl_::pyclass::IsIntoPyObjectRef::<#field_type>::VALUE } + >::convert_field::<#field_type>(val, py), + _ => ::core::unreachable!("Wrong complex enum variant found in variant wrapper PyClass"), + } + } + }; + + field_names.push(field_name); + fields_types.push(field_type.clone()); + field_getters.push(field_getter); + field_getter_impls.push(field_getter_impl); + } + + Ok((field_getters, field_getter_impls)) +} + +fn impl_complex_enum_tuple_variant_len( + ctx: &Ctx, + + variant_cls_type: &syn::Type, + num_fields: usize, +) -> Result<(MethodAndSlotDef, syn::ImplItemFn)> { + let Ctx { pyo3_path, .. } = ctx; + + let mut len_method_impl: syn::ImplItemFn = parse_quote! { + fn __len__(slf: #pyo3_path::PyClassGuard<'_, Self>) -> #pyo3_path::PyResult { + ::std::result::Result::Ok(#num_fields) + } + }; + + let variant_len = generate_default_protocol_slot( + variant_cls_type, + &mut len_method_impl, + &__LEN__, + #[cfg(feature = "experimental-inspect")] + FunctionIntrospectionData { + names: &["__len__"], + arguments: Vec::new(), + returns: parse_quote! { ::std::primitive::usize }, + is_returning_not_implemented_on_extraction_error: false, + }, + ctx, + )?; + + Ok((variant_len, len_method_impl)) +} + +fn impl_complex_enum_tuple_variant_getitem( + ctx: &Ctx, + variant_cls: &syn::Ident, + variant_cls_type: &syn::Type, + num_fields: usize, +) -> Result<(MethodAndSlotDef, syn::ImplItemFn)> { + let Ctx { pyo3_path, .. } = ctx; + + let match_arms: Vec<_> = (0..num_fields) + .map(|i| { + let field_access = format_ident!("_{}", i); + quote! { #i => + #pyo3_path::IntoPyObjectExt::into_py_any(#variant_cls::#field_access(slf, py)?, py) + } + }) + .collect(); + + let mut get_item_method_impl: syn::ImplItemFn = parse_quote! { + fn __getitem__(slf: #pyo3_path::PyClassGuard<'_, Self>, py: #pyo3_path::Python<'_>, idx: usize) -> #pyo3_path::PyResult< #pyo3_path::Py<#pyo3_path::PyAny>> { + match idx { + #( #match_arms, )* + _ => ::std::result::Result::Err(#pyo3_path::exceptions::PyIndexError::new_err("tuple index out of range")), + } + } + }; + + let variant_getitem = generate_default_protocol_slot( + variant_cls_type, + &mut get_item_method_impl, + &__GETITEM__, + #[cfg(feature = "experimental-inspect")] + FunctionIntrospectionData { + names: &["__getitem__"], + arguments: vec![FnArg::Regular(RegularArg { + name: Cow::Owned(Ident::new("key", variant_cls.span())), + ty: &parse_quote! { ::std::primitive::usize }, + from_py_with: None, + default_value: None, + option_wrapped_type: None, + annotation: None, + })], + returns: parse_quote! { #pyo3_path::Py<#pyo3_path::PyAny> }, // TODO: figure out correct type + is_returning_not_implemented_on_extraction_error: false, + }, + ctx, + )?; + + Ok((variant_getitem, get_item_method_impl)) +} + +fn impl_complex_enum_tuple_variant_cls( + enum_name: &syn::Ident, + args: &PyClassArgs, + variant: &PyClassEnumTupleVariant<'_>, + ctx: &Ctx, +) -> Result<(TokenStream, Vec, Vec)> { + let Ctx { pyo3_path, .. } = ctx; + let variant_ident = &variant.ident; + let variant_cls = gen_complex_enum_variant_class_ident(enum_name, variant.ident); + let variant_cls_type = parse_quote!(#variant_cls); + + let mut slots = vec![]; + + // represents the index of the field + let mut field_names: Vec = vec![]; + let mut field_types: Vec = vec![]; + + let (mut field_getters, field_getter_impls) = impl_complex_enum_tuple_variant_field_getters( + ctx, + variant, + enum_name, + &variant_cls_type, + variant_ident, + &mut field_names, + &mut field_types, + )?; + + let (qualname, qualname_impl) = impl_complex_enum_variant_qualname( + &get_class_python_name(enum_name, args), + &variant.python_name(), + &variant_cls_type, + ctx, + )?; + + field_getters.push(qualname); + + let num_fields = variant.fields.len(); + + let (variant_len, len_method_impl) = + impl_complex_enum_tuple_variant_len(ctx, &variant_cls_type, num_fields)?; + + slots.push(variant_len); + + let (variant_getitem, getitem_method_impl) = + impl_complex_enum_tuple_variant_getitem(ctx, &variant_cls, &variant_cls_type, num_fields)?; + + slots.push(variant_getitem); + + let (variant_match_args, match_args_method_impl) = + impl_complex_enum_variant_match_args(ctx, &variant_cls_type, &field_names)?; + + field_getters.push(variant_match_args); + + let cls_impl = quote! { + #[doc(hidden)] + #[allow(non_snake_case)] + impl #variant_cls { + #[allow(clippy::too_many_arguments)] + fn __pymethod_constructor__(py: #pyo3_path::Python<'_>, #(#field_names : #field_types,)*) -> #pyo3_path::PyClassInitializer<#variant_cls> { + let base_value = #enum_name::#variant_ident ( #(#field_names,)* ); + <#pyo3_path::PyClassInitializer<#enum_name> as ::std::convert::From<#enum_name>>::from(base_value).add_subclass(#variant_cls) + } + + #len_method_impl + + #getitem_method_impl + + #match_args_method_impl + + #qualname_impl + + #(#field_getter_impls)* + } + }; + + Ok((cls_impl, field_getters, slots)) +} + +fn gen_complex_enum_variant_class_ident(enum_: &Ident, variant: &Ident) -> Ident { + format_ident!("{}_{}", enum_, variant) +} + +fn impl_complex_enum_variant_qualname( + enum_name: &syn::Ident, + variant_ident: &syn::Ident, + variant_cls_type: &syn::Type, + ctx: &Ctx, +) -> syn::Result<(MethodAndMethodDef, syn::ImplItemFn)> { + let Ctx { pyo3_path, .. } = ctx; + let qualname = format!("{}.{}", enum_name, variant_ident); + let mut qualname_impl: syn::ImplItemFn = { + parse_quote! { + #[classattr] + fn __qualname__(py: #pyo3_path::Python<'_>) -> &'static str { + #qualname + } + } + }; + + let spec = FnSpec::parse( + &mut qualname_impl.sig, + &mut qualname_impl.attrs, + Default::default(), + )?; + + // NB: Deliberately add no introspection here, this is __qualname__ + let qualname = impl_py_class_attribute(variant_cls_type, &spec, ctx)?; + Ok((qualname, qualname_impl)) +} + +#[cfg(feature = "experimental-inspect")] +struct FunctionIntrospectionData<'a> { + names: &'a [&'a str], + arguments: Vec>, + is_returning_not_implemented_on_extraction_error: bool, + returns: syn::Type, +} + +#[cfg(feature = "experimental-inspect")] +impl FunctionIntrospectionData<'_> { + fn generate(self, ctx: &Ctx, cls: &syn::Type, slot: &SlotDef) -> TokenStream { + let mut signature = FunctionSignature::from_arguments(self.arguments); + if !slot.takes_args_and_kwargs() { + signature + .python_signature + .make_all_parameters_positional_only(); + } + self.names + .iter() + .flat_map(|name| { + function_introspection_code( + &ctx.pyo3_path, + None, + name, + &signature, + Some("self"), + PyExpr::from_return_type(self.returns.clone(), Some(cls)), + [], + false, + self.is_returning_not_implemented_on_extraction_error, + None, + Some(cls), + ) + }) + .collect() + } +} + +fn generate_protocol_slot( + cls: &syn::Type, + method: &mut syn::ImplItemFn, + slot: &SlotDef, + name: &str, + #[cfg(feature = "experimental-inspect")] introspection_data: FunctionIntrospectionData<'_>, + ctx: &Ctx, +) -> syn::Result { + let spec = FnSpec::parse( + &mut method.sig, + &mut method.attrs, + PyFunctionOptions::default(), + )?; + #[cfg_attr(not(feature = "experimental-inspect"), allow(unused_mut))] + let mut def = slot.generate_type_slot(cls, &spec, name, ctx)?; + #[cfg(feature = "experimental-inspect")] + def.add_introspection(introspection_data.generate(ctx, cls, slot)); + Ok(def) +} + +fn generate_default_protocol_slot( + cls: &syn::Type, + method: &mut syn::ImplItemFn, + slot: &SlotDef, + #[cfg(feature = "experimental-inspect")] introspection_data: FunctionIntrospectionData<'_>, + ctx: &Ctx, +) -> syn::Result { + let spec = FnSpec::parse( + &mut method.sig, + &mut Vec::new(), + PyFunctionOptions::default(), + )?; + let name = spec.name.to_string(); + #[cfg_attr(not(feature = "experimental-inspect"), allow(unused_mut))] + let mut def = slot.generate_type_slot( + &syn::parse_quote!(#cls), + &spec, + &format!("__default_{name}__"), + ctx, + )?; + #[cfg(feature = "experimental-inspect")] + def.add_introspection(introspection_data.generate(ctx, cls, slot)); + Ok(def) +} + +fn simple_enum_default_methods<'a>( + cls: &'a syn::Ident, + unit_variant_names: impl IntoIterator< + Item = (&'a syn::Ident, Cow<'a, syn::Ident>, &'a [syn::Attribute]), + >, + ctx: &Ctx, +) -> Vec { + let cls_type: syn::Type = syn::parse_quote!(#cls); + unit_variant_names + .into_iter() + .map(|(var, py_name, attrs)| { + let spec = ConstSpec { + rust_ident: var.clone(), + attributes: ConstAttributes { + is_class_attr: true, + name: Some(NameAttribute { + kw: syn::parse_quote! { name }, + value: NameLitStr(py_name.into_owned()), + }), + }, + #[cfg(feature = "experimental-inspect")] + expr: None, + #[cfg(feature = "experimental-inspect")] + ty: cls_type.clone(), + #[cfg(feature = "experimental-inspect")] + doc: get_doc(attrs, None), + }; + let method = gen_py_const(&cls_type, &spec, ctx); + let associated_method_tokens = method.associated_method; + let method_def_tokens = method.method_def; + let cfg_attrs = get_cfg_attributes(attrs); + + let associated_method = quote! { + #(#cfg_attrs)* + #associated_method_tokens + }; + let method_def = quote! { + #(#cfg_attrs)* + #method_def_tokens + }; + + MethodAndMethodDef { + associated_method, + method_def, + } + }) + .collect() +} + +#[cfg_attr(not(feature = "experimental-inspect"), expect(unused_variables))] +fn complex_enum_default_methods<'a>( + cls: &'a Ident, + variant_names: impl IntoIterator, &'a [syn::Attribute])>, + ctx: &Ctx, +) -> Vec { + let cls_type = syn::parse_quote!(#cls); + variant_names + .into_iter() + .map(|(var, py_name, attrs)| { + #[cfg(feature = "experimental-inspect")] + let variant_cls = gen_complex_enum_variant_class_ident(cls, &py_name); + let spec = ConstSpec { + rust_ident: var.clone(), + attributes: ConstAttributes { + is_class_attr: true, + name: Some(NameAttribute { + kw: syn::parse_quote! { name }, + value: NameLitStr(py_name.into_owned()), + }), + }, + #[cfg(feature = "experimental-inspect")] + expr: None, + #[cfg(feature = "experimental-inspect")] + ty: parse_quote!(#variant_cls), + #[cfg(feature = "experimental-inspect")] + doc: get_doc(attrs, None), + }; + gen_complex_enum_variant_attr(cls, &cls_type, &spec, ctx) + }) + .collect() +} + +pub fn gen_complex_enum_variant_attr( + cls: &syn::Ident, + cls_type: &syn::Type, + spec: &ConstSpec, + ctx: &Ctx, +) -> MethodAndMethodDef { + let Ctx { pyo3_path, .. } = ctx; + let member = &spec.rust_ident; + let wrapper_ident = format_ident!("__pymethod_variant_cls_{}__", member); + let python_name = spec.null_terminated_python_name(); + + let variant_cls = gen_complex_enum_variant_class_ident(cls, member); + let associated_method = quote! { + fn #wrapper_ident(py: #pyo3_path::Python<'_>) -> #pyo3_path::PyResult<#pyo3_path::Py<#pyo3_path::PyAny>> { + ::std::result::Result::Ok(py.get_type::<#variant_cls>().into_any().unbind()) + } + }; + + let method_def = quote! { + #pyo3_path::impl_::pymethods::PyMethodDefType::ClassAttribute({ + #pyo3_path::impl_::pymethods::PyClassAttributeDef::new( + #python_name, + #cls_type::#wrapper_ident + ) + }) + }; + + MethodAndMethodDef { + associated_method, + method_def, + } +} + +fn complex_enum_variant_new<'a>( + cls: &'a syn::Ident, + variant: PyClassEnumVariant<'a>, + ctx: &Ctx, +) -> Result { + match variant { + PyClassEnumVariant::Struct(struct_variant) => { + complex_enum_struct_variant_new(cls, struct_variant, ctx) + } + PyClassEnumVariant::Tuple(tuple_variant) => { + complex_enum_tuple_variant_new(cls, tuple_variant, ctx) + } + } +} + +fn complex_enum_struct_variant_new<'a>( + cls: &'a syn::Ident, + variant: PyClassEnumStructVariant<'a>, + ctx: &Ctx, +) -> Result { + let Ctx { pyo3_path, .. } = ctx; + let variant_cls = gen_complex_enum_variant_class_ident(cls, variant.ident); + let variant_cls_type: syn::Type = parse_quote!(#variant_cls); + + let arg_py_ident: syn::Ident = parse_quote!(py); + let arg_py_type: syn::Type = parse_quote!(#pyo3_path::Python<'_>); + + let args = { + let mut args = vec![ + // py: Python<'_> + FnArg::Py(PyArg { + name: &arg_py_ident, + ty: &arg_py_type, + }), + ]; + + for field in &variant.fields { + args.push(FnArg::Regular(RegularArg { + name: Cow::Borrowed(field.ident), + ty: field.ty, + from_py_with: None, + default_value: None, + option_wrapped_type: None, + #[cfg(feature = "experimental-inspect")] + annotation: None, + })); + } + args + }; + + let signature = if let Some(constructor) = variant.options.constructor { + FunctionSignature::from_arguments_and_attribute(args, constructor.into_signature())? + } else { + FunctionSignature::from_arguments(args) + }; + + let spec = FnSpec { + tp: crate::method::FnType::FnStatic, + name: &format_ident!("__pymethod_constructor__"), + python_name: format_ident!("__new__"), + signature, + text_signature: None, + asyncness: None, + unsafety: None, + warnings: vec![], + output: syn::ReturnType::Default, + }; + + #[cfg_attr(not(feature = "experimental-inspect"), allow(unused_mut))] + let mut def = + __NEW__.generate_type_slot(&variant_cls_type, &spec, "__default___new____", ctx)?; + #[cfg(feature = "experimental-inspect")] + def.add_introspection(method_introspection_code( + &spec, + &[], + &variant_cls_type, + false, + ctx, + )); + Ok(def) +} + +fn complex_enum_tuple_variant_new<'a>( + cls: &'a syn::Ident, + variant: PyClassEnumTupleVariant<'a>, + ctx: &Ctx, +) -> Result { + let Ctx { pyo3_path, .. } = ctx; + + let variant_cls = gen_complex_enum_variant_class_ident(cls, variant.ident); + let variant_cls_type: syn::Type = parse_quote!(#variant_cls); + + let arg_py_ident: syn::Ident = parse_quote!(py); + let arg_py_type: syn::Type = parse_quote!(#pyo3_path::Python<'_>); + + let args = { + let mut args = vec![FnArg::Py(PyArg { + name: &arg_py_ident, + ty: &arg_py_type, + })]; + + for (i, field) in variant.fields.iter().enumerate() { + args.push(FnArg::Regular(RegularArg { + name: std::borrow::Cow::Owned(format_ident!("_{}", i)), + ty: field.ty, + from_py_with: None, + default_value: None, + option_wrapped_type: None, + #[cfg(feature = "experimental-inspect")] + annotation: None, + })); + } + args + }; + + let signature = if let Some(constructor) = variant.options.constructor { + FunctionSignature::from_arguments_and_attribute(args, constructor.into_signature())? + } else { + FunctionSignature::from_arguments(args) + }; + + let spec = FnSpec { + tp: crate::method::FnType::FnStatic, + name: &format_ident!("__pymethod_constructor__"), + python_name: format_ident!("__new__"), + signature, + text_signature: None, + asyncness: None, + unsafety: None, + warnings: vec![], + output: syn::ReturnType::Default, + }; + + #[cfg_attr(not(feature = "experimental-inspect"), allow(unused_mut))] + let mut def = + __NEW__.generate_type_slot(&variant_cls_type, &spec, "__default___new____", ctx)?; + #[cfg(feature = "experimental-inspect")] + def.add_introspection(method_introspection_code( + &spec, + &[], + &variant_cls_type, + false, + ctx, + )); + Ok(def) +} + +fn complex_enum_variant_field_getter( + variant_cls_type: &syn::Type, + field_name: &Ident, + field_type: &syn::Type, + field_attrs: &[syn::Attribute], + field_span: Span, + ctx: &Ctx, +) -> Result { + let mut arg = parse_quote!(py: Python<'_>); + let py = FnArg::parse(&mut arg)?; + let signature = FunctionSignature::from_arguments(vec![py]); + + let self_type = crate::method::SelfType::TryFromBoundRef { + span: field_span, + non_null: true, + }; + + let spec = FnSpec { + tp: crate::method::FnType::Getter(self_type.clone()), + name: field_name, + python_name: field_name.unraw(), + signature, + text_signature: None, + asyncness: None, + unsafety: None, + warnings: vec![], + output: parse_quote!(-> #field_type), + }; + + let property_type = PropertyType::Function { + self_type: &self_type, + spec: &spec, + doc: get_doc(field_attrs, None), + }; + + #[cfg_attr(not(feature = "experimental-inspect"), allow(unused_mut))] + let mut getter = impl_py_getter_def(variant_cls_type, property_type, ctx)?; + #[cfg(feature = "experimental-inspect")] + getter.add_introspection(method_introspection_code( + &spec, + field_attrs, + variant_cls_type, + false, + ctx, + )); + Ok(getter) +} + +fn descriptors_to_items( + cls: &Ident, + rename_all: Option<&RenameAllAttribute>, + frozen: Option, + field_options: Vec<(&syn::Field, FieldPyO3Options)>, + ctx: &Ctx, +) -> Result> { + let ty = syn::parse_quote!(#cls); + let mut items = Vec::new(); + for (field_index, (field, options)) in field_options.into_iter().enumerate() { + if let FieldPyO3Options { + name: Some(name), + get: None, + set: None, + } = options + { + return Err(syn::Error::new_spanned(name, USELESS_NAME)); + } + + if options.get.is_some() { + let renaming_rule = rename_all.map(|rename_all| rename_all.value.rule); + #[cfg_attr(not(feature = "experimental-inspect"), allow(unused_mut))] + let mut getter = impl_py_getter_def( + &ty, + PropertyType::Descriptor { + field_index, + field, + python_name: options.name.as_ref(), + renaming_rule, + }, + ctx, + )?; + #[cfg(feature = "experimental-inspect")] + { + // We generate introspection data + let parent = parse_quote!(#cls); + let return_type = field.ty.clone(); + getter.add_introspection(function_introspection_code( + &ctx.pyo3_path, + None, + &field_python_name(field, options.name.as_ref(), renaming_rule)?, + &FunctionSignature::from_arguments(vec![]), + Some("self"), + PyExpr::from_into_py_object_maybe_ref(return_type, Some(&parent)), + vec![PyExpr::builtin("property")], + false, + false, + get_doc(&field.attrs, None).as_ref(), + Some(&parent), + )); + } + items.push(getter); + } + + if let Some(set) = options.set { + ensure_spanned!(frozen.is_none(), set.span() => "cannot use `#[pyo3(set)]` on a `frozen` class"); + let renaming_rule = rename_all.map(|rename_all| rename_all.value.rule); + #[cfg_attr(not(feature = "experimental-inspect"), allow(unused_mut))] + let mut setter = impl_py_setter_def( + &ty, + PropertyType::Descriptor { + field_index, + field, + python_name: options.name.as_ref(), + renaming_rule, + }, + ctx, + )?; + #[cfg(feature = "experimental-inspect")] + { + // We generate introspection data + let name = field_python_name(field, options.name.as_ref(), renaming_rule)?; + setter.add_introspection(function_introspection_code( + &ctx.pyo3_path, + None, + &name, + &FunctionSignature::from_arguments(vec![FnArg::Regular(RegularArg { + name: Cow::Owned(format_ident!("value")), + ty: &field.ty, + from_py_with: None, + default_value: None, + option_wrapped_type: None, + annotation: None, + })]), + Some("self"), + PyExpr::none(), + vec![PyExpr::attribute( + PyExpr::attribute( + PyExpr::from_type( + syn::TypePath { + qself: None, + path: cls.clone().into(), + } + .into(), + None, + ), + name.clone(), + ), + "setter", + )], + false, + false, + get_doc(&field.attrs, None).as_ref(), + Some(&parse_quote!(#cls)), + )); + } + items.push(setter); + }; + } + Ok(items) +} + +fn impl_pytypeinfo(cls: &Ident, attr: &PyClassArgs, ctx: &Ctx) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + + #[cfg(feature = "experimental-inspect")] + let type_hint = { + let type_hint = get_class_type_hint(cls, attr, ctx); + quote! { const TYPE_HINT: #pyo3_path::inspect::PyStaticExpr = #type_hint; } + }; + #[cfg(not(feature = "experimental-inspect"))] + let type_hint = quote! {}; + #[cfg(not(feature = "experimental-inspect"))] + let _ = attr; + + quote! { + unsafe impl #pyo3_path::type_object::PyTypeInfo for #cls { + + const NAME: &str = ::NAME; + const MODULE: ::std::option::Option<&str> = ::MODULE; + + #type_hint + + #[inline] + fn type_object_raw(py: #pyo3_path::Python<'_>) -> *mut #pyo3_path::ffi::PyTypeObject { + use #pyo3_path::prelude::PyTypeMethods; + <#cls as #pyo3_path::impl_::pyclass::PyClassImpl>::lazy_type_object() + .get_or_try_init(py) + .unwrap_or_else(|e| #pyo3_path::impl_::pyclass::type_object_init_failed( + py, + e, + ::NAME + )) + .as_type_ptr() + } + } + } +} + +fn pyclass_richcmp_arms( + options: &PyClassPyO3Options, + ctx: &Ctx, +) -> std::result::Result { + let Ctx { pyo3_path, .. } = ctx; + + let eq_arms = options + .eq + .map(|eq| eq.span) + .or(options.eq_int.map(|eq_int| eq_int.span)) + .map(|span| { + quote_spanned! { span => + #pyo3_path::pyclass::CompareOp::Eq => { + #pyo3_path::IntoPyObjectExt::into_py_any(self_val == other, py) + }, + #pyo3_path::pyclass::CompareOp::Ne => { + #pyo3_path::IntoPyObjectExt::into_py_any(self_val != other, py) + }, + } + }) + .unwrap_or_default(); + + if let Some(ord) = options.ord { + ensure_spanned!(options.eq.is_some(), ord.span() => "The `ord` option requires the `eq` option."); + } + + let ord_arms = options + .ord + .map(|ord| { + quote_spanned! { ord.span() => + #pyo3_path::pyclass::CompareOp::Gt => { + #pyo3_path::IntoPyObjectExt::into_py_any(self_val > other, py) + }, + #pyo3_path::pyclass::CompareOp::Lt => { + #pyo3_path::IntoPyObjectExt::into_py_any(self_val < other, py) + }, + #pyo3_path::pyclass::CompareOp::Le => { + #pyo3_path::IntoPyObjectExt::into_py_any(self_val <= other, py) + }, + #pyo3_path::pyclass::CompareOp::Ge => { + #pyo3_path::IntoPyObjectExt::into_py_any(self_val >= other, py) + }, + } + }) + .unwrap_or_else(|| quote! { _ => ::std::result::Result::Ok(py.NotImplemented()) }); + + Ok(quote! { + #eq_arms + #ord_arms + }) +} + +fn pyclass_richcmp_simple_enum( + options: &PyClassPyO3Options, + cls: &syn::Type, + repr_type: &syn::Ident, + ctx: &Ctx, +) -> Result<(Option, Option)> { + let Ctx { pyo3_path, .. } = ctx; + if let Some(eq_int) = options.eq_int { + ensure_spanned!(options.eq.is_some(), eq_int.span() => "The `eq_int` option requires the `eq` option."); + } + + if options.eq.is_none() && options.eq_int.is_none() { + return Ok((None, None)); + } + + let arms = pyclass_richcmp_arms(options, ctx)?; + + let eq = options.eq.map(|eq| { + quote_spanned! { eq.span() => + let self_val = self; + if let ::std::result::Result::Ok(other) = #pyo3_path::types::PyAnyMethods::extract::<#pyo3_path::PyClassGuard<'_, Self>>(other) { + let other = &*other; + return match op { + #arms + } + } + } + }); + + let eq_int = options.eq_int.map(|eq_int| { + quote_spanned! { eq_int.span() => + let self_val = self.__pyo3__int__(); + if let ::std::result::Result::Ok(other) = #pyo3_path::types::PyAnyMethods::extract::<#repr_type>(other).or_else(|_| { + #pyo3_path::types::PyAnyMethods::extract::<#pyo3_path::PyClassGuard<'_, Self>>(other).map(|o| o.__pyo3__int__()) + }) { + return match op { + #arms + } + } + } + }); + + let mut richcmp_impl = parse_quote! { + fn __pyo3__generated____richcmp__( + &self, + py: #pyo3_path::Python, + other: &#pyo3_path::Bound<'_, #pyo3_path::PyAny>, + op: #pyo3_path::pyclass::CompareOp + ) -> #pyo3_path::PyResult<#pyo3_path::Py<#pyo3_path::PyAny>> { + #eq + + #eq_int + + ::std::result::Result::Ok(py.NotImplemented()) + } + }; + #[cfg(feature = "experimental-inspect")] + let any = parse_quote!(#pyo3_path::Py<#pyo3_path::PyAny>); + #[cfg(feature = "experimental-inspect")] + let introspection = FunctionIntrospectionData { + names: &["__eq__", "__ne__"], + // `value` is the parameter name CPython uses in the `tp_richcompare` slot wrappers + arguments: vec![FnArg::Regular(RegularArg { + name: Cow::Owned(format_ident!("value")), + ty: &any, + from_py_with: None, + default_value: None, + option_wrapped_type: None, + annotation: None, + })], + returns: parse_quote!(::std::primitive::bool), + is_returning_not_implemented_on_extraction_error: true, + }; + let richcmp_slot = if options.eq.is_some() { + generate_protocol_slot( + cls, + &mut richcmp_impl, + &__RICHCMP__, + "__richcmp__", + #[cfg(feature = "experimental-inspect")] + introspection, + ctx, + )? + } else { + generate_default_protocol_slot( + cls, + &mut richcmp_impl, + &__RICHCMP__, + #[cfg(feature = "experimental-inspect")] + introspection, + ctx, + )? + }; + Ok((Some(richcmp_impl), Some(richcmp_slot))) +} + +fn pyclass_richcmp( + options: &PyClassPyO3Options, + cls: &syn::Type, + ctx: &Ctx, +) -> Result<(Option, Option)> { + let Ctx { pyo3_path, .. } = ctx; + if let Some(eq_int) = options.eq_int { + bail_spanned!(eq_int.span() => "`eq_int` can only be used on simple enums.") + } + + let arms = pyclass_richcmp_arms(options, ctx)?; + if options.eq.is_some() { + let mut richcmp_impl = parse_quote! { + fn __pyo3__generated____richcmp__( + &self, + py: #pyo3_path::Python, + other: &#pyo3_path::Bound<'_, #pyo3_path::PyAny>, + op: #pyo3_path::pyclass::CompareOp + ) -> #pyo3_path::PyResult<#pyo3_path::Py<#pyo3_path::PyAny>> { + let self_val = self; + if let ::std::result::Result::Ok(other) = #pyo3_path::types::PyAnyMethods::extract::<#pyo3_path::PyClassGuard<'_, Self>>(other) { + let other = &*other; + match op { + #arms + } + } else { + ::std::result::Result::Ok(py.NotImplemented()) + } + } + }; + let richcmp_slot = generate_protocol_slot( + cls, + &mut richcmp_impl, + &__RICHCMP__, + "__richcmp__", + #[cfg(feature = "experimental-inspect")] + FunctionIntrospectionData { + names: if options.ord.is_some() { + &["__eq__", "__ne__", "__lt__", "__le__", "__gt__", "__ge__"] + } else { + &["__eq__", "__ne__"] + }, + // `value` is the parameter name CPython uses in the `tp_richcompare` slot wrappers + arguments: vec![FnArg::Regular(RegularArg { + name: Cow::Owned(format_ident!("value")), + ty: &parse_quote!(&#cls), + from_py_with: None, + default_value: None, + option_wrapped_type: None, + annotation: None, + })], + returns: parse_quote! { ::std::primitive::bool }, + is_returning_not_implemented_on_extraction_error: true, + }, + ctx, + )?; + Ok((Some(richcmp_impl), Some(richcmp_slot))) + } else { + Ok((None, None)) + } +} + +fn pyclass_hash( + options: &PyClassPyO3Options, + cls: &syn::Type, + ctx: &Ctx, +) -> Result<(Option, Option)> { + if options.hash.is_some() { + ensure_spanned!( + options.frozen.is_some(), options.hash.span() => "The `hash` option requires the `frozen` option."; + options.eq.is_some(), options.hash.span() => "The `hash` option requires the `eq` option."; + ); + } + match options.hash { + Some(opt) => { + let mut hash_impl = parse_quote_spanned! { opt.span() => + fn __pyo3__generated____hash__(&self) -> u64 { + let mut s = ::std::collections::hash_map::DefaultHasher::new(); + ::std::hash::Hash::hash(self, &mut s); + ::std::hash::Hasher::finish(&s) + } + }; + let hash_slot = generate_protocol_slot( + cls, + &mut hash_impl, + &__HASH__, + "__hash__", + #[cfg(feature = "experimental-inspect")] + FunctionIntrospectionData { + names: &["__hash__"], + arguments: Vec::new(), + returns: parse_quote! { ::std::primitive::u64 }, + is_returning_not_implemented_on_extraction_error: false, + }, + ctx, + )?; + Ok((Some(hash_impl), Some(hash_slot))) + } + None => Ok((None, None)), + } +} + +fn pyclass_new_impl<'a>( + options: &PyClassPyO3Options, + ty: &syn::Type, + fields: impl Iterator, + ctx: &Ctx, +) -> Result<(Option, Option)> { + if options + .new + .as_ref() + .is_some_and(|o| matches!(o.value, NewImplTypeAttributeValue::FromFields)) + { + ensure_spanned!( + options.extends.is_none(), options.new.span() => "The `new=\"from_fields\"` option cannot be used with `extends`."; + ); + } + + let mut tuple_struct: bool = false; + + match &options.new { + Some(opt) => { + let mut field_idents = vec![]; + let mut field_types = vec![]; + for (idx, field) in fields.enumerate() { + tuple_struct = field.ident.is_none(); + + field_idents.push( + field + .ident + .clone() + .unwrap_or_else(|| format_ident!("_{}", idx)), + ); + field_types.push(&field.ty); + } + + let mut new_impl = if tuple_struct { + parse_quote_spanned! { opt.span() => + #[new] + fn __pyo3_generated____new__( #( #field_idents : #field_types ),* ) -> Self { + Self ( + #( #field_idents, )* + ) + } + } + } else { + parse_quote_spanned! { opt.span() => + #[new] + fn __pyo3_generated____new__( #( #field_idents : #field_types ),* ) -> Self { + Self { + #( #field_idents, )* + } + } + } + }; + + let new_slot = generate_protocol_slot( + ty, + &mut new_impl, + &__NEW__, + "__new__", + #[cfg(feature = "experimental-inspect")] + FunctionIntrospectionData { + names: &["__new__"], + arguments: field_idents + .iter() + .zip(field_types.iter()) + .map(|(ident, ty)| { + FnArg::Regular(RegularArg { + name: Cow::Owned(ident.clone()), + ty, + from_py_with: None, + default_value: None, + option_wrapped_type: None, + annotation: None, + }) + }) + .collect(), + returns: ty.clone(), + is_returning_not_implemented_on_extraction_error: false, + }, + ctx, + ) + .unwrap(); + + Ok((Some(new_impl), Some(new_slot))) + } + None => Ok((None, None)), + } +} + +fn pyclass_class_getitem( + options: &PyClassPyO3Options, + cls: &syn::Type, + ctx: &Ctx, +) -> Result<(Option, Option)> { + let Ctx { pyo3_path, .. } = ctx; + match options.generic { + Some(_) => { + let ident = format_ident!("__class_getitem__"); + let mut class_getitem_impl: syn::ImplItemFn = { + parse_quote! { + #[classmethod] + fn #ident<'py>( + cls: &#pyo3_path::Bound<'py, #pyo3_path::types::PyType>, + key: &#pyo3_path::Bound<'py, #pyo3_path::types::PyAny> + ) -> #pyo3_path::PyResult<#pyo3_path::Bound<'py, #pyo3_path::types::PyGenericAlias>> { + #pyo3_path::types::PyGenericAlias::new(cls.py(), cls.as_any(), key) + } + } + }; + + let spec = FnSpec::parse( + &mut class_getitem_impl.sig, + &mut class_getitem_impl.attrs, + Default::default(), + )?; + + let class_getitem_method = crate::pymethod::impl_py_method_def( + cls, + &spec, + spec.get_doc(&class_getitem_impl.attrs).as_ref(), + ctx, + )?; + Ok((Some(class_getitem_impl), Some(class_getitem_method))) + } + None => Ok((None, None)), + } +} + +/// Implements most traits used by `#[pyclass]`. +/// +/// Specifically, it implements traits that only depend on class name, +/// and attributes of `#[pyclass]`, and docstrings. +/// Therefore it doesn't implement traits that depends on struct fields and enum variants. +struct PyClassImplsBuilder<'a> { + /// Identifier of the class Rust struct + cls_ident: &'a Ident, + /// Name of the class in Python + cls_name: &'a Ident, + attr: &'a PyClassArgs, + methods_type: PyClassMethodsType, + default_methods: Vec, + default_slots: Vec, + doc: Option, +} + +impl<'a> PyClassImplsBuilder<'a> { + fn new( + cls_ident: &'a Ident, + cls_name: &'a Ident, + attr: &'a PyClassArgs, + methods_type: PyClassMethodsType, + default_methods: Vec, + default_slots: Vec, + ) -> Self { + Self { + cls_ident, + cls_name, + attr, + methods_type, + default_methods, + default_slots, + doc: None, + } + } + + fn doc(self, doc: PythonDoc) -> Self { + Self { + doc: Some(doc), + ..self + } + } + + fn impl_pyclass(&self, ctx: &Ctx) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + let cls = self.cls_ident; + + let cls_name = get_class_python_name(self.cls_name, self.attr).to_string(); + + let frozen = if self.attr.options.frozen.is_some() { + quote! { #pyo3_path::pyclass::boolean_struct::True } + } else { + quote! { #pyo3_path::pyclass::boolean_struct::False } + }; + + quote! { + impl #pyo3_path::PyClass for #cls { + const NAME: &str = #cls_name; + type Frozen = #frozen; + } + } + } + + fn impl_into_py(&self, ctx: &Ctx) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + let cls = self.cls_ident; + let attr = self.attr; + // If #cls is not extended type, we allow Self->PyObject conversion + if attr.options.extends.is_none() { + let output_type = get_conversion_type_hint(ctx, &format_ident!("OUTPUT_TYPE"), cls); + quote! { + impl<'py> #pyo3_path::conversion::IntoPyObject<'py> for #cls { + type Target = Self; + type Output = #pyo3_path::Bound<'py, >::Target>; + type Error = #pyo3_path::PyErr; + #output_type + + fn into_pyobject(self, py: #pyo3_path::Python<'py>) -> ::std::result::Result< + ::Output, + ::Error, + > { + #pyo3_path::Bound::new(py, self) + } + } + } + } else { + quote! {} + } + } + fn impl_pyclassimpl(&self, ctx: &Ctx) -> Result { + let Ctx { pyo3_path, .. } = ctx; + let cls = self.cls_ident; + let doc = if let Some(doc) = &self.doc { + doc.to_cstr_stream(ctx)? + } else { + c"".to_token_stream() + }; + + let module = if let Some(ModuleAttribute { value, .. }) = &self.attr.options.module { + quote! { ::core::option::Option::Some(#value) } + } else { + quote! { ::core::option::Option::None } + }; + + let is_basetype = self.attr.options.subclass.is_some(); + let base = match &self.attr.options.extends { + Some(extends_attr) => extends_attr.value.clone(), + None => parse_quote! { #pyo3_path::PyAny }, + }; + let is_subclass = self.attr.options.extends.is_some(); + let is_mapping: bool = self.attr.options.mapping.is_some(); + let is_sequence: bool = self.attr.options.sequence.is_some(); + let is_immutable_type = self.attr.options.immutable_type.is_some(); + + ensure_spanned!( + !(is_mapping && is_sequence), + cls.span() => "a `#[pyclass]` cannot be both a `mapping` and a `sequence`" + ); + + let dict_offset = if self.attr.options.dict.is_some() { + quote! { + fn dict_offset() -> ::std::option::Option<#pyo3_path::impl_::pyclass::PyObjectOffset> { + ::std::option::Option::Some(#pyo3_path::impl_::pyclass::dict_offset::()) + } + } + } else { + TokenStream::new() + }; + + let weaklist_offset = if self.attr.options.weakref.is_some() { + quote! { + fn weaklist_offset() -> ::std::option::Option<#pyo3_path::impl_::pyclass::PyObjectOffset> { + ::std::option::Option::Some(#pyo3_path::impl_::pyclass::weaklist_offset::()) + } + } + } else { + TokenStream::new() + }; + + let thread_checker = if self.attr.options.unsendable.is_some() { + quote! { #pyo3_path::impl_::pyclass::ThreadCheckerImpl } + } else { + quote! { #pyo3_path::impl_::pyclass::NoopThreadChecker } + }; + + let (pymethods_items, inventory, inventory_class) = match self.methods_type { + PyClassMethodsType::Specialization => ( + quote! {{ use #pyo3_path::impl_::pyclass::PyMethods as _; collector.py_methods() }}, + None, + None, + ), + PyClassMethodsType::Inventory => { + // To allow multiple #[pymethods] block, we define inventory types. + let inventory_class_name = syn::Ident::new( + &format!("Pyo3MethodsInventoryFor{}", cls.unraw()), + Span::call_site(), + ); + ( + quote! { + ::std::boxed::Box::new( + ::std::iter::Iterator::map( + #pyo3_path::inventory::iter::<::Inventory>(), + #pyo3_path::impl_::pyclass::PyClassInventory::items + ) + ) + }, + Some(quote! { type Inventory = #inventory_class_name; }), + Some(define_inventory_class(&inventory_class_name, ctx)), + ) + } + }; + + let default_methods = self + .default_methods + .iter() + .map(|meth| &meth.associated_method) + .chain( + self.default_slots + .iter() + .map(|meth| &meth.associated_method), + ); + + let default_method_defs = self.default_methods.iter().map(|meth| &meth.method_def); + let default_slot_defs = self.default_slots.iter().map(|slot| &slot.slot_def); + let freelist_slots = self.freelist_slots(ctx); + + let class_mutability = if self.attr.options.frozen.is_some() { + quote! { + ImmutableChild + } + } else { + quote! { + MutableChild + } + }; + + let attr = self.attr; + let dict = if attr.options.dict.is_some() { + quote! { #pyo3_path::impl_::pyclass::PyClassDictSlot } + } else { + quote! { #pyo3_path::impl_::pyclass::PyClassDummySlot } + }; + + // insert space for weak ref + let weakref = if attr.options.weakref.is_some() { + quote! { #pyo3_path::impl_::pyclass::PyClassWeakRefSlot } + } else { + quote! { #pyo3_path::impl_::pyclass::PyClassDummySlot } + }; + + let base_nativetype = if attr.options.extends.is_some() { + quote! { ::BaseNativeType } + } else { + quote! { #pyo3_path::PyAny } + }; + + let pyclass_base_type_impl = attr.options.subclass.map(|subclass| { + quote_spanned! { subclass.span() => + impl #pyo3_path::impl_::pyclass::PyClassBaseType for #cls { + type LayoutAsBase = ::Layout; + type BaseNativeType = ::BaseNativeType; + type Initializer = #pyo3_path::pyclass_init::PyClassInitializer; + type PyClassMutability = ::PyClassMutability; + type Layout = ::Layout; + } + } + }); + + let mut assertions = TokenStream::new(); + + // Classes must implement send / sync, unless `#[pyclass(unsendable)]` is used + if attr.options.unsendable.is_none() { + let pyo3_path = locate_tokens_at(pyo3_path.to_token_stream(), cls.span()); + assertions.extend(quote_spanned! { cls.span() => #pyo3_path::impl_::pyclass::assert_pyclass_send_sync::<#cls>(); }); + }; + + if let Some(kw) = &attr.options.dict { + let pyo3_path = locate_tokens_at(pyo3_path.to_token_stream(), kw.span()); + assertions.extend(quote_spanned! { + kw.span() => + const ASSERT_DICT_SUPPORTED: () = #pyo3_path::impl_::pyclass::assert_dict_supported(); + + }); + } + + if let Some(kw) = &attr.options.weakref { + let pyo3_path = locate_tokens_at(pyo3_path.to_token_stream(), kw.span()); + assertions.extend(quote_spanned! { + kw.span() => { + const ASSERT_WEAKREF_SUPPORTED: () = #pyo3_path::impl_::pyclass::assert_weakref_supported(); + }; + }); + } + + if let Some(kw) = &attr.options.immutable_type { + let pyo3_path = locate_tokens_at(pyo3_path.to_token_stream(), kw.span()); + assertions.extend(quote_spanned! { + kw.span() => { + const ASSERT_IMMUTABLE_SUPPORTED: () = #pyo3_path::impl_::pyclass::assert_immutable_type_supported(); + }; + }); + } + + let deprecation = if self.attr.options.skip_from_py_object.is_none() + && self.attr.options.from_py_object.is_none() + { + quote! { + const _: () = { + #[allow(unused_import)] + use #pyo3_path::impl_::pyclass::Probe as _; + #pyo3_path::impl_::deprecated::HasAutomaticFromPyObject::<{ #pyo3_path::impl_::pyclass::IsClone::<#cls>::VALUE }>::MSG + }; + } + } else { + TokenStream::new() + }; + + let extract_pyclass_with_clone = if let Some(from_py_object) = + self.attr.options.from_py_object + { + let input_type = get_conversion_type_hint(ctx, &format_ident!("INPUT_TYPE"), cls); + quote_spanned! { from_py_object.span() => + impl<'a, 'py> #pyo3_path::FromPyObject<'a, 'py> for #cls + where + Self: ::std::clone::Clone, + { + type Error = #pyo3_path::pyclass::PyClassGuardError<'a, 'py>; + + #input_type + + fn extract(obj: #pyo3_path::Borrowed<'a, 'py, #pyo3_path::PyAny>) -> ::std::result::Result>::Error> { + ::std::result::Result::Ok(::std::clone::Clone::clone(&*obj.extract::<#pyo3_path::PyClassGuard<'_, #cls>>()?)) + } + } + } + } else if self.attr.options.skip_from_py_object.is_none() { + quote!( impl #pyo3_path::impl_::pyclass::ExtractPyClassWithClone for #cls {} ) + } else { + TokenStream::new() + }; + + Ok(quote! { + #deprecation + + #extract_pyclass_with_clone + + #[allow(dead_code)] + const _: () ={ + #assertions + }; + + #pyclass_base_type_impl + + impl #pyo3_path::impl_::pyclass::PyClassImpl for #cls { + const MODULE: ::std::option::Option<&str> = #module; + const IS_BASETYPE: bool = #is_basetype; + const IS_SUBCLASS: bool = #is_subclass; + const IS_MAPPING: bool = #is_mapping; + const IS_SEQUENCE: bool = #is_sequence; + const IS_IMMUTABLE_TYPE: bool = #is_immutable_type; + + type Layout = ::Layout; + type BaseType = #base; + type ThreadChecker = #thread_checker; + #inventory + type PyClassMutability = <<#base as #pyo3_path::impl_::pyclass::PyClassBaseType>::PyClassMutability as #pyo3_path::impl_::pycell::PyClassMutability>::#class_mutability; + type Dict = #dict; + type WeakRef = #weakref; + type BaseNativeType = #base_nativetype; + + fn items_iter() -> #pyo3_path::impl_::pyclass::PyClassItemsIter { + let collector = #pyo3_path::impl_::pyclass::PyClassImplCollector::::new(); + static INTRINSIC_ITEMS: #pyo3_path::impl_::pyclass::PyClassItems = #pyo3_path::impl_::pyclass::PyClassItems { + methods: &[#(#default_method_defs),*], + slots: &[#(#default_slot_defs),* #(#freelist_slots),*], + }; + #pyo3_path::impl_::pyclass::PyClassItemsIter::new(&INTRINSIC_ITEMS, #pymethods_items) + } + + const RAW_DOC: &'static ::std::ffi::CStr = #doc; + + const DOC: &'static ::std::ffi::CStr = { + use #pyo3_path::impl_ as impl_; + use impl_::pyclass::Probe as _; + const DOC_PIECES: &'static [&'static [u8]] = impl_::pyclass::doc::PyClassDocGenerator::< + #cls, + { impl_::pyclass::HasNewTextSignature::<#cls>::VALUE } + >::DOC_PIECES; + const LEN: usize = impl_::concat::combined_len(DOC_PIECES); + const DOC: &'static [u8] = &impl_::concat::combine_to_array::(DOC_PIECES); + impl_::pyclass::doc::doc_bytes_as_cstr(DOC) + }; + + #dict_offset + + #weaklist_offset + + fn lazy_type_object() -> &'static #pyo3_path::impl_::pyclass::LazyTypeObject { + use #pyo3_path::impl_::pyclass::LazyTypeObject; + static TYPE_OBJECT: LazyTypeObject<#cls> = LazyTypeObject::new(); + &TYPE_OBJECT + } + } + + #[doc(hidden)] + #[allow(non_snake_case)] + impl #cls { + #(#default_methods)* + } + + #inventory_class + }) + } + + fn impl_add_to_module(&self, ctx: &Ctx) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + let cls = self.cls_ident; + quote! { + impl #cls { + #[doc(hidden)] + pub const _PYO3_DEF: #pyo3_path::impl_::pymodule::AddClassToModule = #pyo3_path::impl_::pymodule::AddClassToModule::new(); + } + } + } + + fn impl_freelist(&self, ctx: &Ctx) -> TokenStream { + let cls = self.cls_ident; + let Ctx { pyo3_path, .. } = ctx; + + self.attr.options.freelist.as_ref().map_or(quote! {}, |freelist| { + let freelist = &freelist.value; + quote! { + impl #pyo3_path::impl_::pyclass::PyClassWithFreeList for #cls { + #[inline] + fn get_free_list(py: #pyo3_path::Python<'_>) -> &'static ::std::sync::Mutex<#pyo3_path::impl_::freelist::PyObjectFreeList> { + static FREELIST: #pyo3_path::sync::PyOnceLock<::std::sync::Mutex<#pyo3_path::impl_::freelist::PyObjectFreeList>> = #pyo3_path::sync::PyOnceLock::new(); + &FREELIST.get_or_init(py, || ::std::sync::Mutex::new(#pyo3_path::impl_::freelist::PyObjectFreeList::with_capacity(#freelist))) + } + } + } + }) + } + + fn freelist_slots(&self, ctx: &Ctx) -> Vec { + let Ctx { pyo3_path, .. } = ctx; + let cls = self.cls_ident; + + if self.attr.options.freelist.is_some() { + vec![ + quote! { + #pyo3_path::ffi::PyType_Slot { + slot: #pyo3_path::ffi::Py_tp_alloc, + pfunc: #pyo3_path::impl_::pyclass::alloc_with_freelist::<#cls> as *mut _, + } + }, + quote! { + #pyo3_path::ffi::PyType_Slot { + slot: #pyo3_path::ffi::Py_tp_free, + pfunc: #pyo3_path::impl_::pyclass::free_with_freelist::<#cls> as *mut _, + } + }, + ] + } else { + Vec::new() + } + } + + #[cfg(feature = "experimental-inspect")] + fn impl_introspection(&self, ctx: &Ctx, parent: Option<&Ident>) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + let name = get_class_python_name(self.cls_name, self.attr).to_string(); + let ident = self.cls_ident; + let static_introspection = class_introspection_code( + pyo3_path, + ident, + &name, + self.attr.options.extends.as_ref().map(|attr| { + PyExpr::from_type( + syn::TypePath { + qself: None, + path: attr.value.clone(), + } + .into(), + None, + ) + }), + self.attr.options.subclass.is_none(), + parent.map(|p| parse_quote!(#p)).as_ref(), + self.doc.as_ref(), + ); + let introspection_id = introspection_id_const(); + quote! { + #static_introspection + impl #ident { + #introspection_id + } + } + } + + #[cfg(not(feature = "experimental-inspect"))] + fn impl_introspection(&self, _ctx: &Ctx, _parent: Option<&Ident>) -> TokenStream { + quote! {} + } +} + +fn define_inventory_class(inventory_class_name: &syn::Ident, ctx: &Ctx) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + quote! { + #[doc(hidden)] + pub struct #inventory_class_name { + items: #pyo3_path::impl_::pyclass::PyClassItems, + } + impl #inventory_class_name { + pub const fn new(items: #pyo3_path::impl_::pyclass::PyClassItems) -> Self { + Self { items } + } + } + + impl #pyo3_path::impl_::pyclass::PyClassInventory for #inventory_class_name { + fn items(&self) -> &#pyo3_path::impl_::pyclass::PyClassItems { + &self.items + } + } + + #pyo3_path::inventory::collect!(#inventory_class_name); + } +} + +fn generate_cfg_check(variants: &[PyClassEnumUnitVariant<'_>], cls: &syn::Ident) -> TokenStream { + if variants.is_empty() { + return quote! {}; + } + + let mut conditions = Vec::new(); + + for variant in variants { + let cfg_attrs = get_cfg_attributes(&variant.attrs); + + if cfg_attrs.is_empty() { + // There's at least one variant of the enum without cfg attributes, + // so the check is not necessary + return quote! {}; + } + + for attr in cfg_attrs { + if let syn::Meta::List(meta) = &attr.meta { + let cfg_tokens = &meta.tokens; + conditions.push(quote! { not(#cfg_tokens) }); + } + } + } + + quote_spanned! { + cls.span() => + #[cfg(all(#(#conditions),*))] + ::core::compile_error!(concat!("#[pyclass] can't be used on enums without any variants - all variants of enum `", stringify!(#cls), "` have been configured out by cfg attributes")); + } +} + +fn get_conversion_type_hint( + Ctx { pyo3_path, .. }: &Ctx, + konst: &Ident, + cls: &Ident, +) -> TokenStream { + if cfg!(feature = "experimental-inspect") { + quote!(const #konst: #pyo3_path::inspect::PyStaticExpr = <#cls as #pyo3_path::PyTypeInfo>::TYPE_HINT;) + } else { + TokenStream::new() + } +} + +const UNIQUE_GET: &str = "`get` may only be specified once"; +const UNIQUE_SET: &str = "`set` may only be specified once"; +const UNIQUE_NAME: &str = "`name` may only be specified once"; + +const DUPE_SET: &str = "useless `set` - the struct is already annotated with `set_all`"; +const DUPE_GET: &str = "useless `get` - the struct is already annotated with `get_all`"; +const UNIT_GET: &str = + "`get_all` on an unit struct does nothing, because unit structs have no fields"; +const UNIT_SET: &str = + "`set_all` on an unit struct does nothing, because unit structs have no fields"; + +const USELESS_NAME: &str = "`name` is useless without `get` or `set`"; diff --git a/vendor/pyo3-macros-backend/src/pyfunction.rs b/vendor/pyo3-macros-backend/src/pyfunction.rs new file mode 100644 index 0000000..759ed8d --- /dev/null +++ b/vendor/pyo3-macros-backend/src/pyfunction.rs @@ -0,0 +1,483 @@ +use crate::attributes::KeywordAttribute; +use crate::combine_errors::CombineErrors; +#[cfg(feature = "experimental-inspect")] +use crate::introspection::{function_introspection_code, introspection_id_const}; +#[cfg(feature = "experimental-inspect")] +use crate::py_expr::PyExpr; +#[cfg(feature = "experimental-inspect")] +use crate::utils::get_doc; +use crate::utils::Ctx; +use crate::{ + attributes::{ + self, get_pyo3_options, take_attributes, take_pyo3_options, CrateAttribute, + FromPyWithAttribute, NameAttribute, TextSignatureAttribute, + }, + method::{self, CallingConvention, ClassMethodReceiver, FnArg, SelfConversionPolicy}, + pymethod::check_generic, +}; +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote, ToTokens}; +use std::cmp::PartialEq; +use std::ffi::CString; +#[cfg(feature = "experimental-inspect")] +use std::iter::empty; +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; +#[cfg(feature = "experimental-inspect")] +use syn::ReturnType; +use syn::{ext::IdentExt, spanned::Spanned, LitCStr, LitStr, Path, Result, Token}; + +mod signature; + +pub use self::signature::{ConstructorAttribute, FunctionSignature, SignatureAttribute}; + +#[derive(Clone, Debug)] +pub struct PyFunctionArgPyO3Attributes { + pub from_py_with: Option, + pub cancel_handle: Option, +} + +enum PyFunctionArgPyO3Attribute { + FromPyWith(FromPyWithAttribute), + CancelHandle(attributes::kw::cancel_handle), +} + +impl Parse for PyFunctionArgPyO3Attribute { + fn parse(input: ParseStream<'_>) -> Result { + let lookahead = input.lookahead1(); + if lookahead.peek(attributes::kw::cancel_handle) { + input.parse().map(PyFunctionArgPyO3Attribute::CancelHandle) + } else if lookahead.peek(attributes::kw::from_py_with) { + input.parse().map(PyFunctionArgPyO3Attribute::FromPyWith) + } else { + Err(lookahead.error()) + } + } +} + +impl PyFunctionArgPyO3Attributes { + /// Parses #[pyo3(from_python_with = "func")] + pub fn from_attrs(attrs: &mut Vec) -> syn::Result { + let mut attributes = PyFunctionArgPyO3Attributes { + from_py_with: None, + cancel_handle: None, + }; + take_attributes(attrs, |attr| { + if let Some(pyo3_attrs) = get_pyo3_options(attr)? { + for attr in pyo3_attrs { + match attr { + PyFunctionArgPyO3Attribute::FromPyWith(from_py_with) => { + ensure_spanned!( + attributes.from_py_with.is_none(), + from_py_with.span() => "`from_py_with` may only be specified once per argument" + ); + attributes.from_py_with = Some(from_py_with); + } + PyFunctionArgPyO3Attribute::CancelHandle(cancel_handle) => { + ensure_spanned!( + attributes.cancel_handle.is_none(), + cancel_handle.span() => "`cancel_handle` may only be specified once per argument" + ); + attributes.cancel_handle = Some(cancel_handle); + } + } + ensure_spanned!( + attributes.from_py_with.is_none() || attributes.cancel_handle.is_none(), + attributes.cancel_handle.unwrap().span() => "`from_py_with` and `cancel_handle` cannot be specified together" + ); + } + Ok(true) + } else { + Ok(false) + } + })?; + Ok(attributes) + } +} + +type PyFunctionWarningMessageAttribute = KeywordAttribute; +type PyFunctionWarningCategoryAttribute = KeywordAttribute; + +pub struct PyFunctionWarningAttribute { + pub message: PyFunctionWarningMessageAttribute, + pub category: Option, + pub span: Span, +} + +#[derive(PartialEq, Clone)] +pub enum PyFunctionWarningCategory { + Path(Path), + UserWarning, + DeprecationWarning, // TODO: unused for now, intended for pyo3(deprecated) special-case +} + +#[derive(Clone)] +pub struct PyFunctionWarning { + pub message: LitStr, + pub category: PyFunctionWarningCategory, + pub span: Span, +} + +impl From for PyFunctionWarning { + fn from(value: PyFunctionWarningAttribute) -> Self { + Self { + message: value.message.value, + category: value + .category + .map_or(PyFunctionWarningCategory::UserWarning, |cat| { + PyFunctionWarningCategory::Path(cat.value) + }), + span: value.span, + } + } +} + +pub trait WarningFactory { + fn build_py_warning(&self, ctx: &Ctx) -> TokenStream; + fn span(&self) -> Span; +} + +impl WarningFactory for PyFunctionWarning { + fn build_py_warning(&self, ctx: &Ctx) -> TokenStream { + let message = &self.message.value(); + let c_message = LitCStr::new( + &CString::new(message.clone()).unwrap(), + Spanned::span(&message), + ); + let pyo3_path = &ctx.pyo3_path; + let category = match &self.category { + PyFunctionWarningCategory::Path(path) => quote! {#path}, + PyFunctionWarningCategory::UserWarning => { + quote! {#pyo3_path::exceptions::PyUserWarning} + } + PyFunctionWarningCategory::DeprecationWarning => { + quote! {#pyo3_path::exceptions::PyDeprecationWarning} + } + }; + quote! { + #pyo3_path::PyErr::warn(py, &<#category as #pyo3_path::PyTypeInfo>::type_object(py), #c_message, 1)?; + } + } + + fn span(&self) -> Span { + self.span + } +} + +impl WarningFactory for Vec { + fn build_py_warning(&self, ctx: &Ctx) -> TokenStream { + let warnings = self.iter().map(|warning| warning.build_py_warning(ctx)); + + quote! { + #(#warnings)* + } + } + + fn span(&self) -> Span { + self.iter() + .map(|val| val.span()) + .reduce(|acc, span| acc.join(span).unwrap_or(acc)) + .unwrap() + } +} + +impl Parse for PyFunctionWarningAttribute { + fn parse(input: ParseStream<'_>) -> Result { + let mut message: Option = None; + let mut category: Option = None; + + let span = input.parse::()?.span(); + + let content; + syn::parenthesized!(content in input); + + while !content.is_empty() { + let lookahead = content.lookahead1(); + + if lookahead.peek(attributes::kw::message) { + message = content + .parse::() + .map(Some)?; + } else if lookahead.peek(attributes::kw::category) { + category = content + .parse::() + .map(Some)?; + } else { + return Err(lookahead.error()); + } + + if content.peek(Token![,]) { + content.parse::()?; + } + } + + Ok(PyFunctionWarningAttribute { + message: message.ok_or(syn::Error::new( + content.span(), + "missing `message` in `warn` attribute", + ))?, + category, + span, + }) + } +} + +impl ToTokens for PyFunctionWarningAttribute { + fn to_tokens(&self, tokens: &mut TokenStream) { + let message_tokens = self.message.to_token_stream(); + let category_tokens = self + .category + .as_ref() + .map_or(quote! {}, |cat| cat.to_token_stream()); + + let token_stream = quote! { + warn(#message_tokens, #category_tokens) + }; + + tokens.extend(token_stream); + } +} + +#[derive(Default)] +pub struct PyFunctionOptions { + pub pass_module: Option, + pub name: Option, + pub signature: Option, + pub text_signature: Option, + pub krate: Option, + pub warnings: Vec, +} + +impl Parse for PyFunctionOptions { + fn parse(input: ParseStream<'_>) -> Result { + let mut options = PyFunctionOptions::default(); + + let attrs = Punctuated::::parse_terminated(input)?; + options.add_attributes(attrs)?; + + Ok(options) + } +} + +pub enum PyFunctionOption { + Name(NameAttribute), + PassModule(attributes::kw::pass_module), + Signature(SignatureAttribute), + TextSignature(TextSignatureAttribute), + Crate(CrateAttribute), + Warning(PyFunctionWarningAttribute), +} + +impl Parse for PyFunctionOption { + fn parse(input: ParseStream<'_>) -> Result { + let lookahead = input.lookahead1(); + if lookahead.peek(attributes::kw::name) { + input.parse().map(PyFunctionOption::Name) + } else if lookahead.peek(attributes::kw::pass_module) { + input.parse().map(PyFunctionOption::PassModule) + } else if lookahead.peek(attributes::kw::signature) { + input.parse().map(PyFunctionOption::Signature) + } else if lookahead.peek(attributes::kw::text_signature) { + input.parse().map(PyFunctionOption::TextSignature) + } else if lookahead.peek(syn::Token![crate]) { + input.parse().map(PyFunctionOption::Crate) + } else if lookahead.peek(attributes::kw::warn) { + input.parse().map(PyFunctionOption::Warning) + } else { + Err(lookahead.error()) + } + } +} + +impl PyFunctionOptions { + pub fn from_attrs(attrs: &mut Vec) -> syn::Result { + let mut options = PyFunctionOptions::default(); + options.add_attributes(take_pyo3_options(attrs)?)?; + Ok(options) + } + + pub fn add_attributes( + &mut self, + attrs: impl IntoIterator, + ) -> Result<()> { + macro_rules! set_option { + ($key:ident) => { + { + ensure_spanned!( + self.$key.is_none(), + $key.span() => concat!("`", stringify!($key), "` may only be specified once") + ); + self.$key = Some($key); + } + }; + } + for attr in attrs { + match attr { + PyFunctionOption::Name(name) => set_option!(name), + PyFunctionOption::PassModule(pass_module) => set_option!(pass_module), + PyFunctionOption::Signature(signature) => set_option!(signature), + PyFunctionOption::TextSignature(text_signature) => set_option!(text_signature), + PyFunctionOption::Crate(krate) => set_option!(krate), + PyFunctionOption::Warning(warning) => { + self.warnings.push(warning.into()); + } + } + } + Ok(()) + } +} + +pub fn build_py_function( + ast: &mut syn::ItemFn, + mut options: PyFunctionOptions, +) -> syn::Result { + options.add_attributes(take_pyo3_options(&mut ast.attrs)?)?; + impl_wrap_pyfunction(ast, options) +} + +/// Generates python wrapper over a function that allows adding it to a python module as a python +/// function +pub fn impl_wrap_pyfunction( + func: &mut syn::ItemFn, + options: PyFunctionOptions, +) -> syn::Result { + check_generic(&func.sig)?; + let PyFunctionOptions { + pass_module, + name, + signature, + text_signature, + krate, + warnings, + } = options; + + let ctx = &Ctx::new(&krate, Some(&func.sig)); + let Ctx { pyo3_path, .. } = &ctx; + + let python_name = name + .as_ref() + .map_or_else(|| &func.sig.ident, |name| &name.value.0) + .unraw(); + + let tp = if pass_module.is_some() { + let span = match func.sig.inputs.first() { + Some(syn::FnArg::Typed(first_arg)) => first_arg.ty.span(), + Some(syn::FnArg::Receiver(_)) | None => bail_spanned!( + func.sig.paren_token.span.join() => "expected `&PyModule` or `Py` as first argument with `pass_module`" + ), + }; + method::FnType::FnModule(span) + } else { + method::FnType::FnStatic + }; + + let arguments = func + .sig + .inputs + .iter_mut() + .skip(if tp.skip_first_rust_argument_in_python_signature() { + 1 + } else { + 0 + }) + .map(FnArg::parse) + .try_combine_syn_errors()?; + + let signature = if let Some(signature) = signature { + FunctionSignature::from_arguments_and_attribute(arguments, signature)? + } else { + FunctionSignature::from_arguments(arguments) + }; + + let spec = method::FnSpec { + tp, + name: &func.sig.ident, + python_name, + signature, + text_signature, + asyncness: func.sig.asyncness, + unsafety: func.sig.unsafety, + warnings, + output: func.sig.output.clone(), + }; + + let vis = &func.vis; + let name = &func.sig.ident; + + #[cfg(feature = "experimental-inspect")] + let introspection = function_introspection_code( + pyo3_path, + Some(name), + // `name` is the Rust identifier, which `#[pyo3(name = "...")]` overrides for Python + &spec.python_name.to_string(), + &spec.signature, + None, + match &func.sig.output { + ReturnType::Type(_, t) => PyExpr::from_return_type((**t).clone(), None), + ReturnType::Default => PyExpr::none(), + }, + empty(), + func.sig.asyncness.is_some(), + false, + get_doc(&func.attrs, None).as_ref(), + None, + ); + #[cfg(not(feature = "experimental-inspect"))] + let introspection = quote! {}; + #[cfg(feature = "experimental-inspect")] + let introspection_id = introspection_id_const(); + #[cfg(not(feature = "experimental-inspect"))] + let introspection_id = quote! {}; + + let wrapper_ident = format_ident!("__pyfunction_{}", spec.name); + if spec.asyncness.is_some() { + ensure_spanned!( + cfg!(feature = "experimental-async"), + spec.asyncness.span() => "async functions are only supported with the `experimental-async` feature" + ); + } + let calling_convention = CallingConvention::from_signature(&spec.signature); + let wrapper = spec.get_wrapper_function( + &wrapper_ident, + None, + calling_convention, + SelfConversionPolicy::checked(), + ClassMethodReceiver::Class, + ctx, + )?; + let methoddef = spec.get_methoddef( + wrapper_ident, + spec.get_doc(&func.attrs).as_ref(), + calling_convention, + ctx, + )?; + + let wrapped_pyfunction = quote! { + // Create a module with the same name as the `#[pyfunction]` - this way `use ` + // will actually bring both the module and the function into scope. + #[doc(hidden)] + #vis mod #name { + pub(crate) struct MakeDef; + pub static _PYO3_DEF: #pyo3_path::impl_::pyfunction::PyFunctionDef = MakeDef::_PYO3_DEF; + #introspection_id + } + + // Generate the definition in the same scope as the original function - + // this avoids complications around the fact that the generated module has a different scope + // (and `super` doesn't always refer to the outer scope, e.g. if the `#[pyfunction] is + // inside a function body) + #[allow(unknown_lints, non_local_definitions)] + impl #name::MakeDef { + // We're using this to initialize a static, so it's fine. + #[allow(clippy::declare_interior_mutable_const)] + const _PYO3_DEF: #pyo3_path::impl_::pyfunction::PyFunctionDef = + #pyo3_path::impl_::pyfunction::PyFunctionDef::from_method_def(#methoddef); + } + + #[allow(non_snake_case)] + #wrapper + + #introspection + }; + Ok(wrapped_pyfunction) +} diff --git a/vendor/pyo3-macros-backend/src/pyfunction/signature.rs b/vendor/pyo3-macros-backend/src/pyfunction/signature.rs new file mode 100644 index 0000000..f8873ee --- /dev/null +++ b/vendor/pyo3-macros-backend/src/pyfunction/signature.rs @@ -0,0 +1,657 @@ +#[cfg(feature = "experimental-inspect")] +use crate::py_expr::PyExpr; +use crate::{ + attributes::{kw, KeywordAttribute}, + method::FnArg, + utils::expr_to_python, +}; +use proc_macro2::{Span, TokenStream}; +use quote::ToTokens; +use syn::{ + ext::IdentExt, + parse::{Parse, ParseStream}, + punctuated::Punctuated, + spanned::Spanned, + Expr, Token, +}; + +#[derive(Clone)] +pub struct Signature { + paren_token: syn::token::Paren, + pub items: Punctuated, + pub returns: Option<(Token![->], PyTypeAnnotation)>, +} + +impl Parse for Signature { + fn parse(input: ParseStream<'_>) -> syn::Result { + let content; + let paren_token = syn::parenthesized!(content in input); + let items = content.parse_terminated(SignatureItem::parse, Token![,])?; + let returns = if input.peek(Token![->]) { + Some((input.parse()?, input.parse()?)) + } else { + None + }; + Ok(Signature { + paren_token, + items, + returns, + }) + } +} + +impl ToTokens for Signature { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.paren_token + .surround(tokens, |tokens| self.items.to_tokens(tokens)); + if let Some((arrow, returns)) = &self.returns { + arrow.to_tokens(tokens); + returns.to_tokens(tokens); + } + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct SignatureItemArgument { + pub ident: syn::Ident, + pub colon_and_annotation: Option<(Token![:], PyTypeAnnotation)>, + pub eq_and_default: Option<(Token![=], syn::Expr)>, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct SignatureItemPosargsSep { + pub slash: Token![/], +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct SignatureItemVarargsSep { + pub asterisk: Token![*], +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct SignatureItemVarargs { + pub sep: SignatureItemVarargsSep, + pub ident: syn::Ident, + pub colon_and_annotation: Option<(Token![:], PyTypeAnnotation)>, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct SignatureItemKwargs { + pub asterisks: (Token![*], Token![*]), + pub ident: syn::Ident, + pub colon_and_annotation: Option<(Token![:], PyTypeAnnotation)>, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum SignatureItem { + Argument(Box), + PosargsSep(SignatureItemPosargsSep), + VarargsSep(SignatureItemVarargsSep), + Varargs(SignatureItemVarargs), + Kwargs(SignatureItemKwargs), +} + +impl Parse for SignatureItem { + fn parse(input: ParseStream<'_>) -> syn::Result { + let lookahead = input.lookahead1(); + if lookahead.peek(Token![*]) { + if input.peek2(Token![*]) { + input.parse().map(SignatureItem::Kwargs) + } else { + let sep = input.parse()?; + if input.is_empty() || input.peek(Token![,]) { + Ok(SignatureItem::VarargsSep(sep)) + } else { + Ok(SignatureItem::Varargs(SignatureItemVarargs { + sep, + ident: input.parse()?, + colon_and_annotation: if input.peek(Token![:]) { + Some((input.parse()?, input.parse()?)) + } else { + None + }, + })) + } + } + } else if lookahead.peek(Token![/]) { + input.parse().map(SignatureItem::PosargsSep) + } else { + input.parse().map(SignatureItem::Argument) + } + } +} + +impl ToTokens for SignatureItem { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + SignatureItem::Argument(arg) => arg.to_tokens(tokens), + SignatureItem::Varargs(varargs) => varargs.to_tokens(tokens), + SignatureItem::VarargsSep(sep) => sep.to_tokens(tokens), + SignatureItem::Kwargs(kwargs) => kwargs.to_tokens(tokens), + SignatureItem::PosargsSep(sep) => sep.to_tokens(tokens), + } + } +} + +impl Parse for SignatureItemArgument { + fn parse(input: ParseStream<'_>) -> syn::Result { + Ok(Self { + ident: input.parse()?, + colon_and_annotation: if input.peek(Token![:]) { + Some((input.parse()?, input.parse()?)) + } else { + None + }, + eq_and_default: if input.peek(Token![=]) { + Some((input.parse()?, input.parse()?)) + } else { + None + }, + }) + } +} + +impl ToTokens for SignatureItemArgument { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.ident.to_tokens(tokens); + if let Some((colon, annotation)) = &self.colon_and_annotation { + colon.to_tokens(tokens); + annotation.to_tokens(tokens); + } + if let Some((eq, default)) = &self.eq_and_default { + eq.to_tokens(tokens); + default.to_tokens(tokens); + } + } +} + +impl Parse for SignatureItemVarargsSep { + fn parse(input: ParseStream<'_>) -> syn::Result { + Ok(Self { + asterisk: input.parse()?, + }) + } +} + +impl ToTokens for SignatureItemVarargsSep { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.asterisk.to_tokens(tokens); + } +} + +impl Parse for SignatureItemVarargs { + fn parse(input: ParseStream<'_>) -> syn::Result { + Ok(Self { + sep: input.parse()?, + ident: input.parse()?, + colon_and_annotation: if input.peek(Token![:]) { + Some((input.parse()?, input.parse()?)) + } else { + None + }, + }) + } +} + +impl ToTokens for SignatureItemVarargs { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.sep.to_tokens(tokens); + self.ident.to_tokens(tokens); + } +} + +impl Parse for SignatureItemKwargs { + fn parse(input: ParseStream<'_>) -> syn::Result { + Ok(Self { + asterisks: (input.parse()?, input.parse()?), + ident: input.parse()?, + colon_and_annotation: if input.peek(Token![:]) { + Some((input.parse()?, input.parse()?)) + } else { + None + }, + }) + } +} + +impl ToTokens for SignatureItemKwargs { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.asterisks.0.to_tokens(tokens); + self.asterisks.1.to_tokens(tokens); + self.ident.to_tokens(tokens); + } +} + +impl Parse for SignatureItemPosargsSep { + fn parse(input: ParseStream<'_>) -> syn::Result { + Ok(Self { + slash: input.parse()?, + }) + } +} + +impl ToTokens for SignatureItemPosargsSep { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.slash.to_tokens(tokens); + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct PyTypeAnnotation(syn::LitStr); + +impl Parse for PyTypeAnnotation { + fn parse(input: ParseStream<'_>) -> syn::Result { + Ok(Self(input.parse()?)) + } +} + +impl ToTokens for PyTypeAnnotation { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.0.to_tokens(tokens); + } +} + +impl PyTypeAnnotation { + #[cfg(feature = "experimental-inspect")] + pub fn as_type_hint(&self) -> PyExpr { + PyExpr::str_constant(self.0.value()) + } +} + +pub type SignatureAttribute = KeywordAttribute; +pub type ConstructorAttribute = KeywordAttribute; + +impl ConstructorAttribute { + pub fn into_signature(self) -> SignatureAttribute { + SignatureAttribute { + kw: kw::signature(self.kw.span), + value: self.value, + } + } +} + +#[derive(Default, Clone)] +pub struct PythonSignature { + pub positional_parameters: Vec, + pub positional_only_parameters: usize, + /// Vector of expressions representing positional defaults + pub default_positional_parameters: Vec, + pub varargs: Option, + // Tuples of keyword name and optional default value + pub keyword_only_parameters: Vec<(String, Option)>, + pub kwargs: Option, +} + +impl PythonSignature { + pub fn has_no_args(&self) -> bool { + self.positional_parameters.is_empty() + && self.keyword_only_parameters.is_empty() + && self.varargs.is_none() + && self.kwargs.is_none() + } + + pub fn required_positional_parameters(&self) -> usize { + self.positional_parameters + .len() + .checked_sub(self.default_positional_parameters.len()) + .expect("should always have positional defaults <= positional parameters") + } + + /// Makes every positional parameter positional-only, exactly as a trailing `/` in a + /// signature does. Deliberately leaves keyword-only parameters alone. + pub fn make_all_parameters_positional_only(&mut self) { + self.positional_only_parameters = self.positional_parameters.len(); + } +} + +#[derive(Clone)] +pub struct FunctionSignature<'a> { + pub arguments: Vec>, + pub python_signature: PythonSignature, + pub attribute: Option, +} + +pub enum ParseState { + /// Accepting positional parameters, which might be positional only + Positional, + /// Accepting positional parameters after '/' + PositionalAfterPosargs, + /// Accepting keyword-only parameters after '*' or '*args' + Keywords, + /// After `**kwargs` nothing is allowed + Done, +} + +impl ParseState { + fn add_argument( + &mut self, + signature: &mut PythonSignature, + name: String, + default_value: Option, + span: Span, + ) -> syn::Result<()> { + match self { + ParseState::Positional | ParseState::PositionalAfterPosargs => { + signature.positional_parameters.push(name); + if let Some(default_value) = default_value { + signature.default_positional_parameters.push(default_value); + // Now all subsequent positional parameters must also have defaults + } else if !signature.default_positional_parameters.is_empty() { + bail_spanned!(span => "cannot have required positional parameter after an optional parameter") + } + Ok(()) + } + ParseState::Keywords => { + signature + .keyword_only_parameters + .push((name, default_value)); + Ok(()) + } + ParseState::Done => { + bail_spanned!(span => format!("no more arguments are allowed after `**{}`", signature.kwargs.as_deref().unwrap_or(""))) + } + } + } + + fn add_varargs( + &mut self, + signature: &mut PythonSignature, + varargs: &SignatureItemVarargs, + ) -> syn::Result<()> { + match self { + ParseState::Positional | ParseState::PositionalAfterPosargs => { + signature.varargs = Some(varargs.ident.to_string()); + *self = ParseState::Keywords; + Ok(()) + } + ParseState::Keywords => { + bail_spanned!(varargs.span() => format!("`*{}` not allowed after `*{}`", varargs.ident, signature.varargs.as_deref().unwrap_or(""))) + } + ParseState::Done => { + bail_spanned!(varargs.span() => format!("`*{}` not allowed after `**{}`", varargs.ident, signature.kwargs.as_deref().unwrap_or(""))) + } + } + } + + fn add_kwargs( + &mut self, + signature: &mut PythonSignature, + kwargs: &SignatureItemKwargs, + ) -> syn::Result<()> { + match self { + ParseState::Positional | ParseState::PositionalAfterPosargs | ParseState::Keywords => { + signature.kwargs = Some(kwargs.ident.to_string()); + *self = ParseState::Done; + Ok(()) + } + ParseState::Done => { + bail_spanned!(kwargs.span() => format!("`**{}` not allowed after `**{}`", kwargs.ident, signature.kwargs.as_deref().unwrap_or(""))) + } + } + } + + fn finish_pos_only_args( + &mut self, + signature: &mut PythonSignature, + span: Span, + ) -> syn::Result<()> { + match self { + ParseState::Positional => { + signature.make_all_parameters_positional_only(); + *self = ParseState::PositionalAfterPosargs; + Ok(()) + } + ParseState::PositionalAfterPosargs => { + bail_spanned!(span => "`/` not allowed after `/`") + } + ParseState::Keywords => { + bail_spanned!(span => format!("`/` not allowed after `*{}`", signature.varargs.as_deref().unwrap_or(""))) + } + ParseState::Done => { + bail_spanned!(span => format!("`/` not allowed after `**{}`", signature.kwargs.as_deref().unwrap_or(""))) + } + } + } + + fn finish_pos_args(&mut self, signature: &PythonSignature, span: Span) -> syn::Result<()> { + match self { + ParseState::Positional | ParseState::PositionalAfterPosargs => { + *self = ParseState::Keywords; + Ok(()) + } + ParseState::Keywords => { + bail_spanned!(span => format!("`*` not allowed after `*{}`", signature.varargs.as_deref().unwrap_or(""))) + } + ParseState::Done => { + bail_spanned!(span => format!("`*` not allowed after `**{}`", signature.kwargs.as_deref().unwrap_or(""))) + } + } + } +} + +impl<'a> FunctionSignature<'a> { + pub fn from_arguments_and_attribute( + mut arguments: Vec>, + attribute: SignatureAttribute, + ) -> syn::Result { + let mut parse_state = ParseState::Positional; + let mut python_signature = PythonSignature::default(); + + let mut args_iter = arguments.iter_mut(); + + let mut next_non_py_argument_checked = |name: &syn::Ident| { + for fn_arg in args_iter.by_ref() { + match fn_arg { + FnArg::Py(..) => { + // If the user incorrectly tried to include py: Python in the + // signature, give a useful error as a hint. + ensure_spanned!( + name != fn_arg.name(), + name.span() => "arguments of type `Python` must not be part of the signature" + ); + // Otherwise try next argument. + continue; + } + FnArg::CancelHandle(..) => { + // If the user incorrectly tried to include cancel: CoroutineCancel in the + // signature, give a useful error as a hint. + ensure_spanned!( + name != fn_arg.name(), + name.span() => "`cancel_handle` argument must not be part of the signature" + ); + // Otherwise try next argument. + continue; + } + _ => { + ensure_spanned!( + name == fn_arg.name(), + name.span() => format!( + "expected argument from function definition `{}` but got argument `{}`", + fn_arg.name().unraw(), + name.unraw(), + ) + ); + return Ok(fn_arg); + } + } + } + bail_spanned!( + name.span() => "signature entry does not have a corresponding function argument" + ) + }; + + for item in &attribute.value.items { + match item { + SignatureItem::Argument(arg) => { + let fn_arg = next_non_py_argument_checked(&arg.ident)?; + parse_state.add_argument( + &mut python_signature, + arg.ident.unraw().to_string(), + arg.eq_and_default + .as_ref() + .map(|(_, default)| default.clone()), + arg.span(), + )?; + let FnArg::Regular(fn_arg) = fn_arg else { + unreachable!( + "`Python` and `CancelHandle` are already handled above and `*args`/`**kwargs` are \ + parsed and transformed below. Because the have to come last and are only allowed \ + once, this has to be a regular argument." + ); + }; + if let Some((_, default)) = &arg.eq_and_default { + fn_arg.default_value = Some(Box::new(default.clone())); + } + #[cfg(feature = "experimental-inspect")] + if let Some((_, annotation)) = &arg.colon_and_annotation { + fn_arg.annotation = Some(annotation.as_type_hint()); + } + } + SignatureItem::VarargsSep(sep) => { + parse_state.finish_pos_args(&python_signature, sep.span())? + } + SignatureItem::Varargs(varargs) => { + let fn_arg = next_non_py_argument_checked(&varargs.ident)?; + fn_arg.to_varargs_mut()?; + parse_state.add_varargs(&mut python_signature, varargs)?; + #[cfg(feature = "experimental-inspect")] + if let Some((_, annotation)) = &varargs.colon_and_annotation { + let FnArg::VarArgs(fn_arg) = fn_arg else { + unreachable!( + "`Python` and `CancelHandle` are already handled above and `*args`/`**kwargs` are \ + parsed and transformed below. Because the have to come last and are only allowed \ + once, this has to be a regular argument." + ); + }; + fn_arg.annotation = Some(annotation.as_type_hint()); + } + } + SignatureItem::Kwargs(kwargs) => { + let fn_arg = next_non_py_argument_checked(&kwargs.ident)?; + fn_arg.to_kwargs_mut()?; + parse_state.add_kwargs(&mut python_signature, kwargs)?; + #[cfg(feature = "experimental-inspect")] + if let Some((_, annotation)) = &kwargs.colon_and_annotation { + let FnArg::KwArgs(fn_arg) = fn_arg else { + unreachable!( + "`Python` and `CancelHandle` are already handled above and `*args`/`**kwargs` are \ + parsed and transformed below. Because the have to come last and are only allowed \ + once, this has to be a regular argument." + ); + }; + fn_arg.annotation = Some(annotation.as_type_hint()); + } + } + SignatureItem::PosargsSep(sep) => { + parse_state.finish_pos_only_args(&mut python_signature, sep.span())? + } + }; + } + + // Ensure no non-py arguments remain + if let Some(arg) = + args_iter.find(|arg| !matches!(arg, FnArg::Py(..) | FnArg::CancelHandle(..))) + { + bail_spanned!( + attribute.kw.span() => format!("missing signature entry for argument `{}`", arg.name()) + ); + } + + Ok(FunctionSignature { + arguments, + python_signature, + attribute: Some(attribute), + }) + } + + /// Without `#[pyo3(signature)]` or `#[args]` - just take the Rust function arguments as positional. + pub fn from_arguments(arguments: Vec>) -> Self { + let mut python_signature = PythonSignature::default(); + for arg in &arguments { + // Python<'_> arguments don't show in Python signature + if matches!(arg, FnArg::Py(..) | FnArg::CancelHandle(..)) { + continue; + } + + python_signature + .positional_parameters + .push(arg.name().unraw().to_string()); + } + + Self { + arguments, + python_signature, + attribute: None, + } + } + + pub fn text_signature(&self, self_argument: Option<&str>) -> String { + let mut output = String::new(); + output.push('('); + + if let Some(arg) = self_argument { + output.push('$'); + output.push_str(arg); + } + + let mut maybe_push_comma = { + let mut first = self_argument.is_none(); + move |output: &mut String| { + if !first { + output.push_str(", "); + } else { + first = false; + } + } + }; + + let py_sig = &self.python_signature; + + let defaults = std::iter::repeat_n(None, py_sig.required_positional_parameters()) + .chain(py_sig.default_positional_parameters.iter().map(Some)); + + for (i, (parameter, default)) in + std::iter::zip(&py_sig.positional_parameters, defaults).enumerate() + { + maybe_push_comma(&mut output); + + output.push_str(parameter); + + if let Some(expr) = default { + output.push('='); + output.push_str(&expr_to_python(expr)); + } + + if py_sig.positional_only_parameters > 0 && i + 1 == py_sig.positional_only_parameters { + output.push_str(", /") + } + } + + if let Some(varargs) = &py_sig.varargs { + maybe_push_comma(&mut output); + output.push('*'); + output.push_str(varargs); + } else if !py_sig.keyword_only_parameters.is_empty() { + maybe_push_comma(&mut output); + output.push('*'); + } + + for (parameter, default) in &py_sig.keyword_only_parameters { + maybe_push_comma(&mut output); + output.push_str(parameter); + if let Some(expr) = default { + output.push('='); + output.push_str(&expr_to_python(expr)); + } + } + + if let Some(kwargs) = &py_sig.kwargs { + maybe_push_comma(&mut output); + output.push_str("**"); + output.push_str(kwargs); + } + + output.push(')'); + output + } +} diff --git a/vendor/pyo3-macros-backend/src/pyimpl.rs b/vendor/pyo3-macros-backend/src/pyimpl.rs new file mode 100644 index 0000000..471d1bb --- /dev/null +++ b/vendor/pyo3-macros-backend/src/pyimpl.rs @@ -0,0 +1,516 @@ +use std::collections::HashSet; + +use crate::combine_errors::CombineErrors; +#[cfg(feature = "experimental-inspect")] +use crate::get_doc; +#[cfg(feature = "experimental-inspect")] +use crate::introspection::{attribute_introspection_code, function_introspection_code}; +#[cfg(feature = "experimental-inspect")] +use crate::method::{FnSpec, FnType}; +#[cfg(feature = "experimental-inspect")] +use crate::py_expr::PyExpr; +use crate::utils::{has_attribute, has_attribute_with_namespace, Ctx, PyO3CratePath}; +use crate::{ + attributes::{take_pyo3_options, CrateAttribute}, + konst::{ConstAttributes, ConstSpec}, + pyfunction::PyFunctionOptions, + pymethod::{ + self, is_proto_method, GeneratedPyMethod, MethodAndMethodDef, MethodAndSlotDef, PyMethod, + }, +}; +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; +use syn::{ + parse::{Parse, ParseStream}, + spanned::Spanned, + ImplItemFn, Result, +}; +#[cfg(feature = "experimental-inspect")] +use syn::{parse_quote, Ident, ReturnType}; + +/// The mechanism used to collect `#[pymethods]` into the type object +#[derive(Copy, Clone)] +pub enum PyClassMethodsType { + Specialization, + Inventory, +} + +enum PyImplPyO3Option { + Crate(CrateAttribute), +} + +impl Parse for PyImplPyO3Option { + fn parse(input: ParseStream<'_>) -> Result { + let lookahead = input.lookahead1(); + if lookahead.peek(syn::Token![crate]) { + input.parse().map(PyImplPyO3Option::Crate) + } else { + Err(lookahead.error()) + } + } +} + +#[derive(Default)] +pub struct PyImplOptions { + krate: Option, +} + +impl PyImplOptions { + pub fn from_attrs(attrs: &mut Vec) -> Result { + let mut options: PyImplOptions = Default::default(); + + for option in take_pyo3_options(attrs)? { + match option { + PyImplPyO3Option::Crate(path) => options.set_crate(path)?, + } + } + + Ok(options) + } + + fn set_crate(&mut self, path: CrateAttribute) -> Result<()> { + ensure_spanned!( + self.krate.is_none(), + path.span() => "`crate` may only be specified once" + ); + + self.krate = Some(path); + Ok(()) + } +} + +pub fn build_py_methods( + ast: &mut syn::ItemImpl, + methods_type: PyClassMethodsType, +) -> syn::Result { + if let Some((_, path, _)) = &ast.trait_ { + bail_spanned!(path.span() => "#[pymethods] cannot be used on trait impl blocks"); + } else if ast.generics != Default::default() { + bail_spanned!( + ast.generics.span() => + "#[pymethods] cannot be used with lifetime parameters or generics" + ); + } else { + let options = PyImplOptions::from_attrs(&mut ast.attrs)?; + impl_methods(&ast.self_ty, &mut ast.items, methods_type, options) + } +} + +fn check_pyfunction(pyo3_path: &PyO3CratePath, meth: &mut ImplItemFn) -> syn::Result<()> { + let mut error = None; + + meth.attrs.retain(|attr| { + let attrs = [attr.clone()]; + + if has_attribute(&attrs, "pyfunction") + || has_attribute_with_namespace(&attrs, Some(pyo3_path), &["pyfunction"]) + || has_attribute_with_namespace(&attrs, Some(pyo3_path), &["prelude", "pyfunction"]) { + error = Some(err_spanned!(meth.sig.span() => "functions inside #[pymethods] do not need to be annotated with #[pyfunction]")); + false + } else { + true + } + }); + + error.map_or(Ok(()), Err) +} + +pub fn impl_methods( + ty: &syn::Type, + impls: &mut [syn::ImplItem], + methods_type: PyClassMethodsType, + options: PyImplOptions, +) -> syn::Result { + let mut extra_fragments = Vec::new(); + let mut proto_impls = Vec::new(); + let mut methods = Vec::new(); + let mut associated_methods = Vec::new(); + + let mut implemented_proto_fragments = HashSet::new(); + + let _: Vec<()> = impls + .iter_mut() + .map(|iimpl| { + match iimpl { + syn::ImplItem::Fn(meth) => { + let ctx = &Ctx::new(&options.krate, Some(&meth.sig)); + let mut fun_options = PyFunctionOptions::from_attrs(&mut meth.attrs)?; + fun_options.krate = fun_options.krate.or_else(|| options.krate.clone()); + + check_pyfunction(&ctx.pyo3_path, meth)?; + let method = PyMethod::parse(&mut meth.sig, &mut meth.attrs, fun_options)?; + #[cfg(feature = "experimental-inspect")] + extra_fragments.push(method_introspection_code( + &method.spec, + &meth.attrs, + ty, + method.is_returning_not_implemented_on_extraction_error(), + ctx, + )); + match pymethod::gen_py_method(ty, method, &meth.attrs, ctx)? { + GeneratedPyMethod::Method(MethodAndMethodDef { + associated_method, + method_def, + }) => { + let attrs = get_cfg_attributes(&meth.attrs); + associated_methods.push(quote!(#(#attrs)* #associated_method)); + methods.push(quote!(#(#attrs)* #method_def)); + } + GeneratedPyMethod::SlotTraitImpl(method_name, token_stream) => { + implemented_proto_fragments.insert(method_name); + let attrs = get_cfg_attributes(&meth.attrs); + extra_fragments.push(quote!(#(#attrs)* #token_stream)); + } + GeneratedPyMethod::Proto(MethodAndSlotDef { + associated_method, + slot_def, + }) => { + let attrs = get_cfg_attributes(&meth.attrs); + proto_impls.push(quote!(#(#attrs)* #slot_def)); + associated_methods.push(quote!(#(#attrs)* #associated_method)); + } + } + } + syn::ImplItem::Const(konst) => { + let ctx = &Ctx::new(&options.krate, None); + #[cfg(feature = "experimental-inspect")] + let doc = get_doc(&konst.attrs, None); + let attributes = ConstAttributes::from_attrs(&mut konst.attrs)?; + if attributes.is_class_attr { + let spec = ConstSpec { + rust_ident: konst.ident.clone(), + attributes, + #[cfg(feature = "experimental-inspect")] + expr: Some(konst.expr.clone()), + #[cfg(feature = "experimental-inspect")] + ty: konst.ty.clone(), + #[cfg(feature = "experimental-inspect")] + doc, + }; + let attrs = get_cfg_attributes(&konst.attrs); + let MethodAndMethodDef { + associated_method, + method_def, + } = gen_py_const(ty, &spec, ctx); + methods.push(quote!(#(#attrs)* #method_def)); + associated_methods.push(quote!(#(#attrs)* #associated_method)); + if is_proto_method(&spec.python_name().to_string()) { + // If this is a known protocol method e.g. __contains__, then allow this + // symbol even though it's not an uppercase constant. + konst + .attrs + .push(syn::parse_quote!(#[allow(non_upper_case_globals)])); + } + } + } + syn::ImplItem::Macro(m) => bail_spanned!( + m.span() => + "macros cannot be used as items in `#[pymethods]` impl blocks\n\ + = note: this was previously accepted and ignored" + ), + _ => {} + } + Ok(()) + }) + .try_combine_syn_errors()?; + + let ctx = &Ctx::new(&options.krate, None); + + add_shared_proto_slots(ty, &mut proto_impls, implemented_proto_fragments, ctx); + + let items = match methods_type { + PyClassMethodsType::Specialization => impl_py_methods(ty, methods, proto_impls, ctx), + PyClassMethodsType::Inventory => submit_methods_inventory(ty, methods, proto_impls, ctx), + }; + + Ok(quote! { + #(#extra_fragments)* + + #items + + #[doc(hidden)] + #[allow(non_snake_case)] + impl #ty { + #(#associated_methods)* + } + }) +} + +pub fn gen_py_const(cls: &syn::Type, spec: &ConstSpec, ctx: &Ctx) -> MethodAndMethodDef { + let member = &spec.rust_ident; + let wrapper_ident = format_ident!("__pymethod_{}__", member); + let python_name = spec.null_terminated_python_name(); + let Ctx { pyo3_path, .. } = ctx; + + let associated_method = quote! { + fn #wrapper_ident(py: #pyo3_path::Python<'_>) -> #pyo3_path::PyResult<#pyo3_path::Py<#pyo3_path::PyAny>> { + #pyo3_path::IntoPyObjectExt::into_py_any(#cls::#member, py) + } + }; + + let method_def = quote! { + #pyo3_path::impl_::pymethods::PyMethodDefType::ClassAttribute({ + #pyo3_path::impl_::pymethods::PyClassAttributeDef::new( + #python_name, + #cls::#wrapper_ident + ) + }) + }; + + #[cfg_attr(not(feature = "experimental-inspect"), allow(unused_mut))] + let mut def = MethodAndMethodDef { + associated_method, + method_def, + }; + + #[cfg(feature = "experimental-inspect")] + def.add_introspection(attribute_introspection_code( + &ctx.pyo3_path, + Some(cls), + spec.python_name().to_string(), + spec.expr + .as_ref() + .map_or_else(PyExpr::ellipsis, PyExpr::constant_from_expression), + spec.ty.clone(), + spec.doc.as_ref(), + true, + )); + + def +} + +fn impl_py_methods( + ty: &syn::Type, + methods: Vec, + proto_impls: Vec, + ctx: &Ctx, +) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + quote! { + #[allow(unknown_lints, non_local_definitions)] + impl #pyo3_path::impl_::pyclass::PyMethods<#ty> + for #pyo3_path::impl_::pyclass::PyClassImplCollector<#ty> + { + fn py_methods(self) -> &'static #pyo3_path::impl_::pyclass::PyClassItems { + static ITEMS: #pyo3_path::impl_::pyclass::PyClassItems = #pyo3_path::impl_::pyclass::PyClassItems { + methods: &[#(#methods),*], + slots: &[#(#proto_impls),*] + }; + &ITEMS + } + } + } +} + +fn add_shared_proto_slots( + ty: &syn::Type, + proto_impls: &mut Vec, + mut implemented_proto_fragments: HashSet, + ctx: &Ctx, +) { + let Ctx { pyo3_path, .. } = ctx; + macro_rules! try_add_shared_slot { + ($slot:ident, $($fragments:literal),*) => {{ + let mut implemented = false; + $(implemented |= implemented_proto_fragments.remove($fragments));*; + if implemented { + proto_impls.push(quote! { #pyo3_path::impl_::pyclass::$slot!(#ty) }) + } + }}; + } + + try_add_shared_slot!( + generate_pyclass_getattro_slot, + "__getattribute__", + "__getattr__" + ); + try_add_shared_slot!(generate_pyclass_setattr_slot, "__setattr__", "__delattr__"); + try_add_shared_slot!(generate_pyclass_setdescr_slot, "__set__", "__delete__"); + try_add_shared_slot!(generate_pyclass_setitem_slot, "__setitem__", "__delitem__"); + try_add_shared_slot!(generate_pyclass_add_slot, "__add__", "__radd__"); + try_add_shared_slot!(generate_pyclass_sub_slot, "__sub__", "__rsub__"); + try_add_shared_slot!(generate_pyclass_mul_slot, "__mul__", "__rmul__"); + try_add_shared_slot!(generate_pyclass_mod_slot, "__mod__", "__rmod__"); + try_add_shared_slot!(generate_pyclass_divmod_slot, "__divmod__", "__rdivmod__"); + try_add_shared_slot!(generate_pyclass_lshift_slot, "__lshift__", "__rlshift__"); + try_add_shared_slot!(generate_pyclass_rshift_slot, "__rshift__", "__rrshift__"); + try_add_shared_slot!(generate_pyclass_and_slot, "__and__", "__rand__"); + try_add_shared_slot!(generate_pyclass_or_slot, "__or__", "__ror__"); + try_add_shared_slot!(generate_pyclass_xor_slot, "__xor__", "__rxor__"); + try_add_shared_slot!(generate_pyclass_matmul_slot, "__matmul__", "__rmatmul__"); + try_add_shared_slot!(generate_pyclass_truediv_slot, "__truediv__", "__rtruediv__"); + try_add_shared_slot!( + generate_pyclass_floordiv_slot, + "__floordiv__", + "__rfloordiv__" + ); + try_add_shared_slot!(generate_pyclass_pow_slot, "__pow__", "__rpow__"); + try_add_shared_slot!( + generate_pyclass_richcompare_slot, + "__lt__", + "__le__", + "__eq__", + "__ne__", + "__gt__", + "__ge__" + ); + + // if this assertion trips, a slot fragment has been implemented which has not been added in the + // list above + assert!(implemented_proto_fragments.is_empty()); +} + +fn submit_methods_inventory( + ty: &syn::Type, + methods: Vec, + proto_impls: Vec, + ctx: &Ctx, +) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + quote! { + #pyo3_path::inventory::submit! { + type Inventory = <#ty as #pyo3_path::impl_::pyclass::PyClassImpl>::Inventory; + Inventory::new(#pyo3_path::impl_::pyclass::PyClassItems { methods: &[#(#methods),*], slots: &[#(#proto_impls),*] }) + } + } +} + +pub(crate) fn get_cfg_attributes(attrs: &[syn::Attribute]) -> Vec<&syn::Attribute> { + attrs + .iter() + .filter(|attr| attr.path().is_ident("cfg")) + .collect() +} + +#[cfg(feature = "experimental-inspect")] +pub fn method_introspection_code( + spec: &FnSpec<'_>, + attrs: &[syn::Attribute], + parent: &syn::Type, + is_returning_not_implemented_on_extraction_error: bool, + ctx: &Ctx, +) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + + let name = spec.python_name.to_string(); + + // __richcmp__ special case + if name == "__richcmp__" { + // We expend into each individual method + return ["__eq__", "__ne__", "__lt__", "__le__", "__gt__", "__ge__"] + .into_iter() + .map(|method_name| { + let mut spec = (*spec).clone(); + spec.python_name = Ident::new(method_name, spec.python_name.span()); + // We remove the CompareOp arg, this is safe because the signature is always the same + // First the other value to compare with then the CompareOp + // We cant to keep the first argument type, hence this hack + spec.signature.arguments.pop(); + spec.signature.python_signature.positional_parameters.pop(); + // the `CompareOp` parameter is gone; keep the positional-only count in range + spec.signature + .python_signature + .make_all_parameters_positional_only(); + method_introspection_code( + &spec, + attrs, + parent, + is_returning_not_implemented_on_extraction_error, + ctx, + ) + }) + .collect(); + } + // We map or ignore some magic methods + // TODO: this might create a naming conflict + let name = match name.as_str() { + "__concat__" => "__add__".into(), + "__repeat__" => "__mul__".into(), + "__inplace_concat__" => "__iadd__".into(), + "__inplace_repeat__" => "__imul__".into(), + "__getbuffer__" | "__releasebuffer__" | "__traverse__" | "__clear__" => return quote! {}, + _ => name, + }; + + // We introduce self/cls argument and setup decorators + let mut first_argument = None; + let mut decorators = Vec::new(); + match &spec.tp { + FnType::Getter(_) => { + first_argument = Some("self"); + decorators.push(PyExpr::builtin("property")); + } + FnType::Setter(_) => { + first_argument = Some("self"); + decorators.push(PyExpr::attribute( + PyExpr::attribute(PyExpr::from_type(parent.clone(), None), name.clone()), + "setter", + )); + } + FnType::Deleter(_) => { + first_argument = Some("self"); + decorators.push(PyExpr::attribute( + PyExpr::attribute(PyExpr::from_type(parent.clone(), None), name.clone()), + "deleter", + )); + } + FnType::Fn(_) => { + first_argument = Some("self"); + } + FnType::FnClass(_) => { + first_argument = Some("cls"); + if spec.python_name != "__new__" { + // special case __new__ - does not get the decorator + decorators.push(PyExpr::builtin("classmethod")); + } + } + FnType::FnStatic => { + if spec.python_name != "__new__" { + decorators.push(PyExpr::builtin("staticmethod")); + } else { + // special case __new__ - does not get the decorator and gets first argument + first_argument = Some("cls"); + } + } + FnType::FnModule(_) => (), // TODO: not sure this can happen + FnType::ClassAttribute => { + // We return an attribute because there is no decorator for this case + return attribute_introspection_code( + pyo3_path, + Some(parent), + name, + PyExpr::ellipsis(), + if let ReturnType::Type(_, t) = &spec.output { + (**t).clone() + } else { + parse_quote!(#pyo3_path::Py<#pyo3_path::types::PyNone>) + }, + get_doc(attrs, None).as_ref(), + true, + ); + } + } + let return_type = if spec.python_name == "__new__" { + // Hack to return Self while implementing IntoPyObject + // TODO: use typing.Self? + PyExpr::from_return_type(parse_quote!(#pyo3_path::PyClassGuard), Some(parent)) + } else { + match spec.output.clone() { + ReturnType::Type(_, t) => PyExpr::from_return_type(*t, Some(parent)), + ReturnType::Default => PyExpr::none(), + } + }; + function_introspection_code( + pyo3_path, + None, + &name, + &spec.signature, + first_argument, + return_type, + decorators, + spec.asyncness.is_some(), + is_returning_not_implemented_on_extraction_error, + get_doc(attrs, None).as_ref(), + Some(parent), + ) +} diff --git a/vendor/pyo3-macros-backend/src/pymethod.rs b/vendor/pyo3-macros-backend/src/pymethod.rs new file mode 100644 index 0000000..885e8f7 --- /dev/null +++ b/vendor/pyo3-macros-backend/src/pymethod.rs @@ -0,0 +1,1971 @@ +use std::borrow::Cow; +use std::ffi::CString; + +use crate::attributes::{FromPyWithAttribute, NameAttribute, RenamingRule}; +#[cfg(feature = "experimental-inspect")] +use crate::introspection::unique_element_id; +use crate::method::{ + CallingConvention, ClassMethodReceiver, ExtractErrorMode, PyArg, SelfConversionPolicy, +}; +use crate::params::{impl_arg_params, impl_regular_arg_param, Holders}; +use crate::pyfunction::WarningFactory; +use crate::utils::PythonDoc; +use crate::utils::{Ctx, StaticIdent}; +use crate::{ + method::{FnArg, FnSpec, FnType, SelfType}, + pyfunction::PyFunctionOptions, +}; +use crate::{quotes, utils}; +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote, quote_spanned, ToTokens}; +use syn::LitCStr; +use syn::{ext::IdentExt, spanned::Spanned, Field, Ident, Result}; + +/// Generated code for a single pymethod item. +pub struct MethodAndMethodDef { + /// The implementation of the Python wrapper for the pymethod + pub associated_method: TokenStream, + /// The method def which will be used to register this pymethod + pub method_def: TokenStream, +} + +#[cfg(feature = "experimental-inspect")] +impl MethodAndMethodDef { + pub fn add_introspection(&mut self, data: TokenStream) { + let const_name = format_ident!("_{}", unique_element_id()); // We need an explicit name here + self.associated_method.extend(quote! { + const #const_name: () = { + #data + }; + }); + } +} + +/// Generated code for a single pymethod item which is registered by a slot. +pub struct MethodAndSlotDef { + /// The implementation of the Python wrapper for the pymethod + pub associated_method: TokenStream, + /// The slot def which will be used to register this pymethod + pub slot_def: TokenStream, +} + +#[cfg(feature = "experimental-inspect")] +impl MethodAndSlotDef { + pub fn add_introspection(&mut self, data: TokenStream) { + let const_name = format_ident!("_{}", unique_element_id()); // We need an explicit name here + self.associated_method.extend(quote! { + const #const_name: () = { + #data + }; + }); + } +} + +pub enum GeneratedPyMethod { + Method(MethodAndMethodDef), + Proto(MethodAndSlotDef), + SlotTraitImpl(String, TokenStream), +} + +pub struct PyMethod<'a> { + kind: PyMethodKind, + method_name: String, + pub spec: FnSpec<'a>, +} + +enum PyMethodKind { + Fn, + Proto(PyMethodProtoKind), +} + +impl PyMethodKind { + fn from_name(name: &str) -> Self { + match name { + // Protocol implemented through slots + "__new__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__NEW__)), + "__init__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__INIT__)), + "__str__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__STR__)), + "__repr__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__REPR__)), + "__hash__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__HASH__)), + "__richcmp__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__RICHCMP__)), + "__get__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__GET__)), + "__iter__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__ITER__)), + "__next__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__NEXT__)), + "__await__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__AWAIT__)), + "__aiter__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__AITER__)), + "__anext__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__ANEXT__)), + "__len__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__LEN__)), + "__contains__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__CONTAINS__)), + "__concat__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__CONCAT__)), + "__repeat__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__REPEAT__)), + "__inplace_concat__" => { + PyMethodKind::Proto(PyMethodProtoKind::Slot(&__INPLACE_CONCAT__)) + } + "__inplace_repeat__" => { + PyMethodKind::Proto(PyMethodProtoKind::Slot(&__INPLACE_REPEAT__)) + } + "__getitem__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__GETITEM__)), + "__pos__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__POS__)), + "__neg__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__NEG__)), + "__abs__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__ABS__)), + "__invert__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__INVERT__)), + "__index__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__INDEX__)), + "__int__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__INT__)), + "__float__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__FLOAT__)), + "__bool__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__BOOL__)), + "__iadd__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__IADD__)), + "__isub__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__ISUB__)), + "__imul__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__IMUL__)), + "__imatmul__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__IMATMUL__)), + "__itruediv__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__ITRUEDIV__)), + "__ifloordiv__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__IFLOORDIV__)), + "__imod__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__IMOD__)), + "__ipow__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__IPOW__)), + "__ilshift__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__ILSHIFT__)), + "__irshift__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__IRSHIFT__)), + "__iand__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__IAND__)), + "__ixor__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__IXOR__)), + "__ior__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__IOR__)), + "__getbuffer__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__GETBUFFER__)), + "__releasebuffer__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__RELEASEBUFFER__)), + // Protocols implemented through traits + "__getattribute__" => { + PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__GETATTRIBUTE__)) + } + "__getattr__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__GETATTR__)), + "__setattr__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__SETATTR__)), + "__delattr__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__DELATTR__)), + "__set__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__SET__)), + "__delete__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__DELETE__)), + "__setitem__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__SETITEM__)), + "__delitem__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__DELITEM__)), + "__add__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__ADD__)), + "__radd__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__RADD__)), + "__sub__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__SUB__)), + "__rsub__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__RSUB__)), + "__mul__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__MUL__)), + "__rmul__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__RMUL__)), + "__matmul__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__MATMUL__)), + "__rmatmul__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__RMATMUL__)), + "__floordiv__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__FLOORDIV__)), + "__rfloordiv__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__RFLOORDIV__)), + "__truediv__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__TRUEDIV__)), + "__rtruediv__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__RTRUEDIV__)), + "__divmod__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__DIVMOD__)), + "__rdivmod__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__RDIVMOD__)), + "__mod__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__MOD__)), + "__rmod__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__RMOD__)), + "__lshift__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__LSHIFT__)), + "__rlshift__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__RLSHIFT__)), + "__rshift__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__RSHIFT__)), + "__rrshift__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__RRSHIFT__)), + "__and__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__AND__)), + "__rand__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__RAND__)), + "__xor__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__XOR__)), + "__rxor__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__RXOR__)), + "__or__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__OR__)), + "__ror__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__ROR__)), + "__pow__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__POW__)), + "__rpow__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__RPOW__)), + "__lt__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__LT__)), + "__le__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__LE__)), + "__eq__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__EQ__)), + "__ne__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__NE__)), + "__gt__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__GT__)), + "__ge__" => PyMethodKind::Proto(PyMethodProtoKind::SlotFragment(&__GE__)), + // Some tricky protocols which don't fit the pattern of the rest + "__call__" => PyMethodKind::Proto(PyMethodProtoKind::Call), + "__traverse__" => PyMethodKind::Proto(PyMethodProtoKind::Traverse), + "__clear__" => PyMethodKind::Proto(PyMethodProtoKind::Clear), + // Not a proto + _ => PyMethodKind::Fn, + } + } +} + +enum PyMethodProtoKind { + Slot(&'static SlotDef), + Call, + Traverse, + Clear, + SlotFragment(&'static SlotFragmentDef), +} + +impl PyMethodProtoKind { + /// Whether Python hands this protocol an `args`/`kwargs` pair. + /// + /// `tp_new`, `tp_init` and `tp_call` do, so they accept keyword arguments and a + /// `#[pyo3(signature = ...)]` has something to act on. Every other protocol is reached + /// through a slot wrapper with a fixed C-level signature: its parameters are positional-only + /// and a signature attribute would have nothing to unpack. + /// + /// Should `signature` ever be accepted on protocol methods just to supply type hints, only + /// the `ensure_no_forbidden_protocol_attributes` use goes away: which parameters Python sees + /// as positional-only is dictated by CPython, not by what the user declares. + fn takes_args_and_kwargs(&self) -> bool { + match self { + PyMethodProtoKind::Slot(slot) => slot.takes_args_and_kwargs(), + PyMethodProtoKind::Call => true, + PyMethodProtoKind::SlotFragment(_) + | PyMethodProtoKind::Traverse + | PyMethodProtoKind::Clear => false, + } + } +} + +impl<'a> PyMethod<'a> { + pub fn parse( + sig: &'a mut syn::Signature, + meth_attrs: &mut Vec, + options: PyFunctionOptions, + ) -> Result { + check_generic(sig)?; + ensure_function_options_valid(&options)?; + let mut spec = FnSpec::parse(sig, meth_attrs, options)?; + + let method_name = spec.python_name.to_string(); + let kind = PyMethodKind::from_name(&method_name); + + // The parameters of a method backed by a type slot are positional-only, record that in + // the signature. Nothing else can: `#[pyo3(signature = ...)]` is rejected for exactly + // these methods, see `ensure_no_forbidden_protocol_attributes`. + if let PyMethodKind::Proto(proto) = &kind { + if !proto.takes_args_and_kwargs() { + spec.signature + .python_signature + .make_all_parameters_positional_only(); + } + } + + Ok(Self { + kind, + method_name, + spec, + }) + } + + #[cfg(feature = "experimental-inspect")] + pub fn is_returning_not_implemented_on_extraction_error(&self) -> bool { + match &self.kind { + PyMethodKind::Fn => false, + PyMethodKind::Proto(proto) => match proto { + PyMethodProtoKind::Slot(slot) => { + matches!(slot.extract_error_mode, ExtractErrorMode::NotImplemented) + } + PyMethodProtoKind::SlotFragment(slot) => { + matches!(slot.extract_error_mode, ExtractErrorMode::NotImplemented) + } + PyMethodProtoKind::Call + | PyMethodProtoKind::Traverse + | PyMethodProtoKind::Clear => false, + }, + } + } +} + +pub fn is_proto_method(name: &str) -> bool { + match PyMethodKind::from_name(name) { + PyMethodKind::Fn => false, + PyMethodKind::Proto(_) => true, + } +} + +pub fn gen_py_method( + cls: &syn::Type, + method: PyMethod<'_>, + meth_attrs: &[syn::Attribute], + ctx: &Ctx, +) -> Result { + let spec = &method.spec; + + if spec.asyncness.is_some() { + ensure_spanned!( + cfg!(feature = "experimental-async"), + spec.asyncness.span() => "async functions are only supported with the `experimental-async` feature" + ); + } + + Ok(match (method.kind, &spec.tp) { + // Class attributes go before protos so that class attributes can be used to set proto + // method to None. + (_, FnType::ClassAttribute) => { + GeneratedPyMethod::Method(impl_py_class_attribute(cls, spec, ctx)?) + } + (PyMethodKind::Proto(proto_kind), _) => { + ensure_no_forbidden_protocol_attributes(&proto_kind, spec, &method.method_name)?; + match proto_kind { + PyMethodProtoKind::Slot(slot_def) => { + let slot = slot_def.generate_type_slot(cls, spec, &method.method_name, ctx)?; + GeneratedPyMethod::Proto(slot) + } + PyMethodProtoKind::Call => { + GeneratedPyMethod::Proto(impl_call_slot(cls, spec, ctx)?) + } + PyMethodProtoKind::Traverse => { + GeneratedPyMethod::Proto(impl_traverse_slot(cls, spec, ctx)?) + } + PyMethodProtoKind::Clear => { + GeneratedPyMethod::Proto(impl_clear_slot(cls, spec, ctx)?) + } + PyMethodProtoKind::SlotFragment(slot_fragment_def) => { + let proto = slot_fragment_def.generate_pyproto_fragment(cls, spec, ctx)?; + GeneratedPyMethod::SlotTraitImpl(method.method_name, proto) + } + } + } + // ordinary functions (with some specialties) + (_, FnType::Fn(_) | FnType::FnClass(_) | FnType::FnStatic) => GeneratedPyMethod::Method( + impl_py_method_def(cls, spec, spec.get_doc(meth_attrs).as_ref(), ctx)?, + ), + (_, FnType::Getter(self_type)) => GeneratedPyMethod::Method(impl_py_getter_def( + cls, + PropertyType::Function { + self_type, + spec, + doc: spec.get_doc(meth_attrs), + }, + ctx, + )?), + (_, FnType::Setter(self_type)) => GeneratedPyMethod::Method(impl_py_setter_def( + cls, + PropertyType::Function { + self_type, + spec, + doc: spec.get_doc(meth_attrs), + }, + ctx, + )?), + (_, FnType::Deleter(self_type)) => GeneratedPyMethod::Method(impl_py_deleter_def( + cls, + self_type, + spec, + spec.get_doc(meth_attrs), + ctx, + )?), + (_, FnType::FnModule(_)) => { + unreachable!("methods cannot be FnModule") + } + }) +} + +pub fn check_generic(sig: &syn::Signature) -> syn::Result<()> { + let err_msg = |typ| format!("Python functions cannot have generic {typ} parameters"); + for param in &sig.generics.params { + match param { + syn::GenericParam::Lifetime(_) => {} + syn::GenericParam::Type(_) => bail_spanned!(param.span() => err_msg("type")), + syn::GenericParam::Const(_) => bail_spanned!(param.span() => err_msg("const")), + } + } + Ok(()) +} + +fn ensure_function_options_valid(options: &PyFunctionOptions) -> syn::Result<()> { + if let Some(pass_module) = &options.pass_module { + bail_spanned!(pass_module.span() => "`pass_module` cannot be used on Python methods"); + } + Ok(()) +} + +fn ensure_no_forbidden_protocol_attributes( + proto_kind: &PyMethodProtoKind, + spec: &FnSpec<'_>, + method_name: &str, +) -> syn::Result<()> { + if let Some(signature) = &spec.signature.attribute { + // __new__, __init__ and __call__ are allowed to have a signature, but nothing else is. + if !proto_kind.takes_args_and_kwargs() { + bail_spanned!(signature.kw.span() => format!("`signature` cannot be used with magic method `{}`", method_name)); + } + } + if let Some(text_signature) = &spec.text_signature { + // __new__ is also allowed a text_signature (no other proto method is) + if !matches!( + proto_kind, + PyMethodProtoKind::Slot(SlotDef { + calling_convention: SlotCallingConvention::TpNew, + .. + }) + ) { + bail_spanned!(text_signature.kw.span() => format!("`text_signature` cannot be used with magic method `{}`", method_name)); + } + } + Ok(()) +} + +pub fn impl_py_method_def( + cls: &syn::Type, + spec: &FnSpec<'_>, + doc: Option<&PythonDoc>, + ctx: &Ctx, +) -> Result { + let Ctx { pyo3_path, .. } = ctx; + let wrapper_ident = format_ident!("__pymethod_{}__", spec.python_name); + let calling_convention = CallingConvention::from_signature(&spec.signature); + let associated_method = spec.get_wrapper_function( + &wrapper_ident, + Some(cls), + calling_convention, + // SAFETY: Methods in `tp_methods` are dispatched through CPython's + // method-wrapper descriptor, which enforces that the receiver is an + // instance of the owning type before reaching the C function. The + // trusted path is therefore valid. + unsafe { SelfConversionPolicy::trusted() }, + ClassMethodReceiver::Class, + ctx, + )?; + let methoddef = spec.get_methoddef( + quote! { #cls::#wrapper_ident }, + doc, + calling_convention, + ctx, + )?; + let method_def = quote! { + #pyo3_path::impl_::pymethods::PyMethodDefType::Method(#methoddef) + }; + Ok(MethodAndMethodDef { + associated_method, + method_def, + }) +} + +fn impl_call_slot(cls: &syn::Type, spec: &FnSpec<'_>, ctx: &Ctx) -> Result { + let Ctx { pyo3_path, .. } = ctx; + let wrapper_ident = syn::Ident::new("__pymethod___call____", Span::call_site()); + let associated_method = spec.get_wrapper_function( + &wrapper_ident, + Some(cls), + CallingConvention::Varargs, + // SAFETY: The `tp_call` slot is dispatched by CPython, which guarantees + // the receiver is of the correct type. + unsafe { SelfConversionPolicy::trusted() }, + ClassMethodReceiver::Instance, + ctx, + )?; + let slot_def = quote! { + #pyo3_path::ffi::PyType_Slot { + slot: #pyo3_path::ffi::Py_tp_call, + pfunc: #pyo3_path::impl_::trampoline::get_trampoline_function!(ternaryfunc, #cls::#wrapper_ident) as _ + } + }; + Ok(MethodAndSlotDef { + associated_method, + slot_def, + }) +} + +fn impl_traverse_slot( + cls: &syn::Type, + spec: &FnSpec<'_>, + ctx: &Ctx, +) -> syn::Result { + let Ctx { pyo3_path, .. } = ctx; + if let (Some(py_arg), _) = split_off_python_arg(&spec.signature.arguments) { + return Err(syn::Error::new_spanned(py_arg.ty, "__traverse__ may not take `Python`. \ + Usually, an implementation of `__traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError>` \ + should do nothing but calls to `visit.call`. Most importantly, safe access to the Python interpreter is \ + prohibited inside implementations of `__traverse__`, i.e. `Python::attach` will panic.")); + } + + // check that the receiver does not try to smuggle an (implicit) `Python` token into here + if let FnType::Fn(SelfType::TryFromBoundRef { span, .. }) + | FnType::Fn(SelfType::Receiver { + mutable: true, + span, + .. + }) = spec.tp + { + bail_spanned! { span => + "__traverse__ may not take a receiver other than `&self`. Usually, an implementation of \ + `__traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError>` \ + should do nothing but calls to `visit.call`. Most importantly, safe access to the Python interpreter is \ + prohibited inside implementations of `__traverse__`, i.e. `Python::attach` will panic." + } + } + + ensure_spanned!( + spec.warnings.is_empty(), + spec.warnings.span() => "__traverse__ cannot be used with #[pyo3(warn)]" + ); + + let rust_fn_ident = spec.name; + + let associated_method = quote! { + pub unsafe extern "C" fn __pymethod_traverse__( + slf: *mut #pyo3_path::ffi::PyObject, + visit: #pyo3_path::ffi::visitproc, + arg: *mut ::std::ffi::c_void, + ) -> ::std::ffi::c_int { + #pyo3_path::impl_::pymethods::_call_traverse::<#cls>(slf, #cls::#rust_fn_ident, visit, arg, #cls::__pymethod_traverse__) + } + }; + let slot_def = quote! { + #pyo3_path::ffi::PyType_Slot { + slot: #pyo3_path::ffi::Py_tp_traverse, + pfunc: #cls::__pymethod_traverse__ as #pyo3_path::ffi::traverseproc as _ + } + }; + Ok(MethodAndSlotDef { + associated_method, + slot_def, + }) +} + +fn impl_clear_slot(cls: &syn::Type, spec: &FnSpec<'_>, ctx: &Ctx) -> syn::Result { + let Ctx { pyo3_path, .. } = ctx; + let (py_arg, args) = split_off_python_arg(&spec.signature.arguments); + let self_type = match &spec.tp { + FnType::Fn(self_type) => self_type, + _ => bail_spanned!(spec.name.span() => "expected instance method for `__clear__` function"), + }; + let mut holders = Holders::new(); + let slf = self_type.receiver( + cls, + ExtractErrorMode::Raise, + // SAFETY: The `tp_clear` slot is dispatched by CPython, which guarantees the + // receiver is of the correct type. + unsafe { SelfConversionPolicy::trusted() }, + &mut holders, + ctx, + ); + + if let [arg, ..] = args { + bail_spanned!(arg.ty().span() => "`__clear__` function expected to have no arguments"); + } + + let name = &spec.name; + let holders = holders.init_holders(ctx); + let fncall = if py_arg.is_some() { + quote!(#cls::#name(#slf, py)) + } else { + quote!(#cls::#name(#slf)) + }; + + let associated_method = quote! { + pub unsafe extern "C" fn __pymethod___clear____( + _slf: *mut #pyo3_path::ffi::PyObject, + ) -> ::std::ffi::c_int { + #pyo3_path::impl_::pymethods::_call_clear::<#cls>(_slf, |py, _slf| { + #holders + let result = #fncall; + let result = #pyo3_path::impl_::wrap::converter(&result).wrap(result)?; + ::std::result::Result::Ok(result) + }, #cls::__pymethod___clear____) + } + }; + let slot_def = quote! { + #pyo3_path::ffi::PyType_Slot { + slot: #pyo3_path::ffi::Py_tp_clear, + pfunc: #cls::__pymethod___clear____ as #pyo3_path::ffi::inquiry as _ + } + }; + Ok(MethodAndSlotDef { + associated_method, + slot_def, + }) +} + +pub(crate) fn impl_py_class_attribute( + cls: &syn::Type, + spec: &FnSpec<'_>, + ctx: &Ctx, +) -> syn::Result { + let Ctx { pyo3_path, .. } = ctx; + let (py_arg, args) = split_off_python_arg(&spec.signature.arguments); + ensure_spanned!( + args.is_empty(), + args[0].ty().span() => "#[classattr] can only have one argument (of type pyo3::Python)" + ); + + ensure_spanned!( + spec.warnings.is_empty(), + spec.warnings.span() + => "#[classattr] cannot be used with #[pyo3(warn)]" + ); + + let name = &spec.name; + let fncall = if py_arg.is_some() { + quote!(function(py)) + } else { + quote!(function()) + }; + + let wrapper_ident = format_ident!("__pymethod_{}__", name); + let python_name = spec.null_terminated_python_name(); + let body = quotes::ok_wrap(fncall, ctx); + + let associated_method = quote! { + fn #wrapper_ident(py: #pyo3_path::Python<'_>) -> #pyo3_path::PyResult<#pyo3_path::Py<#pyo3_path::PyAny>> { + let function = #cls::#name; // Shadow the method name to avoid #3017 + let result = #body; + #pyo3_path::impl_::wrap::converter(&result).map_into_pyobject(py, result) + } + }; + + let method_def = quote! { + #pyo3_path::impl_::pymethods::PyMethodDefType::ClassAttribute({ + #pyo3_path::impl_::pymethods::PyClassAttributeDef::new( + #python_name, + #cls::#wrapper_ident + ) + }) + }; + + Ok(MethodAndMethodDef { + associated_method, + method_def, + }) +} + +fn impl_call_setter( + cls: &syn::Type, + spec: &FnSpec<'_>, + self_type: &SelfType, + holders: &mut Holders, + ctx: &Ctx, +) -> syn::Result { + let (py_arg, args) = split_off_python_arg(&spec.signature.arguments); + let slf = self_type.receiver( + cls, + ExtractErrorMode::Raise, + // SAFETY: The setter function is dispatched by CPython's method-wrapper + // descriptor, which enforces the receiver is of the correct type. + unsafe { SelfConversionPolicy::trusted() }, + holders, + ctx, + ); + + if args.is_empty() { + bail_spanned!(spec.name.span() => "setter function expected to have one argument"); + } else if args.len() > 1 { + bail_spanned!( + args[1].ty().span() => + "setter function can have at most two arguments ([pyo3::Python,] and value)" + ); + } + + let name = &spec.name; + let fncall = if py_arg.is_some() { + quote!(#cls::#name(#slf, py, _val)) + } else { + quote!(#cls::#name(#slf, _val)) + }; + + Ok(fncall) +} + +// Used here for PropertyType::Function, used in pyclass for descriptors. +pub fn impl_py_setter_def( + cls: &syn::Type, + property_type: PropertyType<'_>, + ctx: &Ctx, +) -> Result { + let Ctx { pyo3_path, .. } = ctx; + let python_name = property_type.null_terminated_python_name()?; + let doc = property_type.doc(); + let mut holders = Holders::new(); + let setter_impl = match property_type { + PropertyType::Descriptor { + field_index, field, .. + } => { + let slf = SelfType::Receiver { + mutable: true, + span: Span::call_site(), + non_null: true, + } + .receiver( + cls, + ExtractErrorMode::Raise, + // SAFETY: The setter function is dispatched by CPython, which + // guarantees the receiver is of the correct type. + unsafe { SelfConversionPolicy::trusted() }, + &mut holders, + ctx, + ); + if let Some(ident) = &field.ident { + // named struct field + quote!({ #slf.#ident = _val; }) + } else { + // tuple struct field + let index = syn::Index::from(field_index); + quote!({ #slf.#index = _val; }) + } + } + PropertyType::Function { + spec, self_type, .. + } => impl_call_setter(cls, spec, self_type, &mut holders, ctx)?, + }; + + let wrapper_ident = match property_type { + PropertyType::Descriptor { + field: syn::Field { + ident: Some(ident), .. + }, + .. + } => { + format_ident!("__pymethod_set_{}__", ident) + } + PropertyType::Descriptor { field_index, .. } => { + format_ident!("__pymethod_set_field_{}__", field_index) + } + PropertyType::Function { spec, .. } => { + format_ident!("__pymethod_set_{}__", spec.name) + } + }; + + let extract = match &property_type { + PropertyType::Function { spec, .. } => { + let (_, args) = split_off_python_arg(&spec.signature.arguments); + let value_arg = &args[0]; + let (from_py_with, ident) = + if let Some(from_py_with) = &value_arg.from_py_with().as_ref().map(|f| &f.value) { + let ident = syn::Ident::new("from_py_with", from_py_with.span()); + ( + quote_spanned! { from_py_with.span() => + let #ident = #from_py_with; + }, + ident, + ) + } else { + (quote!(), syn::Ident::new("dummy", Span::call_site())) + }; + + let arg = if let FnArg::Regular(arg) = &value_arg { + arg + } else { + bail_spanned!(value_arg.name().span() => "The #[setter] value argument can't be *args, **kwargs or `cancel_handle`."); + }; + + let extract = impl_regular_arg_param( + arg, + ident, + quote!(::std::option::Option::Some(_value)), + &mut holders, + ctx, + ); + + quote! { + #from_py_with + let _val = #extract; + } + } + PropertyType::Descriptor { field, .. } => { + let span = field.ty.span(); + let name = field + .ident + .as_ref() + .map(|i| i.to_string()) + .unwrap_or_default(); + + let holder = holders.push_holder(span); + quote! { + #[allow(unused_imports, reason = "`Probe` trait used on negative case only")] + use #pyo3_path::impl_::pyclass::Probe as _; + let _val = #pyo3_path::impl_::extract_argument::extract_argument(_value, &mut #holder, #name)?; + } + } + }; + + let mut cfg_attrs = TokenStream::new(); + if let PropertyType::Descriptor { field, .. } = &property_type { + for attr in field + .attrs + .iter() + .filter(|attr| attr.path().is_ident("cfg")) + { + attr.to_tokens(&mut cfg_attrs); + } + } + + let warnings = if let PropertyType::Function { spec, .. } = &property_type { + spec.warnings.build_py_warning(ctx) + } else { + quote!() + }; + + let init_holders = holders.init_holders(ctx); + let associated_method = quote! { + #cfg_attrs + unsafe fn #wrapper_ident( + py: #pyo3_path::Python<'_>, + _slf: ::std::ptr::NonNull<#pyo3_path::ffi::PyObject>, + _value: ::std::ptr::NonNull<#pyo3_path::ffi::PyObject>, + ) -> #pyo3_path::PyResult<::std::ffi::c_int> { + use ::std::convert::Into; + let _value = #pyo3_path::impl_::extract_argument::cast_non_null_function_argument(py, _value); + #init_holders + #extract + #warnings + let result = #setter_impl; + #pyo3_path::impl_::callback::convert(py, result) + } + }; + + let doc = doc_to_optional_cstr(doc.as_deref(), ctx)?; + let method_def = quote! { + #cfg_attrs + #pyo3_path::impl_::pymethods::PyMethodDefType::Setter( + #pyo3_path::impl_::pymethods::PySetterDef::new( + #python_name, + #cls::#wrapper_ident, + #doc + ) + ) + }; + + Ok(MethodAndMethodDef { + associated_method, + method_def, + }) +} + +fn impl_call_getter( + cls: &syn::Type, + spec: &FnSpec<'_>, + self_type: &SelfType, + holders: &mut Holders, + ctx: &Ctx, +) -> syn::Result { + let (py_arg, args) = split_off_python_arg(&spec.signature.arguments); + let slf = self_type.receiver( + cls, + ExtractErrorMode::Raise, + // SAFETY: The getter function is dispatched by CPython's method-wrapper + // descriptor, which enforces the receiver is of the correct type. + unsafe { SelfConversionPolicy::trusted() }, + holders, + ctx, + ); + ensure_spanned!( + args.is_empty(), + args[0].ty().span() => "getter function can only have one argument (of type pyo3::Python)" + ); + + let name = &spec.name; + let fncall = if py_arg.is_some() { + quote!(#cls::#name(#slf, py)) + } else { + quote!(#cls::#name(#slf)) + }; + + Ok(fncall) +} + +// Used here for PropertyType::Function, used in pyclass for descriptors. +pub fn impl_py_getter_def( + cls: &syn::Type, + property_type: PropertyType<'_>, + ctx: &Ctx, +) -> Result { + let Ctx { pyo3_path, .. } = ctx; + let python_name = property_type.null_terminated_python_name()?; + let doc = property_type.doc(); + + let mut cfg_attrs = TokenStream::new(); + if let PropertyType::Descriptor { field, .. } = &property_type { + for attr in field + .attrs + .iter() + .filter(|attr| attr.path().is_ident("cfg")) + { + attr.to_tokens(&mut cfg_attrs); + } + } + + let mut holders = Holders::new(); + match property_type { + PropertyType::Descriptor { + field_index, field, .. + } => { + let ty = &field.ty; + let field = if let Some(ident) = &field.ident { + ident.to_token_stream() + } else { + syn::Index::from(field_index).to_token_stream() + }; + + let doc = doc_to_optional_cstr(doc.as_deref(), ctx)?; + let generator = quote_spanned! { ty.span() => + GENERATOR.generate(#python_name, #doc) + }; + // This is separate from `generator` so that the unsafe below does not inherit the span and thus does not + // trigger the `unsafe_code` lint + let method_def = quote! { + #cfg_attrs + { + #[allow(unused_imports, reason = "`Probe` trait used on negative case only")] + use #pyo3_path::impl_::pyclass::Probe as _; + + const GENERATOR: #pyo3_path::impl_::pyclass::PyClassGetterGenerator::< + #cls, + #ty, + { ::std::mem::offset_of!(#cls, #field) }, + { #pyo3_path::impl_::pyclass::IsPyT::<#ty>::VALUE }, + { #pyo3_path::impl_::pyclass::IsIntoPyObjectRef::<#ty>::VALUE }, + > = unsafe { #pyo3_path::impl_::pyclass::PyClassGetterGenerator::new() }; + #generator + } + }; + + Ok(MethodAndMethodDef { + associated_method: quote! {}, + method_def, + }) + } + // Forward to `IntoPyCallbackOutput`, to handle `#[getter]`s returning results. + PropertyType::Function { + spec, self_type, .. + } => { + let wrapper_ident = format_ident!("__pymethod_get_{}__", spec.name); + let call = impl_call_getter(cls, spec, self_type, &mut holders, ctx)?; + let body = quote! { + #pyo3_path::impl_::callback::convert(py, #call) + }; + + let init_holders = holders.init_holders(ctx); + let warnings = spec.warnings.build_py_warning(ctx); + + let associated_method = quote! { + #cfg_attrs + unsafe fn #wrapper_ident( + py: #pyo3_path::Python<'_>, + _slf: ::std::ptr::NonNull<#pyo3_path::ffi::PyObject> + ) -> #pyo3_path::PyResult<*mut #pyo3_path::ffi::PyObject> { + #init_holders + #warnings + let result = #body; + result + } + }; + + let doc = doc_to_optional_cstr(doc.as_deref(), ctx)?; + let method_def = quote! { + #cfg_attrs + #pyo3_path::impl_::pymethods::PyMethodDefType::Getter( + #pyo3_path::impl_::pymethods::PyGetterDef::new( + #python_name, + #cls::#wrapper_ident, + #doc + ) + ) + }; + + Ok(MethodAndMethodDef { + associated_method, + method_def, + }) + } + } +} + +pub fn impl_py_deleter_def( + cls: &syn::Type, + self_type: &SelfType, + spec: &FnSpec<'_>, + doc: Option, + ctx: &Ctx, +) -> Result { + let Ctx { pyo3_path, .. } = ctx; + let python_name = spec.null_terminated_python_name(); + let mut holders = Holders::new(); + let deleter_impl = impl_call_deleter(cls, spec, self_type, &mut holders, ctx)?; + let wrapper_ident = format_ident!("__pymethod_delete_{}__", spec.name); + let warnings = spec.warnings.build_py_warning(ctx); + let init_holders = holders.init_holders(ctx); + let doc = doc_to_optional_cstr(doc.as_ref(), ctx)?; + let associated_method = quote! { + unsafe fn #wrapper_ident( + py: #pyo3_path::Python<'_>, + _slf: ::std::ptr::NonNull<#pyo3_path::ffi::PyObject>, + ) -> #pyo3_path::PyResult<::std::ffi::c_int> { + #init_holders + #warnings + let result = #deleter_impl; + #pyo3_path::impl_::callback::convert(py, result) + } + }; + + let method_def = quote! { + #pyo3_path::impl_::pymethods::PyMethodDefType::Deleter( + #pyo3_path::impl_::pymethods::PyDeleterDef::new( + #python_name, + #cls::#wrapper_ident, + #doc + ) + ) + }; + + Ok(MethodAndMethodDef { + associated_method, + method_def, + }) +} + +fn impl_call_deleter( + cls: &syn::Type, + spec: &FnSpec<'_>, + self_type: &SelfType, + holders: &mut Holders, + ctx: &Ctx, +) -> Result { + let (py_arg, args) = split_off_python_arg(&spec.signature.arguments); + let slf = self_type.receiver( + cls, + ExtractErrorMode::Raise, + // SAFETY: The deleter function is dispatched by CPython's method-wrapper + // descriptor, which enforces the receiver is of the correct type. + unsafe { SelfConversionPolicy::trusted() }, + holders, + ctx, + ); + + if !args.is_empty() { + bail_spanned!(spec.name.span() => + "deleter function can have at most one argument ([pyo3::Python,])" + ); + } + + let name = &spec.name; + let fncall = if py_arg.is_some() { + quote!(#cls::#name(#slf, py)) + } else { + quote!(#cls::#name(#slf)) + }; + + Ok(fncall) +} + +/// Split an argument of pyo3::Python from the front of the arg list, if present +fn split_off_python_arg<'a, 'b>(args: &'a [FnArg<'b>]) -> (Option<&'a PyArg<'b>>, &'a [FnArg<'b>]) { + match args { + [FnArg::Py(py), args @ ..] => (Some(py), args), + args => (None, args), + } +} + +pub enum PropertyType<'a> { + Descriptor { + field_index: usize, + field: &'a Field, + python_name: Option<&'a NameAttribute>, + renaming_rule: Option, + }, + Function { + self_type: &'a SelfType, + spec: &'a FnSpec<'a>, + doc: Option, + }, +} + +impl PropertyType<'_> { + fn null_terminated_python_name(&self) -> Result { + match self { + PropertyType::Descriptor { + field, + python_name, + renaming_rule, + .. + } => { + let name = field_python_name(field, *python_name, *renaming_rule)?; + let name = CString::new(name).unwrap(); + Ok(LitCStr::new(&name, field.span())) + } + PropertyType::Function { spec, .. } => Ok(spec.null_terminated_python_name()), + } + } + + fn doc(&self) -> Option> { + Some(match self { + PropertyType::Descriptor { field, .. } => { + Cow::Owned(utils::get_doc(&field.attrs, None)?) + } + PropertyType::Function { doc, .. } => Cow::Borrowed(doc.as_ref()?), + }) + } +} + +pub const __NEW__: SlotDef = SlotDef::new("Py_tp_new", "newfunc"); +pub const __INIT__: SlotDef = SlotDef::new("Py_tp_init", "initproc"); +pub const __STR__: SlotDef = SlotDef::new("Py_tp_str", "reprfunc"); +pub const __REPR__: SlotDef = SlotDef::new("Py_tp_repr", "reprfunc"); +pub const __HASH__: SlotDef = + SlotDef::new("Py_tp_hash", "hashfunc").return_conversion(TokenGenerator( + |Ctx { pyo3_path, .. }: &Ctx| quote! { #pyo3_path::impl_::callback::HashCallbackOutput }, + )); +pub const __RICHCMP__: SlotDef = SlotDef::new("Py_tp_richcompare", "richcmpfunc") + .extract_error_mode(ExtractErrorMode::NotImplemented); +const __GET__: SlotDef = SlotDef::new("Py_tp_descr_get", "descrgetfunc"); +const __ITER__: SlotDef = SlotDef::new("Py_tp_iter", "getiterfunc"); +const __NEXT__: SlotDef = SlotDef::new("Py_tp_iternext", "iternextfunc") + .return_specialized_conversion( + TokenGenerator(|_| quote! { IterBaseKind, IterOptionKind, IterResultOptionKind }), + TokenGenerator(|_| quote! { iter_tag }), + ); +const __AWAIT__: SlotDef = SlotDef::new("Py_am_await", "unaryfunc"); +const __AITER__: SlotDef = SlotDef::new("Py_am_aiter", "unaryfunc"); +const __ANEXT__: SlotDef = SlotDef::new("Py_am_anext", "unaryfunc").return_specialized_conversion( + TokenGenerator( + |_| quote! { AsyncIterBaseKind, AsyncIterOptionKind, AsyncIterResultOptionKind }, + ), + TokenGenerator(|_| quote! { async_iter_tag }), +); +pub const __LEN__: SlotDef = SlotDef::new("Py_mp_length", "lenfunc"); +const __CONTAINS__: SlotDef = SlotDef::new("Py_sq_contains", "objobjproc"); +const __CONCAT__: SlotDef = SlotDef::new("Py_sq_concat", "binaryfunc"); +const __REPEAT__: SlotDef = SlotDef::new("Py_sq_repeat", "ssizeargfunc"); +const __INPLACE_CONCAT__: SlotDef = SlotDef::new("Py_sq_inplace_concat", "binaryfunc"); +const __INPLACE_REPEAT__: SlotDef = SlotDef::new("Py_sq_inplace_repeat", "ssizeargfunc"); +pub const __GETITEM__: SlotDef = SlotDef::new("Py_mp_subscript", "binaryfunc"); + +const __POS__: SlotDef = SlotDef::new("Py_nb_positive", "unaryfunc"); +const __NEG__: SlotDef = SlotDef::new("Py_nb_negative", "unaryfunc"); +const __ABS__: SlotDef = SlotDef::new("Py_nb_absolute", "unaryfunc"); +const __INVERT__: SlotDef = SlotDef::new("Py_nb_invert", "unaryfunc"); +const __INDEX__: SlotDef = SlotDef::new("Py_nb_index", "unaryfunc"); +pub const __INT__: SlotDef = SlotDef::new("Py_nb_int", "unaryfunc"); +const __FLOAT__: SlotDef = SlotDef::new("Py_nb_float", "unaryfunc"); +const __BOOL__: SlotDef = SlotDef::new("Py_nb_bool", "inquiry"); + +const __IADD__: SlotDef = SlotDef::binary_inplace_operator("Py_nb_inplace_add"); +const __ISUB__: SlotDef = SlotDef::binary_inplace_operator("Py_nb_inplace_subtract"); +const __IMUL__: SlotDef = SlotDef::binary_inplace_operator("Py_nb_inplace_multiply"); +const __IMATMUL__: SlotDef = SlotDef::binary_inplace_operator("Py_nb_inplace_matrix_multiply"); +const __ITRUEDIV__: SlotDef = SlotDef::binary_inplace_operator("Py_nb_inplace_true_divide"); +const __IFLOORDIV__: SlotDef = SlotDef::binary_inplace_operator("Py_nb_inplace_floor_divide"); +const __IMOD__: SlotDef = SlotDef::binary_inplace_operator("Py_nb_inplace_remainder"); +const __ILSHIFT__: SlotDef = SlotDef::binary_inplace_operator("Py_nb_inplace_lshift"); +const __IRSHIFT__: SlotDef = SlotDef::binary_inplace_operator("Py_nb_inplace_rshift"); +const __IAND__: SlotDef = SlotDef::binary_inplace_operator("Py_nb_inplace_and"); +const __IXOR__: SlotDef = SlotDef::binary_inplace_operator("Py_nb_inplace_xor"); +const __IOR__: SlotDef = SlotDef::binary_inplace_operator("Py_nb_inplace_or"); + +const __IPOW__: SlotDef = SlotDef::new("Py_nb_inplace_power", "ternaryfunc") + .extract_error_mode(ExtractErrorMode::NotImplemented) + .return_self(); + +const __GETBUFFER__: SlotDef = SlotDef::new("Py_bf_getbuffer", "getbufferproc").require_unsafe(); +const __RELEASEBUFFER__: SlotDef = + SlotDef::new("Py_bf_releasebuffer", "releasebufferproc").require_unsafe(); +const __CLEAR__: SlotDef = SlotDef::new("Py_tp_clear", "inquiry"); + +#[derive(Clone, Copy)] +enum Ty { + Object, + MaybeNullObject, + NonNullObject, + CompareOp, + Int, + PyHashT, + PySsizeT, + Void, + PyBuffer, +} + +impl Ty { + fn ffi_type(self, ctx: &Ctx) -> TokenStream { + let Ctx { + pyo3_path, + output_span, + } = ctx; + let pyo3_path = pyo3_path.to_tokens_spanned(*output_span); + match self { + Ty::Object | Ty::MaybeNullObject => quote! { *mut #pyo3_path::ffi::PyObject }, + Ty::NonNullObject => quote! { ::std::ptr::NonNull<#pyo3_path::ffi::PyObject> }, + Ty::Int | Ty::CompareOp => quote! { ::std::ffi::c_int }, + Ty::PyHashT => quote! { #pyo3_path::ffi::Py_hash_t }, + Ty::PySsizeT => quote! { #pyo3_path::ffi::Py_ssize_t }, + Ty::Void => quote! { () }, + Ty::PyBuffer => quote! { *mut #pyo3_path::ffi::Py_buffer }, + } + } + + fn extract( + self, + ident: &syn::Ident, + arg: &FnArg<'_>, + extract_error_mode: ExtractErrorMode, + holders: &mut Holders, + ctx: &Ctx, + ) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + match self { + Ty::Object => extract_object( + extract_error_mode, + holders, + arg, + REF_FROM_PTR, + CAST_FUNCTION_ARGUMENT, + quote! { #ident }, + ctx + ), + Ty::MaybeNullObject => extract_object( + extract_error_mode, + holders, + arg, + REF_FROM_PTR, + CAST_FUNCTION_ARGUMENT, + quote! { + if #ident.is_null() { + #pyo3_path::ffi::Py_None() + } else { + #ident + } + }, + ctx + ), + Ty::NonNullObject => extract_object( + extract_error_mode, + holders, + arg, + REF_FROM_NON_NULL, + CAST_NON_NULL_FUNCTION_ARGUMENT, + quote! { #ident }, + ctx + ), + Ty::CompareOp => extract_error_mode.handle_error( + quote! { + #pyo3_path::class::basic::CompareOp::from_raw(#ident) + .ok_or_else(|| #pyo3_path::exceptions::PyValueError::new_err("invalid comparison operator")) + }, + ctx + ), + Ty::PySsizeT => { + let ty = arg.ty(); + extract_error_mode.handle_error( + quote! { + ::std::convert::TryInto::<#ty>::try_into(#ident).map_err(|e| #pyo3_path::exceptions::PyValueError::new_err(e.to_string())) + }, + ctx + ) + } + // Just pass other types through unmodified + Ty::PyBuffer | Ty::Int | Ty::PyHashT | Ty::Void => quote! { #ident }, + } + } +} + +const REF_FROM_PTR: StaticIdent = StaticIdent::new("ref_from_ptr"); +const REF_FROM_NON_NULL: StaticIdent = StaticIdent::new("ref_from_non_null"); + +const CAST_FUNCTION_ARGUMENT: StaticIdent = StaticIdent::new("cast_function_argument"); +const CAST_NON_NULL_FUNCTION_ARGUMENT: StaticIdent = + StaticIdent::new("cast_non_null_function_argument"); + +fn extract_object( + extract_error_mode: ExtractErrorMode, + holders: &mut Holders, + arg: &FnArg<'_>, + ref_from_method: StaticIdent, + cast_method: StaticIdent, + source_ptr: TokenStream, + ctx: &Ctx, +) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + let name = arg.name().unraw().to_string(); + + let extract = if let Some(FromPyWithAttribute { + kw, + value: extractor, + }) = arg.from_py_with() + { + let extractor = quote_spanned! { kw.span => + { let from_py_with: fn(_) -> _ = #extractor; from_py_with } + }; + + quote! { + #pyo3_path::impl_::extract_argument::from_py_with( + unsafe { #pyo3_path::Bound::#ref_from_method(py, &#source_ptr) }, + #name, + #extractor, + ) + } + } else { + let holder = holders.push_holder(Span::call_site()); + quote! {{ + #[allow(unused_imports, reason = "`Probe` trait used on negative case only")] + use #pyo3_path::impl_::pyclass::Probe as _; + #pyo3_path::impl_::extract_argument::extract_argument( + unsafe { #pyo3_path::impl_::extract_argument::#cast_method(py, #source_ptr) }, + &mut #holder, + #name + ) + }} + }; + + let extracted = extract_error_mode.handle_error(extract, ctx); + quote!(#extracted) +} + +enum ReturnMode { + ReturnSelf, + Conversion(TokenGenerator), + SpecializedConversion(TokenGenerator, TokenGenerator), +} + +impl ReturnMode { + fn return_call_output(&self, call: TokenStream, ctx: &Ctx) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + match self { + ReturnMode::Conversion(conversion) => { + let conversion = TokenGeneratorCtx(*conversion, ctx); + quote! { + let _result: #pyo3_path::PyResult<#conversion> = #pyo3_path::impl_::callback::convert(py, #call); + #pyo3_path::impl_::callback::convert(py, _result) + } + } + ReturnMode::SpecializedConversion(traits, tag) => { + let traits = TokenGeneratorCtx(*traits, ctx); + let tag = TokenGeneratorCtx(*tag, ctx); + quote! { + let _result = #call; + use #pyo3_path::impl_::pymethods::{#traits}; + (&_result).#tag().convert(py, _result) + } + } + ReturnMode::ReturnSelf => quote! { + let _result: #pyo3_path::PyResult<()> = #pyo3_path::impl_::callback::convert(py, #call); + _result?; + #pyo3_path::ffi::Py_XINCREF(_slf); + ::std::result::Result::Ok(_slf) + }, + } + } +} + +pub struct SlotDef { + slot: StaticIdent, + func_ty: StaticIdent, + calling_convention: SlotCallingConvention, + ret_ty: Ty, + extract_error_mode: ExtractErrorMode, + return_mode: Option, + require_unsafe: bool, +} + +enum SlotCallingConvention { + /// Specific set of arguments for the slot function + FixedArguments(&'static [Ty]), + /// Arbitrary arguments for `__new__` from the signature (extracted from args / kwargs) + TpNew, + TpInit, +} + +impl SlotDef { + /// Whether this slot receives Python's `args`/`kwargs` pair rather than a fixed set of + /// positional arguments. + /// + /// Only `tp_new` and `tp_init` do; every other slot is exposed to Python through a slot + /// wrapper which rejects keyword arguments, e.g. `__eq__` has the signature + /// `($self, value, /)`. + pub const fn takes_args_and_kwargs(&self) -> bool { + matches!( + self.calling_convention, + SlotCallingConvention::TpNew | SlotCallingConvention::TpInit + ) + } + + const fn new(slot: &'static str, func_ty: &'static str) -> Self { + // The FFI function pointer type determines the arguments and return type + let (calling_convention, ret_ty) = match func_ty.as_bytes() { + b"newfunc" => (SlotCallingConvention::TpNew, Ty::Object), + b"initproc" => (SlotCallingConvention::TpInit, Ty::Int), + b"reprfunc" => (SlotCallingConvention::FixedArguments(&[]), Ty::Object), + b"hashfunc" => (SlotCallingConvention::FixedArguments(&[]), Ty::PyHashT), + b"richcmpfunc" => ( + SlotCallingConvention::FixedArguments(&[Ty::Object, Ty::CompareOp]), + Ty::Object, + ), + b"descrgetfunc" => ( + SlotCallingConvention::FixedArguments(&[Ty::MaybeNullObject, Ty::MaybeNullObject]), + Ty::Object, + ), + b"getiterfunc" => (SlotCallingConvention::FixedArguments(&[]), Ty::Object), + b"iternextfunc" => (SlotCallingConvention::FixedArguments(&[]), Ty::Object), + b"unaryfunc" => (SlotCallingConvention::FixedArguments(&[]), Ty::Object), + b"lenfunc" => (SlotCallingConvention::FixedArguments(&[]), Ty::PySsizeT), + b"objobjproc" => ( + SlotCallingConvention::FixedArguments(&[Ty::Object]), + Ty::Int, + ), + b"binaryfunc" => ( + SlotCallingConvention::FixedArguments(&[Ty::Object]), + Ty::Object, + ), + b"inquiry" => (SlotCallingConvention::FixedArguments(&[]), Ty::Int), + b"ssizeargfunc" => ( + SlotCallingConvention::FixedArguments(&[Ty::PySsizeT]), + Ty::Object, + ), + b"getbufferproc" => ( + SlotCallingConvention::FixedArguments(&[Ty::PyBuffer, Ty::Int]), + Ty::Int, + ), + b"releasebufferproc" => ( + SlotCallingConvention::FixedArguments(&[Ty::PyBuffer]), + Ty::Void, + ), + b"ternaryfunc" => ( + SlotCallingConvention::FixedArguments(&[Ty::Object, Ty::Object]), + Ty::Object, + ), + _ => panic!("don't know calling convention for func_ty"), + }; + + SlotDef { + slot: StaticIdent::new(slot), + func_ty: StaticIdent::new(func_ty), + calling_convention, + ret_ty, + extract_error_mode: ExtractErrorMode::Raise, + return_mode: None, + require_unsafe: false, + } + } + + /// Specialized constructor for binary inplace operators + const fn binary_inplace_operator(slot: &'static str) -> Self { + SlotDef::new(slot, "binaryfunc") + .extract_error_mode(ExtractErrorMode::NotImplemented) + .return_self() + } + + const fn return_conversion(mut self, return_conversion: TokenGenerator) -> Self { + self.return_mode = Some(ReturnMode::Conversion(return_conversion)); + self + } + + const fn return_specialized_conversion( + mut self, + traits: TokenGenerator, + tag: TokenGenerator, + ) -> Self { + self.return_mode = Some(ReturnMode::SpecializedConversion(traits, tag)); + self + } + + const fn extract_error_mode(mut self, extract_error_mode: ExtractErrorMode) -> Self { + self.extract_error_mode = extract_error_mode; + self + } + + const fn return_self(mut self) -> Self { + self.return_mode = Some(ReturnMode::ReturnSelf); + self + } + + const fn require_unsafe(mut self) -> Self { + self.require_unsafe = true; + self + } + + pub fn generate_type_slot( + &self, + cls: &syn::Type, + spec: &FnSpec<'_>, + method_name: &str, + ctx: &Ctx, + ) -> Result { + let Ctx { pyo3_path, .. } = ctx; + let SlotDef { + slot, + func_ty, + calling_convention, + extract_error_mode, + ret_ty, + return_mode, + require_unsafe, + } = self; + if *require_unsafe { + ensure_spanned!( + spec.unsafety.is_some(), + spec.name.span() => format!("`{}` must be `unsafe fn`", method_name) + ); + } + let wrapper_ident = format_ident!("__pymethod_{}__", method_name); + let ret_ty = ret_ty.ffi_type(ctx); + let mut holders = Holders::new(); + let MethodBody { + arg_idents, + arg_types, + body, + } = generate_method_body( + cls, + spec, + calling_convention, + *extract_error_mode, + // SAFETY: All extension-type slots use trusted self: CPython's slot dispatch + // contract guarantees the receiver is of the correct type. + unsafe { SelfConversionPolicy::trusted() }, + &mut holders, + return_mode.as_ref(), + ctx, + )?; + let name = spec.name; + let holders = holders.init_holders(ctx); + let associated_method = quote! { + #[allow(non_snake_case)] + unsafe fn #wrapper_ident( + py: #pyo3_path::Python<'_>, + #(#arg_idents: #arg_types),* + ) -> #pyo3_path::PyResult<#ret_ty> { + let function = #cls::#name; // Shadow the method name to avoid #3017 + #holders + #body + } + }; + let slot_def = quote! { + #pyo3_path::ffi::PyType_Slot { + slot: #pyo3_path::ffi::#slot, + pfunc: #pyo3_path::impl_::trampoline::get_trampoline_function!(#func_ty, #cls::#wrapper_ident) as #pyo3_path::ffi::#func_ty as _ + } + }; + Ok(MethodAndSlotDef { + associated_method, + slot_def, + }) + } +} + +#[allow(clippy::too_many_arguments)] +fn generate_method_body( + cls: &syn::Type, + spec: &FnSpec<'_>, + calling_convention: &SlotCallingConvention, + extract_error_mode: ExtractErrorMode, + self_conversion: SelfConversionPolicy, + holders: &mut Holders, + // NB ignored if calling_convention is SlotCallingConvention::TpNew, possibly should merge into that enum + return_mode: Option<&ReturnMode>, + ctx: &Ctx, +) -> Result { + let Ctx { + pyo3_path, + output_span, + } = ctx; + let self_arg = spec.tp.self_arg( + Some(cls), + extract_error_mode, + self_conversion, + match calling_convention { + SlotCallingConvention::TpNew => ClassMethodReceiver::Class, + SlotCallingConvention::TpInit | SlotCallingConvention::FixedArguments(_) => { + ClassMethodReceiver::Instance + } + }, + holders, + ctx, + ); + let rust_name = spec.name; + let warnings = spec.warnings.build_py_warning(ctx); + + let (arg_idents, arg_types, body) = match calling_convention { + SlotCallingConvention::TpNew => { + let arg_idents = vec![ + format_ident!("_slf"), + format_ident!("_args"), + format_ident!("_kwargs"), + ]; + let arg_types = vec![ + quote! { *mut #pyo3_path::ffi::PyTypeObject }, + quote! { *mut #pyo3_path::ffi::PyObject }, + quote! { *mut #pyo3_path::ffi::PyObject }, + ]; + let (arg_convert, args) = impl_arg_params(spec, Some(cls), false, holders, ctx); + let args = self_arg.into_iter().chain(args); + let call = quote_spanned! {*output_span=> #cls::#rust_name(#(#args),*) }; + + // Use just the text_signature_call_signature() because the class' Python name + // isn't known to `#[pymethods]` - that has to be attached at runtime from the PyClassImpl + // trait implementation created by `#[pyclass]`. + let text_signature_impl = spec.text_signature_call_signature().map(|text_signature| { + quote! { + #[allow(unknown_lints, non_local_definitions)] + impl #pyo3_path::impl_::pyclass::doc::PyClassNewTextSignature for #cls { + const TEXT_SIGNATURE: &'static str = #text_signature; + } + } + }); + + let py = syn::Ident::new("py", Span::call_site()); + let initializer = syn::Ident::new("initializer", Span::call_site()); + let slf = syn::Ident::new("_slf", Span::call_site()); + + // Having just this call emitted at the span of the return value helps surface errors + // if the user passed an invalid return type. + let conversion = quote_spanned! { *output_span => + #pyo3_path::impl_::pymethods::tp_new_impl::<_, #cls>(#py, #initializer, #slf) + }; + + let value = syn::Ident::new("value", Span::call_site()); + let resolver = quote_spanned! { *output_span => + #pyo3_path::impl_::pymethods::tp_new_resolver::<#cls, _>(&#value).resolve(#value); + }; + + let body = quote! { + #text_signature_impl + #warnings + #arg_convert + + let result = #call; + let #value = #pyo3_path::impl_::wrap::OkWrapper::new(&result).ok_wrap(result)?; + let #initializer = #resolver; + unsafe { #conversion } + }; + (arg_idents, arg_types, body) + } + SlotCallingConvention::TpInit => { + let arg_idents = vec![ + format_ident!("_slf"), + format_ident!("_args"), + format_ident!("_kwargs"), + ]; + let arg_types = vec![ + quote! { *mut #pyo3_path::ffi::PyObject }, + quote! { *mut #pyo3_path::ffi::PyObject }, + quote! { *mut #pyo3_path::ffi::PyObject }, + ]; + let (arg_convert, args) = impl_arg_params(spec, Some(cls), false, holders, ctx); + let args = self_arg.into_iter().chain(args); + let call = quote! {{ + let r = #cls::#rust_name(#(#args),*); + #pyo3_path::impl_::wrap::converter(&r) + .wrap(r) + .map_err(::core::convert::Into::<#pyo3_path::PyErr>::into)? + }}; + let output = quote_spanned! { *output_span => result.convert(py) }; + + let body = quote! { + use #pyo3_path::impl_::callback::IntoPyCallbackOutput; + #warnings + #arg_convert + let result = #call; + #output + }; + (arg_idents, arg_types, body) + } + SlotCallingConvention::FixedArguments(arguments) => { + let arg_idents: Vec<_> = std::iter::once(format_ident!("_slf")) + .chain((0..arguments.len()).map(|i| format_ident!("arg{}", i))) + .collect(); + let arg_types: Vec<_> = std::iter::once(quote! { *mut #pyo3_path::ffi::PyObject }) + .chain(arguments.iter().map(|arg| arg.ffi_type(ctx))) + .collect(); + + let args = extract_proto_arguments(spec, arguments, extract_error_mode, holders, ctx)?; + let args = self_arg.into_iter().chain(args); + let call = quote! { #cls::#rust_name(#(#args),*) }; + let result = if let Some(return_mode) = return_mode { + return_mode.return_call_output(call, ctx) + } else { + quote! { + let result = #call; + #pyo3_path::impl_::callback::convert(py, result) + } + }; + let body = quote! { + #warnings + #result + }; + (arg_idents, arg_types, body) + } + }; + + Ok(MethodBody { + arg_idents, + arg_types, + body, + }) +} + +struct SlotFragmentDef { + fragment: &'static str, + arguments: &'static [Ty], + extract_error_mode: ExtractErrorMode, + ret_ty: Ty, + /// Self-conversion policy for this slot fragment. + /// + /// Most slot fragments are called by CPython with a receiver that is + /// guaranteed to be of the correct type (`Trusted`). However, binary + /// operator fragments are combined into a single slot (e.g. `nb_add`) + /// where the runtime helper may swap operands and call the reflected + /// fragment with a receiver of an unknown (potentially wrong) type. + /// Those fragments must use `Checked` so that a type mismatch returns + /// `NotImplemented` instead of causing undefined behaviour. + self_conversion: SelfConversionPolicy, +} + +impl SlotFragmentDef { + const fn new(fragment: &'static str, arguments: &'static [Ty]) -> Self { + SlotFragmentDef { + fragment, + arguments, + extract_error_mode: ExtractErrorMode::Raise, + ret_ty: Ty::Void, + self_conversion: SelfConversionPolicy::checked(), + } + } + + const fn binary_operator(fragment: &'static str) -> Self { + // Binary operator fragments (`__add__`, `__radd__`, etc.) are combined + // into a shared slot (e.g. `nb_add`) that may call the forward fragment + // with a non-class receiver (e.g. `1 + MyClass()` → `nb_add(1, c)`). + // The runtime helper then tries the reflected fragment with the operands + // swapped, which can also produce a non-class `_slf`. Both cases require + // a checked type conversion so that a mismatch gracefully returns + // `NotImplemented` rather than causing undefined behaviour. + // TODO: addressing #6024 could allow to simplify this by using type + // checks to directly dispatch to the right fragment. + SlotFragmentDef { + fragment, + arguments: &[Ty::Object], + extract_error_mode: ExtractErrorMode::NotImplemented, + ret_ty: Ty::Object, + self_conversion: SelfConversionPolicy::checked(), + } + } + + const fn extract_error_mode(mut self, extract_error_mode: ExtractErrorMode) -> Self { + self.extract_error_mode = extract_error_mode; + self + } + + const fn ret_ty(mut self, ret_ty: Ty) -> Self { + self.ret_ty = ret_ty; + self + } + + const fn self_conversion_policy(mut self, policy: SelfConversionPolicy) -> Self { + self.self_conversion = policy; + self + } + + fn generate_pyproto_fragment( + &self, + cls: &syn::Type, + spec: &FnSpec<'_>, + ctx: &Ctx, + ) -> Result { + let Ctx { pyo3_path, .. } = ctx; + let SlotFragmentDef { + fragment, + arguments, + extract_error_mode, + ret_ty, + self_conversion, + } = self; + let fragment_trait = format_ident!("PyClass{}SlotFragment", fragment); + let method = syn::Ident::new(fragment, Span::call_site()); + let wrapper_ident = format_ident!("__pymethod_{}__", fragment); + + let mut holders = Holders::new(); + let MethodBody { + arg_idents, + arg_types, + body, + } = generate_method_body( + cls, + spec, + &SlotCallingConvention::FixedArguments(arguments), + *extract_error_mode, + *self_conversion, + &mut holders, + None, + ctx, + )?; + let ret_ty = ret_ty.ffi_type(ctx); + let holders = holders.init_holders(ctx); + Ok(quote! { + impl #cls { + #[allow(non_snake_case)] + unsafe fn #wrapper_ident( + py: #pyo3_path::Python, + #(#arg_idents: #arg_types),* + ) -> #pyo3_path::PyResult<#ret_ty> { + #holders + #body + } + } + + impl #pyo3_path::impl_::pyclass::#fragment_trait<#cls> for #pyo3_path::impl_::pyclass::PyClassImplCollector<#cls> { + + #[inline] + unsafe fn #method( + self, + py: #pyo3_path::Python, + #(#arg_idents: #arg_types),* + ) -> #pyo3_path::PyResult<#ret_ty> { + #cls::#wrapper_ident(py, #(#arg_idents),*) + } + } + }) + } +} + +/// The reusable components of a method body. +pub struct MethodBody { + pub arg_idents: Vec, + pub arg_types: Vec, + pub body: TokenStream, +} + +const __GETATTRIBUTE__: SlotFragmentDef = SlotFragmentDef::new("__getattribute__", &[Ty::Object]) + .ret_ty(Ty::Object) + // SAFETY: `tp_getattro` is wrapped by CPython to guarantee correct receiver type + .self_conversion_policy(unsafe { SelfConversionPolicy::trusted() }); +const __GETATTR__: SlotFragmentDef = SlotFragmentDef::new("__getattr__", &[Ty::Object]) + .ret_ty(Ty::Object) + // SAFETY: `tp_getattro` is wrapped by CPython to guarantee correct receiver type + .self_conversion_policy(unsafe { SelfConversionPolicy::trusted() }); +const __SETATTR__: SlotFragmentDef = + SlotFragmentDef::new("__setattr__", &[Ty::Object, Ty::NonNullObject]) + // SAFETY: `tp_setattro` is wrapped by CPython to guarantee correct receiver type + .self_conversion_policy(unsafe { SelfConversionPolicy::trusted() }); +const __DELATTR__: SlotFragmentDef = SlotFragmentDef::new("__delattr__", &[Ty::Object]) + // SAFETY: `tp_setattro` is wrapped by CPython to guarantee correct receiver type + .self_conversion_policy(unsafe { SelfConversionPolicy::trusted() }); +const __SET__: SlotFragmentDef = SlotFragmentDef::new("__set__", &[Ty::Object, Ty::NonNullObject]) + // SAFETY: `tp_descr_set` is wrapped by CPython to guarantee correct receiver type + .self_conversion_policy(unsafe { SelfConversionPolicy::trusted() }); +const __DELETE__: SlotFragmentDef = SlotFragmentDef::new("__delete__", &[Ty::Object]) + // SAFETY: `tp_descr_set` is wrapped by CPython to guarantee correct receiver type + .self_conversion_policy(unsafe { SelfConversionPolicy::trusted() }); +const __SETITEM__: SlotFragmentDef = + SlotFragmentDef::new("__setitem__", &[Ty::Object, Ty::NonNullObject]) + // SAFETY: `mp_ass_subscript` is wrapped by CPython to guarantee correct receiver type + .self_conversion_policy(unsafe { SelfConversionPolicy::trusted() }); +const __DELITEM__: SlotFragmentDef = SlotFragmentDef::new("__delitem__", &[Ty::Object]) + // SAFETY: `mp_ass_subscript` is wrapped by CPython to guarantee correct receiver type + .self_conversion_policy(unsafe { SelfConversionPolicy::trusted() }); + +const __ADD__: SlotFragmentDef = SlotFragmentDef::binary_operator("__add__"); +const __RADD__: SlotFragmentDef = SlotFragmentDef::binary_operator("__radd__"); +const __SUB__: SlotFragmentDef = SlotFragmentDef::binary_operator("__sub__"); +const __RSUB__: SlotFragmentDef = SlotFragmentDef::binary_operator("__rsub__"); +const __MUL__: SlotFragmentDef = SlotFragmentDef::binary_operator("__mul__"); +const __RMUL__: SlotFragmentDef = SlotFragmentDef::binary_operator("__rmul__"); +const __MATMUL__: SlotFragmentDef = SlotFragmentDef::binary_operator("__matmul__"); +const __RMATMUL__: SlotFragmentDef = SlotFragmentDef::binary_operator("__rmatmul__"); +const __FLOORDIV__: SlotFragmentDef = SlotFragmentDef::binary_operator("__floordiv__"); +const __RFLOORDIV__: SlotFragmentDef = SlotFragmentDef::binary_operator("__rfloordiv__"); +const __TRUEDIV__: SlotFragmentDef = SlotFragmentDef::binary_operator("__truediv__"); +const __RTRUEDIV__: SlotFragmentDef = SlotFragmentDef::binary_operator("__rtruediv__"); +const __DIVMOD__: SlotFragmentDef = SlotFragmentDef::binary_operator("__divmod__"); +const __RDIVMOD__: SlotFragmentDef = SlotFragmentDef::binary_operator("__rdivmod__"); +const __MOD__: SlotFragmentDef = SlotFragmentDef::binary_operator("__mod__"); +const __RMOD__: SlotFragmentDef = SlotFragmentDef::binary_operator("__rmod__"); +const __LSHIFT__: SlotFragmentDef = SlotFragmentDef::binary_operator("__lshift__"); +const __RLSHIFT__: SlotFragmentDef = SlotFragmentDef::binary_operator("__rlshift__"); +const __RSHIFT__: SlotFragmentDef = SlotFragmentDef::binary_operator("__rshift__"); +const __RRSHIFT__: SlotFragmentDef = SlotFragmentDef::binary_operator("__rrshift__"); +const __AND__: SlotFragmentDef = SlotFragmentDef::binary_operator("__and__"); +const __RAND__: SlotFragmentDef = SlotFragmentDef::binary_operator("__rand__"); +const __XOR__: SlotFragmentDef = SlotFragmentDef::binary_operator("__xor__"); +const __RXOR__: SlotFragmentDef = SlotFragmentDef::binary_operator("__rxor__"); +const __OR__: SlotFragmentDef = SlotFragmentDef::binary_operator("__or__"); +const __ROR__: SlotFragmentDef = SlotFragmentDef::binary_operator("__ror__"); + +const __POW__: SlotFragmentDef = SlotFragmentDef::new("__pow__", &[Ty::Object, Ty::Object]) + .extract_error_mode(ExtractErrorMode::NotImplemented) + .ret_ty(Ty::Object); +const __RPOW__: SlotFragmentDef = SlotFragmentDef::new("__rpow__", &[Ty::Object, Ty::Object]) + .extract_error_mode(ExtractErrorMode::NotImplemented) + .ret_ty(Ty::Object); + +const __LT__: SlotFragmentDef = SlotFragmentDef::new("__lt__", &[Ty::Object]) + .extract_error_mode(ExtractErrorMode::NotImplemented) + .ret_ty(Ty::Object) + // SAFETY: `tp_richcompare` is wrapped by CPython to guarantee correct receiver type + .self_conversion_policy(unsafe { SelfConversionPolicy::trusted() }); +const __LE__: SlotFragmentDef = SlotFragmentDef::new("__le__", &[Ty::Object]) + .extract_error_mode(ExtractErrorMode::NotImplemented) + .ret_ty(Ty::Object) + // SAFETY: `tp_richcompare` is wrapped by CPython to guarantee correct receiver type + .self_conversion_policy(unsafe { SelfConversionPolicy::trusted() }); +const __EQ__: SlotFragmentDef = SlotFragmentDef::new("__eq__", &[Ty::Object]) + .extract_error_mode(ExtractErrorMode::NotImplemented) + .ret_ty(Ty::Object) + // SAFETY: `tp_richcompare` is wrapped by CPython to guarantee correct receiver type + .self_conversion_policy(unsafe { SelfConversionPolicy::trusted() }); +const __NE__: SlotFragmentDef = SlotFragmentDef::new("__ne__", &[Ty::Object]) + .extract_error_mode(ExtractErrorMode::NotImplemented) + .ret_ty(Ty::Object) + // SAFETY: `tp_richcompare` is wrapped by CPython to guarantee correct receiver type + .self_conversion_policy(unsafe { SelfConversionPolicy::trusted() }); +const __GT__: SlotFragmentDef = SlotFragmentDef::new("__gt__", &[Ty::Object]) + .extract_error_mode(ExtractErrorMode::NotImplemented) + .ret_ty(Ty::Object) + // SAFETY: `tp_richcompare` is wrapped by CPython to guarantee correct receiver type + .self_conversion_policy(unsafe { SelfConversionPolicy::trusted() }); +const __GE__: SlotFragmentDef = SlotFragmentDef::new("__ge__", &[Ty::Object]) + .extract_error_mode(ExtractErrorMode::NotImplemented) + .ret_ty(Ty::Object) + // SAFETY: `tp_richcompare` is wrapped by CPython to guarantee correct receiver type + .self_conversion_policy(unsafe { SelfConversionPolicy::trusted() }); + +fn extract_proto_arguments( + spec: &FnSpec<'_>, + proto_args: &[Ty], + extract_error_mode: ExtractErrorMode, + holders: &mut Holders, + ctx: &Ctx, +) -> Result> { + let mut args = Vec::with_capacity(spec.signature.arguments.len()); + let mut non_python_args = 0; + + for arg in &spec.signature.arguments { + if let FnArg::Py(..) = arg { + args.push(quote! { py }); + } else { + let ident = syn::Ident::new(&format!("arg{non_python_args}"), Span::call_site()); + let conversions = proto_args.get(non_python_args) + .ok_or_else(|| err_spanned!(arg.ty().span() => format!("Expected at most {} non-python arguments", proto_args.len())))? + .extract(&ident, arg, extract_error_mode, holders, ctx); + non_python_args += 1; + args.push(conversions); + } + } + + if non_python_args != proto_args.len() { + bail_spanned!(spec.name.span() => format!("Expected {} arguments, got {}", proto_args.len(), non_python_args)); + } + Ok(args) +} + +#[derive(Clone, Copy)] +struct TokenGenerator(fn(&Ctx) -> TokenStream); + +struct TokenGeneratorCtx<'ctx>(TokenGenerator, &'ctx Ctx); + +impl ToTokens for TokenGeneratorCtx<'_> { + fn to_tokens(&self, tokens: &mut TokenStream) { + let Self(TokenGenerator(gen), ctx) = self; + (gen)(ctx).to_tokens(tokens) + } +} + +pub fn field_python_name( + field: &Field, + name_attr: Option<&NameAttribute>, + renaming_rule: Option, +) -> Result { + if let Some(name_attr) = name_attr { + return Ok(name_attr.value.0.to_string()); + } + let Some(ident) = &field.ident else { + bail_spanned!(field.span() => "`get` and `set` with tuple struct fields require `name`"); + }; + let mut name = ident.unraw().to_string(); + if let Some(rule) = renaming_rule { + name = utils::apply_renaming_rule(rule, &name); + } + Ok(name) +} + +fn doc_to_optional_cstr(doc: Option<&PythonDoc>, ctx: &Ctx) -> Result { + Ok(if let Some(doc) = doc { + let doc = doc.to_cstr_stream(ctx)?; + quote!(::std::option::Option::Some(#doc)) + } else { + quote!(::std::option::Option::None) + }) +} diff --git a/vendor/pyo3-macros-backend/src/quotes.rs b/vendor/pyo3-macros-backend/src/quotes.rs new file mode 100644 index 0000000..7786837 --- /dev/null +++ b/vendor/pyo3-macros-backend/src/quotes.rs @@ -0,0 +1,36 @@ +use crate::utils::Ctx; +use proc_macro2::TokenStream; +use quote::{quote, quote_spanned}; + +pub(crate) fn some_wrap(obj: TokenStream, ctx: &Ctx) -> TokenStream { + let Ctx { pyo3_path, .. } = ctx; + quote! { + #pyo3_path::impl_::wrap::SomeWrap::wrap(#obj) + } +} + +pub(crate) fn ok_wrap(obj: TokenStream, ctx: &Ctx) -> TokenStream { + let Ctx { + pyo3_path, + output_span, + } = ctx; + let pyo3_path = pyo3_path.to_tokens_spanned(*output_span); + quote_spanned! { *output_span => { + let obj = #obj; + #[allow(clippy::useless_conversion, reason = "needed for Into conversion, may be redundant")] + #pyo3_path::impl_::wrap::converter(&obj).wrap(obj).map_err(::core::convert::Into::<#pyo3_path::PyErr>::into) + }} +} + +pub(crate) fn map_result_into_ptr(result: TokenStream, ctx: &Ctx) -> TokenStream { + let Ctx { + pyo3_path, + output_span, + } = ctx; + let pyo3_path = pyo3_path.to_tokens_spanned(*output_span); + let py = syn::Ident::new("py", proc_macro2::Span::call_site()); + quote_spanned! { *output_span => { + let result = #result; + #pyo3_path::impl_::wrap::converter(&result).map_into_ptr(#py, result) + }} +} diff --git a/vendor/pyo3-macros-backend/src/utils.rs b/vendor/pyo3-macros-backend/src/utils.rs new file mode 100644 index 0000000..eacc9f7 --- /dev/null +++ b/vendor/pyo3-macros-backend/src/utils.rs @@ -0,0 +1,394 @@ +use crate::attributes::{CrateAttribute, RenamingRule}; +use proc_macro2::{Span, TokenStream, TokenTree}; +use quote::{quote, ToTokens, TokenStreamExt}; +use std::ffi::CString; +use std::mem::take; +use syn::spanned::Spanned; +use syn::{Expr, ExprLit, Lit, LitCStr}; + +/// Macro inspired by `anyhow::anyhow!` to create a compiler error with the given span. +macro_rules! err_spanned { + ($span:expr => $msg:expr) => { + syn::Error::new($span, $msg) + }; +} + +/// Macro inspired by `anyhow::bail!` to return a compiler error with the given span. +macro_rules! bail_spanned { + ($span:expr => $msg:expr) => { + return Err(err_spanned!($span => $msg)) + }; +} + +/// Macro inspired by `anyhow::ensure!` to return a compiler error with the given span if the +/// specified condition is not met. +macro_rules! ensure_spanned { + ($condition:expr, $span:expr => $msg:expr) => { + if !($condition) { + bail_spanned!($span => $msg); + } + }; + ($($condition:expr, $span:expr => $msg:expr;)*) => { + if let Some(e) = [$( + (!($condition)).then(|| err_spanned!($span => $msg)), + )*] + .into_iter() + .flatten() + .reduce(|mut acc, e| { + acc.combine(e); + acc + }) { + return Err(e); + } + }; +} + +/// Check if the given type `ty` is `pyo3::Python`. +pub fn is_python(ty: &syn::Type) -> bool { + match unwrap_ty_group(ty) { + syn::Type::Path(typath) => typath + .path + .segments + .last() + .map(|seg| seg.ident == "Python") + .unwrap_or(false), + _ => false, + } +} + +/// If `ty` is `Option`, return `Some(T)`, else `None`. +pub fn option_type_argument(ty: &syn::Type) -> Option<&syn::Type> { + if let syn::Type::Path(syn::TypePath { path, .. }) = ty { + let seg = path.segments.last().filter(|s| s.ident == "Option")?; + if let syn::PathArguments::AngleBracketed(params) = &seg.arguments { + if let syn::GenericArgument::Type(ty) = params.args.first()? { + return Some(ty); + } + } + } + None +} + +/// A syntax tree which evaluates to a string for Python. +/// +/// Typically, the tokens will just be that string, but if the original docs included macro +/// expressions then the tokens will be a concatenation expression of the strings and +/// macro parts. contents such as parse the string contents. +#[derive(Clone)] +pub struct PythonDoc { + pub parts: Vec, +} + +/// Collects all #[doc = "..."] attributes into a TokenStream evaluating to a string. +/// +/// If this doc is for a callable, the provided `text_signature` can be passed to prepend +/// this to the documentation suitable for Python to extract this into the `__text_signature__` +/// attribute. +pub fn get_doc(attrs: &[syn::Attribute], mut text_signature: Option) -> Option { + // insert special divider between `__text_signature__` and doc + // (assume text_signature is itself well-formed) + if let Some(text_signature) = &mut text_signature { + text_signature.push_str("\n--\n\n"); + } + + let mut parts = Vec::new(); + let mut first = true; + let mut current_part = text_signature.unwrap_or_default(); + let mut current_part_span: Option = None; + + for attr in attrs { + if attr.path().is_ident("doc") { + if let Ok(nv) = attr.meta.require_name_value() { + if !first { + current_part.push('\n'); + } else { + first = false; + } + if let Expr::Lit(ExprLit { + lit: Lit::Str(lit_str), + .. + }) = &nv.value + { + // Strip single left space from literal strings, if needed. + // e.g. `/// Hello world` expands to #[doc = " Hello world"] + let doc_line = lit_str.value(); + current_part.push_str(doc_line.strip_prefix(' ').unwrap_or(&doc_line)); + current_part_span = current_part_span + .map_or_else(|| Some(lit_str.span()), |s| s.join(lit_str.span())); + } else { + // This is probably a macro doc from Rust 1.54, e.g. #[doc = include_str!(...)] + // Reset the string buffer, write that part, and then push this macro part too. + if !current_part.is_empty() { + parts.push(StrOrExpr::Str { + value: take(&mut current_part), + span: take(&mut current_part_span), + }); + } + parts.push(StrOrExpr::Expr(nv.value.clone())); + } + } + } + } + if !current_part.is_empty() { + parts.push(StrOrExpr::Str { + value: current_part, + span: current_part_span, + }); + } + if parts.is_empty() { + None + } else { + Some(PythonDoc { parts }) + } +} + +impl PythonDoc { + pub fn to_cstr_stream(&self, ctx: &Ctx) -> syn::Result { + let parts = &self.parts; + if let [StrOrExpr::Str { value, span }] = &parts[..] { + // Simple case, a single string. We serialize as such + return match CString::new(value.clone()) { + Ok(null_terminated_value) => Ok(LitCStr::new( + &null_terminated_value, + span.unwrap_or_else(Span::call_site), + ) + .into_token_stream()), + Err(e) => Err(syn::Error::new( + span.unwrap_or_else(Span::call_site), + format!( + "Python doc may not contain nul byte, found nul at position {}", + e.nul_position() + ), + )), + }; + } + let Ctx { pyo3_path, .. } = ctx; + Ok(quote!(#pyo3_path::ffi::c_str!(concat!(#(#parts),*)))) + } +} + +/// A plain string or an expression +#[derive(Clone)] +pub enum StrOrExpr { + Str { value: String, span: Option }, + Expr(Expr), +} + +impl ToTokens for StrOrExpr { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + StrOrExpr::Str { value, .. } => value.to_tokens(tokens), + StrOrExpr::Expr(expr) => expr.to_tokens(tokens), + } + } +} + +pub fn unwrap_ty_group(mut ty: &syn::Type) -> &syn::Type { + while let syn::Type::Group(g) = ty { + ty = &*g.elem; + } + ty +} + +pub struct Ctx { + /// Where we can find the pyo3 crate + pub pyo3_path: PyO3CratePath, + + /// If we are in a pymethod or pyfunction, + /// this will be the span of the return type + pub output_span: Span, +} + +impl Ctx { + pub(crate) fn new(attr: &Option, signature: Option<&syn::Signature>) -> Self { + let pyo3_path = match attr { + Some(attr) => PyO3CratePath::Given(attr.value.0.clone()), + None => PyO3CratePath::Default, + }; + + let output_span = if let Some(syn::Signature { + output: syn::ReturnType::Type(_, output_type), + .. + }) = &signature + { + output_type.span() + } else { + Span::call_site() + }; + + Self { + pyo3_path, + output_span, + } + } +} + +#[derive(Clone)] +pub enum PyO3CratePath { + Given(syn::Path), + Default, +} + +impl PyO3CratePath { + pub fn to_tokens_spanned(&self, span: Span) -> TokenStream { + match self { + Self::Given(path) => quote::quote_spanned! { span => #path }, + Self::Default => quote::quote_spanned! { span => ::pyo3 }, + } + } +} + +impl quote::ToTokens for PyO3CratePath { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + Self::Given(path) => path.to_tokens(tokens), + Self::Default => quote::quote! { ::pyo3 }.to_tokens(tokens), + } + } +} + +pub fn apply_renaming_rule(rule: RenamingRule, name: &str) -> String { + use heck::*; + + match rule { + RenamingRule::CamelCase => name.to_lower_camel_case(), + RenamingRule::KebabCase => name.to_kebab_case(), + RenamingRule::Lowercase => name.to_lowercase(), + RenamingRule::PascalCase => name.to_upper_camel_case(), + RenamingRule::ScreamingKebabCase => name.to_shouty_kebab_case(), + RenamingRule::ScreamingSnakeCase => name.to_shouty_snake_case(), + RenamingRule::SnakeCase => name.to_snake_case(), + RenamingRule::Uppercase => name.to_uppercase(), + } +} + +pub(crate) enum IdentOrStr<'a> { + Str(&'a str), + Ident(syn::Ident), +} + +pub(crate) fn has_attribute(attrs: &[syn::Attribute], ident: &str) -> bool { + has_attribute_with_namespace(attrs, None, &[ident]) +} + +pub(crate) fn has_attribute_with_namespace( + attrs: &[syn::Attribute], + crate_path: Option<&PyO3CratePath>, + idents: &[&str], +) -> bool { + let mut segments = vec![]; + if let Some(c) = crate_path { + match c { + PyO3CratePath::Given(paths) => { + for p in &paths.segments { + segments.push(IdentOrStr::Ident(p.ident.clone())); + } + } + PyO3CratePath::Default => segments.push(IdentOrStr::Str("pyo3")), + } + }; + for i in idents { + segments.push(IdentOrStr::Str(i)); + } + + attrs.iter().any(|attr| { + segments + .iter() + .eq(attr.path().segments.iter().map(|v| &v.ident)) + }) +} + +pub fn expr_to_python(expr: &syn::Expr) -> String { + match expr { + // literal values + syn::Expr::Lit(syn::ExprLit { lit, .. }) => match lit { + syn::Lit::Str(s) => s.token().to_string(), + syn::Lit::Char(c) => c.token().to_string(), + syn::Lit::Int(i) => i.base10_digits().to_string(), + syn::Lit::Float(f) => f.base10_digits().to_string(), + syn::Lit::Bool(b) => { + if b.value() { + "True".to_string() + } else { + "False".to_string() + } + } + _ => "...".to_string(), + }, + // None + syn::Expr::Path(syn::ExprPath { qself, path, .. }) + if qself.is_none() && path.is_ident("None") => + { + "None".to_string() + } + // others, unsupported yet so defaults to `...` + _ => "...".to_string(), + } +} + +/// Helper struct for hard-coded identifiers used in the macro code. +#[derive(Clone, Copy)] +pub struct StaticIdent(&'static str); + +impl StaticIdent { + pub const fn new(name: &'static str) -> Self { + Self(name) + } +} + +impl ToTokens for StaticIdent { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(syn::Ident::new(self.0, Span::call_site())); + } +} + +/// Adjusts a tokes stream so that the location for the stream comes from `Span`. +/// +/// This affects where error messages will arise in the compiler output. +pub(crate) fn locate_tokens_at(tokens: TokenStream, span: Span) -> TokenStream { + fn set_span_recursively(tokens: TokenStream, span: Span) -> TokenStream { + tokens + .into_iter() + .map(|tt| match tt { + TokenTree::Group(g) => { + let inner = set_span_recursively(g.stream(), span); + let mut new_group = proc_macro2::Group::new(g.delimiter(), inner); + new_group.set_span(span); + TokenTree::Group(new_group) + } + TokenTree::Ident(mut ident) => { + ident.set_span(span); + TokenTree::Ident(ident) + } + TokenTree::Punct(mut punct) => { + punct.set_span(span); + TokenTree::Punct(punct) + } + TokenTree::Literal(mut lit) => { + lit.set_span(span); + TokenTree::Literal(lit) + } + }) + .collect() + } + + let output_span = tokens.span().located_at(span); + set_span_recursively(tokens, output_span) +} + +/// Replaces all explicit lifetimes in `self` with elided (`'_`) lifetimes +/// +/// This is useful if `Self` is used in `const` context, where explicit +/// lifetimes are not allowed (yet). +#[cfg(feature = "experimental-inspect")] +pub(crate) fn elide_lifetimes(ty: &mut syn::Type) { + struct ElideLifetimesVisitor; + + impl syn::visit_mut::VisitMut for ElideLifetimesVisitor { + fn visit_lifetime_mut(&mut self, l: &mut syn::Lifetime) { + *l = syn::Lifetime::new("'_", l.span()); + } + } + + syn::visit_mut::VisitMut::visit_type_mut(&mut ElideLifetimesVisitor, ty); +} diff --git a/vendor/pyo3-macros/.cargo-checksum.json b/vendor/pyo3-macros/.cargo-checksum.json new file mode 100644 index 0000000..61cb27f --- /dev/null +++ b/vendor/pyo3-macros/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo_vcs_info.json":"696fe0b053bf3321d15410a79502e6b87134c77e51b00e6dc1fa75d7eaaf81a6","Cargo.lock":"383ac7c520f89d6f85b15d5adb66a5020c382c38a9ca9930b6641fe8d6ca2b68","Cargo.toml":"246dd2bad7ef1a5c56bf79c89ee9844115cc79fdbe659e647e38d30d7535ac10","Cargo.toml.orig":"d8c5002ae0de060115be9dc71af01f21affaab37db7cd84a96021369667583de","LICENSE-APACHE":"32c76dbe0e73d79100d5ece77c158399f2e2541bc5c78548a4ba45c1cb53c5c9","LICENSE-MIT":"afcbe3b2e6b37172b5a9ca869ee4c0b8cdc09316e5d4384864154482c33e5af6","src/lib.rs":"25d7af1ae4bf8cb5fbf13f92adcc4c0f1ffa4de64e9b731e5d7a58b0f2eb9278"},"package":"73225868fc1cd84eef2c3c230ddb91273bf1de46aeb8a4248da76d32a0924a1c"} \ No newline at end of file diff --git a/vendor/pyo3-macros/.cargo_vcs_info.json b/vendor/pyo3-macros/.cargo_vcs_info.json new file mode 100644 index 0000000..7284d8a --- /dev/null +++ b/vendor/pyo3-macros/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "a70d17f898df41b3d1632ee987f624f5222d8d39" + }, + "path_in_vcs": "pyo3-macros" +} \ No newline at end of file diff --git a/vendor/pyo3-macros/Cargo.lock b/vendor/pyo3-macros/Cargo.lock new file mode 100644 index 0000000..b7f3d42 --- /dev/null +++ b/vendor/pyo3-macros/Cargo.lock @@ -0,0 +1,66 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pyo3-macros" +version = "0.29.2" +dependencies = [ + "proc-macro2", + "pyo3-macros-backend", + "quote", + "syn", +] + +[[package]] +name = "pyo3-macros-backend" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "571575aa3749fa6216757dd47d2a3e7ef360f329a40f0666a9fbd14889024952" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" diff --git a/vendor/pyo3-macros/Cargo.toml b/vendor/pyo3-macros/Cargo.toml new file mode 100644 index 0000000..2cbb956 --- /dev/null +++ b/vendor/pyo3-macros/Cargo.toml @@ -0,0 +1,106 @@ +# 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.83" +name = "pyo3-macros" +version = "0.29.2" +authors = ["PyO3 Project and Contributors "] +build = false +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Proc macros for PyO3 package" +homepage = "https://github.com/pyo3/pyo3" +readme = false +keywords = [ + "pyo3", + "python", + "cpython", + "ffi", +] +categories = [ + "api-bindings", + "development-tools::ffi", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/pyo3/pyo3" + +[features] +experimental-async = ["pyo3-macros-backend/experimental-async"] +experimental-inspect = ["pyo3-macros-backend/experimental-inspect"] +multiple-pymethods = [] + +[lib] +name = "pyo3_macros" +path = "src/lib.rs" +proc-macro = true + +[dependencies.proc-macro2] +version = "1.0.60" +default-features = false + +[dependencies.pyo3-macros-backend] +version = "=0.29.2" + +[dependencies.quote] +version = "1" + +[dependencies.syn] +version = "2" +features = [ + "full", + "extra-traits", +] + +[lints.clippy] +checked_conversions = "warn" +dbg_macro = "warn" +explicit_into_iter_loop = "warn" +explicit_iter_loop = "warn" +filter_map_next = "warn" +flat_map_option = "warn" +let_unit_value = "warn" +manual_assert = "warn" +manual_ok_or = "warn" +todo = "warn" +undocumented_unsafe_blocks = "warn" +unnecessary_wraps = "warn" +used_underscore_binding = "warn" +useless_transmute = "warn" + +[lints.rust] +elided_lifetimes_in_paths = "warn" +invalid_doc_attributes = "warn" +rust_2021_prelude_collisions = "warn" +unsafe_op_in_unsafe_fn = "warn" +unused_lifetimes = "warn" + +[lints.rust.rust_2018_idioms] +level = "warn" +priority = -1 + +[lints.rust.unexpected_cfgs] +level = "warn" +priority = 0 +check-cfg = [ + "cfg(pyo3_disable_reference_pool)", + "cfg(pyo3_leak_on_drop_without_reference_pool)", + "cfg(pyo3_use_raw_dylib)", + 'cfg(pyo3_dll, values("python3", "python3_d", "python3t", "python3t_d", "python38", "python38_d", "python39", "python39_d", "python310", "python310_d", "python311", "python311_d", "python312", "python312_d", "python313", "python313_d", "python313t", "python313t_d", "python314", "python314_d", "python314t", "python314t_d", "python315", "python315_d", "python315t", "python315t_d", "python316", "python316_d", "python316t", "python316t_d", "libpypy3.11-c"))', +] + +[lints.rustdoc] +bare_urls = "warn" +broken_intra_doc_links = "warn" diff --git a/vendor/pyo3-macros/Cargo.toml.orig b/vendor/pyo3-macros/Cargo.toml.orig new file mode 100644 index 0000000..bbafe62 --- /dev/null +++ b/vendor/pyo3-macros/Cargo.toml.orig @@ -0,0 +1,29 @@ +[package] +name = "pyo3-macros" +version = "0.29.2" +description = "Proc macros for PyO3 package" +authors = ["PyO3 Project and Contributors "] +keywords = ["pyo3", "python", "cpython", "ffi"] +homepage = "https://github.com/pyo3/pyo3" +repository = "https://github.com/pyo3/pyo3" +categories = ["api-bindings", "development-tools::ffi"] +license = "MIT OR Apache-2.0" +edition = "2021" +rust-version.workspace = true + +[lib] +proc-macro = true + +[features] +multiple-pymethods = [] +experimental-async = ["pyo3-macros-backend/experimental-async"] +experimental-inspect = ["pyo3-macros-backend/experimental-inspect"] + +[dependencies] +proc-macro2 = { version = "1.0.60", default-features = false } +quote = "1" +syn = { version = "2", features = ["full", "extra-traits"] } +pyo3-macros-backend = { path = "../pyo3-macros-backend", version = "=0.29.2" } + +[lints] +workspace = true diff --git a/vendor/pyo3-macros/LICENSE-APACHE b/vendor/pyo3-macros/LICENSE-APACHE new file mode 100644 index 0000000..72207b8 --- /dev/null +++ b/vendor/pyo3-macros/LICENSE-APACHE @@ -0,0 +1,178 @@ +Copyright (c) 2017-present PyO3 Project and Contributors. https://github.com/PyO3 + + 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/pyo3-macros/LICENSE-MIT b/vendor/pyo3-macros/LICENSE-MIT new file mode 100644 index 0000000..cd0ad00 --- /dev/null +++ b/vendor/pyo3-macros/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2023-present PyO3 Project and Contributors. https://github.com/PyO3 + +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/pyo3-macros/src/lib.rs b/vendor/pyo3-macros/src/lib.rs new file mode 100644 index 0000000..bba0736 --- /dev/null +++ b/vendor/pyo3-macros/src/lib.rs @@ -0,0 +1,257 @@ +//! This crate declares only the proc macro attributes, as a crate defining proc macro attributes +//! must not contain any other public items. + +#![cfg_attr(docsrs, feature(doc_cfg))] +use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; +use pyo3_macros_backend::{ + build_derive_from_pyobject, build_derive_into_pyobject, build_py_class, build_py_enum, + build_py_function, build_py_methods, pymodule_function_impl, pymodule_module_impl, PyClassArgs, + PyClassMethodsType, PyFunctionOptions, PyModuleOptions, +}; +use quote::quote; +use syn::{parse_macro_input, Item}; + +/// A proc macro used to implement Python modules. +/// +/// The name of the module will be taken from the module name, unless `#[pyo3(name = "my_name")]` +/// is also annotated on the module to override the name. **Important**: the module name should +/// match the `lib.name` setting in `Cargo.toml`, so that Python is able to import the module +/// without needing a custom import loader. +/// +/// Modules annotated with `#[pymodule]` can also be annotated with the following: +/// +/// | Annotation | Description | +/// | :- | :- | +/// | `#[pyo3(name = "...")]` | Defines the name of the module in Python. | +/// | `#[pyo3(submodule)]` | Skips adding a `PyInit_` FFI symbol to the compiled binary. | +/// | `#[pyo3(module = "...")]` | Defines the Python `dotted.path` to the parent module for use in introspection. | +/// | `#[pyo3(crate = "pyo3")]` | Defines the path to PyO3 to use code generated by the macro. | +/// | `#[pyo3(gil_used = true)]` | Declares the GIL is needed to run this module safely under free-threaded Python. | +/// +/// For more on creating Python modules see the [module section of the guide][1]. +/// +/// It is also possible to use this macro on functions but this is a deprecated usage. In this case, +/// due to technical limitations on how `#[pymodule]` is implemented, a function marked +/// `#[pymodule]` cannot have a module with the same name in the same scope. (The +/// `#[pymodule]` implementation generates a hidden module with the same name containing +/// metadata about the module, which is used by `wrap_pymodule!`). +/// +#[doc = concat!("[1]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/module.html")] +#[proc_macro_attribute] +pub fn pymodule(args: TokenStream, input: TokenStream) -> TokenStream { + let options = parse_macro_input!(args as PyModuleOptions); + + let mut ast = parse_macro_input!(input as Item); + let expanded = match &mut ast { + Item::Mod(module) => { + match pymodule_module_impl(module, options) { + // #[pymodule] on a module will rebuild the original ast, so we don't emit it here + Ok(expanded) => return expanded.into(), + Err(e) => Err(e), + } + } + Item::Fn(function) => pymodule_function_impl(function, options), + unsupported => Err(syn::Error::new_spanned( + unsupported, + "#[pymodule] only supports modules and functions.", + )), + } + .unwrap_or_compile_error(); + + quote!( + #ast + #expanded + ) + .into() +} + +#[proc_macro_attribute] +pub fn pyclass(attr: TokenStream, input: TokenStream) -> TokenStream { + let item = parse_macro_input!(input as Item); + match item { + Item::Struct(struct_) => pyclass_impl(attr, struct_, methods_type()), + Item::Enum(enum_) => pyclass_enum_impl(attr, enum_, methods_type()), + unsupported => { + syn::Error::new_spanned(unsupported, "#[pyclass] only supports structs and enums.") + .into_compile_error() + .into() + } + } +} + +/// A proc macro used to expose methods to Python. +/// +/// Methods within a `#[pymethods]` block can be annotated with as well as the following: +/// +/// | Annotation | Description | +/// | :- | :- | +/// | [`#[new]`][4] | Defines the class constructor, like Python's `__new__` method. | +/// | [`#[getter]`][5] and [`#[setter]`][5] | These define getters and setters, similar to Python's `@property` decorator. This is useful for getters/setters that require computation or side effects; if that is not the case consider using [`#[pyo3(get, set)]`][12] on the struct's field(s).| +/// | [`#[staticmethod]`][6]| Defines the method as a staticmethod, like Python's `@staticmethod` decorator.| +/// | [`#[classmethod]`][7] | Defines the method as a classmethod, like Python's `@classmethod` decorator.| +/// | [`#[classattr]`][9] | Defines a class variable. | +/// | [`#[args]`][10] | Deprecated way to define a method's default arguments and allows the function to receive `*args` and `**kwargs`. Use `#[pyo3(signature = (...))]` instead. | +/// | [`#[pyo3( | Any of the `#[pyo3]` options supported on [`macro@pyfunction`]. | +/// +/// For more on creating class methods, +/// see the [class section of the guide][1]. +/// +/// If the [`multiple-pymethods`][2] feature is enabled, it is possible to implement +/// multiple `#[pymethods]` blocks for a single `#[pyclass]`. +/// This will add a transitive dependency on the [`inventory`][3] crate. +/// +#[doc = concat!("[1]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#instance-methods")] +#[doc = concat!("[2]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/features.html#multiple-pymethods")] +/// [3]: https://docs.rs/inventory/ +#[doc = concat!("[4]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#constructor")] +#[doc = concat!("[5]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#object-properties-using-getter-and-setter")] +#[doc = concat!("[6]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#static-methods")] +#[doc = concat!("[7]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#class-methods")] +#[doc = concat!("[8]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#callable-objects")] +#[doc = concat!("[9]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#class-attributes")] +#[doc = concat!("[10]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#method-arguments")] +#[doc = concat!("[11]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/function.html#function-options")] +#[doc = concat!("[12]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#object-properties-using-pyo3get-set")] +#[proc_macro_attribute] +pub fn pymethods(attr: TokenStream, input: TokenStream) -> TokenStream { + let methods_type = if cfg!(feature = "multiple-pymethods") { + PyClassMethodsType::Inventory + } else { + PyClassMethodsType::Specialization + }; + pymethods_impl(attr, input, methods_type) +} + +/// A proc macro used to expose Rust functions to Python. +/// +/// Functions annotated with `#[pyfunction]` can also be annotated with the following `#[pyo3]` +/// options: +/// +/// | Annotation | Description | +/// | :- | :- | +/// | `#[pyo3(name = "...")]` | Defines the name of the function in Python. | +/// | `#[pyo3(text_signature = "...")]` | Defines the `__text_signature__` attribute of the function in Python. | +/// | `#[pyo3(pass_module)]` | Passes the module containing the function as a `&PyModule` first argument to the function. | +/// | `#[pyo3(warn(message = "...", category = ...))]` | Generate warning given a message and a category | +/// +/// For more on exposing functions see the [function section of the guide][1]. +/// +/// Due to technical limitations on how `#[pyfunction]` is implemented, a function marked +/// `#[pyfunction]` cannot have a module with the same name in the same scope. (The +/// `#[pyfunction]` implementation generates a hidden module with the same name containing +/// metadata about the function, which is used by `wrap_pyfunction!`). +/// +#[doc = concat!("[1]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/function.html")] +#[proc_macro_attribute] +pub fn pyfunction(attr: TokenStream, input: TokenStream) -> TokenStream { + let mut ast = parse_macro_input!(input as syn::ItemFn); + let options = parse_macro_input!(attr as PyFunctionOptions); + + let expanded = build_py_function(&mut ast, options).unwrap_or_compile_error(); + + quote!( + #ast + #expanded + ) + .into() +} + +#[proc_macro_derive(IntoPyObject, attributes(pyo3))] +pub fn derive_into_py_object(item: TokenStream) -> TokenStream { + let ast = parse_macro_input!(item as syn::DeriveInput); + let expanded = build_derive_into_pyobject::(&ast).unwrap_or_compile_error(); + quote!( + #expanded + ) + .into() +} + +#[proc_macro_derive(IntoPyObjectRef, attributes(pyo3))] +pub fn derive_into_py_object_ref(item: TokenStream) -> TokenStream { + let ast = parse_macro_input!(item as syn::DeriveInput); + let expanded = + pyo3_macros_backend::build_derive_into_pyobject::(&ast).unwrap_or_compile_error(); + quote!( + #expanded + ) + .into() +} + +#[proc_macro_derive(FromPyObject, attributes(pyo3))] +pub fn derive_from_py_object(item: TokenStream) -> TokenStream { + let ast = parse_macro_input!(item as syn::DeriveInput); + let expanded = build_derive_from_pyobject(&ast).unwrap_or_compile_error(); + quote!( + #expanded + ) + .into() +} + +fn pyclass_impl( + attrs: TokenStream, + mut ast: syn::ItemStruct, + methods_type: PyClassMethodsType, +) -> TokenStream { + let args = parse_macro_input!(attrs with PyClassArgs::parse_struct_args); + let expanded = build_py_class(&mut ast, args, methods_type).unwrap_or_compile_error(); + + quote!( + #ast + #expanded + ) + .into() +} + +fn pyclass_enum_impl( + attrs: TokenStream, + mut ast: syn::ItemEnum, + methods_type: PyClassMethodsType, +) -> TokenStream { + let args = parse_macro_input!(attrs with PyClassArgs::parse_enum_args); + let expanded = build_py_enum(&mut ast, args, methods_type).unwrap_or_compile_error(); + + quote!( + #ast + #expanded + ) + .into() +} + +fn pymethods_impl( + attr: TokenStream, + input: TokenStream, + methods_type: PyClassMethodsType, +) -> TokenStream { + let mut ast = parse_macro_input!(input as syn::ItemImpl); + // Apply all options as a #[pyo3] attribute on the ItemImpl + // e.g. #[pymethods(crate = "crate")] impl Foo { } + // -> #[pyo3(crate = "crate")] impl Foo { } + let attr: TokenStream2 = attr.into(); + ast.attrs.push(syn::parse_quote!( #[pyo3(#attr)] )); + let expanded = build_py_methods(&mut ast, methods_type).unwrap_or_compile_error(); + + quote!( + #ast + #expanded + ) + .into() +} + +fn methods_type() -> PyClassMethodsType { + if cfg!(feature = "multiple-pymethods") { + PyClassMethodsType::Inventory + } else { + PyClassMethodsType::Specialization + } +} + +trait UnwrapOrCompileError { + fn unwrap_or_compile_error(self) -> TokenStream2; +} + +impl UnwrapOrCompileError for syn::Result { + fn unwrap_or_compile_error(self) -> TokenStream2 { + self.unwrap_or_else(|e| e.into_compile_error()) + } +} diff --git a/vendor/pyo3/.cargo-checksum.json b/vendor/pyo3/.cargo-checksum.json new file mode 100644 index 0000000..971fdad --- /dev/null +++ b/vendor/pyo3/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo_vcs_info.json":"28149e8e220d0d602337cddf1a4c6d026d61bc35b45d71bcc7ceab233b2d942e",".netlify/internal_banner.html":"ee5b05838e55a064e9f3f0f149236c06b1f4b38a60f6296a9bfff76e808ad6b6",".netlify/redirect.sh":"6ce8f65a0ce8f84c4a2efbc1d0a51e8b25d8691a59993bea1e44de18b3b43e9f",".towncrier.template.md":"fbf956ee01d1ea738fa606c2d4d8ae3ff9c88a5ea058692a9ef2a07464e59069","Architecture.md":"36188a19b7906cc60dc501cbc087d73afcc881b920214a879e3958afddbd7d02","CHANGELOG.md":"4ce4dc4a35e21b2a9b7cc318a17b78f860ff04c631c50facb0c842d46932b5f6","CITATION.cff":"2d5aa5df590c4e47799ac644d15c56f9a3c5b2f3ef3b8e96946d372903ac7270","Cargo.lock":"0fd9cdf5d6cd76aeda30b43a2e3a45df0e76fecd1dee76a5bd29ea97bfa220ad","Cargo.toml":"ea1b4d0e5ee0eaa7179f413f68b9f59351ed0c154df80539b6587f3b53e7e04a","Cargo.toml.orig":"978aef1c0ec8efd00d693eec3b5f48b2e776be25650ed6b0becaaa216f70dc6c","Code-of-Conduct.md":"92d4a344e60e7310c654de92a26d84c99dafbfd4fab149a85d4e22f38232bafb","Contributing.md":"4cc17557be05f75204f81d5daca47f8c61cd91fc16b4c6a43e4a897dea0d24c5","LICENSE-APACHE":"32c76dbe0e73d79100d5ece77c158399f2e2541bc5c78548a4ba45c1cb53c5c9","LICENSE-MIT":"afcbe3b2e6b37172b5a9ca869ee4c0b8cdc09316e5d4384864154482c33e5af6","README.md":"62ff9c84d4a6414f4413482524cde6df9d80b541a418473c1f5418968a6a48eb","Releasing.md":"2029b18c73fe56998e3ce692a7fa590c646be56adfce96cd794f490837be45f8","assets/script.py":"e269075461009f6d5c937427d3d63c1fb99ba214828c1bffadc7142cbc12afdb","branding/favicon/pyo3_16x16.png":"866812e76952262780e23522f427c7d120e707a6038849fc6201b4f44ddbd923","branding/favicon/pyo3_32x32.png":"e8a1cd2b6ba99290fd73953fe146d2ec991b73a9a07aba7d0a83450336fc3afb","branding/pyo3logo.png":"ee487ca7b02e47af39c55c4ea0d809eee084f3182a5b2cfee3e067cefb983414","branding/pyo3logo.svg":"62a14ddaaafefac353401bd31f5cdf83c9dc3cd196a41b0c030cc1e02e002ebf","branding/pyotr.png":"c59747a779c19df29f027477f278648fbd8fe77a1926e10b0d621c6c790d2785","branding/pyotr.svg":"49f7d4a798a12f921c53866d3ba9078710edf40b60ffbe198a992d0260b47019","build.rs":"6a7a6776a428a6f5bc3310d2a84415c6ac2cffe82c4a6ae8aba09f4feb2a6ec4","guide/book.toml":"4f0a5d9165de21286d5a17e322bb3f88104227179cbcd8c8f4cd07423339ff1e","guide/glossary_linker.py":"4a20bd8f0ef2e72a1c3cff153a6d5f9376f9abdf0fda57032271cbb728a192f4","guide/pyclass-parameters.md":"271a6e1dea46a87a4e261d689bec68158d5dd19f72bd1dd951ab8c31a6087aec","guide/pyo3_version.py":"eba678b7a6ceaba7b6e9efff11786e1fcc4138a5f49d8887403066b23a1058c3","guide/src/SUMMARY.md":"069c3371a62d18571607ae08e8a6ef10d65116c9b07b4f923abf84981aeca49a","guide/src/advanced.md":"5766b9259d99b86584b8b5c9aca37f6144259f60d17388aec4a9dc22544d9573","guide/src/advanced/sharing-types.md":"3a973348087615fe7185462606db5977809e0c1ce3203440cf23ac17c40cb3ae","guide/src/async-await.md":"98fce7b8d90972a38836628e84fbab03668117f842946167257a90698874d992","guide/src/building-and-distribution.md":"8215fdd8612fe93f0e2125c1bae56454d7a055bee9a9294dba4349e18fce2ca9","guide/src/building-and-distribution/multiple-python-versions.md":"4f30e23cc12ddf14325121e91843dc7e0800bb0b0cd38030a5c05a38a0f36fe6","guide/src/changelog.md":"439803753b2afb2157fbcb7384c4465684736c0a42d63ef8f4a5bd8356dbfa69","guide/src/class.md":"dbf400ceaafcf04046c16afe194b9119bc189e613cf88c3d01456a97f8b66cd1","guide/src/class/call.md":"631c9e3be070ae7141f4c7517a5d1f7665c61a8128789390751e0807eb119ddf","guide/src/class/numeric.md":"929e6ca3373b048c84a4d4b42bf4ce1ade6426253b84d714e9418578b72bcf1e","guide/src/class/object.md":"e24de2dcb783169c4baf9a9e42c9f225e647edea7f5b8dcef5cff4cea0ef4475","guide/src/class/protocols.md":"d72b977268cc9fd5b6fc1da55ce414aff1061d8e6122465a465dd486d311fe6d","guide/src/class/thread-safety.md":"6a0e9e76abbbe397fb4c95251503c6d8e556af846c94bb12233c2e5f47f8b3dc","guide/src/contributing.md":"655723bc7de5aa185b05be39400e87000595bcf268dd3066f7fc091be0a1aac0","guide/src/conversions.md":"8c27cff72407ec7c1c8303cdfa4d25d85524c2fece55a74f8ea41d8f0e1e0ad0","guide/src/conversions/tables.md":"2436d1eba019184b5496e2515efec1fd3b1dc0c880fff5defa204223c7a12430","guide/src/conversions/traits.md":"77caa2ebc7aca63142bfeeb0d83c5e7eddca41100562ca5283dfc1ff8b35b772","guide/src/debugging.md":"5c6e35542cc0623bd19fb65c3ab22d0a0ec280a0f2b13834177639cfc4d67997","guide/src/ecosystem.md":"d2a663465d9842f91bee793899dd5dd51e5431b5ced03d8bbb205c0eeaf5cc1c","guide/src/ecosystem/async-await.md":"d0eb65ea5fe4aee73313087e0984dad403058ff02e784be52de4001c95125b7b","guide/src/ecosystem/logging.md":"bada31c10b1a9560b6d75a72d83379a7e0f5981d518f4f9b1de7b753ab5fdf09","guide/src/ecosystem/tracing.md":"35b19e79c41a60225b02526131fff96d68da0aa1081aa59a63df6e7d33967a1f","guide/src/exception.md":"568dc0278968a21cad43bfe7a67ca36a1aaaee2b36b8373f85e02d62c2ced459","guide/src/faq.md":"23245260bad13bb34079fedeb3a551c9b4de52a69f21d1c21167a79a07be9253","guide/src/features.md":"d9579f64d96ab1de63d501de21fb492e6699389b2b2768809a9d1947740cd670","guide/src/free-threading.md":"43f691d77191e59b2d3f0b5b8e764a2c5f0fc368bdcd7484127c219bcc6991d9","guide/src/function-calls.md":"7a7f84b340f532210f5293656682a5c8087542e50774ab07e1096b2d350a4484","guide/src/function.md":"98c89f51c71269898a5f1344ce89bdb5adfc01364a08d61d0e4cb2aa69e256df","guide/src/function/error-handling.md":"2e2fb6949bb17240d843f183f0b5a471457c45103a07cdd2f4f3ae2086643557","guide/src/function/signature.md":"f5815cba746a5dfc20815021d3af14e2b85ec25fcd1cfbbe41297f55111b1b2a","guide/src/getting-started.md":"f7b7add2be29bcc617adb7024c4b0510e71c748e733d8ada26e72815d0c1f07d","guide/src/glossary.md":"03bd9a5ace99fe322b49d66a62b5b1dec725bbddefd3d8d2e7373cbde08f03ca","guide/src/index.md":"beb934f27361c588935edc23957ab726681eb7ceb978a040f2b24874f9c73b3c","guide/src/migration.md":"70b744a7bb5441379d9381c375f799835e64afb39836ddf7def676a93d09c7f6","guide/src/module.md":"43fe808771720bf2d47dc30a238193e5cd5d8471834d35e91e3648cc3eeaa2dc","guide/src/parallelism.md":"57c11133f0fde3db794a74f56fcc100be3f2b29f4c717740daab41e5cc0de7d1","guide/src/performance.md":"853ac9b8fb9404c5e6bf0448dc26f8bfbab7116590e3594de34d52b64c537992","guide/src/python-from-rust.md":"e591d0f1612afb49fa45d4cd9876bf866d4b6bf768236250e7517e7168608285","guide/src/python-from-rust/calling-existing-code.md":"4eb64e98b1cefef990fbed07239620da7df4e82bcd852f512e7b3d6eeac302c2","guide/src/python-from-rust/function-calls.md":"ed24b5bf9c07b0767145ec9fe4b635705d4b33af90c24f07603f20cf62287d15","guide/src/python-typing-hints.md":"aa9c6d27f522acb526cf6a1131270ee65a90df7281f4f05ca4f478b01f958284","guide/src/rust-from-python.md":"7e1da8b958da7b428f76302cb91e159ec36973dc8368cf6033c3e3512a3e496a","guide/src/trait-bounds.md":"3244d7c1f868977e7f50a61d1835b9cf67179a50edd86a6d531a09315143a49e","guide/src/type-stub.md":"d05ded0aa70c145d3974186c420838ac92ce794902f919848a6345804f7f0433","guide/src/types.md":"66b4427882790da6c6b1f7ab3c363d9dea7d6cf35eefd5a21633859189008ca9","guide/theme/tabs.css":"52f01167d17416decf41850495045171bae0844fc2b1adfe87ff9965656281e5","guide/theme/tabs.js":"6977231d92925deca576a4dd396bf3a21df2805554f93ba0ff36cc11adbb2100","newsfragments/.gitignore":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","pyo3-runtime/LICENSE-APACHE":"32c76dbe0e73d79100d5ece77c158399f2e2541bc5c78548a4ba45c1cb53c5c9","pyo3-runtime/LICENSE-MIT":"afcbe3b2e6b37172b5a9ca869ee4c0b8cdc09316e5d4384864154482c33e5af6","pyo3-runtime/README.md":"022371b6e623237264fb9654101bc33288f8842b5dfb9b4f5dca7215125268ba","pyo3-runtime/pyproject.toml":"93c17a8242e36102dbe7f785295eef3d26d09c0ce55b4ebf24baeb5743e5d5b8","pyo3-runtime/src/pyo3_runtime/__init__.py":"b172e1ee0dca0b84021717191814e91b6b1c47b866981b0c8eae8ba91a6d9118","pyo3-runtime/tests/__init__.py":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","src/buffer.rs":"c22b7d5dab213b2bd08bbfaf2931e66d6c9c0943eda3b7a67397efadcfbc0ab6","src/byteswriter.rs":"40d0d259c9e12999ec75515801e048a613106a344a6ada922e1b49312081435b","src/call.rs":"aca6a8ba189bf0c981635749f5bc03afb3db887c42c19ccabc456448fcb9f0e7","src/conversion.rs":"6a63e193c45a5f9972f71e721aa9ec312eccd433a951ed6d18d3c034b5ee227a","src/conversions/anyhow.rs":"e3b5aa1f057427c122300fb984fffcee1ca6c52ff560fb8660600c9fc37035fa","src/conversions/bigdecimal.rs":"e9b34949a9f333f628a45fc2a30f439c381f56bd43d16cfa2681818127df5b91","src/conversions/bytes.rs":"51b21215a64d74d40bdd1d7cff5b4aff01bfbdfda232e5b55e5b3bafc1c13019","src/conversions/chrono.rs":"ff5f857f66ffc70b4634ea4bc94a1b92276314d41bdb886b978eca21f8e99a70","src/conversions/chrono_tz.rs":"6447745b218d42b49f89467b7c60239701f6296280ceed34e38946a39c1255d4","src/conversions/either.rs":"0d857c9b5a8e5c4bc6457d76440c1e1c9811f7518a3bbe1840ef2fe0245b5f18","src/conversions/eyre.rs":"4b340eab51c25ea9745a6a7f9bf195de80673d01545c71ca7863314b9859c72e","src/conversions/hashbrown.rs":"d6eae19b0dc2ccde5808e7eceaa90292ed80d35f56992d96fe5796b3cf71b90a","src/conversions/indexmap.rs":"8089871c1b61dda052ac430cf04ea6ff8d731bcf8b78492400fcc579c614142e","src/conversions/jiff.rs":"beddf5ad39d27bc658bbe1bf82b99a6648b5df2ea004ee01dd065c1dbb47c787","src/conversions/mod.rs":"14649ee27d0444e2cb96def6c4e7b884f681464ec98bdb1f4ef91d84f7741c08","src/conversions/num_bigint.rs":"4df7e55be203b3481d19f3fc4dd9a0082a443569393734e844fb639c41e7610a","src/conversions/num_complex.rs":"eb86acdf5aba9050ac869c4a8315f2b43953de6c7470c6776bbe239f25a1854f","src/conversions/num_rational.rs":"d51fb7cd60eb863701a7a73386ab4cb6852468aed30d8597d4ef34defdde3bee","src/conversions/ordered_float.rs":"f5e0bcdb93e5d29d8eb5d90f56c575a86671aef0adc296d340e5604b6b3e0723","src/conversions/rust_decimal.rs":"a2459fbea52bddd8c1a10597b1f0ae5ee7cefb78b1b0974fce0e38a48b7a9295","src/conversions/serde.rs":"ce6f918c99cb1605ae5f36265e5487b36acadd4dff06946654fc5b26d879d3f6","src/conversions/smallvec.rs":"680c4a0bd2ae5bf4f0bfbc66b5d3286edd36cd8d0fa9dff6fb449df499aa2ddf","src/conversions/std/array.rs":"19dffd39b80347c105ac2e2d75f4aa0b54dee1cb051c3021fb713000512562bf","src/conversions/std/cell.rs":"895b96bbb1c8a8ce1f34bfc6693e054efb4a25f5da324a97fbdd73815963235a","src/conversions/std/cstring.rs":"c23eb326149c370e8593be5b4d79777cd2343a61dd04b36d658fb0951d35bd31","src/conversions/std/ipaddr.rs":"0436faf047a86361280e24a1b9ccb5682f80e0ec69a082a283c0d6e9d8811ccf","src/conversions/std/map.rs":"e4f41606e1f86bb8bccb8509ecb892f143da03a2f779c3cd107bf1f06ca20973","src/conversions/std/mod.rs":"f876ea416ffe3dc367f28f462a3e16924a6f771d898d9b79e62854ce22a19ca8","src/conversions/std/num.rs":"723cd05b0d3e5f11c79b64efc953b402802872dd85ddb7ad3a91f239c45f5dda","src/conversions/std/option.rs":"692bd54b81a3fd4ad5a985dda4e85f2d730b7c1a654fe8b5206df823ba99dc8b","src/conversions/std/osstr.rs":"a64bf29be7c7dd54cf273541661a66badbe37211992b3064809cb8900e6bd31b","src/conversions/std/path.rs":"46cc0c9e6df6f2d1d70386d3691ee35f7e4e6c0259ef9ce7a9b773ba0f9efec9","src/conversions/std/set.rs":"9a095f3bf77b8698d69bdf190465a8b151af31b1b74a5458775a3ac9f69c6cb6","src/conversions/std/slice.rs":"6f39cb8743c44f08825fa64da10fb7b5fa3d8ef4aa1460ee99c1d28944e74c79","src/conversions/std/string.rs":"9d95575d5f1f2cf039f210e7a07d48dd2c5c6f43db6e93c926afd64483c9b8ad","src/conversions/std/time.rs":"c3c10c288d7af950ce38d43b77759c0a480301841d88299d324bdeb2d2e9422e","src/conversions/std/vec.rs":"10058bd238c704079cdac7ab271eedf673ce8c0478698030a9c4e9d345747b4f","src/conversions/time.rs":"9531df4769341951d5f77744686a940c3e391fc4e2b3050db80d59e0f367053f","src/conversions/uuid.rs":"5548ba6ec120f74eeca12450af868208af74f0be37bd14ddafebcc86670ec4a9","src/coroutine.rs":"5cc42bb4105257351ea0a776d8c3a3f5a82e2224515a346bdb57d21be7b9131d","src/coroutine/cancel.rs":"d9ce8af7f7654c50a51fe4c85b59fd9f89b9b4b969ec75df8f85090793b80707","src/coroutine/waker.rs":"1f66ee6a8f7c60a80834ad71c2c7f790579fa9aa0902b7b3ca152cf9f6df72b7","src/err/cast_error.rs":"a5b7b678d3ca9a8d2980c68e6639d95f52fd6507790984811343fd4269890e58","src/err/err_state.rs":"b19c4c035657ae8349f43a350caa55656ac41b9366bb7d4c48ab9d0aabe968f0","src/err/impls.rs":"7925227755d38b09bfcd5ca2f07ed08069c0b6ecf14e73ba62b0750ad36d24be","src/err/mod.rs":"e99d15214f41ad3e9e6ad5dd191d245c4531ca9cfbfa625c4167d9afd72216ec","src/exceptions.rs":"27b87ac56cb93fdd0eaba92bb1685db83c03dcb654acd6d3bfbb9cc903ab4368","src/ffi/mod.rs":"3ecce95edf3624e3a64dd1c602662bae839fb38f9d9ff927b033ca994c7e348e","src/ffi/tests.rs":"b3d43b8112191d1cd54d8afc66de9e403557aff6df0bb8eaa583afd26c69fef8","src/ffi_ptr_ext.rs":"acea3a5c27a5f075cb39ff52188a37486e5d66b5f7c81adc1e7be24ea6e65457","src/fmt.rs":"d73aea94947d853aef56692547eb2cb3738befa300b3776e3819473a4eea34ab","src/impl_.rs":"3d4f5ccde92b4e36cb5d61ef18406b12ce17ac1142f5dd35c71cee45640874b5","src/impl_/callback.rs":"0ad30d1d546ffb947169f5fd2cad75304a2575454cf5f2ca2730111357cf3355","src/impl_/concat.rs":"b77b997590ebbd91f24fcd17491316c16abf567326538b850ce9232f0b650417","src/impl_/coroutine.rs":"aeaed9da3d2e7140225952c60d3a3cd87476b002bbd9f68bb85e69e4ea4123b1","src/impl_/deprecated.rs":"b8457ddc6257b836d1e68921f60c4120c835582af5edb8e54ffadec9a3c4d0f0","src/impl_/exceptions.rs":"c616434fa6a70ca84d469bb33bfe28e38711ee98b9bfc1d5c96c747e2d3c6c05","src/impl_/extract_argument.rs":"550b43d187e0bc69e8a27cc9852f18aaedc2b0002f889bfb99d1a646d1705cfd","src/impl_/freelist.rs":"c12fcc90aa526605335abca9cd706b97187e7fa0520fec3b20e6f0a11e0cc6c8","src/impl_/frompyobject.rs":"5ac3bfde55853a04be84192098e6dffbbfeee6d8daec520d981901ebac9c97fc","src/impl_/introspection.rs":"81c0d99186f5619d09f9218eb935a0b58496888dfe12c97a157ec479c54cf647","src/impl_/panic.rs":"b3a9b832355a850a44ceb792ccc0101aa027f8c21ac2f9bd52772e0ba6dcbb0b","src/impl_/pycell.rs":"5d070d4115e90e9b168f70331a6ff4ee05c820109ee23a6d7b5b1c88b9e21568","src/impl_/pyclass.rs":"f9f0ee2a74d31df81509fec780c8d91ed7147af5cb02eee5f90d2d3847d5a12d","src/impl_/pyclass/assertions.rs":"d6e8d934cc33f1852da046f2841964a6172546ce6aad46c4203d462ed3e25ebb","src/impl_/pyclass/doc.rs":"afadb5aebcee1f44d727123b9288d72542e424642e0c3e62c6a43fba8e89f817","src/impl_/pyclass/lazy_type_object.rs":"99791e3165b854d93b50010961fc9fa6fb7ca0b519b7ffa3209a5de8afcd16e8","src/impl_/pyclass/probes.rs":"7a3f5956e27d2e9996c94d2f265547f7351182e460011a7185852024de2ee592","src/impl_/pyclass_init.rs":"02d0727d552866e422d5620be3b7c3ea1cac03daa995ca285de34a6ac7858928","src/impl_/pyfunction.rs":"2a27f028f8f0738b89b3e41d1f47faf5bcc956ab60ec6ff6657756efd4f4699f","src/impl_/pymethods.rs":"39f38c86b3725d70cdffa0d3be6603b4575a719c8d9390adb976d74388153cf5","src/impl_/pymodule.rs":"8074d298a06ef08307ebed44c0f827aad10fd177a5dd92b2659dade8f1a56d7b","src/impl_/trampoline.rs":"c6eedf33cd1677e022783d6c4e042de2e07f2c35ad121b8ff14e192ab274500d","src/impl_/unindent.rs":"47388d04240ce50386f1833d75ccde8e1b24aaea14d3d64131b0cb064e516cca","src/impl_/wrap.rs":"0b23bf52cb1bca480e6fd4c148223855e20292f0d35e5db5dfc741c5fe98769d","src/inspect.rs":"df16394f245f159d72fc3025de52615400a428fcf3212c1376736c6d24325a12","src/instance.rs":"7f8b8083a28703ebc61cb1d6456fbb7a78eeb8e147985e4aab506423128381c3","src/internal.rs":"c0630c50cff2d1b8c512824209b48dc6f2d393c789f71ed525f00a28c81120a5","src/internal/get_slot.rs":"e5f6fc520887efe637a621935e83dec1937e77571d96f74bd02b775bcf8e7d02","src/internal/macros.rs":"aeff9d5263c4fa2c46e16953488b1f64dd6e52d2068faed24a4eab6f945293e8","src/internal/pyclass_init.rs":"52ab23a2732a6e1d910379896975ddce1c53ccd582bdff3754f2b38c96d7cd94","src/internal/state.rs":"9bc1baee1c3f6ad86d860bc23297ad15aed5e7a6eeec19c93a3b78255789ec85","src/internal_tricks.rs":"547f08f442b5ddf6a81f76fc1cda6bb828c14b45777b7e60576713f015c099c6","src/interpreter_lifecycle.rs":"5c239f63add9f825f50f3bccf4686dcce9b552fa6d92c278feed4e499cc1432d","src/lib.rs":"d0899dad5942370d5e7f76f902b502373338b7654184f3f7d18a5d3f5a8c84ce","src/macros.rs":"bf07ee5f175d5c05712ea5ac53880a18d8abc86c1e6f58b17d274049f83423a3","src/marker.rs":"3255f90c8eba236f0cc5594adca4a3cb0bf17c26b9c242d803e6d5d6a7dc7182","src/marshal.rs":"31078c967fb7330a588abe8a91d3e02163279e3a72ef2effebaa1b4d539f92aa","src/panic.rs":"3bc18cf2e4f7e1cddb615413f709675f5ba112aebec994b5951974b884e79920","src/platform.rs":"f7e5e9dcd9c33c8ac7777188d6ec73ee2f0115ac40d7827032fe865c08cf1dd6","src/prelude.rs":"5334a1e67266211ce3f11506cdaca5cf8de486ab66bddc9e02315792194672cf","src/py_result_ext.rs":"3e9e519b7c981623ae9d71e139af1c483060a3072cf88196985bfc9e5d9a854b","src/pybacked.rs":"b367dd89112830bf796bf032d1215c2575de723d9c04564a085b00b0de61dbe1","src/pycell.rs":"fa5b906fb32362747891ee26c4874e50526ec196a07a7a92e83c299a69605328","src/pycell/impl_.rs":"fd46f7e937cb0391402b4ccd21162f963fa3c7e1dc5262e8c4152774841e734f","src/pyclass.rs":"43513f9001dab3ed2866f6eed8927f5bc1060eff93f4310ae0dc4ca258c7ad6e","src/pyclass/create_type_object.rs":"eb80110a038661e88079dfb580cd58b2e668c18b014fca4c08111c61d705d9ff","src/pyclass/gc.rs":"ffb96b16114d8867e521dec98baee5dd4e3839eb61c8bb33b24b26f2566e8feb","src/pyclass/guard.rs":"5b1debcedb797dd56828f6812777bcd5030296f8a43f6d15fbc564423f46330a","src/pyclass_init.rs":"886f4ae4bdb640218b09efc363202ba455581c580f2bf5441a1a418055f480be","src/sealed.rs":"964f88bc9074a26a3e97420b6cd8724e2e7f819e92dded81f97db339ade4668d","src/sync.rs":"e2468740085bb021492eb67b6d593436844803c132070ad914cb30bde84cee44","src/sync/critical_section.rs":"b4d74e20d0dac742b3cbad0ff163d31d8ea3e5ca01247232b08f07659c9ef481","src/sync/once_lock.rs":"c67ecdc73c7763b0c043a814e09e2d7bf000b936bfb3874ecc2f126a6ded8087","src/test_utils.rs":"566c4c9830f293b12db27cc2cfe9b66e48a7639af4f22c5f789f5eb68cfc841d","src/tests/hygiene/misc.rs":"b9cfdcb7d778ea427cfcf3dac2809a2f2aa22c7a53ff20310d2fc447e03f5fc4","src/tests/hygiene/mod.rs":"b8ce3a05eb223a8c48e36642ffa44190de235b57172f2446df81a6af2c013703","src/tests/hygiene/pyclass.rs":"cb69348d32bb5a9a637aa58ba4ae74226ced087645a70521fce48fcaf365be32","src/tests/hygiene/pyfunction.rs":"dcecb90d05399a255bbf60617496ba5ad42053862b216f67ec1b41b41aadbf56","src/tests/hygiene/pymethods.rs":"a3c26220fa5065c82ad03b65310fecf78f41e69a5f00b82fc352afc881635753","src/tests/hygiene/pymodule.rs":"dd8ed2cb5ddbb635cbaf404a0a1dee68c6273a5d368819738d6e56940307d3d6","src/tests/mod.rs":"0f4d8f6671646280d2a5a841018a2da9a382a273fee1372235594ee3db17b18d","src/type_object.rs":"51bad77b6fd017a5a899be7d8c037f30a77ddac1b642a7847842e8004c69f2c8","src/types/any.rs":"65886dfa06294654a247de4eac2ce497ff297316660420deae90b55f76704869","src/types/boolobject.rs":"6b406ec9484c7874e54ae388cdc8ef0411455ac6ece149edb91cca8ccbfc5795","src/types/bytearray.rs":"1bb0a1112f0aaf2e4f55fb594ebfb199196c821a7fcc3a230c10f0374811a4e3","src/types/bytes.rs":"45c55b9fc832ca986aa59e611948499ef462f518e5ff9bf7bc31d9809ff73517","src/types/capsule.rs":"7bc233d76e5e3476fd4fb06233822f913b221d72707ed9e244e3e8e1f6fb3f6e","src/types/code.rs":"9fbf4cc5b25d0579fe0fa5e3df8b129596ca2b62dfe649d56ef2b5c53ce8159e","src/types/complex.rs":"99f887f9e86adf489076724e5aea98def893a4c70d044a91e5d1ce295bedb3a9","src/types/datetime.rs":"5926f838c5f6ec4cc985973dfea019dd895fea261693de69bb2fed8224f6ecdb","src/types/dict.rs":"b2ad96b0930ab30a8f3227c35dc4d3c14b2597abb3c426896f09c2a25c599d89","src/types/ellipsis.rs":"29efa20b074225ad507526e3f2d239456f3baa1806ef6d2b0327995dc2cc148a","src/types/float.rs":"fd14d3c4bf057ae913578d971d7ac8b2abffe26f621148b134e34c8ce31ecd9b","src/types/frame.rs":"a9cbe5c0242daaa60324dc9f8b138b57fa020b0ad20ee54bd6033e9a7df4c211","src/types/frozenset.rs":"f0dafc9bd2c53420c55c5a65f53ab72d95732c95a189ae160307305a989c5ca6","src/types/function.rs":"e4326492be98ef8316c12f246acae84f8b6d0420ec7667a34d961034d85d5613","src/types/genericalias.rs":"3fbbc33ef7fb9179fd3faadfbfd2c8ad5d9c948de2ecd4bb8572ddfc9a57d3a3","src/types/iterator.rs":"20678ff46d29926fe77e9d80318a818c3e92ae3cdc053325f516ca3113ee32b3","src/types/list.rs":"6ee0357edb8e2bcc03b35b6327cc7050988732d4a5a32bd4f9a5dd7420610b57","src/types/mapping.rs":"cb3ad2ff2225800af714d8387215ca10521bf996e524e353e4128692d121048e","src/types/mappingproxy.rs":"118feb23b4e2a9066f4deede927768f9c4ba1241a67bae4344087087975b97b5","src/types/memoryview.rs":"114c532931b45a707236c2ef572c9dacc3baaa7ecdab9b9a200cc4f82a7ddc3d","src/types/mod.rs":"d45973b0bba0330ba351ef63f8858cff27544dac0b54c988e2220555a22a1fc0","src/types/module.rs":"2676c6f14cdd2016724389745a0e6ac955ef6b4d6eb3a06ef2ddfcc31a2b04a8","src/types/mutex.rs":"a28de29edfe2fb8c37eaa5ffe766516da680686059bf33aac8ebd500f15b8803","src/types/none.rs":"b95e1b70e718a15872aaf3c46882aad4cf3536626d71f153507714a10ec785b3","src/types/notimplemented.rs":"8cd94da82a4792990e089a1b3318dae6bf75a073e54c2b6628132923cf3961e9","src/types/num.rs":"c6940824a3df6747be7e3f835996381bc3177c3b05b9ee06f94db726b459f97b","src/types/pysuper.rs":"60826bf3c31fccd8e5bff31fb1c7b81f09075281741eadd50a06236aefa35d4b","src/types/range.rs":"45062aec8e14b959acae820ced77d1faf5176f1a83fe11f9ac28caf199bc4c6d","src/types/sequence.rs":"b1532a7499e5367257308357f70d0a8421d97ef9402703222ad6b1b985a13924","src/types/set.rs":"fb27dbd4f85b755c04a1ad73df03e87d83b8b1b473ccfe8bc3c768a52ae09d65","src/types/slice.rs":"de83fba5c2a40bb68cef45641e7c84cbb9a3edb90c5715e76dc2f327243c4aab","src/types/string.rs":"8c95cb001babbd67676cfb7577db1272f21a9b605be9ced9d4662626cd0d5843","src/types/traceback.rs":"b8a95f4f893b0c27d6240a47da46e6872f56c6ac4100b2fc6d461d63a7d81ae4","src/types/tuple.rs":"a5f1e619320ad7cb23ea8d2acbb871eacfda009eac117534faf15aded61a25a3","src/types/typeobject.rs":"5ca4522483560b5828f5f86de98b5aae05c3b77517fd937565315f3d250704f8","src/types/weakref/anyref.rs":"fa1f75db02b4ad58d1067fd8dd1f88e51683b296a6d9d2634f36d8b28c2c92f1","src/types/weakref/mod.rs":"411b8ae0ab077bf3c9e39917f046f775deb44f7cc8801370169f1d48c0f35b38","src/types/weakref/proxy.rs":"6dd6e7ff67810bb1c4b0328d96b39519aeaeb2576c6bb34f299312dea68e1639","src/types/weakref/reference.rs":"b792cf400ddfd6df3f719d58608d6248c7b074d86303fe10d00e27c4f76fe2a9","src/version.rs":"3c40746371872a280c6beefd65e3a6c5f6f5f8ea32a6df722630081768a48aa5","tests/test_anyhow.rs":"2af5a0767f2906b2ea4c46ec049d3485395dba589cca7130da1ebcaeeee8b832","tests/test_append_to_inittab.rs":"50aca088e431b3c6c70d7f515a821814d5cc8946483d83aab66ceb8c37d0c63e","tests/test_arithmetics.rs":"159bed91d5ffac8816e93d53cff9b4b51994887dc8e84a402e2e850acc90e7ab","tests/test_buffer.rs":"fcf3bbfbf3ae4f94812cba53b63f434ca2a4f486cd94d6296d41f2372cd49059","tests/test_buffer_protocol.rs":"23fff84253463540a90d7f9ec9faf39c069169b77dc19ba5750801d33a187434","tests/test_bytes.rs":"a48b4380947e296cf3da603bd2fc8a63e33b429930ee9d101ee9a9833e67346a","tests/test_class_attributes.rs":"b8eb795b0cd03b79522836b85fb6b7c45eed2cc8bb578e63f31a21a22f6b33de","tests/test_class_basics.rs":"9eabd5f0f6d0bc193a31a843ea52ec80c476795dd02aab5a32b8dfa736a77d49","tests/test_class_comparisons.rs":"283e636489e9270c7b67467fb3118e38ccf98eaf547717fef43a14f9d56151dd","tests/test_class_conversion.rs":"fd9a76fb7eaef94c64aebdf7fadbd202ef6bcea569ef83f63475b4fd8af880aa","tests/test_class_formatting.rs":"c9d94bf982cb4ba759b9eadd2e7bed95cd13362c49c6d09b5846d3cc97642248","tests/test_class_init.rs":"0b583da67d2a8963bdd2225f962b4f740daad589cfdac4997431961fa5a0af3f","tests/test_class_new.rs":"21ecfb2253e0aac14f3ed7b7620ac26c5a1d28b23890b60833071ef690d3a929","tests/test_coroutine.rs":"d32ddc350aa5d2bd81559902d7fc38122e0be2aa48d080369f220387d9af1285","tests/test_datetime.rs":"0f1315dec4539b81b231d3ba26604f5a014a950b815f3376a606163a42e00d38","tests/test_datetime_import.rs":"2ace4ec294e08043f297584e5cde015dca27bcd8175826e647d83764c93ed7e8","tests/test_declarative_module.rs":"ed63a1db281707a6abe1c616e05ed4569ec535153d36b12ea153bbd6b4bea526","tests/test_default_impls.rs":"2cbb60ed0f4a33780095455835631bd44ada91698c6962a9cf690f6705aba286","tests/test_enum.rs":"e4d7ae1633c02c3586a9d352ddd69dfc33a72a6609ca2a47c8cea2d927ccf814","tests/test_exceptions.rs":"b6c0bb38050bab2ec010ca138244f7834bb54a666f8a1029cd0e23207a84a38b","tests/test_field_cfg.rs":"3ef6ea6056eaefb0b261db06155c738f233ccf10f73a60feb52d2b412b0f32e1","tests/test_frompy_intopy_roundtrip.rs":"057ae673cef3fa3b1acd5ceca98a7248f0958d60ae3b6cbf0fba740899485ee8","tests/test_frompyobject.rs":"1a7d3521eaa96180732ad50b1439431e7d171117245382c246e575acd073f475","tests/test_gc.rs":"419b4ecc8d9efe990d2d7fad3751b6de9ca7156b34cd8c6afb0f91bcc7bb99a6","tests/test_getter_setter.rs":"c71b8db8e3c3728eaf6c4642b665c60fde9764109bf094a91b395953db177a8d","tests/test_inheritance.rs":"f3edb0a2118b689ef0cb4a85f87c0e34171d6a59caa43760e87a508cc535eff4","tests/test_init_race.rs":"3b150670f17801b6b53f62ad5322a3b2aa525170085ba1be1a880bd4e35d3b34","tests/test_intopyobject.rs":"8b012e53e38be8ea084c543e4fee5e9561228e205e3900f855a6df04b447c3a2","tests/test_macro_docs.rs":"03091dd2a3594eb7fd00875d6a53328a477602832d1f7a5035028101fb2ba8b1","tests/test_macros.rs":"c43870560027a02c64dfedaede3c00d66113f795c251f53807fc9a1dc0e2a3a9","tests/test_mapping.rs":"5323d5c46712ded107510c7c31ee7747f32a48d0cb2a388606041c25315deda1","tests/test_methods.rs":"96ae3717d2d31742ff21a6257fa05e511c2b6be4397c8af956540ea0995c499c","tests/test_module.rs":"0167faf98fcbb4bd0ce77877f5f9facf9a992064d35895a514aa357e70bca238","tests/test_multiple_pymethods.rs":"c53cd687ef1ecedfb7465f21ccfc06a0c7a6696d1aa4d5a6ed0b57639e69f09e","tests/test_proto_methods.rs":"f9a117e3d546444fdffa5c88443140db1b49ab1e34dffb455fc6f872aeac1e36","tests/test_pybuffer_drop_without_interpreter.rs":"d067c747301ead7eef46a3210057959e89c4b338488febe664b6bf8cef4a26e9","tests/test_pyerr_debug_unformattable.rs":"95159479261b084d1edc3362ac4121ef1937ed726bee017ed5bd9b7410df31a7","tests/test_pyfunction.rs":"d55056683532033eb7f6a382db5eda3ec0a7305c4fec9787464e98267d95e260","tests/test_pyself.rs":"3f01015bde93bae45b5e48ea4f62306478b8fa8303f3c6c8ba40aad644489cab","tests/test_sequence.rs":"f306bb0ff3460458e4faf1a98400a21775b1933598ecc8c9e348511929334462","tests/test_serde.rs":"a8ff6c2ce4ff2d97db63257982a365a5981d96a29099b162dd725c78a4340edf","tests/test_static_slots.rs":"ce4812bb59f1dda0b42a8d29b234ba1a94beb3f33a1c9afa78685b027bd6dfdf","tests/test_string.rs":"599aaad62697dff9c72a00d7335c2b8593a477f4575fb26291f7f020e9f482f8","tests/test_super.rs":"21012c989d7c2be2acf0e526e4a24f08ee850925c090a4b52e353293866bfb36","tests/test_text_signature.rs":"447d57fbd356d381ccba0522436f361b7f70277e49067f6ab6041d5d53e17f47","tests/test_utils/mod.rs":"d1a296afa3186609981c28d959488fcd0adca9155706b643c19b204c5d3bc2cf","tests/test_variable_arguments.rs":"80f1a3cc635abea840d95793ac2f8daacbcca52dc6784470c5a8dc740a9dc812","tests/test_various.rs":"6e40251e89ce14b2fab209fdc9996cd5f63fce78d71be69e0bc1066718afcf90","typos.toml":"e7ad1ff3643548383b8cd3089f8ba3d1ba3be8df88ce88d9d0565bc51470708a","uv.lock":"8440d8869900092ef4b3d298ece638ab286808080dc31a985a6171a8fb1c52a8","wasm/common.mk":"aa799b92ba1e9f3c65f325c9b41a2469312f871afc25da05fa88bbb297900d1d","wasm/emscripten/.gitignore":"d434707aeed0fe006fa067341575227f3f2c9de7194e6df8c89976e70f3ea698","wasm/emscripten/Makefile":"6d8696b0ec1257a44c7474c2bc0684fd7c63ef407ab8cf911456cc19f8acc1fb","wasm/emscripten/runner.py":"e488f0a396650249924f5e4c4c58249be81f371d7276ae5774a9e6c1dcc383b2","wasm/wasi/.gitignore":"74c78a6f9b94098d327f5d16a0d18213c97a502c640132049d7ef0e615b3bbe5","wasm/wasi/Makefile":"fda8ede683096a4ea044777452167f482b3a97b13b049f354ef6cc237a9a4389"},"package":"4688ddedf473e32662b9b067670129a8afb8c18e351482c70d62ba4a88171e8b"} \ No newline at end of file diff --git a/vendor/pyo3/.cargo_vcs_info.json b/vendor/pyo3/.cargo_vcs_info.json new file mode 100644 index 0000000..3f872ab --- /dev/null +++ b/vendor/pyo3/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "a70d17f898df41b3d1632ee987f624f5222d8d39" + }, + "path_in_vcs": "" +} \ No newline at end of file diff --git a/vendor/pyo3/.netlify/internal_banner.html b/vendor/pyo3/.netlify/internal_banner.html new file mode 100644 index 0000000..6f1024e --- /dev/null +++ b/vendor/pyo3/.netlify/internal_banner.html @@ -0,0 +1,47 @@ +
+
+ ⚠️ Internal Docs ⚠️ Not Public API 👉 + + Official Docs Here + +
+ + +
+ diff --git a/vendor/pyo3/.netlify/redirect.sh b/vendor/pyo3/.netlify/redirect.sh new file mode 100644 index 0000000..46d2dbe --- /dev/null +++ b/vendor/pyo3/.netlify/redirect.sh @@ -0,0 +1,49 @@ +# Add redirect for each documented version +set +x # these loops get very spammy and fill the deploy log + +for d in netlify_build/v*; do + version="${d/netlify_build\/v/}" + echo "/v$version/doc/* https://docs.rs/pyo3/$version/:splat" >> netlify_build/_redirects + if [ $version != $PYO3_VERSION ]; then + # for old versions, mark the files in the latest version as the canonical URL + for file in $(find $d -type f); do + file_path="${file/$d\//}" + # remove index.html and/or .html suffix to match the page URL on the + # final netlfiy site + url_path="$file_path" + if [[ $file_path == index.html ]]; then + url_path="" + elif [[ $file_path == *.html ]]; then + url_path="${file_path%.html}" + fi + echo "/v$version/$url_path" >> netlify_build/_headers + if test -f "netlify_build/v$PYO3_VERSION/$file_path"; then + echo " Link: ; rel=\"canonical\"" >> netlify_build/_headers + else + # this file doesn't exist in the latest guide, don't index it + echo " X-Robots-Tag: noindex" >> netlify_build/_headers + fi + done + fi +done + +# Add latest redirect +echo "/latest/* /v${PYO3_VERSION}/:splat 302" >> netlify_build/_redirects + +# some backwards compatbiility redirects +echo "/latest/building_and_distribution/* /latest/building-and-distribution/:splat 302" >> netlify_build/_redirects +echo "/latest/building-and-distribution/multiple_python_versions/* /latest/building-and-distribution/multiple-python-versions:splat 302" >> netlify_build/_redirects +echo "/latest/function/error_handling/* /latest/function/error-handling/:splat 302" >> netlify_build/_redirects +echo "/latest/getting_started/* /latest/getting-started/:splat 302" >> netlify_build/_redirects +echo "/latest/python_from_rust/* /latest/python-from-rust/:splat 302" >> netlify_build/_redirects +echo "/latest/python_typing_hints/* /latest/python-typing-hints/:splat 302" >> netlify_build/_redirects +echo "/latest/trait_bounds/* /latest/trait-bounds/:splat 302" >> netlify_build/_redirects + +## Add landing page redirect +if [ "${CONTEXT}" == "deploy-preview" ]; then + echo "/ /main/" >> netlify_build/_redirects +else + echo "/ /v${PYO3_VERSION}/ 302" >> netlify_build/_redirects +fi + +set -x \ No newline at end of file diff --git a/vendor/pyo3/.towncrier.template.md b/vendor/pyo3/.towncrier.template.md new file mode 100644 index 0000000..e46ee0e --- /dev/null +++ b/vendor/pyo3/.towncrier.template.md @@ -0,0 +1,21 @@ +{% for section_text, section in sections.items() %}{%- if section %}{{section_text}}{% endif -%} + +{% if section %} +{% for category in ['packaging', 'added', 'changed', 'removed', 'fixed' ] if category in section %} + +### {{ definitions[category]['name'] }} + +{% if definitions[category]['showcontent'] %} +{% for text, pull_requests in section[category].items() %} +- {{ text }} {{ pull_requests|join(', ') }} +{% endfor %} +{% else %} +- {{ section[category]['']|join(', ') }} +{% endif %} +{% endfor %} +{% else %} + +No significant changes. +{% endif %} + +{% endfor %} diff --git a/vendor/pyo3/Architecture.md b/vendor/pyo3/Architecture.md new file mode 100644 index 0000000..82872c7 --- /dev/null +++ b/vendor/pyo3/Architecture.md @@ -0,0 +1,200 @@ + + + + +# PyO3: Architecture + +This document roughly describes the high-level architecture of PyO3. +If you want to become familiar with the codebase you are in the right place! + +## Overview + +PyO3 provides a bridge between Rust and Python, based on the [Python/C API]. +Thus, PyO3 has low-level bindings of these API as its core. +On top of that, we have higher-level bindings to operate Python objects safely. +Also, to define Python classes and functions in Rust code, we have `trait PyClass` and a set of +protocol traits (e.g., `PyIterProtocol`) for supporting object protocols (i.e., `__dunder__` methods). +Since implementing `PyClass` requires lots of boilerplate, we have a proc-macro `#[pyclass]`. + +To summarize, there are six main parts to the PyO3 codebase. + +1. [Low-level bindings of Python/C API.](#1-low-level-bindings-of-python-capi) + - [`pyo3-ffi`] and [`src/ffi`] +2. [Bindings to Python objects.](#2-bindings-to-python-objects) + - [`src/instance.rs`] and [`src/types`] +3. [`PyClass` and related functionalities.](#3-pyclass-and-related-functionalities) + - [`src/pycell.rs`], [`src/pyclass.rs`], and more +4. [Procedural macros to simplify usage for users.](#4-procedural-macros-to-simplify-usage-for-users) + - [`src/impl_`], [`pyo3-macros`] and [`pyo3-macros-backend`] +5. [`build.rs` and `pyo3-build-config`](#5-buildrs-and-pyo3-build-config) + - [`build.rs`](https://github.com/PyO3/pyo3/tree/main/build.rs) + - [`pyo3-build-config`] + +## 1. Low-level bindings of Python/C API + +[`pyo3-ffi`] contains wrappers of the [Python/C API]. This is currently done by hand rather than +automated tooling because: + +- it gives us best control about how to adapt C conventions to Rust, and +- there are many Python interpreter versions we support in a single set of files. + +We aim to provide straight-forward Rust wrappers resembling the file structure of [`cpython/Include`](https://github.com/python/cpython/tree/main/Include). + +We are continuously updating the module to match the latest CPython version which PyO3 supports (i.e. as of time of writing Python 3.13). The tracking issue is [#1289](https://github.com/PyO3/pyo3/issues/1289), and contribution is welcome. + +In the [`pyo3-ffi`] crate, there is lots of conditional compilation such as `#[cfg(Py_LIMITED_API)]`, +`#[cfg(Py_3_8)]`, and `#[cfg(PyPy)]`. +`Py_LIMITED_API` corresponds to `#define Py_LIMITED_API` macro in Python/C API. +With `Py_LIMITED_API`, we can build a Python-version-agnostic binary called an +[abi3 wheel](https://pyo3.rs/latest/building-and-distribution.html#py_limited_apiabi3abi3t). +`Py_3_8` means that the API is available from Python >= 3.8. +There are also `Py_3_9`, `Py_3_10`, and so on. +`PyPy` means that the API definition is for PyPy. +Those flags are set in [`build.rs`](#6-buildrs-and-pyo3-build-config). + +## 2. Bindings to Python objects + +[`src/types`] contains bindings to [built-in types](https://docs.python.org/3/library/stdtypes.html) +of Python, such as `dict` and `list`. +For historical reasons, Python's `object` is called `PyAny` in PyO3 and located in [`src/types/any.rs`]. + +Currently, `PyAny` is a straightforward wrapper of `ffi::PyObject`, defined as: + +```rust +#[repr(transparent)] +pub struct PyAny(UnsafeCell); +``` + +Concrete Python objects are implemented by wrapping `PyAny`, e.g.,: + +```rust +#[repr(transparent)] +pub struct PyDict(PyAny); +``` + +These types are not intended to be accessed directly, and instead are used through the `Py` and `Bound` smart pointers. + +We have some macros in [`src/types/mod.rs`] which make it easier to implement APIs for concrete Python types. + +## 3. `PyClass` and related functionalities + +[`src/pycell.rs`], [`src/pyclass.rs`], and [`src/type_object.rs`] contain types and +traits to make `#[pyclass]` work. +Also, [`src/pyclass_init.rs`] and [`src/impl_/pyclass.rs`] have related functionalities. + +To realize object-oriented programming in C, all Python objects have `ob_base: PyObject` as their +first field in their structure definition. Thanks to this guarantee, casting `*mut A` to `*mut PyObject` +is valid if `A` is a Python object. + +To ensure this guarantee, we have a wrapper struct `PyClassObject` in [`src/pycell/impl_.rs`] which is roughly: + +```rust +#[repr(C)] +pub struct PyClassObject { + ob_base: crate::ffi::PyObject, + inner: T, +} +``` + +Thus, when copying a Rust struct to a Python object, we first allocate `PyClassObject` on the Python heap and then +move `T` into it. + +The primary way to interact with Python objects implemented in Rust is through the `Bound<'py, T>` smart pointer. +By having the `'py` lifetime of the `Python<'py>` token, this ties the lifetime of the `Bound<'py, T>` smart pointer to the lifetime for which the thread is attached to the Python interpreter and allows PyO3 to call Python APIs at maximum efficiency. + +`Bound<'py, T>` requires that `T` implements `PyClass`. +This trait is somewhat complex and derives many traits, but the most important one is `PyTypeInfo` +in [`src/type_object.rs`]. +`PyTypeInfo` is also implemented for built-in types. +In Python, all objects have their types, and types are also objects of `type`. +For example, you can see `type({})` shows `dict` and `type(type({}))` shows `type` in Python REPL. +`T: PyTypeInfo` implies that `T` has a corresponding type object. + +### Protocol methods + +Python has some built-in special methods called dunder methods, such as `__iter__`. +They are called "slots" in the [abstract objects layer](https://docs.python.org/3/c-api/abstract.html) in +Python/C API. +We provide a way to implement those protocols similarly, by recognizing special +names in `#[pymethods]`, with a few new ones for slots that can not be +implemented in Python, such as GC support. + +## 4. Procedural macros to simplify usage for users. + +[`pyo3-macros`] provides five proc-macro APIs: `pymodule`, `pyfunction`, `pyclass`, +`pymethods`, and `#[derive(FromPyObject)]`. +[`pyo3-macros-backend`] has the actual implementations of these APIs. +[`src/impl_`] contains `#[doc(hidden)]` functionality used in code generated by these proc-macros, +such as parsing function arguments. + +## 5. `build.rs` and `pyo3-build-config` + +PyO3 supports a wide range of OSes, interpreters and use cases. The correct environment must be +detected at build time in order to set up relevant conditional compilation correctly. This logic +is captured in the [`pyo3-build-config`] crate, which is a `build-dependency` of `pyo3` and +`pyo3-macros`, and can also be used by downstream users in the same way. + +In [`pyo3-build-config`]'s `build.rs` the build environment is detected and inlined into the crate +as a "config file". This works in all cases except for cross-compiling, where it is necessary to +capture this from the `pyo3` `build.rs` to get some extra environment variables that Cargo doesn't +set for build dependencies. + +The `pyo3` `build.rs` also runs some safety checks such as ensuring the Python version detected is +actually supported. + +Some of the functionality of `pyo3-build-config`: + +- Find the interpreter for build and detect the Python version. + - We have to set some version flags like `#[cfg(Py_3_8)]`. + - If the interpreter is PyPy, we set `#[cfg(PyPy)`. + - If the `PYO3_CONFIG_FILE` environment variable is set then that file's contents will be used + instead of any detected configuration. + - If the `PYO3_NO_PYTHON` environment variable is set then the interpreter detection is bypassed + entirely and only abi3 extensions can be built. +- Check if we are building a Python extension. + - If we are building an extension (e.g., Python library installable by `pip`), + we don't link `libpython` on most platforms (to allow for statically-linked Python interpreters). + The `PYO3_BUILD_EXTENSION_MODULE` environment variable suppresses linking. +- Cross-compiling configuration + - If `TARGET` architecture and `HOST` architecture differ, we can find cross compile information + from environment variables (`PYO3_CROSS_LIB_DIR`, `PYO3_CROSS_PYTHON_VERSION` and + `PYO3_CROSS_PYTHON_IMPLEMENTATION`) or system files. + When cross compiling extension modules it is often possible to make it work without any + additional user input. + - On Windows, `pyo3-ffi` uses Rust's `raw-dylib` linking feature to link against the Python DLL + directly without needing import libraries (`.lib` files). The build script emits a `pyo3_dll` + cfg with the target DLL name, and the `extern_libpython!` macro expands to the appropriate + `#[link(name = "...", kind = "raw-dylib")]` attribute. This enables cross compiling Python + extensions for Windows without having to install any Windows Python libraries. + This can be opted out by setting `PYO3_USE_RAW_DYLIB` to anything other than "1". + + + +[python/c api]: https://docs.python.org/3/c-api/ + + + +[`pyo3-macros`]: https://github.com/PyO3/pyo3/tree/main/pyo3-macros +[`pyo3-macros-backend`]: https://github.com/PyO3/pyo3/tree/main/pyo3-macros-backend +[`pyo3-build-config`]: https://github.com/PyO3/pyo3/tree/main/pyo3-build-config +[`pyo3-ffi`]: https://github.com/PyO3/pyo3/tree/main/pyo3-ffi + + + +[`src/class`]: https://github.com/PyO3/pyo3/tree/main/src/class +[`src/ffi`]: https://github.com/PyO3/pyo3/tree/main/src/ffi +[`src/types`]: https://github.com/PyO3/pyo3/tree/main/src/types + + + +[`src/impl_`]: https://github.com/PyO3/pyo3/blob/main/src/impl_ +[`src/instance.rs`]: https://github.com/PyO3/pyo3/tree/main/src/instance.rs +[`src/pycell.rs`]: https://github.com/PyO3/pyo3/tree/main/src/pycell.rs +[`src/pyclass.rs`]: https://github.com/PyO3/pyo3/tree/main/src/pyclass.rs +[`src/pyclass_init.rs`]: https://github.com/PyO3/pyo3/tree/main/src/pyclass_init.rs +[`src/pyclass_slot.rs`]: https://github.com/PyO3/pyo3/tree/main/src/pyclass_slot.rs +[`src/type_object.rs`]: https://github.com/PyO3/pyo3/tree/main/src/type_object.rs +[`src/class/methods.rs`]: https://github.com/PyO3/pyo3/tree/main/src/class/methods.rs +[`src/class/impl_.rs`]: https://github.com/PyO3/pyo3/tree/main/src/class/impl_.rs +[`src/types/any.rs`]: https://github.com/PyO3/pyo3/tree/main/src/types/any.rs +[`src/types/mod.rs`]: https://github.com/PyO3/pyo3/tree/main/src/types/mod.rs diff --git a/vendor/pyo3/CHANGELOG.md b/vendor/pyo3/CHANGELOG.md new file mode 100644 index 0000000..9c69a4f --- /dev/null +++ b/vendor/pyo3/CHANGELOG.md @@ -0,0 +1,2805 @@ +# Changelog + +All notable changes to this project will be documented in this file. For help with updating to new +PyO3 versions, please see the [migration guide](https://pyo3.rs/latest/migration.html). + +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). + +To see unreleased changes, please see the [CHANGELOG on the main branch guide](https://pyo3.rs/main/changelog.html). + + + +## [0.29.2] - 2026-08-05 + +### Packaging + +- Add `PYO3_USE_RAW_DYLIB=0` opt-out of `raw-dylib` linking for Windows. [#6185](https://github.com/PyO3/pyo3/pull/6185) + +### Fixed + +- Fix PyO3 0.29 regression with failure to link under Cygwin / MSYS2. [#6185](https://github.com/PyO3/pyo3/pull/6185) +- Fix stubs generation for field getters (`#[pyo3(get)]`) when `IntoPyObject` is only implemented on references of the field type. [#6276](https://github.com/PyO3/pyo3/pull/6276) +- Fix `#[classmethod]` magic methods receiving the instance instead of its type when invoked through a type slot. [#6283](https://github.com/PyO3/pyo3/pull/6283) +- Fix `pyo3_build_config::add_libpython_rpath_link_args` emitting Unix-style rpath linker arguments on Windows and Cygwin. [#6284](https://github.com/PyO3/pyo3/pull/6284) +- Fix PyO3 0.29.1 regression on PyPy causing crashes when deallocating `#[pyclass]` instances. [#6294](https://github.com/PyO3/pyo3/pull/6294) +- Fix missing trailing nul in Python 3.9 `#[pyclass]` docstrings. [#6296](https://github.com/PyO3/pyo3/pull/6296) +- Fix reference count leak of `#[classattr]` values created from `fn` items. [#6297](https://github.com/PyO3/pyo3/pull/6297) + +## [0.29.1] - 2026-08-02 + +### Changed + +- Use the inline definition of `Py_TYPE` in the unlimited API on 3.14+ [#6179](https://github.com/PyO3/pyo3/pull/6179) + +### Fixed + +- Fix incorrect pointer arithmetic in FFI definitions `PyObject_GET_WEAKREFS_LISTPTR` and `PyHeapType_GET_MEMBERS`. [#6145](https://github.com/PyO3/pyo3/pull/6145) +- Fix compilation error with `nightly` feature on PyPy and GraalPy due to `!Ungil` implementations for FFI types not available on those platforms. [#6146](https://github.com/PyO3/pyo3/pull/6146) +- Fix `append_to_inittab` and `PyInit_` internal module definition corruption on 32-bit and big-endian platforms on Python 3.15+. [#6150](https://github.com/PyO3/pyo3/pull/6150) +- Fix return value of `PyClassGuardMutSuper::as_super` being scoped to the full guard lifetime, now the `&mut` borrow of the `as_super()` call. [#6181](https://github.com/PyO3/pyo3/pull/6181) +- Fix builds for free-threaded interpreters older than 3.15 erroring with "cannot set a minimum Python version" when an `abi3t-py3*` feature is enabled and the configuration comes from `PYO3_CONFIG_FILE`, sysconfigdata or cross-compilation defaults. [#6192](https://github.com/PyO3/pyo3/pull/6192) +- Fix a memory leak when deallocating `#[pyclass(dict)]` instances with a populated `__dict__`. [#6198](https://github.com/PyO3/pyo3/pull/6198) +- Fix an abort inside a `#[pyclass]`'s GC traversal when the traversal is stopped early. [#6206](https://github.com/PyO3/pyo3/pull/6206) +- Fix reference cycles through the `__dict__` of a `#[pyclass(dict)]` never being collected. [#6206](https://github.com/PyO3/pyo3/pull/6206) +- Fix building on GraalPy 3.13. [#6208](https://github.com/PyO3/pyo3/pull/6208) +- Fix reference count leak of references to `#[pyclass]` type objects held by their instances on instance deallocation. [#6224](https://github.com/PyO3/pyo3/pull/6224) +- Fix FFI definitions `PyByteArray_GET_SIZE`, `PyList_GET_SIZE`, and `PySet_GET_SIZE` to use an atomic load for free-threaded Python. [#6230](https://github.com/PyO3/pyo3/pull/6230) +- Fix a memory leak on Python 3.11 and 3.12 where creating an instance of a `#[pyclass(dict)]` class leaked one empty dict per instance. [#6234](https://github.com/PyO3/pyo3/pull/6234) +- Fix `experimental-inspect` type stubs to emit the arguments of many magic methods as positional-only to match runtime behavior, rather than positional-or-keyword. [#6239](https://github.com/PyO3/pyo3/pull/6239) +- Fix `experimental-inspect` type stubs to emit the Python name rather than the Rust name for `#[pyfunction(name = "...")]`. [#6254](https://github.com/PyO3/pyo3/pull/6254) +- Fix `experimental-inspect` generating invalid internal JSON when `#[pymodule]` members are gated by `#[cfg]`. [#6255](https://github.com/PyO3/pyo3/pull/6255) +- Fix `__inplace_concat__` and `__inplace_repeat__` overriding `__concat__` and `__repeat__` when both were defined. [#6260](https://github.com/PyO3/pyo3/pull/6260) +- Fix conversion of out-of-range `time::Duration` values to return `OverflowError` instead of panicking. [#6266](https://github.com/PyO3/pyo3/pull/6266) +- Fix `experimental-inspect` type stubs padding blank lines inside indented docstrings. [#6270](https://github.com/PyO3/pyo3/pull/6270) + +## [0.29.0] - 2026-06-11 + +### Packaging + +- Support the new PEP 803 abi3t ABI with new `abi3t` and `abi3t-py315` features. [#5807](https://github.com/PyO3/pyo3/pull/5807) +- `pyo3-macros-backend` no longer depends on `pyo3-build-config`. [#5809](https://github.com/PyO3/pyo3/pull/5809) +- Drop support for Python 3.13t (3.14t and above continue to be supported; CPython declared free-threading supported starting with Python 3.14). [#5865](https://github.com/PyO3/pyo3/pull/5865) +- Drop support for Python 3.7. [#5912](https://github.com/PyO3/pyo3/pull/5912) +- Extend range of supported versions of `hashbrown` optional dependency to include version 0.17. [#5973](https://github.com/PyO3/pyo3/pull/5973) +- Support Python 3.15.0b1. [#6014](https://github.com/PyO3/pyo3/pull/6014) +- `pyo3-ffi` is now `no_std`. [#6022](https://github.com/PyO3/pyo3/pull/6022) + +### Added + +- Add `PyErr::set_traceback` to set the traceback of an exception object. [#5349](https://github.com/PyO3/pyo3/pull/5349) +- Add `PyUnicodeDecodeError::new_err_from_utf8` to create a `PyErr` from a `str::Utf8Error`. [#5668](https://github.com/PyO3/pyo3/pull/5668) +- `experimental-inspect`: implement `INPUT_TYPE` and `OUTPUT_TYPE` on optional third-party crate conversions. [#5770](https://github.com/PyO3/pyo3/pull/5770) +- `experimental-inspect`: include doc comments in generated stubs. [#5782](https://github.com/PyO3/pyo3/pull/5782) +- Add `pyo3_build_config::PythonAbi`, `pyo3_build_config::PythonAbiKind`, `pyo3_build_config::PythonAbiBuilder`, `pyo3_build_config::InterpreterConfig::target_abi`, and `pyo3_build_config::InterpreterConfigBuilder::target_abi`. [#5807](https://github.com/PyO3/pyo3/pull/5807) +- Add `Borrowed::get` as an equivalent to `Bound::get` and `Py::get`. [#5849](https://github.com/PyO3/pyo3/pull/5849) +- Add `PyFrame::new`, `PyTraceBack::new`, and `PyFrameMethods::line_number`. [#5857](https://github.com/PyO3/pyo3/pull/5857) +- Add `PyUntypedBuffer::obj` to retrieve the Python object owning the buffer. [#5870](https://github.com/PyO3/pyo3/pull/5870) +- Add `PyCapsule::new_with_value` and `PyCapsule::new_with_value_and_destructor`. [#5881](https://github.com/PyO3/pyo3/pull/5881) +- Add `PyErr::set_context` and `PyErr::context`. [#5887](https://github.com/PyO3/pyo3/pull/5887) +- Add a small CLI to `pyo3-introspection` to generate stubs. [#5904](https://github.com/PyO3/pyo3/pull/5904) +- Add `Python::version_str`. [#5921](https://github.com/PyO3/pyo3/pull/5921) +- Add `TryFrom<&Bound>` for `PyRef`, `PyRefMut`, `PyClassGuard` and `PyClassGuardMut`. [#5922](https://github.com/PyO3/pyo3/pull/5922) +- Add `From<&Bound>` for `Bound` and `Py` [#5922](https://github.com/PyO3/pyo3/pull/5922) +- Add `PyDictMethods::set_default` and `PyDictMethods::set_default_ref` to allow atomically setting default values in a PyDict. [#5955](https://github.com/PyO3/pyo3/pull/5955) +- add `PyFrameMethods::outer|code|var|builtins|globals|locals`. [#5967](https://github.com/PyO3/pyo3/pull/5967) +- Add `From` conversions for `PyErr` from `std::time::TryFromFloatSecsError`, `std::time::SystemTimeError`, `std::path::StripPrefixError`, `std::env::JoinPathsError`, `std::char::ParseCharError`, and `std::char::CharTryFromError`. [#6001](https://github.com/PyO3/pyo3/pull/6001) +- Add `pyo3_build_config::InterpreterConfigBuilder`. [#6034](https://github.com/PyO3/pyo3/pull/6034) +- Add `PyCapsule::import_pointer` [#6066](https://github.com/PyO3/pyo3/pull/6066) +- Add `PyClassGuardMapMut`. [#6073](https://github.com/PyO3/pyo3/pull/6073) +- Expose `PyListMethods::get_item_unchecked`, `PyTupleMethods::get_item_unchecked`, and `PyTupleMethods::get_borrowed_item_unchecked` on abi3. [#6075](https://github.com/PyO3/pyo3/pull/6075) +- Add `PyClassGuardMapSuper`. [#6104](https://github.com/PyO3/pyo3/pull/6104) +- Add `PyClassGuard` and `PyClassGuardMut` to `pyo3::prelude`. [#6112](https://github.com/PyO3/pyo3/pull/6112) +- Add `Debug` impls for `PyClassGuard` and `PyClassGuardMut`. [#6112](https://github.com/PyO3/pyo3/pull/6112) +- Enable extending `PyDateTime`, `PyDate`, `PyTime`, `PyDelta` and `PyTzInfo` on abi3 with python 3.12+. [#6115](https://github.com/PyO3/pyo3/pull/6115) +- Expose `PyFunction` available on abi3. [#6117](https://github.com/PyO3/pyo3/pull/6117) +- FFI definitions: + - Added FFI definitions `PyUnstable_Object_IsUniquelyReferenced`, `PyUnstable_Object_IsUniquelyReferencedTemporary`, `PyUnstable_EnableTryIncref`, and `PyUnstable_TryIncref`. [#5828](https://github.com/PyO3/pyo3/pull/5828) + - Add FFI definitions `ffi::PyErr_GetHandledException` and `ffi::PyErr_SetHandledException`. [#5887](https://github.com/PyO3/pyo3/pull/5887) + - Add FFI definition `Py_HASH_SIPHASH13`. [#5891](https://github.com/PyO3/pyo3/pull/5891) + - Add FFI definition `PyStructSequence_UnnamedField` constant on Python 3.9 and up (or 3.11 with abi3 features). [#5892](https://github.com/PyO3/pyo3/pull/5892) + - Add FFI definitions `PyUnstable_InterpreterFrame_GetCode`, `PyUnstable_InterpreterFrame_GetLasti`, `PyUnstable_InterpreterFrame_GetLine`, and `PyUnstable_ExecutableKinds`. [#5932](https://github.com/PyO3/pyo3/pull/5932) + - Add FFI definitions `PyMarshal_WriteLongToFile`, `PyMarshal_WriteObjectToFile`, `PyMarshal_ReadLongFromFile`, `PyMarshal_ReadShortFromFile`, `PyMarshal_ReadObjectFromFile`, and `PyMarshal_ReadLastObjectFromFile`. [#5934](https://github.com/PyO3/pyo3/pull/5934) + - Add FFI definitions `PyObject_GetAIter`, `PyAIter_Check`, `PyMapping_HasKeyWithError`, `PyMapping_HasKeyStringWithError`, `PyMapping_GetOptionalItem`, `PyMapping_GetOptionalItemString`, `PySequence_ITEM`, `PySequence_Fast_GET_SIZE`, `PySequence_Fast_GET_ITEM`, and `PySequence_Fast_ITEMS`. [#5942](https://github.com/PyO3/pyo3/pull/5942) + - Add FFI definition `compat::PyObject_HasAttrWithError`. [#5944](https://github.com/PyO3/pyo3/pull/5944) + - Add FFI definitions `PyDict_SetDefault`, `PyDict_SetDefaultRef`, `PyDict_ContainsString`, `PyDict_Pop`, `PyDict_PopString`, `PyDict_ClearWatcher`, `PyDict_Watch`, `PyDict_Unwatch`, and `PyFrozenDict_New`. [#5947](https://github.com/PyO3/pyo3/pull/5947) + - Add FFI definitions `PyDate_FromDate`, `PyDateTime_FromDateAndTime`, `PyDateTime_FromDateAndTimeAndFold`, `PyTime_FromTime`, `PyTime_FromTimeAndFold`, and `PyDelta_FromDSU`. [#5949](https://github.com/PyO3/pyo3/pull/5949) + - Add FFI definitions `PyDict_SetDefaultRef` and `compat::PyDict_SetDefaultRef`. [#5955](https://github.com/PyO3/pyo3/pull/5955) + versions. + - Add FFI definitions for non-limited API header `cpython/bytearrayobject.h`. [#5966](https://github.com/PyO3/pyo3/pull/5966) + - Add FFI definitions for non-limited API version of `PyCellObject` and associated functions. [#5978](https://github.com/PyO3/pyo3/pull/5978) + - Add FFI definition `PyErr_WarnExplicitObject`. [#5979](https://github.com/PyO3/pyo3/pull/5979) + - Add FFI definition `PyTracebackObject`. [#5980](https://github.com/PyO3/pyo3/pull/5980) + - Add FFI definition `PyTuple_FromArray` on 3.15+. [#5990](https://github.com/PyO3/pyo3/pull/5990) + - Add FFI definitions for the PEP 820 PySlot C API. [#6014](https://github.com/PyO3/pyo3/pull/6014) + - Add FFI definitions for the critical section API in the limited API on Python 3.15 + and newer. [#6014](https://github.com/PyO3/pyo3/pull/6014) + - Add FFI definitions for [PEP 757](https://peps.python.org/pep-0757/) `PyLong` import / export API on Python 3.14+. [#6016](https://github.com/PyO3/pyo3/pull/6016) + - Add FFI definitions `PyEval_SetProfileAllThreads` and `PyEval_SetTraceAllThreads`. [#6038](https://github.com/PyO3/pyo3/pull/6038) + - Add FFI definition `Py_UNICODE_TODECIMAL`. [#6041](https://github.com/PyO3/pyo3/pull/6041) + +### Changed + +- Change exception enrichment on `#[pyfunction]` argument extraction error to use `PyErr::add_note` instead of replacing `TypeError` instances. [#5349](https://github.com/PyO3/pyo3/pull/5349) +- Deprecate super-class initialization via tuples. [#5741](https://github.com/PyO3/pyo3/pull/5741) +- Change module initialization uses the PyModExport and PyABIInfo APIs on Python 3.15+. [#5753](https://github.com/PyO3/pyo3/pull/5753) +- Deprecate `Py::get_refcnt` and `PyAnyMethods::get_refcnt` in favor of `pyo3::ffi::Py_REFCNT(obj.as_ptr())`. [#5797](https://github.com/PyO3/pyo3/pull/5797) +- Change `PyEnvironmentError`, `PyIOError`, and `PyWindowsError` to be type aliases of `PyOSError` (as is the case in Python since 3.3). [#5803](https://github.com/PyO3/pyo3/pull/5803) +- Change `pyo3_build_config::InterpreterConfig::from_interpreter` to require an additional `stable_abi_version` argument. The old behavior is the same as passing `None`. [#5807](https://github.com/PyO3/pyo3/pull/5807) +- Change `PyList::new` to no longer have `ExactSizeIterator` bound. [#5830](https://github.com/PyO3/pyo3/pull/5830) +- `experimental-inspect`: emit `#[classattribute]` as plain Python class attributes and not functions annotated with `@classattribute` and `@property`. [#5839](https://github.com/PyO3/pyo3/pull/5839) +- `experimental-inspect`: use `object` as the input annotation type of magic methods that return `NonImplemented` if the input value is not of the correct type. [#5841](https://github.com/PyO3/pyo3/pull/5841) +- Deprecate `pyo3-build-config/resolve-config` feature. [#5862](https://github.com/PyO3/pyo3/pull/5862) +- Change `pyo3-ffi` to use raw-dylib for Windows linking. [#5866](https://github.com/PyO3/pyo3/pull/5866) +- Deprecate `generate-import-lib` feature. [#5866](https://github.com/PyO3/pyo3/pull/5866) +- Allow zero-sized types in `PyCapsule::new`. [#5889](https://github.com/PyO3/pyo3/pull/5889) +- `PyDate::from_timestamp` argument is now a `f64` (the Python API expects a float and not an integer) [#5896](https://github.com/PyO3/pyo3/pull/5896) +- `experimental-inspect`: Change `PathBuf::extract` input type hint from `str | os.PathLike` to `str | os.PathLike[str]` [#5897](https://github.com/PyO3/pyo3/pull/5897) +- Remove lifetime from `PythonVersionInfo`. [#5921](https://github.com/PyO3/pyo3/pull/5921) +- Remove redundant type checks for methods where CPython guarantees the type of `self`. [#5930](https://github.com/PyO3/pyo3/pull/5930) +- Elide temporary reference count cycles inside `PyAnyMethods::call`, `PyAnyMethods::call1` and `PyAnyMethods::call_method1` for arguments passed as Rust tuples containing borrowed references to Python objects. [#5941](https://github.com/PyO3/pyo3/pull/5941) +- Allow type annotations to be used in `#[pyo3(signature = ...)]` when `experimental-inspect` feature is not enabled (they will be ignored). [#5999](https://github.com/PyO3/pyo3/pull/5999) +- `pyo3-ffi` will now rebuild when the Python virtual environment changes in-place. [#6008](https://github.com/PyO3/pyo3/pull/6008) +- Change module initialization on 3.15+ to use PEP 820 PySlot API internally. [#6014](https://github.com/PyO3/pyo3/pull/6014) +- Deprecate direct access to all `pyo3_build_config::InterpreterConfig` fields; getter methods have been added as replacements. [#6034](https://github.com/PyO3/pyo3/pull/6034) +- FFI definitions `_PyCode_GetExtra`, `_PyCode_SetExtra`, and `_PyEval_RequestCodeExtraIndex` have been updated to `PyUnstable_Code_GetExtra`, `PyUnstable_Code_SetExtra`, and `PyUnstable_Eval_RequestCodeExtraIndex`. [#6038](https://github.com/PyO3/pyo3/pull/6038) +- Change `PyCapsule::import` to return an error if the pointer is not properly aligned. [#6066](https://github.com/PyO3/pyo3/pull/6066) +- Change `PyClassGuardMap` to be only for `PyClassGuard::map` and return `PyClassGuardMapMut` from `PyClassGuardMut::map`. [#6073](https://github.com/PyO3/pyo3/pull/6073) +- Change `with_critical_section_mutex2` closure to take `Option` instead of `EnteredCriticalSection` as the second argument. [#6098](https://github.com/PyO3/pyo3/pull/6098) +- `PyClassGuardMut::as_super` now returns `PyClassGuardMutSuper`. [#6104](https://github.com/PyO3/pyo3/pull/6104) +- `experimental-inspect`: Generate relative imports instead of absolute ones (useful if the stubs are not describing a root package) [#6097](https://github.com/PyO3/pyo3/pull/6097) + +### Removed + +- Removed the broken (and unfixable) implementations of `From`, `From`, and `From` for `PyErr`. [#5668](https://github.com/PyO3/pyo3/pull/5668) +- Remove `Py_TRACE_REFS` support (unsupported from Python 3.13). [#5824](https://github.com/PyO3/pyo3/pull/5824) +- `experimental-inspect`: Remove the `TypeInfo` enum and the `FromPyObject::type_input` and `IntoPyObject::type_output` functions. They are replaced by the `PyStaticExpr` enum and the `FromPyObject::INPUT_TYPE` and the `IntoPyObject::OUTPUT_TYPE` associated constants. [#5893](https://github.com/PyO3/pyo3/pull/5893) +- Remove all functionality deprecated in PyO3 0.27. [#6068](https://github.com/PyO3/pyo3/pull/6068) +- FFI definitions: + - Remove private FFI definitions `_PyStack_AsDict`, `_PyObject_CallNoArg`, `_PyObject_FastCall`, `_PyObject_FastCallTstate`. `_PyObject_VectorcallTstate`, `_PyObject_MakeTpCall`, `_Py_CheckFunctionResult`, `_PyObject_CallFunction_SizeT`, `_PyObject_CallMethod_SizeT`, and `_PySequence_IterSearch`. [#5942](https://github.com/PyO3/pyo3/pull/5942) + - Remove FFI definitions `PY_ITERSEARCH_COUNT`, `PY_ITERSEARCH_INDEX`, and `PY_ITERSEARCH_CONTAINS`. [#5942](https://github.com/PyO3/pyo3/pull/5942) + - Removed private FFI definitions `_PySet_NextEntry`, and `_PyLong_NumBits`. [#5946](https://github.com/PyO3/pyo3/pull/5946) + - Remove private FFI definitions `_PyFloat_CAST`, `_PyRun_SimpleFileObject`, `_PyRun_AnyFileObject`, `_PyRun_InteractiveLoopObject`, `_PyUnicode_CheckConsistency`, `_PyUnicode_COMPACT_DATA`, `_PyUnicode_NONCOMPACT_DATA`, `_PyUnicode_Ready`, and `_Py_HashBytes`. [#6036](https://github.com/PyO3/pyo3/pull/6036) + - Remove private FFI definition `_PyEval_EvalFrameDefault`. [#6038](https://github.com/PyO3/pyo3/pull/6038) + - Remove private FFI definition `_PyBytes_Resize`. [#6042](https://github.com/PyO3/pyo3/pull/6042) + - Remove private FFI definitions `_PyErr_BadInternalCall`, `_Py_GetAllocatedBlocks`, `_PyObject_GC_Malloc`, `_PyObject_GC_Calloc`, and `_PyLong_NumBits`. [#6053](https://github.com/PyO3/pyo3/pull/6053) + - Remove `Default` for FFI definitions `PyHeapTypeObject`, `PyObjectArenaAllocator`, `PyHash_FuncDef`, and `PyType_Spec`. [#6093](https://github.com/PyO3/pyo3/pull/6093) + +### Fixed + +- Fix `add_libpython_rpath_link_args` emitting rpath link args on wasm targets which don't support rpath. [#5447](https://github.com/PyO3/pyo3/pull/5447) +- Fix `From` and `From` for `PyErr` producing `TypeError` due to broken internals. [#5668](https://github.com/PyO3/pyo3/pull/5668) +- Fix `PyMappingProxy::is_type_of` and `PyWeakrefReference::is_type_of` not accepting subclasses. [#5883](https://github.com/PyO3/pyo3/pull/5883) +- Fix `getattr_opt` not treating `AttributeError` subclasses as missing attributes on Python < 3.13. [#5985](https://github.com/PyO3/pyo3/pull/5985) +- Fix compilation error for `#[new]` return types that contain named lifetimes. [#5998](https://github.com/PyO3/pyo3/pull/5998) +- Fix missing `'static` bound on `PyCapsule` destructors. [#6049](https://github.com/PyO3/pyo3/pull/6049) +- Fix case where `PyFrame::builtins` could return a non-dict object. [#6052](https://github.com/PyO3/pyo3/pull/6052) +- Fix type confusion when returning a `#[pyclass]` from a different pyclass' `#[new]` method. [#6062](https://github.com/PyO3/pyo3/pull/6062) +- Fix soundness issue caused by variance in `PyClassGuardMap` by splitting off the mutable variant. [#6073](https://github.com/PyO3/pyo3/pull/6073) +- Fix nondeterministic JSON metadata emitted by the `experimental-inspect` proc macros (to enable reproducible builds). [#6076](https://github.com/PyO3/pyo3/pull/6076) +- Fix UB in `PyEval_RestoreThread` when the interpreter is shutting down on Python 3.13 and older (hang the thread instead of allowing `pthread_exit` to jump across Rust frames). [#6085](https://github.com/PyO3/pyo3/pull/6085) +- Fix possible out of bounds read in `BoundListIterator` and `BoundTupleIterator`'s `nth` and `nth_back` implementations. [#6086](https://github.com/PyO3/pyo3/pull/6086) +- Fix `BoundListIterator` and `BoundTupleIterator` not being exhausted when `nth` or `nth_back` is called with N larger than the remaining count of items. [#6086](https://github.com/PyO3/pyo3/pull/6086) +- Fix missing `Sync` bound on closure type in `PyCFunction::new_closure`. [#6096](https://github.com/PyO3/pyo3/pull/6096) +- Fix soundness issue caused by exposing a mutable reference from `PyClassGuardMut::as_super` by moving into `PyClassGuardMutSuper`. [#6104](https://github.com/PyO3/pyo3/pull/6104) +- FFI definitions: + - Fix missing FFI definition for `PyTypeObject.tp_versions_used` on Python 3.13 and newer. [#5917](https://github.com/PyO3/pyo3/pull/5917) + - Mark FFI definitions no longer available on 3.11 and up: `PyUnicode_Encode`, `PyUnicode_EncodeASCII`, `PyUnicode_EncodeCharmap`, `PyUnicode_EncodeDecimal`, `PyUnicode_EncodeLatin1`, `PyUnicode_EncodeRawUnicodeEscape`, `PyUnicode_EncodeUTF7`, `PyUnicode_EncodeUTF8`, `PyUnicode_EncodeUTF16`, `PyUnicode_EncodeUTF32`, `PyUnicode_EncodeUnicodeEscape`, `PyUnicode_TransformDecimalToASCII`, and `PyUnicode_TranslateCharmap`. [#6041](https://github.com/PyO3/pyo3/pull/6041) + - Mark FFI definition `PyUnicode_ClearFreeList` no longer available on 3.9 and up. [#6041](https://github.com/PyO3/pyo3/pull/6041) + - Fix FFI definition `PyErr_SetInterruptEx` missing `c_int` return type. [#6043](https://github.com/PyO3/pyo3/pull/6043) + - Fix return type of FFI definition `PyBuffer_SizeFromFormat` on Python 3.8 (was changed from `c_int` to `Py_ssize_t` on Python 3.9). [#6090](https://github.com/PyO3/pyo3/pull/6090) + - Fix return type of FFI definition `PyUnicode_Tailmatch` on PyPy (is `c_int`, unlike CPython). [#6090](https://github.com/PyO3/pyo3/pull/6090) + + +## [0.28.3] - 2026-04-02 + +### Fixed + +- Fix compile error with `#[pyclass(get_all)]` on a type named `Probe`. [#5837](https://github.com/PyO3/pyo3/pull/5837) +- Fix compile error in debug builds related to `_Py_NegativeRefcount` with Python < 3.12. [#5847](https://github.com/PyO3/pyo3/pull/5847) +- Fix a race condition where `Python::attach` or `try_attach` could return before `site.py` had finished running. [#5903](https://github.com/PyO3/pyo3/pull/5903) +- Fix unsoundness in `PyBytesWriter::write_vectored` with Python 3.15 prerelease versions. [#5907](https://github.com/PyO3/pyo3/pull/5907) +- Fix deadlock in `.into_pyobject()` implementation for C-like `#[pyclass]` enums. [#5928](https://github.com/PyO3/pyo3/pull/5928) + +## [0.28.2] - 2026-02-18 + +### Fixed + +- Fix complex enum `__qualname__` not using python name [#5815](https://github.com/PyO3/pyo3/pull/5815) +- Fix FFI definition `PyType_GetTypeDataSize` (was incorrectly named `PyObject_GetTypeDataSize`). [#5819](https://github.com/PyO3/pyo3/pull/5819) +- Fix memory corruption when subclassing native types with `abi3` feature on Python 3.12+ (newly enabled in PyO3 0.28.0). [#5823](https://github.com/PyO3/pyo3/pull/5823) + +## [0.28.1] - 2026-02-14 + +### Fixed + +- Fix `*args` / `**kwargs` support in` experimental-async` feature (regressed in 0.28.0). [#5771](https://github.com/PyO3/pyo3/pull/5771) +- Fix `clippy::declare_interior_mutable_const` warning inside `#[pyclass]` generated code on enums. [#5772](https://github.com/PyO3/pyo3/pull/5772) +- Fix `ambiguous_associated_items` compilation error when deriving `FromPyObject` or using `#[pyclass(from_py_object)]` macro on enums with `Error` variant. [#5784](https://github.com/PyO3/pyo3/pull/5784) +- Fix `__qualname__` for complex `#[pyclass]` enum variants to include the enum name. [#5796](https://github.com/PyO3/pyo3/pull/5796) +- Fix missing `std::sync::atomic::Ordering` import for targets without atomic64. [#5808](https://github.com/PyO3/pyo3/pull/5808) + +## [0.28.0] - 2026-02-01 + +### Packaging + +- Bump MSRV to Rust 1.83. [#5531](https://github.com/PyO3/pyo3/pull/5531) +- Bump minimum supported `quote` version to 1.0.37. [#5531](https://github.com/PyO3/pyo3/pull/5531) +- Bump supported GraalPy version to 25.0. [#5542](https://github.com/PyO3/pyo3/pull/5542) +- Drop `memoffset` dependency. [#5545](https://github.com/PyO3/pyo3/pull/5545) +- Support for free-threaded Python is now opt-out rather than opt-in. [#5564](https://github.com/PyO3/pyo3/pull/5564) +- Bump `target-lexicon` dependency to 0.13.3. [#5571](https://github.com/PyO3/pyo3/pull/5571) +- Drop `indoc` and `unindent` dependencies. [#5608](https://github.com/PyO3/pyo3/pull/5608) + +### Added + +- Add `__init__` support in `#[pymethods]`. [#4951](https://github.com/PyO3/pyo3/pull/4951) +- Expose `PySuper` on PyPy, GraalPy and ABI3 [#4951](https://github.com/PyO3/pyo3/pull/4951) +- Add `PyString::from_fmt` and `py_format!` macro. [#5199](https://github.com/PyO3/pyo3/pull/5199) +- Add `#[pyclass(new = "from_fields")]` option. [#5421](https://github.com/PyO3/pyo3/pull/5421) +- Add `pyo3::buffer::PyUntypedBuffer`, a type-erased form of `PyBuffer`. [#5458](https://github.com/PyO3/pyo3/pull/5458) +- Add `PyBytes::new_with_writer` [#5517](https://github.com/PyO3/pyo3/pull/5517) +- Add `PyClass::NAME`. [#5579](https://github.com/PyO3/pyo3/pull/5579) +- Add `pyo3_build_config::add_libpython_rpath_link_args`. [#5624](https://github.com/PyO3/pyo3/pull/5624) +- Add `PyBackedStr::clone_ref` and `PyBackedBytes::clone_ref` methods. [#5654](https://github.com/PyO3/pyo3/pull/5654) +- Add `PyCapsule::new_with_pointer` and `PyCapsule::new_with_pointer_and_destructor` for creating capsules with raw pointers. [#5689](https://github.com/PyO3/pyo3/pull/5689) +- Add `#[deleter]` attribute to implement property deleters in `#[methods]`. [#5699](https://github.com/PyO3/pyo3/pull/5699) +- Add `IntoPyObject` and `FromPyObject` implementations for `uuid::NonNilUuid`. [#5707](https://github.com/PyO3/pyo3/pull/5707) +- Add `PyBackedStr::as_str` and `PyBackedStr::as_py_str` methods. [#5723](https://github.com/PyO3/pyo3/pull/5723) +- Add support for subclassing native types (`PyDict`, exceptions, ...) when building for abi3 on Python 3.12+. [#5733](https://github.com/PyO3/pyo3/pull/5733) +- Add support for subclassing `PyList` when building for Python 3.12+. [#5734](https://github.com/PyO3/pyo3/pull/5734) +- FFI definitions: + - Add FFI definitions `PyEval_GetFrameBuiltins`, `PyEval_GetFrameGlobals` and `PyEval_GetFrameLocals` on Python 3.13 and up. [#5590](https://github.com/PyO3/pyo3/pull/5590) + - Add FFI definitions `PyObject_New`, `PyObject_NewVar`, `PyObject_GC_Resize`, `PyObject_GC_New`, and `PyObject_GC_NewVar`. [#5591](https://github.com/PyO3/pyo3/pull/5591) + - Added FFI definitions and an unsafe Rust API wrapping `Py_BEGIN_CRITICAL_SECTION_MUTEX` and `Py_BEGIN_CRITICAL_SECTION_MUTEX2`. [#5642](https://github.com/PyO3/pyo3/pull/5642) + - Add FFI definition `PyDict_GetItemStringRef` on Python 3.13 and up. [#5659](https://github.com/PyO3/pyo3/pull/5659) + - Add FFI definition `PyIter_NextItem` on Python 3.14 and up, and `compat::PyIter_NextItem` for older versions. [#5661](https://github.com/PyO3/pyo3/pull/5661) + - Add FFI definitions `PyThreadState_GetInterpreter` and `PyThreadState_GetID` on Python 3.9+, `PyThreadState_EnterTracing` and `PyThreadState_LeaveTracing` on Python 3.11+, `PyThreadState_GetUnchecked` on Python 3.13+, and `compat::PyThreadState_GetUnchecked`. [#5711](https://github.com/PyO3/pyo3/pull/5711) + - Add FFI definitions `PyImport_ImportModuleAttr` and `PyImport_ImportModuleAttrString` on Python 3.14+. [#5737](https://github.com/PyO3/pyo3/pull/5737) + - Add FFI definitions for the `PyABIInfo` and `PyModExport` APIs available in Python 3.15. [#5746](https://github.com/PyO3/pyo3/pull/5746) +- `experimental-inspect`: + - Emit base classes. [#5331](https://github.com/PyO3/pyo3/pull/5331) + - Emit `@typing.final` on final classes. [#5552](https://github.com/PyO3/pyo3/pull/5552) + - Generate nested classes for complex enums. [#5708](https://github.com/PyO3/pyo3/pull/5708) + - Emit `async` keyword for async functions. [#5731](https://github.com/PyO3/pyo3/pull/5731) + +### Changed + +- Call `sys.unraisablehook` instead of `PyErr_Print` if panicking on null FFI pointer in `Bound`, `Borrowed` and `Py` constructors. [#5496](https://github.com/PyO3/pyo3/pull/5496) +- Use PEP-489 multi-phase initialization for `#[pymodule]`. [#5525](https://github.com/PyO3/pyo3/pull/5525) +- Deprecate implicit by-value implementation of `FromPyObject` for `#[pyclass]`. [#5550](https://github.com/PyO3/pyo3/pull/5550) +- Deprecate `PyTypeInfo::NAME` and `PyTypeInfo::MODULE`. [#5579](https://github.com/PyO3/pyo3/pull/5579) +- Deprecate `Py::from_{owned,borrowed}[or_{err,opt}]` constructors from raw pointer. [#5585](https://github.com/PyO3/pyo3/pull/5585) +- Deprecate FFI definitions `PyEval_AcquireLock` and `PyEval_ReleaseLock`. [#5590](https://github.com/PyO3/pyo3/pull/5590) +- Relax `'py: 'a` bound in `Py::extract`. [#5594](https://github.com/PyO3/pyo3/pull/5594) +- Add a `T: PyTypeCheck` bound to the `IntoPyObject` implementations on `Bound`, `Borrowed` and `Py`. [#5640](https://github.com/PyO3/pyo3/pull/5640) +- The `with_critical_section` and `with_critical_section2` functions are moved to `pyo3::sync::critical_section`. [#5642](https://github.com/PyO3/pyo3/pull/5642) +- Use `PyIter_NextItem` in `PyIterator::next` implementation. [#5661](https://github.com/PyO3/pyo3/pull/5661) +- `IntoPyObject` for simple enums now uses a singleton value, allowing identity (python `is`) comparisons. [#5665](https://github.com/PyO3/pyo3/pull/5665) +- Allow any `Sequence[int]` in `FromPyObject` on `Cow<[u8]>` and change the error type to `PyErr`. [#5667](https://github.com/PyO3/pyo3/pull/5667) +- `async` pymethods now borrow `self` only for the duration of awaiting the future, not the entire method call. [#5684](https://github.com/PyO3/pyo3/pull/5684) +- Change `CastError` formatted message to directly describe the "is not an instance of" failure condition. [#5693](https://github.com/PyO3/pyo3/pull/5693) +- Add `#[inline]` hints to many methods on `PyBackedStr`. [#5723](https://github.com/PyO3/pyo3/pull/5723) +- Remove redundant internal counters from `BoundSetIterator` and `BoundFrozenSetIterator`. [#5725](https://github.com/PyO3/pyo3/pull/5725) +- Implement `PyIterator::size_hint` on abi3 builds (previously was only on unlimited API builds). [#5727](https://github.com/PyO3/pyo3/pull/5727) +- Deprecate FFI definition `PyImport_ImportModuleNoBlock` (deprecated in Python 3.13). [#5737](https://github.com/PyO3/pyo3/pull/5737) +- `#[new]` can now return arbitrary Python objects. [#5739](https://github.com/PyO3/pyo3/pull/5739) +- `experimental-inspect`: + - Introduce `TypeHint` and make use of it to encode type hint annotations. [#5438](https://github.com/PyO3/pyo3/pull/5438) + - Rename `PyType{Info,Check}::TYPE_INFO` into `PyType{Info,Check}::TYPE_HINT`. [#5438](https://github.com/PyO3/pyo3/pull/5438) [#5619](https://github.com/PyO3/pyo3/pull/5619) [#5641](https://github.com/PyO3/pyo3/pull/5641) + - Fill annotations on function arguments and return values for all types supported natively by PyO3. [#5634](https://github.com/PyO3/pyo3/pull/5634) [#5637](https://github.com/PyO3/pyo3/pull/5637) [#5639](https://github.com/PyO3/pyo3/pull/5639) + - Use `_typeshed.Incomplete` instead of `typing.Any` as default type hint, to make it easier to spot incomplete trait implementations. [#5744](https://github.com/PyO3/pyo3/pull/5744) + - Use general Python expression syntax for type hints. [#5671](https://github.com/PyO3/pyo3/pull/5671) + +### Removed + +- Remove all functionality deprecated in PyO3 0.25 and 0.26. [#5740](https://github.com/PyO3/pyo3/pull/5740) +- FFI definitions: + - Remove FFI definition `PyEval_GetCallStats` (removed from CPython in Python 3.7). [#5590](https://github.com/PyO3/pyo3/pull/5590) + - Remove FFI definitions `PyEval_AcquireLock` and `PyEval_ReleaseLock` on Python 3.13 and up. [#5590](https://github.com/PyO3/pyo3/pull/5590) + - Remove private FFI definitions `_PyObject_New`, `_PyObject_NewVar`, `_PyObject_GC_Resize`, `_PyObject_GC_New`, and `_PyObject_GC_NewVar`. [#5591](https://github.com/PyO3/pyo3/pull/5591) + - Remove private FFI definitions `_PyDict_SetItem_KnownHash`, `_PyDict_Next`, `_PyDict_NewPresized`, `_PyDict_Contains_KnownHash`, and `_PyDict_Contains`. [#5659](https://github.com/PyO3/pyo3/pull/5659) + - Remove private FFI definitions `_PyFrameEvalFunction`, `_PyInterpreterState_GetEvalFrameFunc` and `_PyInterpreterState_SetEvalFrameFunc`. [#5711](https://github.com/PyO3/pyo3/pull/5711) + - Remove private FFI definitions `_PyImport_IsInitialized`, `_PyImport_SetModule`, `_PyImport_SetModuleString`, `_PyImport_AcquireLock`, `_PyImport_ReleaseLock`, `_PyImport_FindBuiltin`, `_PyImport_FindExtensionObject`, `_PyImport_FixupBuiltin`, and `_PyImport_FixupExtensionObject`. [#5737](https://github.com/PyO3/pyo3/pull/5737) + +### Fixed + +- Fix `PyModuleMethods::add_submodule()` to use the last segment of the submodule name as the attribute name on the parent module instead of using the full name. [#5375](https://github.com/PyO3/pyo3/pull/5375) +- Link with libpython for Cygwin extension modules. [#5571](https://github.com/PyO3/pyo3/pull/5571) +- Link against the limited API DLL for Cygwin when abi3 is used. [#5574](https://github.com/PyO3/pyo3/pull/5574) +- Handle errors in `PyIterator` when calling `size_hint` [#5604](https://github.com/PyO3/pyo3/pull/5604) +- Link with libpython for iOS extension modules. [#5605](https://github.com/PyO3/pyo3/pull/5605) +- Correct `IntoPyObject` output type of `PyBackedStr` to be `PyString`, not `PyAny`. [#5655](https://github.com/PyO3/pyo3/pull/5655) +- Fix `async` functions to return `None` rather than empty tuple `()`. [#5685](https://github.com/PyO3/pyo3/pull/5685) +- Fix compile error when using references to `#[pyclass]` types (e.g. `&MyClass`) as arguments to async `#[pyfunction]`s. [#5725](https://github.com/PyO3/pyo3/pull/5725) +- FFI definitions: + - Fix FFI definition `PyMemberDescrObject.d_member` to use `PyMemberDef` for Python 3.11+ (was incorrectly `PyGetSetDef`). [#5647](https://github.com/PyO3/pyo3/pull/5647) + - Mark FFI definition `PyThreadState_GetFrame` available with abi3 in 3.10+. [#5711](https://github.com/PyO3/pyo3/pull/5711) + - Fix FFI definition `PyImport_GetModule` on PyPy. [#5737](https://github.com/PyO3/pyo3/pull/5737) +- `experimental-inspect`: + - fix `__new__` return type to be the built object type and not `None`. [#5555](https://github.com/PyO3/pyo3/pull/5555) + - fix imports of decorators. [#5618](https://github.com/PyO3/pyo3/pull/5618) + - fix the return type annotation of `PyResult<()>` (must be `None` and not `tuple`) [#5674](https://github.com/PyO3/pyo3/pull/5674) + +## [0.27.2] - 2025-11-30 + +### Changed + +- Disable subclassing `PyDict` on GraalPy (unsupported for now, may crash at runtime). [#5653](https://github.com/PyO3/pyo3/pull/5653) + +### Fixed + +- Fix crash when compiling on Rust 1.92+ with both debug assertions and optimizations enabled. [#5638](https://github.com/PyO3/pyo3/pull/5638) +- Fix FFI definition of `PyDictObject` on PyPy. [#5653](https://github.com/PyO3/pyo3/pull/5653) + +## [0.27.1] - 2025-10-21 + +### Fixed + +- Fix `clippy:declare_interior_mutable_const` warning from `#[pyfunction]`. [#5538](https://github.com/PyO3/pyo3/pull/5538) +- Expose `pyo3::types::PySendResult` in public API. [#5539](https://github.com/PyO3/pyo3/pull/5539) + +## [0.27.0] - 2025-10-19 + +### Packaging + +- Extend range of supported versions of `hashbrown` optional dependency to include version 0.16. [#5428](https://github.com/PyO3/pyo3/pull/5428) +- Bump optional `num-bigint` dependency minimum version to 0.4.4. [#5471](https://github.com/PyO3/pyo3/pull/5471) +- Test against Python 3.14 final release. [#5499](https://github.com/PyO3/pyo3/pull/5499) +- Drop support for PyPy 3.9 and 3.10. [#5516](https://github.com/PyO3/pyo3/pull/5516) +- Provide a better error message when building an outdated PyO3 for a too-new Python version. [#5519](https://github.com/PyO3/pyo3/pull/5519) + +### Added + +- Add `FromPyObjectOwned` as convenient trait bound for `FromPyObject` when the data is not borrowed from Python. [#4390](https://github.com/PyO3/pyo3/pull/4390) +- Add `Borrowed::extract`, same as `PyAnyMethods::extract`, but does not restrict the lifetime by deref. [#4390](https://github.com/PyO3/pyo3/pull/4390) +- `experimental-inspect`: basic support for `#[derive(IntoPyObject)]` (no struct fields support yet). [#5365](https://github.com/PyO3/pyo3/pull/5365) +- `experimental-inspect`: support `#[pyo3(get, set)]` and `#[pyclass(get_all, set_all)]`. [#5370](https://github.com/PyO3/pyo3/pull/5370) +- Add `PyTypeCheck::classinfo_object` that returns an object that can be used as parameter in `isinstance` or `issubclass`. [#5387](https://github.com/PyO3/pyo3/pull/5387) +- Implement `PyTypeInfo` on `datetime.*` types even when the limited API is enabled. [#5388](https://github.com/PyO3/pyo3/pull/5388) +- Implement `PyTypeInfo` on `PyIterator`, `PyMapping` and `PySequence`. [#5402](https://github.com/PyO3/pyo3/pull/5402) +- Implement `PyTypeInfo` on `PyCode` when using the stable ABI. [#5403](https://github.com/PyO3/pyo3/pull/5403) +- Implement `PyTypeInfo` on `PyWeakrefReference` when using the stable ABI. [#5404](https://github.com/PyO3/pyo3/pull/5404) +- Add `pyo3::sync::RwLockExt` trait, analogous to `pyo3::sync::MutexExt` for readwrite locks. [#5435](https://github.com/PyO3/pyo3/pull/5435) +- Add `PyString::from_bytes`. [#5437](https://github.com/PyO3/pyo3/pull/5437) +- Implement `AsRef<[u8]>` for `PyBytes`. [#5445](https://github.com/PyO3/pyo3/pull/5445) +- Add `CastError` and `CastIntoError`. [#5468](https://github.com/PyO3/pyo3/pull/5468) +- Add `PyCapsuleMethods::pointer_checked` and `PyCapsuleMethods::is_valid_checked`. [#5474](https://github.com/PyO3/pyo3/pull/5474) +- Add `Borrowed::cast`, `Borrowed::cast_exact` and `Borrowed::cast_unchecked`. [#5475](https://github.com/PyO3/pyo3/pull/5475) +- Add conversions for `jiff::civil::ISOWeekDate`. [#5478](https://github.com/PyO3/pyo3/pull/5478) +- Add conversions for `&Cstr`, `Cstring` and `Cow`. [#5482](https://github.com/PyO3/pyo3/pull/5482) +- add `#[pyclass(skip_from_py_object)]` option, to opt-out of the `FromPyObject: PyClass + Clone` blanket impl. [#5488](https://github.com/PyO3/pyo3/pull/5488) +- Add `PyErr::add_note`. [#5489](https://github.com/PyO3/pyo3/pull/5489) +- Add `FromPyObject` impl for `Cow` & `Cow`. [#5497](https://github.com/PyO3/pyo3/pull/5497) +- Add `#[pyclass(from_py_object)]` pyclass option, to opt-in to the extraction of pyclasses by value (requires `Clone`). [#5506](https://github.com/PyO3/pyo3/pull/5506) + +### Changed + +- Rework `FromPyObject` trait for flexibility and performance: [#4390](https://github.com/PyO3/pyo3/pull/4390) + - Add a second lifetime to `FromPyObject`, to allow borrowing data from Python objects (e.g. `&str` from Python `str`). + - Replace `extract_bound` with `extract`, which takes `Borrowed<'a, 'py, PyAny>`. +- Optimize `FromPyObject` implementations for `Vec` and `[u8; N]` from `bytes` and `bytearray`. [#5244](https://github.com/PyO3/pyo3/pull/5244) +- Deprecate `#[pyfn]` attribute. [#5384](https://github.com/PyO3/pyo3/pull/5384) +- Fetch type name dynamically on cast errors instead of using `PyTypeCheck::NAME`. [#5387](https://github.com/PyO3/pyo3/pull/5387) +- Deprecate `PyTypeCheck::NAME` in favour of `PyTypeCheck::classinfo_object` which provides the type information at runtime. [#5387](https://github.com/PyO3/pyo3/pull/5387) +- `PyClassGuard(Mut)` and `PyRef(Mut)` extraction now returns an opaque Rust error [#5413](https://github.com/PyO3/pyo3/pull/5413) +- Fetch type name dynamically when exporting types implementing `PyTypeInfo` with `#[pymodule_use]`. [#5414](https://github.com/PyO3/pyo3/pull/5414) +- Improve `Debug` representation of `PyBuffer`. [#5442](https://github.com/PyO3/pyo3/pull/5442) +- `experimental-inspect`: change the way introspection data is emitted in the binaries to avoid a pointer indirection and simplify parsing. [#5450](https://github.com/PyO3/pyo3/pull/5450) +- Optimize `Py::drop` for the case when attached to the Python interpreter. [#5454](https://github.com/PyO3/pyo3/pull/5454) +- Replace `DowncastError` and `DowncastIntoError` with `CastError` and `CastIntoError`. [#5468](https://github.com/PyO3/pyo3/pull/5468) +- Enable fast-path for 128-bit integer conversions on `GraalPy`. [#5471](https://github.com/PyO3/pyo3/pull/5471) +- Deprecate `PyAnyMethods::downcast` functions in favour of `Bound::cast` functions. [#5472](https://github.com/PyO3/pyo3/pull/5472) +- Make `PyTypeCheck` an `unsafe trait`. [#5473](https://github.com/PyO3/pyo3/pull/5473) +- Deprecate unchecked `PyCapsuleMethods`: `pointer()`, `reference()`, and `is_valid()`. [#5474](https://github.com/PyO3/pyo3/pull/5474) +- Reduce lifetime of return value in `PyCapsuleMethods::reference`. [#5474](https://github.com/PyO3/pyo3/pull/5474) +- `PyCapsuleMethods::name` now returns `CapsuleName` wrapper instead of `&CStr`. [#5474](https://github.com/PyO3/pyo3/pull/5474) +- Deprecate `import_exception_bound` in favour of `import_exception`. [#5480](https://github.com/PyO3/pyo3/pull/5480) +- `PyList::get_item_unchecked`, `PyTuple::get_item_unchecked`, and `PyTuple::get_borrowed_item_unchecked` no longer check for null values at the provided index. [#5494](https://github.com/PyO3/pyo3/pull/5494) +- Allow converting naive datetime into chrono `DateTime`. [#5507](https://github.com/PyO3/pyo3/pull/5507) + +### Removed + +- Removed `FromPyObjectBound` trait. [#4390](https://github.com/PyO3/pyo3/pull/4390) + +### Fixed + +- Fix compilation failure on `wasm32-wasip2`. [#5368](https://github.com/PyO3/pyo3/pull/5368) +- Fix `OsStr` conversion for non-utf8 strings on Windows. [#5444](https://github.com/PyO3/pyo3/pull/5444) +- Fix issue with `cargo vendor` caused by gitignored build artifact `emscripten/pybuilddir.txt`. [#5456](https://github.com/PyO3/pyo3/pull/5456) +- Stop leaking `PyMethodDef` instances inside `#[pyfunction]` macro generated code. [#5459](https://github.com/PyO3/pyo3/pull/5459) +- Don't export definition of FFI struct `PyObjectObFlagsAndRefcnt` on 32-bit Python 3.14 (doesn't exist). [#5499](https://github.com/PyO3/pyo3/pull/5499) +- Fix failure to build for `abi3` interpreters on Windows using maturin's built-in sysconfig in combination with the `generate-import-lib` feature. [#5503](https://github.com/PyO3/pyo3/pull/5503) +- Fix FFI definitions `PyModule_ExecDef` and `PyModule_FromDefAndSpec2` on PyPy. [#5529](https://github.com/PyO3/pyo3/pull/5529) + +## [0.26.0] - 2025-08-29 + +### Packaging + +- Bump hashbrown dependency to 0.15. [#5152](https://github.com/PyO3/pyo3/pull/5152) +- Update MSRV to 1.74. [#5171](https://github.com/PyO3/pyo3/pull/5171) +- Set the same maximum supported version for alternative interpreters as for CPython. [#5192](https://github.com/PyO3/pyo3/pull/5192) +- Add optional `bytes` dependency to add conversions for `bytes::Bytes`. [#5252](https://github.com/PyO3/pyo3/pull/5252) +- Publish new crate `pyo3-introspection` to pair with the `experimental-inspect` feature. [#5300](https://github.com/PyO3/pyo3/pull/5300) +- The `PYO3_BUILD_EXTENSION_MODULE` now causes the same effect as the `extension-module` feature. Eventually we expect maturin and setuptools-rust to set this environment variable automatically. Users with their own build systems will need to do the same. [#5343](https://github.com/PyO3/pyo3/pull/5343) + +### Added + +- Add `#[pyo3(warn(message = "...", category = ...))]` attribute for automatic warnings generation for `#[pyfunction]` and `#[pymethods]`. [#4364](https://github.com/PyO3/pyo3/pull/4364) +- Add `PyMutex`, available on Python 3.13 and newer. [#4523](https://github.com/PyO3/pyo3/pull/4523) +- Add FFI definition `PyMutex_IsLocked`, available on Python 3.14 and newer. [#4523](https://github.com/PyO3/pyo3/pull/4523) +- Add `PyString::from_encoded_object`. [#5017](https://github.com/PyO3/pyo3/pull/5017) +- `experimental-inspect`: add basic input type annotations. [#5089](https://github.com/PyO3/pyo3/pull/5089) +- Add FFI function definitions for `PyFrameObject` from CPython 3.13. [#5154](https://github.com/PyO3/pyo3/pull/5154) +- `experimental-inspect`: tag modules created using `#[pymodule]` or `#[pymodule_init]` functions as incomplete. [#5207](https://github.com/PyO3/pyo3/pull/5207) +- `experimental-inspect`: add basic return type support. [#5208](https://github.com/PyO3/pyo3/pull/5208) +- Add `PyCode::compile` and `PyCodeMethods::run` to create and execute code objects. [#5217](https://github.com/PyO3/pyo3/pull/5217) +- Add `PyOnceLock` type for thread-safe single-initialization. [#5223](https://github.com/PyO3/pyo3/pull/5223) +- Add `PyClassGuard(Mut)` pyclass holders. In the future they will replace `PyRef(Mut)`. [#5233](https://github.com/PyO3/pyo3/pull/5233) +- `experimental-inspect`: allow annotations in `#[pyo3(signature)]` signature attribute. [#5241](https://github.com/PyO3/pyo3/pull/5241) +- Implement `MutexExt` for parking_lot's/lock_api `ReentrantMutex`. [#5258](https://github.com/PyO3/pyo3/pull/5258) +- `experimental-inspect`: support class associated constants. [#5272](https://github.com/PyO3/pyo3/pull/5272) +- Add `Bound::cast` family of functions superseding the `PyAnyMethods::downcast` family. [#5289](https://github.com/PyO3/pyo3/pull/5289) +- Add FFI definitions `Py_Version` and `Py_IsFinalizing`. [#5317](https://github.com/PyO3/pyo3/pull/5317) +- `experimental-inspect`: add output type annotation for `#[pyclass]`. [#5320](https://github.com/PyO3/pyo3/pull/5320) +- `experimental-inspect`: support `#[pyclass(eq, eq_int, ord, hash, str)]`. [#5338](https://github.com/PyO3/pyo3/pull/5338) +- `experimental-inspect`: add basic support for `#[derive(FromPyObject)]` (no struct fields support yet). [#5339](https://github.com/PyO3/pyo3/pull/5339) +- Add `Python::try_attach`. [#5342](https://github.com/PyO3/pyo3/pull/5342) + +### Changed + +- Use `Py_TPFLAGS_DISALLOW_INSTANTIATION` instead of a `__new__` which always fails for a `#[pyclass]` without a `#[new]` on Python 3.10 and up. [#4568](https://github.com/PyO3/pyo3/pull/4568) +- `PyModule::from_code` now defaults `file_name` to `` if empty. [#4777](https://github.com/PyO3/pyo3/pull/4777) +- Deprecate `PyString::from_object` in favour of `PyString::from_encoded_object`. [#5017](https://github.com/PyO3/pyo3/pull/5017) +- When building with `abi3` for a Python version newer than pyo3 supports, automatically fall back to an abi3 build for the latest supported version. [#5144](https://github.com/PyO3/pyo3/pull/5144) +- Change `is_instance_of` trait bound from `PyTypeInfo` to `PyTypeCheck`. [#5146](https://github.com/PyO3/pyo3/pull/5146) +- Many PyO3 proc macros now report multiple errors instead of only the first one. [#5159](https://github.com/PyO3/pyo3/pull/5159) +- Change `MutexExt` return type to be an associated type. [#5201](https://github.com/PyO3/pyo3/pull/5201) +- Use `PyCallArgs` for `Py::call` and friends so they're equivalent to their `Bound` counterpart. [#5206](https://github.com/PyO3/pyo3/pull/5206) +- Rename `Python::with_gil` to `Python::attach`. [#5209](https://github.com/PyO3/pyo3/pull/5209) +- Rename `Python::allow_threads` to `Python::detach` [#5221](https://github.com/PyO3/pyo3/pull/5221) +- Deprecate `GILOnceCell` type in favour of `PyOnceLock`. [#5223](https://github.com/PyO3/pyo3/pull/5223) +- Rename `pyo3::prepare_freethreaded_python` to `Python::initialize`. [#5247](https://github.com/PyO3/pyo3/pull/5247) +- Convert `PyMemoryError` into/from `io::ErrorKind::OutOfMemory`. [#5256](https://github.com/PyO3/pyo3/pull/5256) +- Deprecate `GILProtected`. [#5285](https://github.com/PyO3/pyo3/pull/5285) +- Move `#[pyclass]` docstring formatting from import time to compile time. [#5286](https://github.com/PyO3/pyo3/pull/5286) +- `Python::attach` will now panic if the Python interpreter is in the process of shutting down. [#5317](https://github.com/PyO3/pyo3/pull/5317) +- Add fast-path to `PyTypeInfo::type_object` for `#[pyclass]` types. [#5324](https://github.com/PyO3/pyo3/pull/5324) +- Deprecate `PyObject` type alias for `Py`. [#5325](https://github.com/PyO3/pyo3/pull/5325) +- Rename `Python::with_gil_unchecked` to `Python::attach_unchecked`. [#5340](https://github.com/PyO3/pyo3/pull/5340) +- Rename `Python::assume_gil_acquired` to `Python::assume_attached`. [#5354](https://github.com/PyO3/pyo3/pull/5354) + +### Removed + +- Remove FFI definition of internals of `PyFrameObject`. [#5154](https://github.com/PyO3/pyo3/pull/5154) +- Remove `Eq` and `PartialEq` implementations on `PyGetSetDef` FFI definition. [#5196](https://github.com/PyO3/pyo3/pull/5196) +- Remove private FFI definitions `_Py_IsCoreInitialized` and `_Py_InitializeMain`. [#5317](https://github.com/PyO3/pyo3/pull/5317) + +### Fixed + +- Use critical section in `PyByteArray::to_vec` on freethreaded build to replicate GIL-enabled "soundness". [#4742](https://github.com/PyO3/pyo3/pull/4742) +- Fix precision loss when converting `bigdecimal` into Python. [#5198](https://github.com/PyO3/pyo3/pull/5198) +- Don't treat win7 target as a cross-compilation. [#5210](https://github.com/PyO3/pyo3/pull/5210) +- WASM targets no longer require exception handling support for Python < 3.14. [#5239](https://github.com/PyO3/pyo3/pull/5239) +- Fix segfault when dropping `PyBuffer` after the Python interpreter has been finalized. [#5242](https://github.com/PyO3/pyo3/pull/5242) +- `experimental-inspect`: better automated imports generation. [#5251](https://github.com/PyO3/pyo3/pull/5251) +- `experimental-inspect`: fix introspection of `__richcmp__`, `__concat__`, `__repeat__`, `__inplace_concat__` and `__inplace_repeat__`. [#5273](https://github.com/PyO3/pyo3/pull/5273) +- fixed a leaked borrow, when converting a mutable sub class into a frozen base class using `PyRef::into_super` [#5281](https://github.com/PyO3/pyo3/pull/5281) +- Fix FFI definition `Py_Exit` (never returns, was `()` return value, now `!`). [#5317](https://github.com/PyO3/pyo3/pull/5317) +- `experimental-inspect`: fix handling of module members gated behind `#[cfg(...)]` attributes. [#5318](https://github.com/PyO3/pyo3/pull/5318) + +## [0.25.1] - 2025-06-12 +### Packaging + +- Add support for Windows on ARM64. [#5145](https://github.com/PyO3/pyo3/pull/5145) +- Add `chrono-local` feature for optional conversions for chrono's `Local` timezone & `DateTime` instances. [#5174](https://github.com/PyO3/pyo3/pull/5174) + +### Added + +- Add FFI definition `PyBytes_AS_STRING`. [#5121](https://github.com/PyO3/pyo3/pull/5121) +- Add support for module associated consts introspection. [#5150](https://github.com/PyO3/pyo3/pull/5150) + +### Changed + +- Enable "vectorcall" FFI definitions on GraalPy. [#5121](https://github.com/PyO3/pyo3/pull/5121) +- Use `Py_Is` function on GraalPy [#5121](https://github.com/PyO3/pyo3/pull/5121) + +### Fixed + +- Report a better compile error for `async` declarations when not using `experimental-async` feature. [#5156](https://github.com/PyO3/pyo3/pull/5156) +- Fix implementation of `FromPyObject` for `uuid::Uuid` on big-endian architectures. [#5161](https://github.com/PyO3/pyo3/pull/5161) +- Fix segmentation faults on 32-bit x86 with Python 3.14. [#5180](https://github.com/PyO3/pyo3/pull/5180) + +## [0.25.0] - 2025-05-14 + +### Packaging + +- Support Python 3.14.0b1. [#4811](https://github.com/PyO3/pyo3/pull/4811) +- Bump supported GraalPy version to 24.2. [#5116](https://github.com/PyO3/pyo3/pull/5116) +- Add optional `bigdecimal` dependency to add conversions for `bigdecimal::BigDecimal`. [#5011](https://github.com/PyO3/pyo3/pull/5011) +- Add optional `time` dependency to add conversions for `time` types. [#5057](https://github.com/PyO3/pyo3/pull/5057) +- Remove `cfg-if` dependency. [#5110](https://github.com/PyO3/pyo3/pull/5110) +- Add optional `ordered_float` dependency to add conversions for `ordered_float::NotNan` and `ordered_float::OrderedFloat`. [#5114](https://github.com/PyO3/pyo3/pull/5114) + +### Added + +- Add initial type stub generation to the `experimental-inspect` feature. [#3977](https://github.com/PyO3/pyo3/pull/3977) +- Add `#[pyclass(generic)]` option to support runtime generic typing. [#4926](https://github.com/PyO3/pyo3/pull/4926) +- Implement `OnceExt` & `MutexExt` for `parking_lot` & `lock_api`. Use the new extension traits by enabling the `arc_lock`, `lock_api`, or `parking_lot` cargo features. [#5044](https://github.com/PyO3/pyo3/pull/5044) +- Implement `From`/`Into` for `Borrowed` -> `Py`. [#5054](https://github.com/PyO3/pyo3/pull/5054) +- Add `PyTzInfo` constructors. [#5055](https://github.com/PyO3/pyo3/pull/5055) +- Add FFI definition `PY_INVALID_STACK_EFFECT`. [#5064](https://github.com/PyO3/pyo3/pull/5064) +- Implement `AsRef>` for `Py`, `Bound` and `Borrowed`. [#5071](https://github.com/PyO3/pyo3/pull/5071) +- Add FFI definition `PyModule_Add` and `compat::PyModule_Add`. [#5085](https://github.com/PyO3/pyo3/pull/5085) +- Add FFI definitions `Py_HashBuffer`, `Py_HashPointer`, and `PyObject_GenericHash`. [#5086](https://github.com/PyO3/pyo3/pull/5086) +- Support `#[pymodule_export]` on `const` items in declarative modules. [#5096](https://github.com/PyO3/pyo3/pull/5096) +- Add `#[pyclass(immutable_type)]` option (on Python 3.14+ with `abi3`, or 3.10+ otherwise) for immutable type objects. [#5101](https://github.com/PyO3/pyo3/pull/5101) +- Support `#[pyo3(rename_all)]` support on `#[derive(IntoPyObject)]`. [#5112](https://github.com/PyO3/pyo3/pull/5112) +- Add `PyRange` wrapper. [#5117](https://github.com/PyO3/pyo3/pull/5117) + +### Changed + +- Enable use of `datetime` types with `abi3` feature enabled. [#4970](https://github.com/PyO3/pyo3/pull/4970) +- Deprecate `timezone_utc` in favor of `PyTzInfo::utc`. [#5055](https://github.com/PyO3/pyo3/pull/5055) +- Reduce visibility of some CPython implementation details: [#5064](https://github.com/PyO3/pyo3/pull/5064) + - The FFI definition `PyCodeObject` is now an opaque struct on all Python versions. + - The FFI definition `PyFutureFeatures` is now only defined up until Python 3.10 (it was present in CPython headers but unused in 3.11 and 3.12). +- Change `PyAnyMethods::is` to take `other: &Bound`. [#5071](https://github.com/PyO3/pyo3/pull/5071) +- Change `Py::is` to take `other: &Py`. [#5071](https://github.com/PyO3/pyo3/pull/5071) +- Change `PyVisit::call` to take `T: Into>>`. [#5071](https://github.com/PyO3/pyo3/pull/5071) +- Expose `PyDateTime_DATE_GET_TZINFO` and `PyDateTime_TIME_GET_TZINFO` on PyPy 3.10 and later. [#5079](https://github.com/PyO3/pyo3/pull/5079) +- Add `#[track_caller]` to `with_gil` and `with_gil_unchecked`. [#5109](https://github.com/PyO3/pyo3/pull/5109) +- Use `std::thread::park()` instead of `libc::pause()` or `sleep(9999999)`. [#5115](https://github.com/PyO3/pyo3/pull/5115) + +### Removed + +- Remove all functionality deprecated in PyO3 0.23. [#4982](https://github.com/PyO3/pyo3/pull/4982) +- Remove deprecated `IntoPy` and `ToPyObject` traits. [#5010](https://github.com/PyO3/pyo3/pull/5010) +- Remove private types from `pyo3-ffi` (i.e. starting with `_Py`) which are not referenced by public APIs: `_PyLocalMonitors`, `_Py_GlobalMonitors`, `_PyCoCached`, `_PyCoLineInstrumentationData`, `_PyCoMonitoringData`, `_PyCompilerSrcLocation`, `_PyErr_StackItem`. [#5064](https://github.com/PyO3/pyo3/pull/5064) +- Remove FFI definition `PyCode_GetNumFree` (PyO3 cannot support it due to knowledge of the code object). [#5064](https://github.com/PyO3/pyo3/pull/5064) +- Remove `AsPyPointer` trait. [#5071](https://github.com/PyO3/pyo3/pull/5071) +- Remove support for the deprecated string form of `from_py_with`. [#5097](https://github.com/PyO3/pyo3/pull/5097) +- Remove FFI definitions of private static variables: `_PyMethodWrapper_Type`, `_PyCoroWrapper_Type`, `_PyImport_FrozenBootstrap`, `_PyImport_FrozenStdlib`, `_PyImport_FrozenTest`, `_PyManagedBuffer_Type`, `_PySet_Dummy`, `_PyWeakref_ProxyType`, and `_PyWeakref_CallableProxyType`. [#5105](https://github.com/PyO3/pyo3/pull/5105) +- Remove FFI definitions `PyASCIIObjectState`, `PyUnicode_IS_ASCII`, `PyUnicode_IS_COMPACT`, and `PyUnicode_IS_COMPACT_ASCII` on Python 3.14 and newer. [#5133](https://github.com/PyO3/pyo3/pull/5133) + +### Fixed + +- Correctly pick up the shared state for conda-based Python installation when reading information from sysconfigdata. [#5037](https://github.com/PyO3/pyo3/pull/5037) +- Fix compile failure with `#[derive(IntoPyObject, FromPyObject)]` when using `#[pyo3()]` options recognised by only one of the two derives. [#5070](https://github.com/PyO3/pyo3/pull/5070) +- Fix various compile errors from missing FFI definitions using certain feature combinations on PyPy and GraalPy. [#5091](https://github.com/PyO3/pyo3/pull/5091) +- Fallback on `backports.zoneinfo` for python <3.9 when converting timezones into python. [#5120](https://github.com/PyO3/pyo3/pull/5120) + +## [0.24.2] - 2025-04-21 + +### Fixed + +- Fix `unused_imports` lint of `#[pyfunction]` and `#[pymethods]` expanded in `macro_rules` context. [#5030](https://github.com/PyO3/pyo3/pull/5030) +- Fix size of `PyCodeObject::_co_instrumentation_version` ffi struct member on Python 3.13 for systems where `uintptr_t` is not 64 bits. [#5048](https://github.com/PyO3/pyo3/pull/5048) +- Fix struct-type complex enum variant fields incorrectly exposing raw identifiers as `r#ident` in Python bindings. [#5050](https://github.com/PyO3/pyo3/pull/5050) + +## [0.24.1] - 2025-03-31 + +### Added + +- Add `abi3-py313` feature. [#4969](https://github.com/PyO3/pyo3/pull/4969) +- Add `PyAnyMethods::getattr_opt`. [#4978](https://github.com/PyO3/pyo3/pull/4978) +- Add `PyInt::new` constructor for all supported number types (i32, u32, i64, u64, isize, usize). [#4984](https://github.com/PyO3/pyo3/pull/4984) +- Add `pyo3::sync::with_critical_section2`. [#4992](https://github.com/PyO3/pyo3/pull/4992) +- Implement `PyCallArgs` for `Borrowed<'_, 'py, PyTuple>`, `&Bound<'py, PyTuple>`, and `&Py`. [#5013](https://github.com/PyO3/pyo3/pull/5013) + +### Fixed + +- Fix `is_type_of` for native types not using same specialized check as `is_type_of_bound`. [#4981](https://github.com/PyO3/pyo3/pull/4981) +- Fix `Probe` class naming issue with `#[pymethods]`. [#4988](https://github.com/PyO3/pyo3/pull/4988) +- Fix compile failure with required `#[pyfunction]` arguments taking `Option<&str>` and `Option<&T>` (for `#[pyclass]` types). [#5002](https://github.com/PyO3/pyo3/pull/5002) +- Fix `PyString::from_object` causing of bounds reads with `encoding` and `errors` parameters which are not nul-terminated. [#5008](https://github.com/PyO3/pyo3/pull/5008) +- Fix compile error when additional options follow after `crate` for `#[pyfunction]`. [#5015](https://github.com/PyO3/pyo3/pull/5015) + +## [0.24.0] - 2025-03-09 + +### Packaging + +- Add supported CPython/PyPy versions to cargo package metadata. [#4756](https://github.com/PyO3/pyo3/pull/4756) +- Bump `target-lexicon` dependency to 0.13. [#4822](https://github.com/PyO3/pyo3/pull/4822) +- Add optional `jiff` dependency to add conversions for `jiff` datetime types. [#4823](https://github.com/PyO3/pyo3/pull/4823) +- Add optional `uuid` dependency to add conversions for `uuid::Uuid`. [#4864](https://github.com/PyO3/pyo3/pull/4864) +- Bump minimum supported `inventory` version to 0.3.5. [#4954](https://github.com/PyO3/pyo3/pull/4954) + +### Added + +- Add `PyIterator::send` method to allow sending values into a python generator. [#4746](https://github.com/PyO3/pyo3/pull/4746) +- Add `PyCallArgs` trait for passing arguments into the Python calling protocol. This enabled using a faster calling convention for certain types, improving performance. [#4768](https://github.com/PyO3/pyo3/pull/4768) +- Add `#[pyo3(default = ...']` option for `#[derive(FromPyObject)]` to set a default value for extracted fields of named structs. [#4829](https://github.com/PyO3/pyo3/pull/4829) +- Add `#[pyo3(into_py_with = ...)]` option for `#[derive(IntoPyObject, IntoPyObjectRef)]`. [#4850](https://github.com/PyO3/pyo3/pull/4850) +- Add FFI definitions `PyThreadState_GetFrame` and `PyFrame_GetBack`. [#4866](https://github.com/PyO3/pyo3/pull/4866) +- Optimize `last` for `BoundListIterator`, `BoundTupleIterator` and `BorrowedTupleIterator`. [#4878](https://github.com/PyO3/pyo3/pull/4878) +- Optimize `Iterator::count()` for `PyDict`, `PyList`, `PyTuple` & `PySet`. [#4878](https://github.com/PyO3/pyo3/pull/4878) +- Optimize `nth`, `nth_back`, `advance_by` and `advance_back_by` for `BoundTupleIterator` [#4897](https://github.com/PyO3/pyo3/pull/4897) +- Add support for `types.GenericAlias` as `pyo3::types::PyGenericAlias`. [#4917](https://github.com/PyO3/pyo3/pull/4917) +- Add `MutextExt` trait to help avoid deadlocks with the GIL while locking a `std::sync::Mutex`. [#4934](https://github.com/PyO3/pyo3/pull/4934) +- Add `#[pyo3(rename_all = "...")]` option for `#[derive(FromPyObject)]`. [#4941](https://github.com/PyO3/pyo3/pull/4941) + +### Changed + +- Optimize `nth`, `nth_back`, `advance_by` and `advance_back_by` for `BoundListIterator`. [#4810](https://github.com/PyO3/pyo3/pull/4810) +- Use `DerefToPyAny` in blanket implementations of `From>` and `From>` for `PyObject`. [#4593](https://github.com/PyO3/pyo3/pull/4593) +- Map `io::ErrorKind::IsADirectory`/`NotADirectory` to the corresponding Python exception on Rust 1.83+. [#4747](https://github.com/PyO3/pyo3/pull/4747) +- `PyAnyMethods::call` and friends now require `PyCallArgs` for their positional arguments. [#4768](https://github.com/PyO3/pyo3/pull/4768) +- Expose FFI definitions for `PyObject_Vectorcall(Method)` on the stable abi on 3.12+. [#4853](https://github.com/PyO3/pyo3/pull/4853) +- `#[pyo3(from_py_with = ...)]` now take a path rather than a string literal [#4860](https://github.com/PyO3/pyo3/pull/4860) +- Format Python traceback in impl Debug for PyErr. [#4900](https://github.com/PyO3/pyo3/pull/4900) +- Convert `PathBuf` & `Path` into Python `pathlib.Path` instead of `PyString`. [#4925](https://github.com/PyO3/pyo3/pull/4925) +- Relax parsing of exotic Python versions. [#4949](https://github.com/PyO3/pyo3/pull/4949) +- PyO3 threads now hang instead of `pthread_exit` trying to acquire the GIL when the interpreter is shutting down. This mimics the [Python 3.14](https://github.com/python/cpython/issues/87135) behavior and avoids undefined behavior and crashes. [#4874](https://github.com/PyO3/pyo3/pull/4874) + +### Removed + +- Remove implementations of `Deref` for `PyAny` and other "native" types. [#4593](https://github.com/PyO3/pyo3/pull/4593) +- Remove implicit default of trailing optional arguments (see #2935) [#4729](https://github.com/PyO3/pyo3/pull/4729) +- Remove the deprecated implicit eq fallback for simple enums. [#4730](https://github.com/PyO3/pyo3/pull/4730) + +### Fixed + +- Correct FFI definition of `PyIter_Send` to return a `PySendResult`. [#4746](https://github.com/PyO3/pyo3/pull/4746) +- Fix a thread safety issue in the runtime borrow checker used by mutable pyclass instances on the free-threaded build. [#4948](https://github.com/PyO3/pyo3/pull/4948) + + +## [0.23.5] - 2025-02-22 + +### Packaging + +- Add support for PyPy3.11 [#4760](https://github.com/PyO3/pyo3/pull/4760) + +### Fixed + +- Fix thread-unsafe implementation of freelist pyclasses on the free-threaded build. [#4902](https://github.com/PyO3/pyo3/pull/4902) +- Re-enable a workaround for situations where CPython incorrectly does not add `__builtins__` to `__globals__` in code executed by `Python::py_run` (was removed in PyO3 0.23.0). [#4921](https://github.com/PyO3/pyo3/pull/4921) + +## [0.23.4] - 2025-01-10 + +### Added + +- Add `PyList::locked_for_each`, which uses a critical section to lock the list on the free-threaded build. [#4789](https://github.com/PyO3/pyo3/pull/4789) +- Add `pyo3_build_config::add_python_framework_link_args` build script API to set rpath when using macOS system Python. [#4833](https://github.com/PyO3/pyo3/pull/4833) + +### Changed + +- Use `datetime.fold` to distinguish ambiguous datetimes when converting to and from `chrono::DateTime` (rather than erroring). [#4791](https://github.com/PyO3/pyo3/pull/4791) +- Optimize PyList iteration on the free-threaded build. [#4789](https://github.com/PyO3/pyo3/pull/4789) + +### Fixed + +- Fix unnecessary internal `py.allow_threads` GIL-switch when attempting to access contents of a `PyErr` which originated from Python (could lead to unintended deadlocks). [#4766](https://github.com/PyO3/pyo3/pull/4766) +- Fix thread-unsafe access of dict internals in `BoundDictIterator` on the free-threaded build. [#4788](https://github.com/PyO3/pyo3/pull/4788) +* Fix unnecessary critical sections in `BoundDictIterator` on the free-threaded build. [#4788](https://github.com/PyO3/pyo3/pull/4788) +- Fix time-of-check to time-of-use issues with list iteration on the free-threaded build. [#4789](https://github.com/PyO3/pyo3/pull/4789) +- Fix `chrono::DateTime` to-Python conversion when `Tz` is `chrono_tz::Tz`. [#4790](https://github.com/PyO3/pyo3/pull/4790) +- Fix `#[pyclass]` not being able to be named `Probe`. [#4794](https://github.com/PyO3/pyo3/pull/4794) +- Fix not treating cross-compilation from x64 to aarch64 on Windows as a cross-compile. [#4800](https://github.com/PyO3/pyo3/pull/4800) +- Fix missing struct fields on GraalPy when subclassing builtin classes. [#4802](https://github.com/PyO3/pyo3/pull/4802) +- Fix generating import lib for PyPy when `abi3` feature is enabled. [#4806](https://github.com/PyO3/pyo3/pull/4806) +- Fix generating import lib for python3.13t when `abi3` feature is enabled. [#4808](https://github.com/PyO3/pyo3/pull/4808) +- Fix compile failure for raw identifiers like `r#box` in `derive(FromPyObject)`. [#4814](https://github.com/PyO3/pyo3/pull/4814) +- Fix compile failure for `#[pyclass]` enum variants with more than 12 fields. [#4832](https://github.com/PyO3/pyo3/pull/4832) + + +## [0.23.3] - 2024-12-03 + +### Packaging + +- Bump optional `python3-dll-a` dependency to 0.2.11. [#4749](https://github.com/PyO3/pyo3/pull/4749) + +### Fixed + +- Fix unresolved symbol link failures on Windows when compiling for Python 3.13t with `abi3` features enabled. [#4733](https://github.com/PyO3/pyo3/pull/4733) +- Fix unresolved symbol link failures on Windows when compiling for Python 3.13t using the `generate-import-lib` feature. [#4749](https://github.com/PyO3/pyo3/pull/4749) +- Fix compile-time regression in PyO3 0.23.0 where changing `PYO3_CONFIG_FILE` would not reconfigure PyO3 for the new interpreter. [#4758](https://github.com/PyO3/pyo3/pull/4758) + +## [0.23.2] - 2024-11-25 + +### Added + +- Add `IntoPyObjectExt` trait. [#4708](https://github.com/PyO3/pyo3/pull/4708) + +### Fixed + +- Fix compile failures when building for free-threaded Python when the `abi3` or `abi3-pyxx` features are enabled. [#4719](https://github.com/PyO3/pyo3/pull/4719) +- Fix `ambiguous_associated_items` lint error in `#[pyclass]` and `#[derive(IntoPyObject)]` macros. [#4725](https://github.com/PyO3/pyo3/pull/4725) + + +## [0.23.1] - 2024-11-16 + +Re-release of 0.23.0 with fixes to docs.rs build. + +## [0.23.0] - 2024-11-15 + +### Packaging + +- Drop support for PyPy 3.7 and 3.8. [#4582](https://github.com/PyO3/pyo3/pull/4582) +- Extend range of supported versions of `hashbrown` optional dependency to include version 0.15. [#4604](https://github.com/PyO3/pyo3/pull/4604) +- Bump minimum version of `eyre` optional dependency to 0.6.8. [#4617](https://github.com/PyO3/pyo3/pull/4617) +- Bump minimum version of `hashbrown` optional dependency to 0.14.5. [#4617](https://github.com/PyO3/pyo3/pull/4617) +- Bump minimum version of `indexmap` optional dependency to 2.5.0. [#4617](https://github.com/PyO3/pyo3/pull/4617) +- Bump minimum version of `num-complex` optional dependency to 0.4.6. [#4617](https://github.com/PyO3/pyo3/pull/4617) +- Bump minimum version of `chrono-tz` optional dependency to 0.10. [#4617](https://github.com/PyO3/pyo3/pull/4617) +- Support free-threaded Python 3.13t. [#4588](https://github.com/PyO3/pyo3/pull/4588) + +### Added + +- Add `IntoPyObject` (fallible) conversion trait to convert from Rust to Python values. [#4060](https://github.com/PyO3/pyo3/pull/4060) +- Add `#[pyclass(str="")]` option to generate `__str__` based on a `Display` implementation or format string. [#4233](https://github.com/PyO3/pyo3/pull/4233) +- Implement `PartialEq` for `Bound<'py, PyInt>` with `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`, `i64`, `i128` and `isize`. [#4317](https://github.com/PyO3/pyo3/pull/4317) +- Implement `PartialEq` and `PartialEq` for `Bound<'py, PyFloat>`. [#4348](https://github.com/PyO3/pyo3/pull/4348) +- Add `as_super` and `into_super` methods for `Bound`. [#4351](https://github.com/PyO3/pyo3/pull/4351) +- Add FFI definitions `PyCFunctionFast` and `PyCFunctionFastWithKeywords` [#4415](https://github.com/PyO3/pyo3/pull/4415) +- Add FFI definitions for `PyMutex` on Python 3.13 and newer. [#4421](https://github.com/PyO3/pyo3/pull/4421) +- Add `PyDict::locked_for_each` to iterate efficiently on freethreaded Python. [#4439](https://github.com/PyO3/pyo3/pull/4439) +- Add FFI definitions `PyObject_GetOptionalAttr`, `PyObject_GetOptionalAttrString`, `PyObject_HasAttrWithError`, `PyObject_HasAttrStringWithError`, `Py_CONSTANT_*` constants, `Py_GetConstant`, `Py_GetConstantBorrowed`, and `PyType_GetModuleByDef` on Python 3.13 and newer. [#4447](https://github.com/PyO3/pyo3/pull/4447) +- Add FFI definitions for the Python critical section API available on Python 3.13 and newer. [#4477](https://github.com/PyO3/pyo3/pull/4477) +- Add derive macro for `IntoPyObject`. [#4495](https://github.com/PyO3/pyo3/pull/4495) +- Add `Borrowed::as_ptr`. [#4520](https://github.com/PyO3/pyo3/pull/4520) +- Add FFI definition for `PyImport_AddModuleRef`. [#4529](https://github.com/PyO3/pyo3/pull/4529) +- Add `PyAnyMethods::try_iter`. [#4553](https://github.com/PyO3/pyo3/pull/4553) +- Add `pyo3::sync::with_critical_section`, a wrapper around the Python Critical Section API added in Python 3.13. [#4587](https://github.com/PyO3/pyo3/pull/4587) +- Add `#[pymodule(gil_used = false)]` option to declare that a module supports the free-threaded build. [#4588](https://github.com/PyO3/pyo3/pull/4588) +- Add `PyModule::gil_used` method to declare that a module supports the free-threaded build. [#4588](https://github.com/PyO3/pyo3/pull/4588) +- Add FFI definition `PyDateTime_CAPSULE_NAME`. [#4634](https://github.com/PyO3/pyo3/pull/4634) +- Add `PyMappingProxy` type to represent the `mappingproxy` Python class. [#4644](https://github.com/PyO3/pyo3/pull/4644) +- Add FFI definitions `PyList_Extend` and `PyList_Clear`. [#4667](https://github.com/PyO3/pyo3/pull/4667) +- Add derive macro for `IntoPyObjectRef`. [#4674](https://github.com/PyO3/pyo3/pull/4674) +- Add `pyo3::sync::OnceExt` and `pyo3::sync::OnceLockExt` traits. [#4676](https://github.com/PyO3/pyo3/pull/4676) + +### Changed + +- Prefer `IntoPyObject` over `IntoPy>>` for `#[pyfunction]` and `#[pymethods]` return types. [#4060](https://github.com/PyO3/pyo3/pull/4060) +- Report multiple errors from `#[pyclass]` and `#[pyo3(..)]` attributes. [#4243](https://github.com/PyO3/pyo3/pull/4243) +- Nested declarative `#[pymodule]` are automatically treated as submodules (no `PyInit_` entrypoint is created). [#4308](https://github.com/PyO3/pyo3/pull/4308) +- Deprecate `PyAnyMethods::is_ellipsis` (`Py::is_ellipsis` was deprecated in PyO3 0.20). [#4322](https://github.com/PyO3/pyo3/pull/4322) +- Deprecate `PyLong` in favor of `PyInt`. [#4347](https://github.com/PyO3/pyo3/pull/4347) +- Rename `IntoPyDict::into_py_dict_bound` to `IntoPyDict::into_py_dict`. [#4388](https://github.com/PyO3/pyo3/pull/4388) +- `PyModule::from_code` now expects `&CStr` as arguments instead of `&str`. [#4404](https://github.com/PyO3/pyo3/pull/4404) +- Use "fastcall" Python calling convention for `#[pyfunction]`s when compiling on abi3 for Python 3.10 and up. [#4415](https://github.com/PyO3/pyo3/pull/4415) +- Remove `Copy` and `Clone` from `PyObject` struct FFI definition. [#4434](https://github.com/PyO3/pyo3/pull/4434) +- `Python::eval` and `Python::run` now take a `&CStr` instead of `&str`. [#4435](https://github.com/PyO3/pyo3/pull/4435) +- Deprecate `IPowModulo`, `PyClassAttributeDef`, `PyGetterDef`, `PyMethodDef`, `PyMethodDefType`, and `PySetterDef` from PyO3's public API. [#4441](https://github.com/PyO3/pyo3/pull/4441) +- `IntoPyObject` impls for `Vec`, `&[u8]`, `[u8; N]`, `Cow<[u8]>` and `SmallVec<[u8; N]>` now convert into Python `bytes` rather than a `list` of integers. [#4442](https://github.com/PyO3/pyo3/pull/4442) +- Emit a compile-time error when attempting to subclass a class that doesn't allow subclassing. [#4453](https://github.com/PyO3/pyo3/pull/4453) +- `IntoPyDict::into_py_dict` is now fallible due to `IntoPyObject` migration. [#4493](https://github.com/PyO3/pyo3/pull/4493) +- The `abi3` feature will now override config files provided via `PYO3_BUILD_CONFIG`. [#4497](https://github.com/PyO3/pyo3/pull/4497) +- Disable the `GILProtected` struct on free-threaded Python. [#4504](https://github.com/PyO3/pyo3/pull/4504) +- Updated FFI definitions for functions and struct fields that have been deprecated or removed from CPython. [#4534](https://github.com/PyO3/pyo3/pull/4534) +- Disable `PyListMethods::get_item_unchecked` on free-threaded Python. [#4539](https://github.com/PyO3/pyo3/pull/4539) +- Add `GILOnceCell::import`. [#4542](https://github.com/PyO3/pyo3/pull/4542) +- Deprecate `PyAnyMethods::iter` in favour of `PyAnyMethods::try_iter`. [#4553](https://github.com/PyO3/pyo3/pull/4553) +- The `#[pyclass]` macro now requires a types to be `Sync`. (Except for `#[pyclass(unsendable)]` types). [#4566](https://github.com/PyO3/pyo3/pull/4566) +- `PyList::new` and `PyTuple::new` are now fallible due to `IntoPyObject` migration. [#4580](https://github.com/PyO3/pyo3/pull/4580) +- `PyErr::matches` is now fallible due to `IntoPyObject` migration. [#4595](https://github.com/PyO3/pyo3/pull/4595) +- Deprecate `ToPyObject` in favour of `IntoPyObject` [#4595](https://github.com/PyO3/pyo3/pull/4595) +- Deprecate `PyWeakrefMethods::get_option`. [#4597](https://github.com/PyO3/pyo3/pull/4597) +- Seal `PyWeakrefMethods` trait. [#4598](https://github.com/PyO3/pyo3/pull/4598) +- Remove `PyNativeTypeInitializer` and `PyObjectInit` from the PyO3 public API. [#4611](https://github.com/PyO3/pyo3/pull/4611) +- Deprecate `IntoPy` in favor of `IntoPyObject` [#4618](https://github.com/PyO3/pyo3/pull/4618) +- Eagerly normalize exceptions in `PyErr::take()` and `PyErr::fetch()` on Python 3.11 and older. [#4655](https://github.com/PyO3/pyo3/pull/4655) +- Move `IntoPy::type_output` to `IntoPyObject::type_output`. [#4657](https://github.com/PyO3/pyo3/pull/4657) +- Change return type of `PyMapping::keys`, `PyMapping::values` and `PyMapping::items` to `Bound<'py, PyList>` instead of `Bound<'py, PySequence>`. [#4661](https://github.com/PyO3/pyo3/pull/4661) +- Complex enums now allow field types that either implement `IntoPyObject` by reference or by value together with `Clone`. This makes `Py` available as field type. [#4694](https://github.com/PyO3/pyo3/pull/4694) + + +### Removed + +- Remove all functionality deprecated in PyO3 0.20. [#4322](https://github.com/PyO3/pyo3/pull/4322) +- Remove all functionality deprecated in PyO3 0.21. [#4323](https://github.com/PyO3/pyo3/pull/4323) +- Deprecate `PyUnicode` in favour of `PyString`. [#4370](https://github.com/PyO3/pyo3/pull/4370) +- Remove deprecated `gil-refs` feature. [#4378](https://github.com/PyO3/pyo3/pull/4378) +- Remove private FFI definitions `_Py_IMMORTAL_REFCNT`, `_Py_IsImmortal`, `_Py_TPFLAGS_STATIC_BUILTIN`, `_Py_Dealloc`, `_Py_IncRef`, `_Py_DecRef`. [#4447](https://github.com/PyO3/pyo3/pull/4447) +- Remove private FFI definitions `_Py_c_sum`, `_Py_c_diff`, `_Py_c_neg`, `_Py_c_prod`, `_Py_c_quot`, `_Py_c_pow`, `_Py_c_abs`. [#4521](https://github.com/PyO3/pyo3/pull/4521) +- Remove `_borrowed` methods of `PyWeakRef` and `PyWeakRefProxy`. [#4528](https://github.com/PyO3/pyo3/pull/4528) +- Removed private FFI definition `_PyErr_ChainExceptions`. [#4534](https://github.com/PyO3/pyo3/pull/4534) + +### Fixed + +- Fix invalid library search path `lib_dir` when cross-compiling. [#4389](https://github.com/PyO3/pyo3/pull/4389) +- Fix FFI definition `Py_Is` for PyPy on 3.10 to call the function defined by PyPy. [#4447](https://github.com/PyO3/pyo3/pull/4447) +- Fix compile failure when using `#[cfg]` attributes for simple enum variants. [#4509](https://github.com/PyO3/pyo3/pull/4509) +- Fix compiler warning for `non_snake_case` method names inside `#[pymethods]` generated code. [#4567](https://github.com/PyO3/pyo3/pull/4567) +- Fix compile error with `#[derive(FromPyObject)]` generic struct with trait bounds. [#4645](https://github.com/PyO3/pyo3/pull/4645) +- Fix compile error for `#[classmethod]` and `#[staticmethod]` on magic methods. [#4654](https://github.com/PyO3/pyo3/pull/4654) +- Fix compile warning for `unsafe_op_in_unsafe_fn` in generated macro code. [#4674](https://github.com/PyO3/pyo3/pull/4674) +- Fix incorrect deprecation warning for `#[pyclass] enum`s with custom `__eq__` implementation. [#4692](https://github.com/PyO3/pyo3/pull/4692) +- Fix `non_upper_case_globals` lint firing for generated `__match_args__` on complex enums. [#4705](https://github.com/PyO3/pyo3/pull/4705) + +## [0.22.5] - 2024-10-15 + +### Fixed + +- Fix regression in 0.22.4 of naming collision in `__clear__` slot and `clear` method generated code. [#4619](https://github.com/PyO3/pyo3/pull/4619) + + +## [0.22.4] - 2024-10-12 + +### Added + +- Add FFI definition `PyWeakref_GetRef` and `compat::PyWeakref_GetRef`. [#4528](https://github.com/PyO3/pyo3/pull/4528) + +### Changed + +- Deprecate `_borrowed` methods on `PyWeakRef` and `PyWeakrefProxy` (just use the owning forms). [#4590](https://github.com/PyO3/pyo3/pull/4590) + +### Fixed + +- Revert removal of private FFI function `_PyLong_NumBits` on Python 3.13 and later. [#4450](https://github.com/PyO3/pyo3/pull/4450) +- Fix `__traverse__` functions for base classes not being called by subclasses created with `#[pyclass(extends = ...)]`. [#4563](https://github.com/PyO3/pyo3/pull/4563) +- Fix regression in 0.22.3 failing compiles under `#![forbid(unsafe_code)]`. [#4574](https://github.com/PyO3/pyo3/pull/4574) +- Fix `create_exception` macro triggering lint and compile errors due to interaction with `gil-refs` feature. [#4589](https://github.com/PyO3/pyo3/pull/4589) +- Workaround possible use-after-free in `_borrowed` methods on `PyWeakRef` and `PyWeakrefProxy` by leaking their contents. [#4590](https://github.com/PyO3/pyo3/pull/4590) +- Fix crash calling `PyType_GetSlot` on static types before Python 3.10. [#4599](https://github.com/PyO3/pyo3/pull/4599) + + +## [0.22.3] - 2024-09-15 + +### Added + +- Add `pyo3::ffi::compat` namespace with compatibility shims for C API functions added in recent versions of Python. +- Add FFI definition `PyDict_GetItemRef` on Python 3.13 and newer, and `compat::PyDict_GetItemRef` for all versions. [#4355](https://github.com/PyO3/pyo3/pull/4355) +- Add FFI definition `PyList_GetItemRef` on Python 3.13 and newer, and `pyo3_ffi::compat::PyList_GetItemRef` for all versions. [#4410](https://github.com/PyO3/pyo3/pull/4410) +- Add FFI definitions `compat::Py_NewRef` and `compat::Py_XNewRef`. [#4445](https://github.com/PyO3/pyo3/pull/4445) +- Add FFI definitions `compat::PyObject_CallNoArgs` and `compat::PyObject_CallMethodNoArgs`. [#4461](https://github.com/PyO3/pyo3/pull/4461) +- Add `GilOnceCell>::clone_ref`. [#4511](https://github.com/PyO3/pyo3/pull/4511) + +### Changed + +- Improve error messages for `#[pyfunction]` defined inside `#[pymethods]`. [#4349](https://github.com/PyO3/pyo3/pull/4349) +- Improve performance of calls to Python by using the vectorcall calling convention where possible. [#4456](https://github.com/PyO3/pyo3/pull/4456) +- Mention the type name in the exception message when trying to instantiate a class with no constructor defined. [#4481](https://github.com/PyO3/pyo3/pull/4481) + +### Removed + +- Remove private FFI definition `_Py_PackageContext`. [#4420](https://github.com/PyO3/pyo3/pull/4420) + +### Fixed + +- Fix compile failure in declarative `#[pymodule]` under presence of `#![no_implicit_prelude]`. [#4328](https://github.com/PyO3/pyo3/pull/4328) +- Fix use of borrowed reference in `PyDict::get_item` (unsafe in free-threaded Python). [#4355](https://github.com/PyO3/pyo3/pull/4355) +- Fix `#[pyclass(eq)]` macro hygiene issues for structs and enums. [#4359](https://github.com/PyO3/pyo3/pull/4359) +- Fix hygiene/span issues of `#[pyfunction]` and `#[pymethods]` generated code which affected expansion in `macro_rules` context. [#4382](https://github.com/PyO3/pyo3/pull/4382) +- Fix `unsafe_code` lint error in `#[pyclass]` generated code. [#4396](https://github.com/PyO3/pyo3/pull/4396) +- Fix async functions returning a tuple only returning the first element to Python. [#4407](https://github.com/PyO3/pyo3/pull/4407) +- Fix use of borrowed reference in `PyList::get_item` (unsafe in free-threaded Python). [#4410](https://github.com/PyO3/pyo3/pull/4410) +- Correct FFI definition `PyArg_ParseTupleAndKeywords` to take `*const *const c_char` instead of `*mut *mut c_char` on Python 3.13 and up. [#4420](https://github.com/PyO3/pyo3/pull/4420) +- Fix a soundness bug with `PyClassInitializer`: panic if adding subclass to existing instance via `PyClassInitializer::from(Py).add_subclass(SubClass)`. [#4454](https://github.com/PyO3/pyo3/pull/4454) +- Fix illegal reference counting op inside implementation of `__traverse__` handlers. [#4479](https://github.com/PyO3/pyo3/pull/4479) + +## [0.22.2] - 2024-07-17 + +### Packaging + +- Require opt-in to freethreaded Python using the `UNSAFE_PYO3_BUILD_FREE_THREADED=1` environment variable (it is not yet supported by PyO3). [#4327](https://github.com/PyO3/pyo3/pull/4327) + +### Changed + +- Use FFI function calls for reference counting on all abi3 versions. [#4324](https://github.com/PyO3/pyo3/pull/4324) +- `#[pymodule(...)]` now directly accepts all relevant `#[pyo3(...)]` options. [#4330](https://github.com/PyO3/pyo3/pull/4330) + +### Fixed + +- Fix compile failure in declarative `#[pymodule]` under presence of `#![no_implicit_prelude]`. [#4328](https://github.com/PyO3/pyo3/pull/4328) +- Fix compile failure due to c-string literals on Rust < 1.79. [#4353](https://github.com/PyO3/pyo3/pull/4353) + +## [0.22.1] - 2024-07-06 + +### Added + +- Add `#[pyo3(submodule)]` option for declarative `#[pymodule]`s. [#4301](https://github.com/PyO3/pyo3/pull/4301) +- Implement `PartialEq` for `Bound<'py, PyBool>`. [#4305](https://github.com/PyO3/pyo3/pull/4305) + +### Fixed + +- Return `NotImplemented` instead of raising `TypeError` from generated equality method when comparing different types. [#4287](https://github.com/PyO3/pyo3/pull/4287) +- Handle full-path `#[pyo3::prelude::pymodule]` and similar for `#[pyclass]` and `#[pyfunction]` in declarative modules. [#4288](https://github.com/PyO3/pyo3/pull/4288) +- Fix 128-bit int regression on big-endian platforms with Python <3.13. [#4291](https://github.com/PyO3/pyo3/pull/4291) +- Stop generating code that will never be covered with declarative modules. [#4297](https://github.com/PyO3/pyo3/pull/4297) +- Fix invalid deprecation warning for trailing optional on `#[setter]` function. [#4304](https://github.com/PyO3/pyo3/pull/4304) + +## [0.22.0] - 2024-06-24 + +### Packaging + +- Update `heck` dependency to 0.5. [#3966](https://github.com/PyO3/pyo3/pull/3966) +- Extend range of supported versions of `chrono-tz` optional dependency to include version 0.10. [#4061](https://github.com/PyO3/pyo3/pull/4061) +- Update MSRV to 1.63. [#4129](https://github.com/PyO3/pyo3/pull/4129) +- Add optional `num-rational` feature to add conversions with Python's `fractions.Fraction`. [#4148](https://github.com/PyO3/pyo3/pull/4148) +- Support Python 3.13. [#4184](https://github.com/PyO3/pyo3/pull/4184) + +### Added + +- Add `PyWeakref`, `PyWeakrefReference` and `PyWeakrefProxy`. [#3835](https://github.com/PyO3/pyo3/pull/3835) +- Support `#[pyclass]` on enums that have tuple variants. [#4072](https://github.com/PyO3/pyo3/pull/4072) +- Add support for scientific notation in `Decimal` conversion. [#4079](https://github.com/PyO3/pyo3/pull/4079) +- Add `pyo3_disable_reference_pool` conditional compilation flag to avoid the overhead of the global reference pool at the cost of known limitations as explained in the performance section of the guide. [#4095](https://github.com/PyO3/pyo3/pull/4095) +- Add `#[pyo3(constructor = (...))]` to customize the generated constructors for complex enum variants. [#4158](https://github.com/PyO3/pyo3/pull/4158) +- Add `PyType::module`, which always matches Python `__module__`. [#4196](https://github.com/PyO3/pyo3/pull/4196) +- Add `PyType::fully_qualified_name` which matches the "fully qualified name" defined in [PEP 737](https://peps.python.org/pep-0737). [#4196](https://github.com/PyO3/pyo3/pull/4196) +- Add `PyTypeMethods::mro` and `PyTypeMethods::bases`. [#4197](https://github.com/PyO3/pyo3/pull/4197) +- Add `#[pyclass(ord)]` to implement ordering based on `PartialOrd`. [#4202](https://github.com/PyO3/pyo3/pull/4202) +- Implement `ToPyObject` and `IntoPy` for `PyBackedStr` and `PyBackedBytes`. [#4205](https://github.com/PyO3/pyo3/pull/4205) +- Add `#[pyclass(hash)]` option to implement `__hash__` in terms of the `Hash` implementation [#4206](https://github.com/PyO3/pyo3/pull/4206) +- Add `#[pyclass(eq)]` option to generate `__eq__` based on `PartialEq`, and `#[pyclass(eq_int)]` for simple enums to implement equality based on their discriminants. [#4210](https://github.com/PyO3/pyo3/pull/4210) +- Implement `From>` for `PyClassInitializer`. [#4214](https://github.com/PyO3/pyo3/pull/4214) +- Add `as_super` methods to `PyRef` and `PyRefMut` for accessing the base class by reference. [#4219](https://github.com/PyO3/pyo3/pull/4219) +- Implement `PartialEq` for `Bound<'py, PyString>`. [#4245](https://github.com/PyO3/pyo3/pull/4245) +- Implement `PyModuleMethods::filename` on PyPy. [#4249](https://github.com/PyO3/pyo3/pull/4249) +- Implement `PartialEq<[u8]>` for `Bound<'py, PyBytes>`. [#4250](https://github.com/PyO3/pyo3/pull/4250) +- Add `pyo3_ffi::c_str` macro to create `&'static CStr` on Rust versions which don't have 1.77's `c""` literals. [#4255](https://github.com/PyO3/pyo3/pull/4255) +- Support `bool` conversion with `numpy` 2.0's `numpy.bool` type [#4258](https://github.com/PyO3/pyo3/pull/4258) +- Add `PyAnyMethods::{bitnot, matmul, floor_div, rem, divmod}`. [#4264](https://github.com/PyO3/pyo3/pull/4264) + +### Changed + +- Change the type of `PySliceIndices::slicelength` and the `length` parameter of `PySlice::indices()`. [#3761](https://github.com/PyO3/pyo3/pull/3761) +- Deprecate implicit default for trailing optional arguments [#4078](https://github.com/PyO3/pyo3/pull/4078) +- `Clone`ing pointers into the Python heap has been moved behind the `py-clone` feature, as it must panic without the GIL being held as a soundness fix. [#4095](https://github.com/PyO3/pyo3/pull/4095) +- Add `#[track_caller]` to all `Py`, `Bound<'py, T>` and `Borrowed<'a, 'py, T>` methods which can panic. [#4098](https://github.com/PyO3/pyo3/pull/4098) +- Change `PyAnyMethods::dir` to be fallible and return `PyResult>` (and similar for `PyAny::dir`). [#4100](https://github.com/PyO3/pyo3/pull/4100) +- The global reference pool (to track pending reference count decrements) is now initialized lazily to avoid the overhead of taking a mutex upon function entry when the functionality is not actually used. [#4178](https://github.com/PyO3/pyo3/pull/4178) +- Emit error messages when using `weakref` or `dict` when compiling for `abi3` for Python older than 3.9. [#4194](https://github.com/PyO3/pyo3/pull/4194) +- Change `PyType::name` to always match Python `__name__`. [#4196](https://github.com/PyO3/pyo3/pull/4196) +- Remove CPython internal ffi call for complex number including: add, sub, mul, div, neg, abs, pow. Added PyAnyMethods::{abs, pos, neg} [#4201](https://github.com/PyO3/pyo3/pull/4201) +- Deprecate implicit integer comparison for simple enums in favor of `#[pyclass(eq_int)]`. [#4210](https://github.com/PyO3/pyo3/pull/4210) +- Set the `module=` attribute of declarative modules' child `#[pymodule]`s and `#[pyclass]`es. [#4213](https://github.com/PyO3/pyo3/pull/4213) +- Set the `module` option for complex enum variants from the value set on the complex enum `module`. [#4228](https://github.com/PyO3/pyo3/pull/4228) +- Respect the Python "limited API" when building for the `abi3` feature on PyPy or GraalPy. [#4237](https://github.com/PyO3/pyo3/pull/4237) +- Optimize code generated by `#[pyo3(get)]` on `#[pyclass]` fields. [#4254](https://github.com/PyO3/pyo3/pull/4254) +- `PyCFunction::new`, `PyCFunction::new_with_keywords` and `PyCFunction::new_closure` now take `&'static CStr` name and doc arguments (previously was `&'static str`). [#4255](https://github.com/PyO3/pyo3/pull/4255) +- The `experimental-declarative-modules` feature is now stabilized and available by default. [#4257](https://github.com/PyO3/pyo3/pull/4257) + +### Fixed + +- Fix panic when `PYO3_CROSS_LIB_DIR` is set to a missing path. [#4043](https://github.com/PyO3/pyo3/pull/4043) +- Fix a compile error when exporting an exception created with `create_exception!` living in a different Rust module using the `declarative-module` feature. [#4086](https://github.com/PyO3/pyo3/pull/4086) +- Fix FFI definitions of `PY_VECTORCALL_ARGUMENTS_OFFSET` and `PyVectorcall_NARGS` to fix a false-positive assertion. [#4104](https://github.com/PyO3/pyo3/pull/4104) +- Disable `PyUnicode_DATA` on PyPy: not exposed by PyPy. [#4116](https://github.com/PyO3/pyo3/pull/4116) +- Correctly handle `#[pyo3(from_py_with = ...)]` attribute on dunder (`__magic__`) method arguments instead of silently ignoring it. [#4117](https://github.com/PyO3/pyo3/pull/4117) +- Fix a compile error when declaring a standalone function or class method with a Python name that is a Rust keyword. [#4226](https://github.com/PyO3/pyo3/pull/4226) +- Fix declarative modules discarding doc comments on the `mod` node. [#4236](https://github.com/PyO3/pyo3/pull/4236) +- Fix `__dict__` attribute missing for `#[pyclass(dict)]` instances when building for `abi3` on Python 3.9. [#4251](https://github.com/PyO3/pyo3/pull/4251) + +## [0.21.2] - 2024-04-16 + +### Changed + +- Deprecate the `PySet::empty()` gil-ref constructor. [#4082](https://github.com/PyO3/pyo3/pull/4082) + +### Fixed + +- Fix compile error for `async fn` in `#[pymethods]` with a `&self` receiver and more than one additional argument. [#4035](https://github.com/PyO3/pyo3/pull/4035) +- Improve error message for wrong receiver type in `__traverse__`. [#4045](https://github.com/PyO3/pyo3/pull/4045) +- Fix compile error when exporting a `#[pyclass]` living in a different Rust module using the `experimental-declarative-modules` feature. [#4054](https://github.com/PyO3/pyo3/pull/4054) +- Fix `missing_docs` lint triggering on documented `#[pymodule]` functions. [#4067](https://github.com/PyO3/pyo3/pull/4067) +- Fix undefined symbol errors for extension modules on AIX (by linking `libpython`). [#4073](https://github.com/PyO3/pyo3/pull/4073) + +## [0.21.1] - 2024-04-01 + +### Added + +- Implement `Send` and `Sync` for `PyBackedStr` and `PyBackedBytes`. [#4007](https://github.com/PyO3/pyo3/pull/4007) +- Implement `Clone`, `Debug`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash` implementation for `PyBackedBytes` and `PyBackedStr`, and `Display` for `PyBackedStr`. [#4020](https://github.com/PyO3/pyo3/pull/4020) +- Add `import_exception_bound!` macro to import exception types without generating GIL Ref functionality for them. [#4027](https://github.com/PyO3/pyo3/pull/4027) + +### Changed + +- Emit deprecation warning for uses of GIL Refs as `#[setter]` function arguments. [#3998](https://github.com/PyO3/pyo3/pull/3998) +- Add `#[inline]` hints on many `Bound` and `Borrowed` methods. [#4024](https://github.com/PyO3/pyo3/pull/4024) + +### Fixed + +- Handle `#[pyo3(from_py_with = "")]` in `#[setter]` methods [#3995](https://github.com/PyO3/pyo3/pull/3995) +- Allow extraction of `&Bound` in `#[setter]` methods. [#3998](https://github.com/PyO3/pyo3/pull/3998) +- Fix some uncovered code blocks emitted by `#[pymodule]`, `#[pyfunction]` and `#[pyclass]` macros. [#4009](https://github.com/PyO3/pyo3/pull/4009) +- Fix typo in the panic message when a class referenced in `pyo3::import_exception!` does not exist. [#4012](https://github.com/PyO3/pyo3/pull/4012) +- Fix compile error when using an async `#[pymethod]` with a receiver and additional arguments. [#4015](https://github.com/PyO3/pyo3/pull/4015) + + +## [0.21.0] - 2024-03-25 + +### Added + +- Add support for GraalPy (24.0 and up). [#3247](https://github.com/PyO3/pyo3/pull/3247) +- Add `PyMemoryView` type. [#3514](https://github.com/PyO3/pyo3/pull/3514) +- Allow `async fn` in for `#[pyfunction]` and `#[pymethods]`, with the `experimental-async` feature. [#3540](https://github.com/PyO3/pyo3/pull/3540) [#3588](https://github.com/PyO3/pyo3/pull/3588) [#3599](https://github.com/PyO3/pyo3/pull/3599) [#3931](https://github.com/PyO3/pyo3/pull/3931) +- Implement `PyTypeInfo` for `PyEllipsis`, `PyNone` and `PyNotImplemented`. [#3577](https://github.com/PyO3/pyo3/pull/3577) +- Support `#[pyclass]` on enums that have non-unit variants. [#3582](https://github.com/PyO3/pyo3/pull/3582) +- Support `chrono` feature with `abi3` feature. [#3664](https://github.com/PyO3/pyo3/pull/3664) +- `FromPyObject`, `IntoPy` and `ToPyObject` are implemented on `std::duration::Duration` [#3670](https://github.com/PyO3/pyo3/pull/3670) +- Add `PyString::to_cow`. Add `Py::to_str`, `Py::to_cow`, and `Py::to_string_lossy`, as ways to access Python string data safely beyond the GIL lifetime. [#3677](https://github.com/PyO3/pyo3/pull/3677) +- Add `Bound` and `Borrowed` smart pointers as a new API for accessing Python objects. [#3686](https://github.com/PyO3/pyo3/pull/3686) +- Add `PyNativeType::as_borrowed` to convert "GIL refs" to the new `Bound` smart pointer. [#3692](https://github.com/PyO3/pyo3/pull/3692) +- Add `FromPyObject::extract_bound` method, to migrate `FromPyObject` implementations to the Bound API. [#3706](https://github.com/PyO3/pyo3/pull/3706) +- Add `gil-refs` feature to allow continued use of the deprecated GIL Refs APIs. [#3707](https://github.com/PyO3/pyo3/pull/3707) +- Add methods to `PyAnyMethods` for binary operators (`add`, `sub`, etc.) [#3712](https://github.com/PyO3/pyo3/pull/3712) +- Add `chrono-tz` feature allowing conversion between `chrono_tz::Tz` and `zoneinfo.ZoneInfo` [#3730](https://github.com/PyO3/pyo3/pull/3730) +- Add FFI definition `PyType_GetModuleByDef`. [#3734](https://github.com/PyO3/pyo3/pull/3734) +- Conversion between `std::time::SystemTime` and `datetime.datetime` [#3736](https://github.com/PyO3/pyo3/pull/3736) +- Add `Py::as_any` and `Py::into_any`. [#3785](https://github.com/PyO3/pyo3/pull/3785) +- Add `PyStringMethods::encode_utf8`. [#3801](https://github.com/PyO3/pyo3/pull/3801) +- Add `PyBackedStr` and `PyBackedBytes`, as alternatives to `&str` and `&bytes` where a Python object owns the data. [#3802](https://github.com/PyO3/pyo3/pull/3802) [#3991](https://github.com/PyO3/pyo3/pull/3991) +- Allow `#[pymodule]` macro on Rust `mod` blocks, with the `experimental-declarative-modules` feature. [#3815](https://github.com/PyO3/pyo3/pull/3815) +- Implement `ExactSizeIterator` for `set` and `frozenset` iterators on `abi3` feature. [#3849](https://github.com/PyO3/pyo3/pull/3849) +- Add `Py::drop_ref` to explicitly drop a `Py`` and immediately decrease the Python reference count if the GIL is already held. [#3871](https://github.com/PyO3/pyo3/pull/3871) +- Allow `#[pymodule]` macro on single argument functions that take `&Bound<'_, PyModule>`. [#3905](https://github.com/PyO3/pyo3/pull/3905) +- Implement `FromPyObject` for `Cow`. [#3928](https://github.com/PyO3/pyo3/pull/3928) +- Implement `Default` for `GILOnceCell`. [#3971](https://github.com/PyO3/pyo3/pull/3971) +- Add `PyDictMethods::into_mapping`, `PyListMethods::into_sequence` and `PyTupleMethods::into_sequence`. [#3982](https://github.com/PyO3/pyo3/pull/3982) + +### Changed + +- `PyDict::from_sequence` now takes a single argument of type `&PyAny` (previously took two arguments `Python` and `PyObject`). [#3532](https://github.com/PyO3/pyo3/pull/3532) +- Deprecate `Py::is_ellipsis` and `PyAny::is_ellipsis` in favour of `any.is(py.Ellipsis())`. [#3577](https://github.com/PyO3/pyo3/pull/3577) +- Split some `PyTypeInfo` functionality into new traits `HasPyGilRef` and `PyTypeCheck`. [#3600](https://github.com/PyO3/pyo3/pull/3600) +- Deprecate `PyTryFrom` and `PyTryInto` traits in favor of `any.downcast()` via the `PyTypeCheck` and `PyTypeInfo` traits. [#3601](https://github.com/PyO3/pyo3/pull/3601) +- Allow async methods to accept `&self`/`&mut self` [#3609](https://github.com/PyO3/pyo3/pull/3609) +- `FromPyObject` for set types now also accept `frozenset` objects as input. [#3632](https://github.com/PyO3/pyo3/pull/3632) +- `FromPyObject` for `bool` now also accepts NumPy's `bool_` as input. [#3638](https://github.com/PyO3/pyo3/pull/3638) +- Add `AsRefSource` associated type to `PyNativeType`. [#3653](https://github.com/PyO3/pyo3/pull/3653) +- Rename `.is_true` to `.is_truthy` on `PyAny` and `Py` to clarify that the test is not based on identity with or equality to the True singleton. [#3657](https://github.com/PyO3/pyo3/pull/3657) +- `PyType::name` is now `PyType::qualname` whereas `PyType::name` efficiently accesses the full name which includes the module name. [#3660](https://github.com/PyO3/pyo3/pull/3660) +- The `Iter(A)NextOutput` types are now deprecated and `__(a)next__` can directly return anything which can be converted into Python objects, i.e. awaitables do not need to be wrapped into `IterANextOutput` or `Option` any more. `Option` can still be used as well and returning `None` will trigger the fast path for `__next__`, stopping iteration without having to raise a `StopIteration` exception. [#3661](https://github.com/PyO3/pyo3/pull/3661) +- Implement `FromPyObject` on `chrono::DateTime` for all `Tz`, not just `FixedOffset` and `Utc`. [#3663](https://github.com/PyO3/pyo3/pull/3663) +- Add lifetime parameter to `PyTzInfoAccess` trait. For the deprecated gil-ref API, the trait is now implemented for `&'py PyTime` and `&'py PyDateTime` instead of `PyTime` and `PyDate`. [#3679](https://github.com/PyO3/pyo3/pull/3679) +- Calls to `__traverse__` become no-ops for unsendable pyclasses if on the wrong thread, thereby avoiding hard aborts at the cost of potential leakage. [#3689](https://github.com/PyO3/pyo3/pull/3689) +- Include `PyNativeType` in `pyo3::prelude`. [#3692](https://github.com/PyO3/pyo3/pull/3692) +- Improve performance of `extract::` (and other integer types) by avoiding call to `__index__()` converting the value to an integer for 3.10+. Gives performance improvement of around 30% for successful extraction. [#3742](https://github.com/PyO3/pyo3/pull/3742) +- Relax bound of `FromPyObject` for `Py` to just `T: PyTypeCheck`. [#3776](https://github.com/PyO3/pyo3/pull/3776) +- `PySet` and `PyFrozenSet` iterators now always iterate the equivalent of `iter(set)`. (A "fast path" with no noticeable performance benefit was removed.) [#3849](https://github.com/PyO3/pyo3/pull/3849) +- Move implementations of `FromPyObject` for `&str`, `Cow`, `&[u8]` and `Cow<[u8]>` onto a temporary trait `FromPyObjectBound` when `gil-refs` feature is deactivated. [#3928](https://github.com/PyO3/pyo3/pull/3928) +- Deprecate `GILPool`, `Python::with_pool`, and `Python::new_pool`. [#3947](https://github.com/PyO3/pyo3/pull/3947) + +### Removed + +- Remove all functionality deprecated in PyO3 0.19. [#3603](https://github.com/PyO3/pyo3/pull/3603) + +### Fixed + +- Match PyPy 7.3.14 in removing PyPy-only symbol `Py_MAX_NDIMS` in favour of `PyBUF_MAX_NDIM`. [#3757](https://github.com/PyO3/pyo3/pull/3757) +- Fix segmentation fault using `datetime` types when an invalid `datetime` module is on sys.path. [#3818](https://github.com/PyO3/pyo3/pull/3818) +- Fix `non_local_definitions` lint warning triggered by many PyO3 macros. [#3901](https://github.com/PyO3/pyo3/pull/3901) +- Disable `PyCode` and `PyCode_Type` on PyPy: `PyCode_Type` is not exposed by PyPy. [#3934](https://github.com/PyO3/pyo3/pull/3934) + +## [0.21.0-beta.0] - 2024-03-10 + +Prerelease of PyO3 0.21. See [the GitHub diff](https://github.com/pyo3/pyo3/compare/v0.21.0-beta.0...v0.21.0) for what changed between 0.21.0-beta.0 and the final release. + +## [0.20.3] - 2024-02-23 + +### Packaging + +- Add `portable-atomic` dependency. [#3619](https://github.com/PyO3/pyo3/pull/3619) +- Check maximum version of Python at build time and for versions not yet supported require opt-in to the `abi3` stable ABI by the environment variable `PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1`. [#3821](https://github.com/PyO3/pyo3/pull/3821) + +### Fixed + +- Use `portable-atomic` to support platforms without 64-bit atomics. [#3619](https://github.com/PyO3/pyo3/pull/3619) +- Fix compilation failure with `either` feature enabled without `experimental-inspect` enabled. [#3834](https://github.com/PyO3/pyo3/pull/3834) + +## [0.20.2] - 2024-01-04 + +### Packaging + +- Pin `pyo3` and `pyo3-ffi` dependencies on `pyo3-build-config` to require the same patch version, i.e. `pyo3` 0.20.2 requires _exactly_ `pyo3-build-config` 0.20.2. [#3721](https://github.com/PyO3/pyo3/pull/3721) + +### Fixed + +- Fix compile failure when building `pyo3` 0.20.0 with latest `pyo3-build-config` 0.20.X. [#3724](https://github.com/PyO3/pyo3/pull/3724) +- Fix docs.rs build. [#3722](https://github.com/PyO3/pyo3/pull/3722) + +## [0.20.1] - 2023-12-30 + +### Added + +- Add optional `either` feature to add conversions for `either::Either` sum type. [#3456](https://github.com/PyO3/pyo3/pull/3456) +- Add optional `smallvec` feature to add conversions for `smallvec::SmallVec`. [#3507](https://github.com/PyO3/pyo3/pull/3507) +- Add `take` and `into_inner` methods to `GILOnceCell` [#3556](https://github.com/PyO3/pyo3/pull/3556) +- `#[classmethod]` methods can now also receive `Py` as their first argument. [#3587](https://github.com/PyO3/pyo3/pull/3587) +- `#[pyfunction(pass_module)]` can now also receive `Py` as their first argument. [#3587](https://github.com/PyO3/pyo3/pull/3587) +- Add `traverse` method to `GILProtected`. [#3616](https://github.com/PyO3/pyo3/pull/3616) +- Added `abi3-py312` feature [#3687](https://github.com/PyO3/pyo3/pull/3687) + +### Fixed + +- Fix minimum version specification for optional `chrono` dependency. [#3512](https://github.com/PyO3/pyo3/pull/3512) +- Silenced new `clippy::unnecessary_fallible_conversions` warning when using a `Py` `self` receiver. [#3564](https://github.com/PyO3/pyo3/pull/3564) + + +## [0.20.0] - 2023-10-11 + +### Packaging + +- Dual-license PyO3 under either the Apache 2.0 OR the MIT license. This makes the project GPLv2 compatible. [#3108](https://github.com/PyO3/pyo3/pull/3108) +- Update MSRV to Rust 1.56. [#3208](https://github.com/PyO3/pyo3/pull/3208) +- Bump `indoc` dependency to 2.0 and `unindent` dependency to 0.2. [#3237](https://github.com/PyO3/pyo3/pull/3237) +- Bump `syn` dependency to 2.0. [#3239](https://github.com/PyO3/pyo3/pull/3239) +- Drop support for debug builds of Python 3.7. [#3387](https://github.com/PyO3/pyo3/pull/3387) +- Bump `chrono` optional dependency to require 0.4.25 or newer. [#3427](https://github.com/PyO3/pyo3/pull/3427) +- Support Python 3.12. [#3488](https://github.com/PyO3/pyo3/pull/3488) + +### Added + +- Support `__lt__`, `__le__`, `__eq__`, `__ne__`, `__gt__` and `__ge__` in `#[pymethods]`. [#3203](https://github.com/PyO3/pyo3/pull/3203) +- Add FFI definition `Py_GETENV`. [#3336](https://github.com/PyO3/pyo3/pull/3336) +- Add `as_ptr` and `into_ptr` inherent methods for `Py`, `PyAny`, `PyRef`, and `PyRefMut`. [#3359](https://github.com/PyO3/pyo3/pull/3359) +- Implement `DoubleEndedIterator` for `PyTupleIterator` and `PyListIterator`. [#3366](https://github.com/PyO3/pyo3/pull/3366) +- Add `#[pyclass(rename_all = "...")]` option: this allows renaming all getters and setters of a struct, or all variants of an enum. Available renaming rules are: `"camelCase"`, `"kebab-case"`, `"lowercase"`, `"PascalCase"`, `"SCREAMING-KEBAB-CASE"`, `"SCREAMING_SNAKE_CASE"`, `"snake_case"`, `"UPPERCASE"`. [#3384](https://github.com/PyO3/pyo3/pull/3384) +- Add FFI definitions `PyObject_GC_IsTracked` and `PyObject_GC_IsFinalized` on Python 3.9 and up (PyPy 3.10 and up). [#3403](https://github.com/PyO3/pyo3/pull/3403) +- Add types for `None`, `Ellipsis`, and `NotImplemented`. [#3408](https://github.com/PyO3/pyo3/pull/3408) +- Add FFI definitions for the `Py_mod_multiple_interpreters` constant and its possible values. [#3494](https://github.com/PyO3/pyo3/pull/3494) +- Add FFI definitions for `PyInterpreterConfig` struct, its constants and `Py_NewInterpreterFromConfig`. [#3502](https://github.com/PyO3/pyo3/pull/3502) + +### Changed + +- Change `PySet::discard` to return `PyResult` (previously returned nothing). [#3281](https://github.com/PyO3/pyo3/pull/3281) +- Optimize implementation of `IntoPy` for Rust tuples to Python tuples. [#3321](https://github.com/PyO3/pyo3/pull/3321) +- Change `PyDict::get_item` to no longer suppress arbitrary exceptions (the return type is now `PyResult>` instead of `Option<&PyAny>`), and deprecate `PyDict::get_item_with_error`. [#3330](https://github.com/PyO3/pyo3/pull/3330) +- Deprecate FFI definitions which are deprecated in Python 3.12. [#3336](https://github.com/PyO3/pyo3/pull/3336) +- `AsPyPointer` is now an `unsafe trait`. [#3358](https://github.com/PyO3/pyo3/pull/3358) +- Accept all `os.PathLike` values in implementation of `FromPyObject` for `PathBuf`. [#3374](https://github.com/PyO3/pyo3/pull/3374) +- Add `__builtins__` to globals in `py.run()` and `py.eval()` if they're missing. [#3378](https://github.com/PyO3/pyo3/pull/3378) +- Optimize implementation of `FromPyObject` for `BigInt` and `BigUint`. [#3379](https://github.com/PyO3/pyo3/pull/3379) +- `PyIterator::from_object` and `PyByteArray::from` now take a single argument of type `&PyAny` (previously took two arguments `Python` and `AsPyPointer`). [#3389](https://github.com/PyO3/pyo3/pull/3389) +- Replace `AsPyPointer` with `AsRef` as a bound in the blanket implementation of `From<&T> for PyObject`. [#3391](https://github.com/PyO3/pyo3/pull/3391) +- Replace blanket `impl IntoPy for &T where T: AsPyPointer` with implementations of `impl IntoPy` for `&PyAny`, `&T where T: AsRef`, and `&Py`. [#3393](https://github.com/PyO3/pyo3/pull/3393) +- Preserve `std::io::Error` kind in implementation of `From` for `PyErr` [#3396](https://github.com/PyO3/pyo3/pull/3396) +- Try to select a relevant `ErrorKind` in implementation of `From` for `OSError` subclass. [#3397](https://github.com/PyO3/pyo3/pull/3397) +- Retrieve the original `PyErr` in implementation of `From` for `PyErr` if the `std::io::Error` has been built using a Python exception (previously would create a new exception wrapping the `std::io::Error`). [#3402](https://github.com/PyO3/pyo3/pull/3402) +- `#[pymodule]` will now return the same module object on repeated import by the same Python interpreter, on Python 3.9 and up. [#3446](https://github.com/PyO3/pyo3/pull/3446) +- Truncate leap-seconds and warn when converting `chrono` types to Python `datetime` types (`datetime` cannot represent leap-seconds). [#3458](https://github.com/PyO3/pyo3/pull/3458) +- `Err` returned from `#[pyfunction]` will now have a non-None `__context__` if called from inside a `catch` block. [#3455](https://github.com/PyO3/pyo3/pull/3455) +- Deprecate undocumented `#[__new__]` form of `#[new]` attribute. [#3505](https://github.com/PyO3/pyo3/pull/3505) + +### Removed + +- Remove all functionality deprecated in PyO3 0.18, including `#[args]` attribute for `#[pymethods]`. [#3232](https://github.com/PyO3/pyo3/pull/3232) +- Remove `IntoPyPointer` trait in favour of `into_ptr` inherent methods. [#3385](https://github.com/PyO3/pyo3/pull/3385) + +### Fixed + +- Handle exceptions properly in `PySet::discard`. [#3281](https://github.com/PyO3/pyo3/pull/3281) +- The `PyTupleIterator` type returned by `PyTuple::iter` is now public and hence can be named by downstream crates. [#3366](https://github.com/PyO3/pyo3/pull/3366) +- Linking of `PyOS_FSPath` on PyPy. [#3374](https://github.com/PyO3/pyo3/pull/3374) +- Fix memory leak in `PyTypeBuilder::build`. [#3401](https://github.com/PyO3/pyo3/pull/3401) +- Disable removed FFI definitions `_Py_GetAllocatedBlocks`, `_PyObject_GC_Malloc`, and `_PyObject_GC_Calloc` on Python 3.11 and up. [#3403](https://github.com/PyO3/pyo3/pull/3403) +- Fix `ResourceWarning` and crashes related to GC when running with debug builds of CPython. [#3404](https://github.com/PyO3/pyo3/pull/3404) +- Some-wrapping of `Option` default arguments will no longer re-wrap `Some(T)` or expressions evaluating to `None`. [#3461](https://github.com/PyO3/pyo3/pull/3461) +- Fix `IterNextOutput::Return` not returning a value on PyPy. [#3471](https://github.com/PyO3/pyo3/pull/3471) +- Emit compile errors instead of ignoring macro invocations inside `#[pymethods]` blocks. [#3491](https://github.com/PyO3/pyo3/pull/3491) +- Emit error on invalid arguments to `#[new]`, `#[classmethod]`, `#[staticmethod]`, and `#[classattr]`. [#3484](https://github.com/PyO3/pyo3/pull/3484) +- Disable `PyMarshal_WriteObjectToString` from `PyMarshal_ReadObjectFromString` with the `abi3` feature. [#3490](https://github.com/PyO3/pyo3/pull/3490) +- Fix FFI definitions for `_PyFrameEvalFunction` on Python 3.11 and up (it now receives a `_PyInterpreterFrame` opaque struct). [#3500](https://github.com/PyO3/pyo3/pull/3500) + + +## [0.19.2] - 2023-08-01 + +### Added + +- Add FFI definitions `PyState_AddModule`, `PyState_RemoveModule` and `PyState_FindModule` for PyPy 3.9 and up. [#3295](https://github.com/PyO3/pyo3/pull/3295) +- Add FFI definitions `_PyObject_CallFunction_SizeT` and `_PyObject_CallMethod_SizeT`. [#3297](https://github.com/PyO3/pyo3/pull/3297) +- Add a "performance" section to the guide collecting performance-related tricks and problems. [#3304](https://github.com/PyO3/pyo3/pull/3304) +- Add `PyErr::Display` for all Python versions, and FFI symbol `PyErr_DisplayException` for Python 3.12. [#3334](https://github.com/PyO3/pyo3/pull/3334) +- Add FFI definition `PyType_GetDict()` for Python 3.12. [#3339](https://github.com/PyO3/pyo3/pull/3339) +- Add `PyAny::downcast_exact`. [#3346](https://github.com/PyO3/pyo3/pull/3346) +- Add `PySlice::full()` to construct a full slice (`::`). [#3353](https://github.com/PyO3/pyo3/pull/3353) + +### Changed + +- Update `PyErr` for 3.12 betas to avoid deprecated ffi methods. [#3306](https://github.com/PyO3/pyo3/pull/3306) +- Update FFI definitions of `object.h` for Python 3.12.0b4. [#3335](https://github.com/PyO3/pyo3/pull/3335) +- Update `pyo3::ffi` struct definitions to be compatible with 3.12.0b4. [#3342](https://github.com/PyO3/pyo3/pull/3342) +- Optimize conversion of `float` to `f64` (and `PyFloat::value`) on non-abi3 builds. [#3345](https://github.com/PyO3/pyo3/pull/3345) + +### Fixed + +- Fix timezone conversion bug for FixedOffset datetimes that were being incorrectly converted to and from UTC. [#3269](https://github.com/PyO3/pyo3/pull/3269) +- Fix `SystemError` raised in `PyUnicodeDecodeError_Create` on PyPy 3.10. [#3297](https://github.com/PyO3/pyo3/pull/3297) +- Correct FFI definition `Py_EnterRecursiveCall` to return `c_int` (was incorrectly returning `()`). [#3300](https://github.com/PyO3/pyo3/pull/3300) +- Fix case where `PyErr::matches` and `PyErr::is_instance` returned results inconsistent with `PyErr::get_type`. [#3313](https://github.com/PyO3/pyo3/pull/3313) +- Fix loss of panic message in `PanicException` when unwinding after the exception was "normalized". [#3326](https://github.com/PyO3/pyo3/pull/3326) +- Fix `PyErr::from_value` and `PyErr::into_value` losing traceback on conversion. [#3328](https://github.com/PyO3/pyo3/pull/3328) +- Fix reference counting of immortal objects on Python 3.12.0b4. [#3335](https://github.com/PyO3/pyo3/pull/3335) + + +## [0.19.1] - 2023-07-03 + +### Packaging + +- Extend range of supported versions of `hashbrown` optional dependency to include version 0.14 [#3258](https://github.com/PyO3/pyo3/pull/3258) +- Extend range of supported versions of `indexmap` optional dependency to include version 2. [#3277](https://github.com/PyO3/pyo3/pull/3277) +- Support PyPy 3.10. [#3289](https://github.com/PyO3/pyo3/pull/3289) + +### Added + +- Add `pyo3::types::PyFrozenSetBuilder` to allow building a `PyFrozenSet` item by item. [#3156](https://github.com/PyO3/pyo3/pull/3156) +- Add support for converting to and from Python's `ipaddress.IPv4Address`/`ipaddress.IPv6Address` and `std::net::IpAddr`. [#3197](https://github.com/PyO3/pyo3/pull/3197) +- Add support for `num-bigint` feature in combination with `abi3`. [#3198](https://github.com/PyO3/pyo3/pull/3198) +- Add `PyErr_GetRaisedException()`, `PyErr_SetRaisedException()` to FFI definitions for Python 3.12 and later. [#3248](https://github.com/PyO3/pyo3/pull/3248) +- Add `Python::with_pool` which is a safer but more limited alternative to `Python::new_pool`. [#3263](https://github.com/PyO3/pyo3/pull/3263) +- Add `PyDict::get_item_with_error` on PyPy. [#3270](https://github.com/PyO3/pyo3/pull/3270) +- Allow `#[new]` methods may to return `Py` in order to return existing instances. [#3287](https://github.com/PyO3/pyo3/pull/3287) + +### Fixed + +- Fix conversion of classes implementing `__complex__` to `Complex` when using `abi3` or PyPy. [#3185](https://github.com/PyO3/pyo3/pull/3185) +- Stop suppressing unrelated exceptions in `PyAny::hasattr`. [#3271](https://github.com/PyO3/pyo3/pull/3271) +- Fix memory leak when creating `PySet` or `PyFrozenSet` or returning types converted into these internally, e.g. `HashSet` or `BTreeSet`. [#3286](https://github.com/PyO3/pyo3/pull/3286) + + +## [0.19.0] - 2023-05-31 + +### Packaging + +- Correct dependency on syn to version 1.0.85 instead of the incorrect version 1.0.56. [#3152](https://github.com/PyO3/pyo3/pull/3152) + +### Added + +- Accept `text_signature` option (and automatically generate signature) for `#[new]` in `#[pymethods]`. [#2980](https://github.com/PyO3/pyo3/pull/2980) +- Add support for converting to and from Python's `decimal.Decimal` and `rust_decimal::Decimal`. [#3016](https://github.com/PyO3/pyo3/pull/3016) +- Add `#[pyo3(from_item_all)]` when deriving `FromPyObject` to specify `get_item` as getter for all fields. [#3120](https://github.com/PyO3/pyo3/pull/3120) +- Add `pyo3::exceptions::PyBaseExceptionGroup` for Python 3.11, and corresponding FFI definition `PyExc_BaseExceptionGroup`. [#3141](https://github.com/PyO3/pyo3/pull/3141) +- Accept `#[new]` with `#[classmethod]` to create a constructor which receives a (subtype's) class/`PyType` as its first argument. [#3157](https://github.com/PyO3/pyo3/pull/3157) +- Add `PyClass::get` and `Py::get` for GIL-independent access to classes with `#[pyclass(frozen)]`. [#3158](https://github.com/PyO3/pyo3/pull/3158) +- Add `PyAny::is_exact_instance` and `PyAny::is_exact_instance_of`. [#3161](https://github.com/PyO3/pyo3/pull/3161) + +### Changed + +- `PyAny::is_instance_of::(obj)` is now equivalent to `T::is_type_of(obj)`, and now returns `bool` instead of `PyResult`. [#2881](https://github.com/PyO3/pyo3/pull/2881) +- Deprecate `text_signature` option on `#[pyclass]` structs. [#2980](https://github.com/PyO3/pyo3/pull/2980) +- No longer wrap `anyhow::Error`/`eyre::Report` containing a basic `PyErr` without a chain in a `PyRuntimeError`. [#3004](https://github.com/PyO3/pyo3/pull/3004) +- - Change `#[getter]` and `#[setter]` to use a common call "trampoline" to slightly reduce generated code size and compile times. [#3029](https://github.com/PyO3/pyo3/pull/3029) +- Improve default values for str, numbers and bool in automatically-generated `text_signature`. [#3050](https://github.com/PyO3/pyo3/pull/3050) +- Improve default value for `None` in automatically-generated `text_signature`. [#3066](https://github.com/PyO3/pyo3/pull/3066) +- Rename `PySequence::list` and `PySequence::tuple` to `PySequence::to_list` and `PySequence::to_tuple`. (The old names continue to exist as deprecated forms.) [#3111](https://github.com/PyO3/pyo3/pull/3111) +- Extend the lifetime of the GIL token returned by `PyRef::py` and `PyRefMut::py` to match the underlying borrow. [#3131](https://github.com/PyO3/pyo3/pull/3131) +- Safe access to the GIL, for example via `Python::with_gil`, is now locked inside of implementations of the `__traverse__` slot. [#3168](https://github.com/PyO3/pyo3/pull/3168) + +### Removed + +- Remove all functionality deprecated in PyO3 0.17, most prominently `Python::acquire_gil` is replaced by `Python::with_gil`. [#2981](https://github.com/PyO3/pyo3/pull/2981) + +### Fixed + +- Correct FFI definitions `PyGetSetDef`, `PyMemberDef`, `PyStructSequence_Field` and `PyStructSequence_Desc` to have `*const c_char` members for `name` and `doc` (not `*mut c_char`). [#3036](https://github.com/PyO3/pyo3/pull/3036) +- Fix panic on `fmt::Display`, instead return `""` string and report error via `sys.unraisablehook()` [#3062](https://github.com/PyO3/pyo3/pull/3062) +- Fix a compile error of "temporary value dropped while borrowed" when `#[pyfunction]`s take references into `#[pyclass]`es [#3142](https://github.com/PyO3/pyo3/pull/3142) +- Fix crashes caused by PyO3 applying deferred reference count updates when entering a `__traverse__` implementation. [#3168](https://github.com/PyO3/pyo3/pull/3168) +- Forbid running the `Drop` implementations of unsendable classes on other threads. [#3176](https://github.com/PyO3/pyo3/pull/3176) +- Fix a compile error when `#[pymethods]` items come from somewhere else (for example, as a macro argument) and a custom receiver like `Py` is used. [#3178](https://github.com/PyO3/pyo3/pull/3178) + + +## [0.18.3] - 2023-04-13 + +### Added + +- Add `GILProtected` to mediate concurrent access to a value using Python's global interpreter lock (GIL). [#2975](https://github.com/PyO3/pyo3/pull/2975) +- Support `PyASCIIObject` / `PyUnicode` and associated methods on big-endian architectures. [#3015](https://github.com/PyO3/pyo3/pull/3015) +- Add FFI definition `_PyDict_Contains_KnownHash()` for CPython 3.10 and up. [#3088](https://github.com/PyO3/pyo3/pull/3088) + +### Fixed + +- Fix compile error for `#[pymethods]` and `#[pyfunction]` called "output". [#3022](https://github.com/PyO3/pyo3/pull/3022) +- Fix compile error in generated code for magic methods implemented as a `#[staticmethod]`. [#3055](https://github.com/PyO3/pyo3/pull/3055) +- Fix `is_instance` for `PyDateTime` (would incorrectly check for a `PyDate`). [#3071](https://github.com/PyO3/pyo3/pull/3071) +- Fix upstream deprecation of `PyUnicode_InternImmortal` since Python 3.10. [#3071](https://github.com/PyO3/pyo3/pull/3087) + + +## [0.18.2] - 2023-03-24 + +### Packaging + +- Disable default features of `chrono` to avoid depending on `time` v0.1.x. [#2939](https://github.com/PyO3/pyo3/pull/2939) + +### Added + +- Implement `IntoPy`, `ToPyObject` and `FromPyObject` for `Cow<[u8]>` to efficiently handle both `bytes` and `bytearray` objects. [#2899](https://github.com/PyO3/pyo3/pull/2899) +- Implement `IntoPy`, `ToPyObject` and `FromPyObject` for `Cell`. [#3014](https://github.com/PyO3/pyo3/pull/3014) +- Add `PyList::to_tuple()`, as a convenient and efficient conversion from lists to tuples. [#3042](https://github.com/PyO3/pyo3/pull/3042) +- Add `PyTuple::to_list()`, as a convenient and efficient conversion from tuples to lists. [#3044](https://github.com/PyO3/pyo3/pull/3044) + +### Changed + +- Optimize `PySequence` conversion for `list` and `tuple` inputs. [#2944](https://github.com/PyO3/pyo3/pull/2944) +- Improve exception raised when creating `#[pyclass]` type object fails during module import. [#2947](https://github.com/PyO3/pyo3/pull/2947) +- Optimize `PyMapping` conversion for `dict` inputs. [#2954](https://github.com/PyO3/pyo3/pull/2954) +- Allow `create_exception!` to take a `dotted.module` to place the exception in a submodule. [#2979](https://github.com/PyO3/pyo3/pull/2979) + +### Fixed + +- Fix a reference counting race condition affecting `PyObject`s cloned in `allow_threads` blocks. [#2952](https://github.com/PyO3/pyo3/pull/2952) +- Fix `clippy::redundant_closure` lint on default arguments in `#[pyo3(signature = (...))]` annotations. [#2990](https://github.com/PyO3/pyo3/pull/2990) +- Fix `non_snake_case` lint on generated code in `#[pyfunction]` macro. [#2993](https://github.com/PyO3/pyo3/pull/2993) +- Fix some FFI definitions for the upcoming PyPy 3.10 release. [#3031](https://github.com/PyO3/pyo3/pull/3031) + + +## [0.18.1] - 2023-02-07 + +### Added + +- Add `PyErr::write_unraisable()`. [#2889](https://github.com/PyO3/pyo3/pull/2889) +- Add `Python::Ellipsis()` and `PyAny::is_ellipsis()` methods. [#2911](https://github.com/PyO3/pyo3/pull/2911) +- Add `PyDict::update()` and `PyDict::update_if_missing()` methods. [#2912](https://github.com/PyO3/pyo3/pull/2912) + +### Changed + +- FFI definition `PyIter_Check` on CPython 3.7 is now implemented as `hasattr(type(obj), "__next__")`, which works correctly on all platforms and adds support for `abi3`. [#2914](https://github.com/PyO3/pyo3/pull/2914) +- Warn about unknown config keys in `PYO3_CONFIG_FILE` instead of denying. [#2926](https://github.com/PyO3/pyo3/pull/2926) + +### Fixed + +- Send errors returned by `__releasebuffer__` to `sys.unraisablehook` rather than causing `SystemError`. [#2886](https://github.com/PyO3/pyo3/pull/2886) +- Fix downcast to `PyIterator` succeeding for Python classes which did not implement `__next__`. [#2914](https://github.com/PyO3/pyo3/pull/2914) +- Fix segfault in `__traverse__` when visiting `None` fields of `Option`. [#2921](https://github.com/PyO3/pyo3/pull/2921) +- Fix `#[pymethods(crate = "...")]` option being ignored. [#2923](https://github.com/PyO3/pyo3/pull/2923) +- Link against `pythonXY_d.dll` for debug Python builds on Windows. [#2937](https://github.com/PyO3/pyo3/pull/2937) + + +## [0.18.0] - 2023-01-17 + +### Packaging + +- Relax `indexmap` optional depecency to allow `>= 1.6, < 2`. [#2849](https://github.com/PyO3/pyo3/pull/2849) +- Relax `hashbrown` optional dependency to allow `>= 0.9, < 0.14`. [#2875](https://github.com/PyO3/pyo3/pull/2875) +- Update `memoffset` dependency to 0.8. [#2875](https://github.com/PyO3/pyo3/pull/2875) + +### Added + +- Add `GILOnceCell::get_or_try_init` for fallible `GILOnceCell` initialization. [#2398](https://github.com/PyO3/pyo3/pull/2398) +- Add experimental feature `experimental-inspect` with `type_input()` and `type_output()` helpers to get the Python type of any Python-compatible object. [#2490](https://github.com/PyO3/pyo3/pull/2490) [#2882](https://github.com/PyO3/pyo3/pull/2882) +- The `#[pyclass]` macro can now take `get_all` and `set_all` to create getters and setters for every field. [#2692](https://github.com/PyO3/pyo3/pull/2692) +- Add `#[pyo3(signature = (...))]` option for `#[pyfunction]` and `#[pymethods]`. [#2702](https://github.com/PyO3/pyo3/pull/2702) +- `pyo3-build-config`: rebuild when `PYO3_ENVIRONMENT_SIGNATURE` environment variable value changes. [#2727](https://github.com/PyO3/pyo3/pull/2727) +- Add conversions between non-zero int types in `std::num` and Python `int`. [#2730](https://github.com/PyO3/pyo3/pull/2730) +- Add `Py::downcast()` as a companion to `PyAny::downcast()`, as well as `downcast_unchecked()` for both types. [#2734](https://github.com/PyO3/pyo3/pull/2734) +- Add types for all built-in `Warning` classes as well as `PyErr::warn_explicit`. [#2742](https://github.com/PyO3/pyo3/pull/2742) +- Add `abi3-py311` feature. [#2776](https://github.com/PyO3/pyo3/pull/2776) +- Add FFI definition `_PyErr_ChainExceptions()` for CPython. [#2788](https://github.com/PyO3/pyo3/pull/2788) +- Add FFI definitions `PyVectorcall_NARGS` and `PY_VECTORCALL_ARGUMENTS_OFFSET` for PyPy 3.8 and up. [#2811](https://github.com/PyO3/pyo3/pull/2811) +- Add `PyList::get_item_unchecked` for PyPy. [#2827](https://github.com/PyO3/pyo3/pull/2827) + +### Changed + +- PyO3's macros now emit a much nicer error message if function return values don't implement the required trait(s). [#2664](https://github.com/PyO3/pyo3/pull/2664) +- Use a TypeError, rather than a ValueError, when refusing to treat a str as a Vec. [#2685](https://github.com/PyO3/pyo3/pull/2685) +- Change `PyCFunction::new_closure` to take `name` and `doc` arguments. [#2686](https://github.com/PyO3/pyo3/pull/2686) +- `PyType::is_subclass`, `PyErr::is_instance` and `PyAny::is_instance` now take `&PyAny` instead of `&PyType` arguments, so that they work with objects that pretend to be types using `__subclasscheck__` and `__instancecheck__`. [#2695](https://github.com/PyO3/pyo3/pull/2695) +- Deprecate `#[args]` attribute and passing "args" specification directly to `#[pyfunction]` in favor of the new `#[pyo3(signature = (...))]` option. [#2702](https://github.com/PyO3/pyo3/pull/2702) +- Deprecate required arguments after `Option` arguments to `#[pyfunction]` and `#[pymethods]` without also using `#[pyo3(signature)]` to specify whether the arguments should be required or have defaults. [#2703](https://github.com/PyO3/pyo3/pull/2703) +- Change `#[pyfunction]` and `#[pymethods]` to use a common call "trampoline" to slightly reduce generated code size and compile times. [#2705](https://github.com/PyO3/pyo3/pull/2705) +- `PyAny::cast_as()` and `Py::cast_as()` are now deprecated in favor of `PyAny::downcast()` and the new `Py::downcast()`. [#2734](https://github.com/PyO3/pyo3/pull/2734) +- Relax lifetime bounds on `PyAny::downcast()`. [#2734](https://github.com/PyO3/pyo3/pull/2734) +- Automatically generate `__text_signature__` for all Python functions created using `#[pyfunction]` and `#[pymethods]`. [#2784](https://github.com/PyO3/pyo3/pull/2784) +- Accept any iterator in `PySet::new` and `PyFrozenSet::new`. [#2795](https://github.com/PyO3/pyo3/pull/2795) +- Mixing `#[cfg(...)]` and `#[pyo3(...)]` attributes on `#[pyclass]` struct fields will now work. [#2796](https://github.com/PyO3/pyo3/pull/2796) +- Re-enable `PyFunction` on when building for abi3 or PyPy. [#2838](https://github.com/PyO3/pyo3/pull/2838) +- Improve `derive(FromPyObject)` to use `intern!` when applicable for `#[pyo3(item)]`. [#2879](https://github.com/PyO3/pyo3/pull/2879) + +### Removed + +- Remove the deprecated `pyproto` feature, `#[pyproto]` macro, and all accompanying APIs. [#2587](https://github.com/PyO3/pyo3/pull/2587) +- Remove all functionality deprecated in PyO3 0.16. [#2843](https://github.com/PyO3/pyo3/pull/2843) + +### Fixed + +- Disable `PyModule::filename` on PyPy. [#2715](https://github.com/PyO3/pyo3/pull/2715) +- `PyCodeObject` is now once again defined with fields on Python 3.7. [#2726](https://github.com/PyO3/pyo3/pull/2726) +- Raise a `TypeError` if `#[new]` pymethods with no arguments receive arguments when called from Python. [#2749](https://github.com/PyO3/pyo3/pull/2749) +- Use the `NOARGS` argument calling convention for methods that have a single `py: Python` argument (as a performance optimization). [#2760](https://github.com/PyO3/pyo3/pull/2760) +- Fix truncation of `isize` values to `c_long` in `PySlice::new`. [#2769](https://github.com/PyO3/pyo3/pull/2769) +- Fix soundness issue with FFI definition `PyUnicodeDecodeError_Create` on PyPy leading to indeterminate behavior (typically a `TypeError`). [#2772](https://github.com/PyO3/pyo3/pull/2772) +- Allow functions taking `**kwargs` to accept keyword arguments which share a name with a positional-only argument (as permitted by PEP 570). [#2800](https://github.com/PyO3/pyo3/pull/2800) +- Fix unresolved symbol for `PyObject_Vectorcall` on PyPy 3.9 and up. [#2811](https://github.com/PyO3/pyo3/pull/2811) +- Fix memory leak in `PyCFunction::new_closure`. [#2842](https://github.com/PyO3/pyo3/pull/2842) + + +## [0.17.3] - 2022-11-01 + +### Packaging + +- Support Python 3.11. (Previous versions of PyO3 0.17 have been tested against Python 3.11 release candidates and are expected to be compatible, this is the first version tested against Python 3.11.0.) [#2708](https://github.com/PyO3/pyo3/pull/2708) + +### Added + +- Implemented `ExactSizeIterator` for `PyListIterator`, `PyDictIterator`, `PySetIterator` and `PyFrozenSetIterator`. [#2676](https://github.com/PyO3/pyo3/pull/2676) + +### Fixed + +- Fix regression of `impl FromPyObject for [T; N]` no longer accepting types passing `PySequence_Check`, e.g. NumPy arrays, since version 0.17.0. This the same fix that was applied `impl FromPyObject for Vec` in version 0.17.1 extended to fixed-size arrays. [#2675](https://github.com/PyO3/pyo3/pull/2675) +- Fix UB in `FunctionDescription::extract_arguments_fastcall` due to creating slices from a null pointer. [#2687](https://github.com/PyO3/pyo3/pull/2687) + + +## [0.17.2] - 2022-10-04 + +### Packaging + +- Added optional `chrono` feature to convert `chrono` types into types in the `datetime` module. [#2612](https://github.com/PyO3/pyo3/pull/2612) + +### Added + +- Add support for `num-bigint` feature on `PyPy`. [#2626](https://github.com/PyO3/pyo3/pull/2626) + +### Fixed + +- Correctly implement `__richcmp__` for enums, fixing `__ne__` returning always returning `True`. [#2622](https://github.com/PyO3/pyo3/pull/2622) +- Fix compile error since 0.17.0 with `Option<&SomePyClass>` argument with a default. [#2630](https://github.com/PyO3/pyo3/pull/2630) +- Fix regression of `impl FromPyObject for Vec` no longer accepting types passing `PySequence_Check`, e.g. NumPy arrays, since 0.17.0. [#2631](https://github.com/PyO3/pyo3/pull/2631) + +## [0.17.1] - 2022-08-28 + +### Fixed + +- Fix visibility of `PyDictItems`, `PyDictKeys`, and `PyDictValues` types added in PyO3 0.17.0. +- Fix compile failure when using `#[pyo3(from_py_with = "...")]` attribute on an argument of type `Option`. [#2592](https://github.com/PyO3/pyo3/pull/2592) +- Fix clippy `redundant-closure` lint on `**kwargs` arguments for `#[pyfunction]` and `#[pymethods]`. [#2595](https://github.com/PyO3/pyo3/pull/2595) + +## [0.17.0] - 2022-08-23 + +### Packaging + +- Update inventory dependency to `0.3` (the `multiple-pymethods` feature now requires Rust 1.62 for correctness). [#2492](https://github.com/PyO3/pyo3/pull/2492) + +### Added + +- Add `timezone_utc`. [#1588](https://github.com/PyO3/pyo3/pull/1588) +- Implement `ToPyObject` for `[T; N]`. [#2313](https://github.com/PyO3/pyo3/pull/2313) +- Add `PyDictKeys`, `PyDictValues` and `PyDictItems` Rust types. [#2358](https://github.com/PyO3/pyo3/pull/2358) +- Add `append_to_inittab`. [#2377](https://github.com/PyO3/pyo3/pull/2377) +- Add FFI definition `PyFrame_GetCode`. [#2406](https://github.com/PyO3/pyo3/pull/2406) +- Add `PyCode` and `PyFrame` high level objects. [#2408](https://github.com/PyO3/pyo3/pull/2408) +- Add FFI definitions `Py_fstring_input`, `sendfunc`, and `_PyErr_StackItem`. [#2423](https://github.com/PyO3/pyo3/pull/2423) +- Add `PyDateTime::new_with_fold`, `PyTime::new_with_fold`, `PyTime::get_fold`, and `PyDateTime::get_fold` for PyPy. [#2428](https://github.com/PyO3/pyo3/pull/2428) +- Add `#[pyclass(frozen)]`. [#2448](https://github.com/PyO3/pyo3/pull/2448) +- Accept `#[pyo3(name)]` on enum variants. [#2457](https://github.com/PyO3/pyo3/pull/2457) +- Add `CompareOp::matches` to implement `__richcmp__` as the result of a Rust `std::cmp::Ordering` comparison. [#2460](https://github.com/PyO3/pyo3/pull/2460) +- Add `PySuper` type. [#2486](https://github.com/PyO3/pyo3/pull/2486) +- Support PyPy on Windows with the `generate-import-lib` feature. [#2506](https://github.com/PyO3/pyo3/pull/2506) +- Add FFI definitions `Py_EnterRecursiveCall` and `Py_LeaveRecursiveCall`. [#2511](https://github.com/PyO3/pyo3/pull/2511) +- Add `PyDict::get_item_with_error`. [#2536](https://github.com/PyO3/pyo3/pull/2536) +- Add `#[pyclass(sequence)]` option. [#2567](https://github.com/PyO3/pyo3/pull/2567) + +### Changed + +- Change datetime constructors taking a `tzinfo` to take `Option<&PyTzInfo>` instead of `Option<&PyObject>`: `PyDateTime::new`, `PyDateTime::new_with_fold`, `PyTime::new`, and `PyTime::new_with_fold`. [#1588](https://github.com/PyO3/pyo3/pull/1588) +- Move `PyTypeObject::type_object` method to the `PyTypeInfo` trait, and deprecate the `PyTypeObject` trait. [#2287](https://github.com/PyO3/pyo3/pull/2287) +- Methods of `Py` and `PyAny` now accept `impl IntoPy>` rather than just `&str` to allow use of the `intern!` macro. [#2312](https://github.com/PyO3/pyo3/pull/2312) +- Change the deprecated `pyproto` feature to be opt-in instead of opt-out. [#2322](https://github.com/PyO3/pyo3/pull/2322) +- Emit better error messages when `#[pyfunction]` return types do not implement `IntoPy`. [#2326](https://github.com/PyO3/pyo3/pull/2326) +- Require `T: IntoPy` for `impl IntoPy for [T; N]` instead of `T: ToPyObject`. [#2326](https://github.com/PyO3/pyo3/pull/2326) +- Deprecate the `ToBorrowedObject` trait. [#2333](https://github.com/PyO3/pyo3/pull/2333) +- Iterators over `PySet` and `PyDict` will now panic if the underlying collection is mutated during the iteration. [#2380](https://github.com/PyO3/pyo3/pull/2380) +- Iterators over `PySet` and `PyDict` will now panic if the underlying collection is mutated during the iteration. [#2380](https://github.com/PyO3/pyo3/pull/2380) +- Allow `#[classattr]` methods to be fallible. [#2385](https://github.com/PyO3/pyo3/pull/2385) +- Prevent multiple `#[pymethods]` with the same name for a single `#[pyclass]`. [#2399](https://github.com/PyO3/pyo3/pull/2399) +- Fixup `lib_name` when using `PYO3_CONFIG_FILE`. [#2404](https://github.com/PyO3/pyo3/pull/2404) +- Add a message to the `ValueError` raised by the `#[derive(FromPyObject)]` implementation for a tuple struct. [#2414](https://github.com/PyO3/pyo3/pull/2414) +- Allow `#[classattr]` methods to take `Python` argument. [#2456](https://github.com/PyO3/pyo3/pull/2456) +- Rework `PyCapsule` type to resolve soundness issues: [#2485](https://github.com/PyO3/pyo3/pull/2485) + - `PyCapsule::new` and `PyCapsule::new_with_destructor` now take `name: Option` instead of `&CStr`. + - The destructor `F` in `PyCapsule::new_with_destructor` must now be `Send`. + - `PyCapsule::get_context` deprecated in favor of `PyCapsule::context` which doesn't take a `py: Python<'_>` argument. + - `PyCapsule::set_context` no longer takes a `py: Python<'_>` argument. + - `PyCapsule::name` now returns `PyResult>` instead of `&CStr`. +- `FromPyObject::extract` for `Vec` no longer accepts Python `str` inputs. [#2500](https://github.com/PyO3/pyo3/pull/2500) +- Ensure each `#[pymodule]` is only initialized once. [#2523](https://github.com/PyO3/pyo3/pull/2523) +- `pyo3_build_config::add_extension_module_link_args` now also emits linker arguments for `wasm32-unknown-emscripten`. [#2538](https://github.com/PyO3/pyo3/pull/2538) +- Type checks for `PySequence` and `PyMapping` now require inputs to inherit from (or register with) `collections.abc.Sequence` and `collections.abc.Mapping` respectively. [#2477](https://github.com/PyO3/pyo3/pull/2477) +- Disable `PyFunction` on when building for abi3 or PyPy. [#2542](https://github.com/PyO3/pyo3/pull/2542) +- Deprecate `Python::acquire_gil`. [#2549](https://github.com/PyO3/pyo3/pull/2549) + +### Removed + +- Remove all functionality deprecated in PyO3 0.15. [#2283](https://github.com/PyO3/pyo3/pull/2283) +- Make the `Dict`, `WeakRef` and `BaseNativeType` members of the `PyClass` private implementation details. [#2572](https://github.com/PyO3/pyo3/pull/2572) + +### Fixed + +- Enable incorrectly disabled FFI definition `PyThreadState_DeleteCurrent`. [#2357](https://github.com/PyO3/pyo3/pull/2357) +- Fix `wrap_pymodule` interactions with name resolution rules: it no longer "sees through" glob imports of `use submodule::*` when `submodule::submodule` is a `#[pymodule]`. [#2363](https://github.com/PyO3/pyo3/pull/2363) +- Correct FFI definition `PyEval_EvalCodeEx` to take `*const *mut PyObject` array arguments instead of `*mut *mut PyObject`. [#2368](https://github.com/PyO3/pyo3/pull/2368) +- Fix "raw-ident" structs (e.g. `#[pyclass] struct r#RawName`) incorrectly having `r#` at the start of the class name created in Python. [#2395](https://github.com/PyO3/pyo3/pull/2395) +- Correct FFI definition `Py_tracefunc` to be `unsafe extern "C" fn` (was previously safe). [#2407](https://github.com/PyO3/pyo3/pull/2407) +- Fix compile failure with `#[pyo3(from_py_with = "...")]` annotations on a field in a `#[derive(FromPyObject)]` struct. [#2414](https://github.com/PyO3/pyo3/pull/2414) +- Fix FFI definitions `_PyDateTime_BaseTime` and `_PyDateTime_BaseDateTime` lacking leading underscores in their names. [#2421](https://github.com/PyO3/pyo3/pull/2421) +- Remove FFI definition `PyArena` on Python 3.10 and up. [#2421](https://github.com/PyO3/pyo3/pull/2421) +- Fix FFI definition `PyCompilerFlags` missing member `cf_feature_version` on Python 3.8 and up. [#2423](https://github.com/PyO3/pyo3/pull/2423) +- Fix FFI definition `PyAsyncMethods` missing member `am_send` on Python 3.10 and up. [#2423](https://github.com/PyO3/pyo3/pull/2423) +- Fix FFI definition `PyGenObject` having multiple incorrect members on various Python versions. [#2423](https://github.com/PyO3/pyo3/pull/2423) +- Fix FFI definition `PySyntaxErrorObject` missing members `end_lineno` and `end_offset` on Python 3.10 and up. [#2423](https://github.com/PyO3/pyo3/pull/2423) +- Fix FFI definition `PyHeapTypeObject` missing member `ht_module` on Python 3.9 and up. [#2423](https://github.com/PyO3/pyo3/pull/2423) +- Fix FFI definition `PyFrameObject` having multiple incorrect members on various Python versions. [#2424](https://github.com/PyO3/pyo3/pull/2424) [#2434](https://github.com/PyO3/pyo3/pull/2434) +- Fix FFI definition `PyTypeObject` missing deprecated field `tp_print` on Python 3.8. [#2428](https://github.com/PyO3/pyo3/pull/2428) +- Fix FFI definitions `PyDateTime_CAPI`. `PyDateTime_Date`, `PyASCIIObject`, `PyBaseExceptionObject`, `PyListObject`, and `PyTypeObject` on PyPy. [#2428](https://github.com/PyO3/pyo3/pull/2428) +- Fix FFI definition `_inittab` field `initfunc` typo'd as `initfun`. [#2431](https://github.com/PyO3/pyo3/pull/2431) +- Fix FFI definitions `_PyDateTime_BaseTime` and `_PyDateTime_BaseDateTime` incorrectly having `fold` member. [#2432](https://github.com/PyO3/pyo3/pull/2432) +- Fix FFI definitions `PyTypeObject`. `PyHeapTypeObject`, and `PyCFunctionObject` having incorrect members on PyPy 3.9. [#2433](https://github.com/PyO3/pyo3/pull/2433) +- Fix FFI definition `PyGetSetDef` to have `*const c_char` for `doc` member (not `*mut c_char`). [#2439](https://github.com/PyO3/pyo3/pull/2439) +- Fix `#[pyo3(from_py_with = "...")]` being ignored for 1-element tuple structs and transparent structs. [#2440](https://github.com/PyO3/pyo3/pull/2440) +- Use `memoffset` to avoid UB when computing `PyCell` layout. [#2450](https://github.com/PyO3/pyo3/pull/2450) +- Fix incorrect enum names being returned by the generated `repr` for enums renamed by `#[pyclass(name = "...")]` [#2457](https://github.com/PyO3/pyo3/pull/2457) +- Fix `PyObject_CallNoArgs` incorrectly being available when building for abi3 on Python 3.9. [#2476](https://github.com/PyO3/pyo3/pull/2476) +- Fix several clippy warnings generated by `#[pyfunction]` arguments. [#2503](https://github.com/PyO3/pyo3/pull/2503) + +## [0.16.6] - 2022-08-23 + +### Changed + +- Fix soundness issues with `PyCapsule` type with select workarounds. Users are encourage to upgrade to PyO3 0.17 at their earliest convenience which contains API breakages which fix the issues in a long-term fashion. [#2522](https://github.com/PyO3/pyo3/pull/2522) + - `PyCapsule::new` and `PyCapsule::new_with_destructor` now take ownership of a copy of the `name` to resolve a possible use-after-free. + - `PyCapsule::name` now returns an empty `CStr` instead of dereferencing a null pointer if the capsule has no name. + - The destructor `F` in `PyCapsule::new_with_destructor` will never be called if the capsule is deleted from a thread other than the one which the capsule was created in (a warning will be emitted). +- Panics during drop of panic payload caught by PyO3 will now abort. [#2544](https://github.com/PyO3/pyo3/pull/2544) + +## [0.16.5] - 2022-05-15 + +### Added + +- Add an experimental `generate-import-lib` feature to support auto-generating non-abi3 python import libraries for Windows targets. [#2364](https://github.com/PyO3/pyo3/pull/2364) +- Add FFI definition `Py_ExitStatusException`. [#2374](https://github.com/PyO3/pyo3/pull/2374) + +### Changed + +- Deprecate experimental `generate-abi3-import-lib` feature in favor of the new `generate-import-lib` feature. [#2364](https://github.com/PyO3/pyo3/pull/2364) + +### Fixed + +- Added missing `warn_default_encoding` field to `PyConfig` on 3.10+. The previously missing field could result in incorrect behavior or crashes. [#2370](https://github.com/PyO3/pyo3/pull/2370) +- Fixed order of `pathconfig_warnings` and `program_name` fields of `PyConfig` on 3.10+. Previously, the order of the fields was swapped and this could lead to incorrect behavior or crashes. [#2370](https://github.com/PyO3/pyo3/pull/2370) + +## [0.16.4] - 2022-04-14 + +### Added + +- Add `PyTzInfoAccess` trait for safe access to time zone information. [#2263](https://github.com/PyO3/pyo3/pull/2263) +- Add an experimental `generate-abi3-import-lib` feature to auto-generate `python3.dll` import libraries for Windows. [#2282](https://github.com/PyO3/pyo3/pull/2282) +- Add FFI definitions for `PyDateTime_BaseTime` and `PyDateTime_BaseDateTime`. [#2294](https://github.com/PyO3/pyo3/pull/2294) + +### Changed + +- Improved performance of failing calls to `FromPyObject::extract` which is common when functions accept multiple distinct types. [#2279](https://github.com/PyO3/pyo3/pull/2279) +- Default to "m" ABI tag when choosing `libpython` link name for CPython 3.7 on Unix. [#2288](https://github.com/PyO3/pyo3/pull/2288) +- Allow to compile "abi3" extensions without a working build host Python interpreter. [#2293](https://github.com/PyO3/pyo3/pull/2293) + +### Fixed + +- Crates depending on PyO3 can collect code coverage via LLVM instrumentation using stable Rust. [#2286](https://github.com/PyO3/pyo3/pull/2286) +- Fix segfault when calling FFI methods `PyDateTime_DATE_GET_TZINFO` or `PyDateTime_TIME_GET_TZINFO` on `datetime` or `time` without a tzinfo. [#2289](https://github.com/PyO3/pyo3/pull/2289) +- Fix directory names starting with the letter `n` breaking serialization of the interpreter configuration on Windows since PyO3 0.16.3. [#2299](https://github.com/PyO3/pyo3/pull/2299) + +## [0.16.3] - 2022-04-05 + +### Packaging + +- Extend `parking_lot` dependency supported versions to include 0.12. [#2239](https://github.com/PyO3/pyo3/pull/2239) + +### Added + +- Add methods to `pyo3_build_config::InterpreterConfig` to run Python scripts using the configured executable. [#2092](https://github.com/PyO3/pyo3/pull/2092) +- Add `as_bytes` method to `Py`. [#2235](https://github.com/PyO3/pyo3/pull/2235) +- Add FFI definitions for `PyType_FromModuleAndSpec`, `PyType_GetModule`, `PyType_GetModuleState` and `PyModule_AddType`. [#2250](https://github.com/PyO3/pyo3/pull/2250) +- Add `pyo3_build_config::cross_compiling_from_to` as a helper to detect when PyO3 is cross-compiling. [#2253](https://github.com/PyO3/pyo3/pull/2253) +- Add `#[pyclass(mapping)]` option to leave sequence slots empty in container implementations. [#2265](https://github.com/PyO3/pyo3/pull/2265) +- Add `PyString::intern` to enable usage of the Python's built-in string interning. [#2268](https://github.com/PyO3/pyo3/pull/2268) +- Add `intern!` macro which can be used to amortize the cost of creating Python strings by storing them inside a `GILOnceCell`. [#2269](https://github.com/PyO3/pyo3/pull/2269) +- Add `PYO3_CROSS_PYTHON_IMPLEMENTATION` environment variable for selecting the default cross Python implementation. [#2272](https://github.com/PyO3/pyo3/pull/2272) + +### Changed + +- Allow `#[pyo3(crate = "...", text_signature = "...")]` options to be used directly in `#[pyclass(crate = "...", text_signature = "...")]`. [#2234](https://github.com/PyO3/pyo3/pull/2234) +- Make `PYO3_CROSS_LIB_DIR` environment variable optional when cross compiling. [#2241](https://github.com/PyO3/pyo3/pull/2241) +- Mark `METH_FASTCALL` calling convention as limited API on Python 3.10. [#2250](https://github.com/PyO3/pyo3/pull/2250) +- Deprecate `pyo3_build_config::cross_compiling` in favor of `pyo3_build_config::cross_compiling_from_to`. [#2253](https://github.com/PyO3/pyo3/pull/2253) + +### Fixed + +- Fix `abi3-py310` feature: use Python 3.10 ABI when available instead of silently falling back to the 3.9 ABI. [#2242](https://github.com/PyO3/pyo3/pull/2242) +- Use shared linking mode when cross compiling against a [Framework bundle](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html) for macOS. [#2233](https://github.com/PyO3/pyo3/pull/2233) +- Fix panic during compilation when `PYO3_CROSS_LIB_DIR` is set for some host/target combinations. [#2232](https://github.com/PyO3/pyo3/pull/2232) +- Correct dependency version for `syn` to require minimal patch version 1.0.56. [#2240](https://github.com/PyO3/pyo3/pull/2240) + +## [0.16.2] - 2022-03-15 + +### Packaging + +- Warn when modules are imported on PyPy 3.7 versions older than PyPy 7.3.8, as they are known to have binary compatibility issues. [#2217](https://github.com/PyO3/pyo3/pull/2217) +- Ensure build script of `pyo3-ffi` runs before that of `pyo3` to fix cross compilation. [#2224](https://github.com/PyO3/pyo3/pull/2224) + +## [0.16.1] - 2022-03-05 + +### Packaging + +- Extend `hashbrown` optional dependency supported versions to include 0.12. [#2197](https://github.com/PyO3/pyo3/pull/2197) + +### Fixed + +- Fix incorrect platform detection for Windows in `pyo3-build-config`. [#2198](https://github.com/PyO3/pyo3/pull/2198) +- Fix regression from 0.16 preventing cross compiling to aarch64 macOS. [#2201](https://github.com/PyO3/pyo3/pull/2201) + +## [0.16.0] - 2022-02-27 + +### Packaging + +- Update MSRV to Rust 1.48. [#2004](https://github.com/PyO3/pyo3/pull/2004) +- Update `indoc` optional dependency to 1.0. [#2004](https://github.com/PyO3/pyo3/pull/2004) +- Drop support for Python 3.6, remove `abi3-py36` feature. [#2006](https://github.com/PyO3/pyo3/pull/2006) +- `pyo3-build-config` no longer enables the `resolve-config` feature by default. [#2008](https://github.com/PyO3/pyo3/pull/2008) +- Update `inventory` optional dependency to 0.2. [#2019](https://github.com/PyO3/pyo3/pull/2019) +- Drop `paste` dependency. [#2081](https://github.com/PyO3/pyo3/pull/2081) +- The bindings found in `pyo3::ffi` are now a re-export of a separate `pyo3-ffi` crate. [#2126](https://github.com/PyO3/pyo3/pull/2126) +- Support PyPy 3.9. [#2143](https://github.com/PyO3/pyo3/pull/2143) + +### Added + +- Add `PyCapsule` type exposing the [Capsule API](https://docs.python.org/3/c-api/capsule.html#capsules). [#1980](https://github.com/PyO3/pyo3/pull/1980) +- Add `pyo3_build_config::Sysconfigdata` and supporting APIs. [#1996](https://github.com/PyO3/pyo3/pull/1996) +- Add `Py::setattr` method. [#2009](https://github.com/PyO3/pyo3/pull/2009) +- Add `#[pyo3(crate = "some::path")]` option to all attribute macros (except the deprecated `#[pyproto]`). [#2022](https://github.com/PyO3/pyo3/pull/2022) +- Enable `create_exception!` macro to take an optional docstring. [#2027](https://github.com/PyO3/pyo3/pull/2027) +- Enable `#[pyclass]` for fieldless (aka C-like) enums. [#2034](https://github.com/PyO3/pyo3/pull/2034) +- Add buffer magic methods `__getbuffer__` and `__releasebuffer__` to `#[pymethods]`. [#2067](https://github.com/PyO3/pyo3/pull/2067) +- Add support for paths in `wrap_pyfunction` and `wrap_pymodule`. [#2081](https://github.com/PyO3/pyo3/pull/2081) +- Enable `wrap_pyfunction!` to wrap a `#[pyfunction]` implemented in a different Rust module or crate. [#2091](https://github.com/PyO3/pyo3/pull/2091) +- Add `PyAny::contains` method (`in` operator for `PyAny`). [#2115](https://github.com/PyO3/pyo3/pull/2115) +- Add `PyMapping::contains` method (`in` operator for `PyMapping`). [#2133](https://github.com/PyO3/pyo3/pull/2133) +- Add garbage collection magic magic methods `__traverse__` and `__clear__` to `#[pymethods]`. [#2159](https://github.com/PyO3/pyo3/pull/2159) +- Add support for `from_py_with` on struct tuples and enums to override the default from-Python conversion. [#2181](https://github.com/PyO3/pyo3/pull/2181) +- Add `eq`, `ne`, `lt`, `le`, `gt`, `ge` methods to `PyAny` that wrap `rich_compare`. [#2175](https://github.com/PyO3/pyo3/pull/2175) +- Add `Py::is` and `PyAny::is` methods to check for object identity. [#2183](https://github.com/PyO3/pyo3/pull/2183) +- Add support for the `__getattribute__` magic method. [#2187](https://github.com/PyO3/pyo3/pull/2187) + +### Changed + +- `PyType::is_subclass`, `PyErr::is_instance` and `PyAny::is_instance` now operate run-time type object instead of a type known at compile-time. The old behavior is still available as `PyType::is_subclass_of`, `PyErr::is_instance_of` and `PyAny::is_instance_of`. [#1985](https://github.com/PyO3/pyo3/pull/1985) +- Rename some methods on `PyErr` (the old names are just marked deprecated for now): [#2026](https://github.com/PyO3/pyo3/pull/2026) + - `pytype` -> `get_type` + - `pvalue` -> `value` (and deprecate equivalent `instance`) + - `ptraceback` -> `traceback` + - `from_instance` -> `from_value` + - `into_instance` -> `into_value` +- `PyErr::new_type` now takes an optional docstring and now returns `PyResult>` rather than a `ffi::PyTypeObject` pointer. [#2027](https://github.com/PyO3/pyo3/pull/2027) +- Deprecate `PyType::is_instance`; it is inconsistent with other `is_instance` methods in PyO3. Instead of `typ.is_instance(obj)`, use `obj.is_instance(typ)`. [#2031](https://github.com/PyO3/pyo3/pull/2031) +- `__getitem__`, `__setitem__` and `__delitem__` in `#[pymethods]` now implement both a Python mapping and sequence by default. [#2065](https://github.com/PyO3/pyo3/pull/2065) +- Improve performance and error messages for `#[derive(FromPyObject)]` for enums. [#2068](https://github.com/PyO3/pyo3/pull/2068) +- Reduce generated LLVM code size (to improve compile times) for: + - internal `handle_panic` helper [#2074](https://github.com/PyO3/pyo3/pull/2074) [#2158](https://github.com/PyO3/pyo3/pull/2158) + - `#[pyfunction]` and `#[pymethods]` argument extraction [#2075](https://github.com/PyO3/pyo3/pull/2075) [#2085](https://github.com/PyO3/pyo3/pull/2085) + - `#[pyclass]` type object creation [#2076](https://github.com/PyO3/pyo3/pull/2076) [#2081](https://github.com/PyO3/pyo3/pull/2081) [#2157](https://github.com/PyO3/pyo3/pull/2157) +- Respect Rust privacy rules for items wrapped with `wrap_pyfunction` and `wrap_pymodule`. [#2081](https://github.com/PyO3/pyo3/pull/2081) +- Add modulo argument to `__ipow__` magic method. [#2083](https://github.com/PyO3/pyo3/pull/2083) +- Fix FFI definition for `_PyCFunctionFast`. [#2126](https://github.com/PyO3/pyo3/pull/2126) +- `PyDateTimeAPI` and `PyDateTime_TimeZone_UTC` are now unsafe functions instead of statics. [#2126](https://github.com/PyO3/pyo3/pull/2126) +- `PyDateTimeAPI` does not implicitly call `PyDateTime_IMPORT` anymore to reflect the original Python API more closely. Before the first call to `PyDateTime_IMPORT` a null pointer is returned. Therefore before calling any of the following FFI functions `PyDateTime_IMPORT` must be called to avoid undefined behavior: [#2126](https://github.com/PyO3/pyo3/pull/2126) + - `PyDateTime_TimeZone_UTC` + - `PyDate_Check` + - `PyDate_CheckExact` + - `PyDateTime_Check` + - `PyDateTime_CheckExact` + - `PyTime_Check` + - `PyTime_CheckExact` + - `PyDelta_Check` + - `PyDelta_CheckExact` + - `PyTZInfo_Check` + - `PyTZInfo_CheckExact` + - `PyDateTime_FromTimestamp` + - `PyDate_FromTimestamp` +- Deprecate the `gc` option for `pyclass` (e.g. `#[pyclass(gc)]`). Just implement a `__traverse__` `#[pymethod]`. [#2159](https://github.com/PyO3/pyo3/pull/2159) +- The `ml_meth` field of `PyMethodDef` is now represented by the `PyMethodDefPointer` union. [2166](https://github.com/PyO3/pyo3/pull/2166) +- Deprecate the `#[pyproto]` traits. [#2173](https://github.com/PyO3/pyo3/pull/2173) + +### Removed + +- Remove all functionality deprecated in PyO3 0.14. [#2007](https://github.com/PyO3/pyo3/pull/2007) +- Remove `Default` impl for `PyMethodDef`. [#2166](https://github.com/PyO3/pyo3/pull/2166) +- Remove `PartialEq` impl for `Py` and `PyAny` (use the new `is` instead). [#2183](https://github.com/PyO3/pyo3/pull/2183) + +### Fixed + +- Fix undefined symbol for `PyObject_HasAttr` on PyPy. [#2025](https://github.com/PyO3/pyo3/pull/2025) +- Fix memory leak in `PyErr::into_value`. [#2026](https://github.com/PyO3/pyo3/pull/2026) +- Fix clippy warning `needless-option-as-deref` in code generated by `#[pyfunction]` and `#[pymethods]`. [#2040](https://github.com/PyO3/pyo3/pull/2040) +- Fix undefined behavior in `PySlice::indices`. [#2061](https://github.com/PyO3/pyo3/pull/2061) +- Fix the `wrap_pymodule!` macro using the wrong name for a `#[pymodule]` with a `#[pyo3(name = "..")]` attribute. [#2081](https://github.com/PyO3/pyo3/pull/2081) +- Fix magic methods in `#[pymethods]` accepting implementations with the wrong number of arguments. [#2083](https://github.com/PyO3/pyo3/pull/2083) +- Fix panic in `#[pyfunction]` generated code when a required argument following an `Option` was not provided. [#2093](https://github.com/PyO3/pyo3/pull/2093) +- Fixed undefined behavior caused by incorrect `ExactSizeIterator` implementations. [#2124](https://github.com/PyO3/pyo3/pull/2124) +- Fix missing FFI definition `PyCMethod_New` on Python 3.9 and up. [#2143](https://github.com/PyO3/pyo3/pull/2143) +- Add missing FFI definitions `_PyLong_NumBits` and `_PyLong_AsByteArray` on PyPy. [#2146](https://github.com/PyO3/pyo3/pull/2146) +- Fix memory leak in implementation of `AsPyPointer` for `Option`. [#2160](https://github.com/PyO3/pyo3/pull/2160) +- Fix FFI definition of `_PyLong_NumBits` to return `size_t` instead of `c_int`. [#2161](https://github.com/PyO3/pyo3/pull/2161) +- Fix `TypeError` thrown when argument parsing failed missing the originating causes. [2177](https://github.com/PyO3/pyo3/pull/2178) + +## [0.15.2] - 2022-04-14 + +### Packaging + +- Backport of PyPy 3.9 support from PyO3 0.16. [#2262](https://github.com/PyO3/pyo3/pull/2262) + +## [0.15.1] - 2021-11-19 + +### Added + +- Add implementations for `Py::as_ref` and `Py::into_ref` for `Py`, `Py` and `Py`. [#1682](https://github.com/PyO3/pyo3/pull/1682) +- Add `PyTraceback` type to represent and format Python tracebacks. [#1977](https://github.com/PyO3/pyo3/pull/1977) + +### Changed + +- `#[classattr]` constants with a known magic method name (which is lowercase) no longer trigger lint warnings expecting constants to be uppercase. [#1971](https://github.com/PyO3/pyo3/pull/1971) + +### Fixed + +- Fix creating `#[classattr]` by functions with the name of a known magic method. [#1971](https://github.com/PyO3/pyo3/pull/1971) +- Fix use of `catch_unwind` in `allow_threads` which can cause fatal crashes. [#1989](https://github.com/PyO3/pyo3/pull/1989) +- Fix build failure on PyPy when abi3 features are activated. [#1991](https://github.com/PyO3/pyo3/pull/1991) +- Fix mingw platform detection. [#1993](https://github.com/PyO3/pyo3/pull/1993) +- Fix panic in `__get__` implementation when accessing descriptor on type object. [#1997](https://github.com/PyO3/pyo3/pull/1997) + +## [0.15.0] - 2021-11-03 + +### Packaging + +- `pyo3`'s `Cargo.toml` now advertises `links = "python"` to inform Cargo that it links against *libpython*. [#1819](https://github.com/PyO3/pyo3/pull/1819) +- Added optional `anyhow` feature to convert `anyhow::Error` into `PyErr`. [#1822](https://github.com/PyO3/pyo3/pull/1822) +- Support Python 3.10. [#1889](https://github.com/PyO3/pyo3/pull/1889) +- Added optional `eyre` feature to convert `eyre::Report` into `PyErr`. [#1893](https://github.com/PyO3/pyo3/pull/1893) +- Support PyPy 3.8. [#1948](https://github.com/PyO3/pyo3/pull/1948) + +### Added + +- Add `PyList::get_item_unchecked` and `PyTuple::get_item_unchecked` to get items without bounds checks. [#1733](https://github.com/PyO3/pyo3/pull/1733) +- Support `#[doc = include_str!(...)]` attributes on Rust 1.54 and up. [#1746](https://github.com/PyO3/pyo3/issues/1746) +- Add `PyAny::py` as a convenience for `PyNativeType::py`. [#1751](https://github.com/PyO3/pyo3/pull/1751) +- Add implementation of `std::ops::Index` for `PyList`, `PyTuple` and `PySequence`. [#1825](https://github.com/PyO3/pyo3/pull/1825) +- Add range indexing implementations of `std::ops::Index` for `PyList`, `PyTuple` and `PySequence`. [#1829](https://github.com/PyO3/pyo3/pull/1829) +- Add `PyMapping` type to represent the Python mapping protocol. [#1844](https://github.com/PyO3/pyo3/pull/1844) +- Add commonly-used sequence methods to `PyList` and `PyTuple`. [#1849](https://github.com/PyO3/pyo3/pull/1849) +- Add `as_sequence` methods to `PyList` and `PyTuple`. [#1860](https://github.com/PyO3/pyo3/pull/1860) +- Add support for magic methods in `#[pymethods]`, intended as a replacement for `#[pyproto]`. [#1864](https://github.com/PyO3/pyo3/pull/1864) +- Add `abi3-py310` feature. [#1889](https://github.com/PyO3/pyo3/pull/1889) +- Add `PyCFunction::new_closure` to create a Python function from a Rust closure. [#1901](https://github.com/PyO3/pyo3/pull/1901) +- Add support for positional-only arguments in `#[pyfunction]`. [#1925](https://github.com/PyO3/pyo3/pull/1925) +- Add `PyErr::take` to attempt to fetch a Python exception if present. [#1957](https://github.com/PyO3/pyo3/pull/1957) + +### Changed + +- `PyList`, `PyTuple` and `PySequence`'s APIs now accepts only `usize` indices instead of `isize`. + [#1733](https://github.com/PyO3/pyo3/pull/1733), [#1802](https://github.com/PyO3/pyo3/pull/1802), + [#1803](https://github.com/PyO3/pyo3/pull/1803) +- `PyList::get_item` and `PyTuple::get_item` now return `PyResult<&PyAny>` instead of panicking. [#1733](https://github.com/PyO3/pyo3/pull/1733) +- `PySequence::in_place_repeat` and `PySequence::in_place_concat` now return `PyResult<&PySequence>` instead of `PyResult<()>`, which is needed in case of immutable sequences such as tuples. [#1803](https://github.com/PyO3/pyo3/pull/1803) +- `PySequence::get_slice` now returns `PyResult<&PySequence>` instead of `PyResult<&PyAny>`. [#1829](https://github.com/PyO3/pyo3/pull/1829) +- Deprecate `PyTuple::split_from`. [#1804](https://github.com/PyO3/pyo3/pull/1804) +- Deprecate `PyTuple::slice`, new method `PyTuple::get_slice` added with `usize` indices. [#1828](https://github.com/PyO3/pyo3/pull/1828) +- Deprecate FFI definitions `PyParser_SimpleParseStringFlags`, `PyParser_SimpleParseStringFlagsFilename`, `PyParser_SimpleParseFileFlags` when building for Python 3.9. [#1830](https://github.com/PyO3/pyo3/pull/1830) +- Mark FFI definitions removed in Python 3.10 `PyParser_ASTFromString`, `PyParser_ASTFromStringObject`, `PyParser_ASTFromFile`, `PyParser_ASTFromFileObject`, `PyParser_SimpleParseStringFlags`, `PyParser_SimpleParseStringFlagsFilename`, `PyParser_SimpleParseFileFlags`, `PyParser_SimpleParseString`, `PyParser_SimpleParseFile`, `Py_SymtableString`, and `Py_SymtableStringObject`. [#1830](https://github.com/PyO3/pyo3/pull/1830) +- `#[pymethods]` now handles magic methods similarly to `#[pyproto]`. In the future, `#[pyproto]` may be deprecated. [#1864](https://github.com/PyO3/pyo3/pull/1864) +- Deprecate FFI definitions `PySys_AddWarnOption`, `PySys_AddWarnOptionUnicode` and `PySys_HasWarnOptions`. [#1887](https://github.com/PyO3/pyo3/pull/1887) +- Deprecate `#[call]` attribute in favor of using `fn __call__`. [#1929](https://github.com/PyO3/pyo3/pull/1929) +- Fix missing FFI definition `_PyImport_FindExtensionObject` on Python 3.10. [#1942](https://github.com/PyO3/pyo3/pull/1942) +- Change `PyErr::fetch` to panic in debug mode if no exception is present. [#1957](https://github.com/PyO3/pyo3/pull/1957) + +### Fixed + +- Fix building with a conda environment on Windows. [#1873](https://github.com/PyO3/pyo3/pull/1873) +- Fix panic on Python 3.6 when calling `Python::with_gil` with Python initialized but threading not initialized. [#1874](https://github.com/PyO3/pyo3/pull/1874) +- Fix incorrect linking to version-specific DLL instead of `python3.dll` when cross-compiling to Windows with `abi3`. [#1880](https://github.com/PyO3/pyo3/pull/1880) +- Fix FFI definition for `PyTuple_ClearFreeList` incorrectly being present for Python 3.9 and up. [#1887](https://github.com/PyO3/pyo3/pull/1887) +- Fix panic in generated `#[derive(FromPyObject)]` for enums. [#1888](https://github.com/PyO3/pyo3/pull/1888) +- Fix cross-compiling to Python 3.7 builds with the "m" abi flag. [#1908](https://github.com/PyO3/pyo3/pull/1908) +- Fix `__mod__` magic method fallback to `__rmod__`. [#1934](https://github.com/PyO3/pyo3/pull/1934). +- Fix missing FFI definition `_PyImport_FindExtensionObject` on Python 3.10. [#1942](https://github.com/PyO3/pyo3/pull/1942) + +## [0.14.5] - 2021-09-05 + +### Added + +- Make `pyo3_build_config::InterpreterConfig` and subfields public. [#1848](https://github.com/PyO3/pyo3/pull/1848) +- Add `resolve-config` feature to the `pyo3-build-config` to control whether its build script does anything. [#1856](https://github.com/PyO3/pyo3/pull/1856) + +### Fixed + +- Fix 0.14.4 compile regression on `s390x-unknown-linux-gnu` target. [#1850](https://github.com/PyO3/pyo3/pull/1850) + +## [0.14.4] - 2021-08-29 + +### Changed + +- Mark `PyString::data` as `unsafe` and disable it and some supporting PyUnicode FFI APIs (which depend on a C bitfield) on big-endian targets. [#1834](https://github.com/PyO3/pyo3/pull/1834) + +## [0.14.3] - 2021-08-22 + +### Added + +- Add `PyString::data` to access the raw bytes stored in a Python string. [#1794](https://github.com/PyO3/pyo3/pull/1794) + +### Fixed + +- Raise `AttributeError` to avoid panic when calling `del` on a `#[setter]` defined class property. [#1779](https://github.com/PyO3/pyo3/pull/1779) +- Restrict FFI definitions `PyGILState_Check` and `Py_tracefunc` to the unlimited API. [#1787](https://github.com/PyO3/pyo3/pull/1787) +- Add missing `_type` field to `PyStatus` struct definition. [#1791](https://github.com/PyO3/pyo3/pull/1791) +- Reduce lower bound `num-complex` optional dependency to support interop with `rust-numpy` and `ndarray` when building with the MSRV of 1.41 [#1799](https://github.com/PyO3/pyo3/pull/1799) +- Fix memory leak in `Python::run_code`. [#1806](https://github.com/PyO3/pyo3/pull/1806) +- Fix memory leak in `PyModule::from_code`. [#1810](https://github.com/PyO3/pyo3/pull/1810) +- Remove use of `pyo3::` in `pyo3::types::datetime` which broke builds using `-Z avoid-dev-deps` [#1811](https://github.com/PyO3/pyo3/pull/1811) + +## [0.14.2] - 2021-08-09 + +### Added + +- Add `indexmap` feature to add `ToPyObject`, `IntoPy` and `FromPyObject` implementations for `indexmap::IndexMap`. [#1728](https://github.com/PyO3/pyo3/pull/1728) +- Add `pyo3_build_config::add_extension_module_link_args` to use in build scripts to set linker arguments (for macOS). [#1755](https://github.com/PyO3/pyo3/pull/1755) +- Add `Python::with_gil_unchecked` unsafe variation of `Python::with_gil` to allow obtaining a `Python` in scenarios where `Python::with_gil` would fail. [#1769](https://github.com/PyO3/pyo3/pull/1769) + +### Changed + +- `PyErr::new` no longer acquires the Python GIL internally. [#1724](https://github.com/PyO3/pyo3/pull/1724) +- Reverted PyO3 0.14.0's use of `cargo:rustc-cdylib-link-arg` in its build script, as Cargo unintentionally allowed crates to pass linker args to downstream crates in this way. Projects supporting macOS may need to restore `.cargo/config.toml` files. [#1755](https://github.com/PyO3/pyo3/pull/1755) + +### Fixed + +- Fix regression in 0.14.0 rejecting usage of `#[doc(hidden)]` on structs and functions annotated with PyO3 macros. [#1722](https://github.com/PyO3/pyo3/pull/1722) +- Fix regression in 0.14.0 leading to incorrect code coverage being computed for `#[pyfunction]`s. [#1726](https://github.com/PyO3/pyo3/pull/1726) +- Fix incorrect FFI definition of `Py_Buffer` on PyPy. [#1737](https://github.com/PyO3/pyo3/pull/1737) +- Fix incorrect calculation of `dictoffset` on 32-bit Windows. [#1475](https://github.com/PyO3/pyo3/pull/1475) +- Fix regression in 0.13.2 leading to linking to incorrect Python library on Windows "gnu" targets. [#1759](https://github.com/PyO3/pyo3/pull/1759) +- Fix compiler warning: deny trailing semicolons in expression macro. [#1762](https://github.com/PyO3/pyo3/pull/1762) +- Fix incorrect FFI definition of `Py_DecodeLocale`. The 2nd argument is now `*mut Py_ssize_t` instead of `Py_ssize_t`. [#1766](https://github.com/PyO3/pyo3/pull/1766) + +## [0.14.1] - 2021-07-04 + +### Added + +- Implement `IntoPy` for `&PathBuf` and `&OsString`. [#1712](https://github.com/PyO3/pyo3/pull/1712) + +### Fixed + +- Fix crashes on PyPy due to incorrect definitions of `PyList_SET_ITEM`. [#1713](https://github.com/PyO3/pyo3/pull/1713) + +## [0.14.0] - 2021-07-03 + +### Packaging + +- Update `num-bigint` optional dependency to 0.4. [#1481](https://github.com/PyO3/pyo3/pull/1481) +- Update `num-complex` optional dependency to 0.4. [#1482](https://github.com/PyO3/pyo3/pull/1482) +- Extend `hashbrown` optional dependency supported versions to include 0.11. [#1496](https://github.com/PyO3/pyo3/pull/1496) +- Support PyPy 3.7. [#1538](https://github.com/PyO3/pyo3/pull/1538) + +### Added + +- Extend conversions for `[T; N]` to all `N` using const generics (on Rust 1.51 and up). [#1128](https://github.com/PyO3/pyo3/pull/1128) +- Add conversions between `OsStr`/ `OsString` and Python strings. [#1379](https://github.com/PyO3/pyo3/pull/1379) +- Add conversions between `Path`/ `PathBuf` and Python strings (and `pathlib.Path` objects). [#1379](https://github.com/PyO3/pyo3/pull/1379) [#1654](https://github.com/PyO3/pyo3/pull/1654) +- Add a new set of `#[pyo3(...)]` attributes to control various PyO3 macro functionality: + - `#[pyo3(from_py_with = "...")]` function arguments and struct fields to override the default from-Python conversion. [#1411](https://github.com/PyO3/pyo3/pull/1411) + - `#[pyo3(name = "...")]` for setting Python names. [#1567](https://github.com/PyO3/pyo3/pull/1567) + - `#[pyo3(text_signature = "...")]` for setting text signature. [#1658](https://github.com/PyO3/pyo3/pull/1658) +- Add FFI definition `PyCFunction_CheckExact` for Python 3.9 and later. [#1425](https://github.com/PyO3/pyo3/pull/1425) +- Add FFI definition `Py_IS_TYPE`. [#1429](https://github.com/PyO3/pyo3/pull/1429) +- Add FFI definition `_Py_InitializeMain`. [#1473](https://github.com/PyO3/pyo3/pull/1473) +- Add FFI definitions from `cpython/import.h`.[#1475](https://github.com/PyO3/pyo3/pull/1475) +- Add tuple and unit struct support for `#[pyclass]` macro. [#1504](https://github.com/PyO3/pyo3/pull/1504) +- Add FFI definition `PyDateTime_TimeZone_UTC`. [#1572](https://github.com/PyO3/pyo3/pull/1572) +- Add support for `#[pyclass(extends=Exception)]`. [#1591](https://github.com/PyO3/pyo3/pull/1591) +- Add `PyErr::cause` and `PyErr::set_cause`. [#1679](https://github.com/PyO3/pyo3/pull/1679) +- Add FFI definitions from `cpython/pystate.h`. [#1687](https://github.com/PyO3/pyo3/pull/1687/) +- Add `wrap_pyfunction!` macro to `pyo3::prelude`. [#1695](https://github.com/PyO3/pyo3/pull/1695) + +### Changed + +- Allow only one `#[pymethods]` block per `#[pyclass]` by default, to remove the dependency on `inventory`. Add a `multiple-pymethods` feature to opt-in the original behavior and dependency on `inventory`. [#1457](https://github.com/PyO3/pyo3/pull/1457) +- Change `PyTimeAccess::get_fold` to return a `bool` instead of a `u8`. [#1397](https://github.com/PyO3/pyo3/pull/1397) +- Deprecate FFI definition `PyCFunction_Call` for Python 3.9 and up. [#1425](https://github.com/PyO3/pyo3/pull/1425) +- Deprecate FFI definition `PyModule_GetFilename`. [#1425](https://github.com/PyO3/pyo3/pull/1425) +- The `auto-initialize` feature is no longer enabled by default. [#1443](https://github.com/PyO3/pyo3/pull/1443) +- Change `PyCFunction::new` and `PyCFunction::new_with_keywords` to take `&'static str` arguments rather than implicitly copying (and leaking) them. [#1450](https://github.com/PyO3/pyo3/pull/1450) +- Deprecate `PyModule::call`, `PyModule::call0`, `PyModule::call1` and `PyModule::get`. [#1492](https://github.com/PyO3/pyo3/pull/1492) +- Add length information to `PyBufferError`s raised from `PyBuffer::copy_to_slice` and `PyBuffer::copy_from_slice`. [#1534](https://github.com/PyO3/pyo3/pull/1534) +- Automatically set `-undefined` and `dynamic_lookup` linker arguments on macOS with the `extension-module` feature. [#1539](https://github.com/PyO3/pyo3/pull/1539) +- Deprecate `#[pyproto]` methods which are easier to implement as `#[pymethods]`: [#1560](https://github.com/PyO3/pyo3/pull/1560) + - `PyBasicProtocol::__bytes__` and `PyBasicProtocol::__format__` + - `PyContextProtocol::__enter__` and `PyContextProtocol::__exit__` + - `PyDescrProtocol::__delete__` and `PyDescrProtocol::__set_name__` + - `PyMappingProtocol::__reversed__` + - `PyNumberProtocol::__complex__` and `PyNumberProtocol::__round__` + - `PyAsyncProtocol::__aenter__` and `PyAsyncProtocol::__aexit__` +- Deprecate several attributes in favor of the new `#[pyo3(...)]` options: + - `#[name = "..."]`, replaced by `#[pyo3(name = "...")]` [#1567](https://github.com/PyO3/pyo3/pull/1567) + - `#[pyfn(m, "name")]`, replaced by `#[pyfn(m)] #[pyo3(name = "...")]`. [#1610](https://github.com/PyO3/pyo3/pull/1610) + - `#[pymodule(name)]`, replaced by `#[pymodule] #[pyo3(name = "...")]` [#1650](https://github.com/PyO3/pyo3/pull/1650) + - `#[text_signature = "..."]`, replaced by `#[pyo3(text_signature = "...")]`. [#1658](https://github.com/PyO3/pyo3/pull/1658) +- Reduce LLVM line counts to improve compilation times. [#1604](https://github.com/PyO3/pyo3/pull/1604) +- No longer call `PyEval_InitThreads` in `#[pymodule]` init code. [#1630](https://github.com/PyO3/pyo3/pull/1630) +- Use `METH_FASTCALL` argument passing convention, when possible, to improve `#[pyfunction]` and method performance. + [#1619](https://github.com/PyO3/pyo3/pull/1619), [#1660](https://github.com/PyO3/pyo3/pull/1660) +- Filter sysconfigdata candidates by architecture when cross-compiling. [#1626](https://github.com/PyO3/pyo3/pull/1626) + +### Removed + +- Remove deprecated exception names `BaseException` etc. [#1426](https://github.com/PyO3/pyo3/pull/1426) +- Remove deprecated methods `Python::is_instance`, `Python::is_subclass`, `Python::release`, `Python::xdecref`, and `Py::from_owned_ptr_or_panic`. [#1426](https://github.com/PyO3/pyo3/pull/1426) +- Remove many FFI definitions which never existed in the Python C-API: + - (previously deprecated) `PyGetSetDef_INIT`, `PyGetSetDef_DICT`, `PyCoro_Check`, `PyCoroWrapper_Check`, and `PyAsyncGen_Check` [#1426](https://github.com/PyO3/pyo3/pull/1426) + - `PyMethodDef_INIT` [#1426](https://github.com/PyO3/pyo3/pull/1426) + - `PyTypeObject_INIT` [#1429](https://github.com/PyO3/pyo3/pull/1429) + - `PyObject_Check`, `PySuper_Check`, and `FreeFunc` [#1438](https://github.com/PyO3/pyo3/pull/1438) + - `PyModuleDef_INIT` [#1630](https://github.com/PyO3/pyo3/pull/1630) +- Remove pyclass implementation details from `PyTypeInfo`: + - `Type`, `DESCRIPTION`, and `FLAGS` [#1456](https://github.com/PyO3/pyo3/pull/1456) + - `BaseType`, `BaseLayout`, `Layout`, `Initializer` [#1596](https://github.com/PyO3/pyo3/pull/1596) +- Remove `PYO3_CROSS_INCLUDE_DIR` environment variable and the associated C header parsing functionality. [#1521](https://github.com/PyO3/pyo3/pull/1521) +- Remove `raw_pycfunction!` macro. [#1619](https://github.com/PyO3/pyo3/pull/1619) +- Remove `PyClassAlloc` trait. [#1657](https://github.com/PyO3/pyo3/pull/1657) +- Remove `PyList::get_parked_item`. [#1664](https://github.com/PyO3/pyo3/pull/1664) + +### Fixed + +- Remove FFI definition `PyCFunction_ClearFreeList` for Python 3.9 and later. [#1425](https://github.com/PyO3/pyo3/pull/1425) +- `PYO3_CROSS_LIB_DIR` environment variable no long required when compiling for x86-64 Python from macOS arm64 and reverse. [#1428](https://github.com/PyO3/pyo3/pull/1428) +- Fix FFI definition `_PyEval_RequestCodeExtraIndex`, which took an argument of the wrong type. [#1429](https://github.com/PyO3/pyo3/pull/1429) +- Fix FFI definition `PyIndex_Check` missing with the `abi3` feature. [#1436](https://github.com/PyO3/pyo3/pull/1436) +- Fix incorrect `TypeError` raised when keyword-only argument passed along with a positional argument in `*args`. [#1440](https://github.com/PyO3/pyo3/pull/1440) +- Fix inability to use a named lifetime for `&PyTuple` of `*args` in `#[pyfunction]`. [#1440](https://github.com/PyO3/pyo3/pull/1440) +- Fix use of Python argument for `#[pymethods]` inside macro expansions. [#1505](https://github.com/PyO3/pyo3/pull/1505) +- No longer include `__doc__` in `__all__` generated for `#[pymodule]`. [#1509](https://github.com/PyO3/pyo3/pull/1509) +- Always use cross-compiling configuration if any of the `PYO3_CROSS` family of environment variables are set. [#1514](https://github.com/PyO3/pyo3/pull/1514) +- Support `EnvironmentError`, `IOError`, and `WindowsError` on PyPy. [#1533](https://github.com/PyO3/pyo3/pull/1533) +- Fix unnecessary rebuilds when cycling between `cargo check` and `cargo clippy` in a Python virtualenv. [#1557](https://github.com/PyO3/pyo3/pull/1557) +- Fix segfault when dereferencing `ffi::PyDateTimeAPI` without the GIL. [#1563](https://github.com/PyO3/pyo3/pull/1563) +- Fix memory leak in `FromPyObject` implementations for `u128` and `i128`. [#1638](https://github.com/PyO3/pyo3/pull/1638) +- Fix `#[pyclass(extends=PyDict)]` leaking the dict contents on drop. [#1657](https://github.com/PyO3/pyo3/pull/1657) +- Fix segfault when calling `PyList::get_item` with negative indices. [#1668](https://github.com/PyO3/pyo3/pull/1668) +- Fix FFI definitions of `PyEval_SetProfile`/`PyEval_SetTrace` to take `Option` parameters. [#1692](https://github.com/PyO3/pyo3/pull/1692) +- Fix `ToPyObject` impl for `HashSet` to accept non-default hashers. [#1702](https://github.com/PyO3/pyo3/pull/1702) + +## [0.13.2] - 2021-02-12 + +### Packaging + +- Lower minimum supported Rust version to 1.41. [#1421](https://github.com/PyO3/pyo3/pull/1421) + +### Added + +- Add unsafe API `with_embedded_python_interpreter` to initialize a Python interpreter, execute a closure, and finalize the interpreter. [#1355](https://github.com/PyO3/pyo3/pull/1355) +- Add `serde` feature which provides implementations of `Serialize` and `Deserialize` for `Py`. [#1366](https://github.com/PyO3/pyo3/pull/1366) +- Add FFI definition `_PyCFunctionFastWithKeywords` on Python 3.7 and up. [#1384](https://github.com/PyO3/pyo3/pull/1384) +- Add `PyDateTime::new_with_fold` method. [#1398](https://github.com/PyO3/pyo3/pull/1398) +- Add `size_hint` impls for `{PyDict,PyList,PySet,PyTuple}Iterator`s. [#1699](https://github.com/PyO3/pyo3/pull/1699) + +### Changed + +- `prepare_freethreaded_python` will no longer register an `atexit` handler to call `Py_Finalize`. This resolves a number of issues with incompatible C extensions causing crashes at finalization. [#1355](https://github.com/PyO3/pyo3/pull/1355) +- Mark `PyLayout::py_init`, `PyClassDict::clear_dict`, and `opt_to_pyobj` safe, as they do not perform any unsafe operations. [#1404](https://github.com/PyO3/pyo3/pull/1404) + +### Fixed + +- Fix support for using `r#raw_idents` as argument names in pyfunctions. [#1383](https://github.com/PyO3/pyo3/pull/1383) +- Fix typo in FFI definition for `PyFunction_GetCode` (was incorrectly `PyFunction_Code`). [#1387](https://github.com/PyO3/pyo3/pull/1387) +- Fix FFI definitions `PyMarshal_WriteObjectToString` and `PyMarshal_ReadObjectFromString` as available in limited API. [#1387](https://github.com/PyO3/pyo3/pull/1387) +- Fix FFI definitions `PyListObject` and those from `funcobject.h` as requiring non-limited API. [#1387](https://github.com/PyO3/pyo3/pull/1387) +- Fix unqualified `Result` usage in `pyobject_native_type_base`. [#1402](https://github.com/PyO3/pyo3/pull/1402) +- Fix build on systems where the default Python encoding is not UTF-8. [#1405](https://github.com/PyO3/pyo3/pull/1405) +- Fix build on mingw / MSYS2. [#1423](https://github.com/PyO3/pyo3/pull/1423) + +## [0.13.1] - 2021-01-10 + +### Added + +- Add support for `#[pyclass(dict)]` and `#[pyclass(weakref)]` with the `abi3` feature on Python 3.9 and up. [#1342](https://github.com/PyO3/pyo3/pull/1342) +- Add FFI definitions `PyOS_BeforeFork`, `PyOS_AfterFork_Parent`, `PyOS_AfterFork_Child` for Python 3.7 and up. [#1348](https://github.com/PyO3/pyo3/pull/1348) +- Add an `auto-initialize` feature to control whether PyO3 should automatically initialize an embedded Python interpreter. For compatibility this feature is enabled by default in PyO3 0.13.1, but is planned to become opt-in from PyO3 0.14.0. [#1347](https://github.com/PyO3/pyo3/pull/1347) +- Add support for cross-compiling to Windows without needing `PYO3_CROSS_INCLUDE_DIR`. [#1350](https://github.com/PyO3/pyo3/pull/1350) + +### Deprecated + +- Deprecate FFI definitions `PyEval_CallObjectWithKeywords`, `PyEval_CallObject`, `PyEval_CallFunction`, `PyEval_CallMethod` when building for Python 3.9. [#1338](https://github.com/PyO3/pyo3/pull/1338) +- Deprecate FFI definitions `PyGetSetDef_DICT` and `PyGetSetDef_INIT` which have never been in the Python API. [#1341](https://github.com/PyO3/pyo3/pull/1341) +- Deprecate FFI definitions `PyGen_NeedsFinalizing`, `PyImport_Cleanup` (removed in 3.9), and `PyOS_InitInterrupts` (3.10). [#1348](https://github.com/PyO3/pyo3/pull/1348) +- Deprecate FFI definition `PyOS_AfterFork` for Python 3.7 and up. [#1348](https://github.com/PyO3/pyo3/pull/1348) +- Deprecate FFI definitions `PyCoro_Check`, `PyAsyncGen_Check`, and `PyCoroWrapper_Check`, which have never been in the Python API (for the first two, it is possible to use `PyCoro_CheckExact` and `PyAsyncGen_CheckExact` instead; these are the actual functions provided by the Python API). [#1348](https://github.com/PyO3/pyo3/pull/1348) +- Deprecate FFI definitions for `PyUnicode_FromUnicode`, `PyUnicode_AsUnicode` and `PyUnicode_AsUnicodeAndSize`, which will be removed from 3.12 and up due to [PEP 623](https://www.python.org/dev/peps/pep-0623/). [#1370](https://github.com/PyO3/pyo3/pull/1370) + +### Removed + +- Remove FFI definition `PyFrame_ClearFreeList` when building for Python 3.9. [#1341](https://github.com/PyO3/pyo3/pull/1341) +- Remove FFI definition `_PyDict_Contains` when building for Python 3.10. [#1341](https://github.com/PyO3/pyo3/pull/1341) +- Remove FFI definitions `PyGen_NeedsFinalizing` and `PyImport_Cleanup` (for 3.9 and up), and `PyOS_InitInterrupts` (3.10). [#1348](https://github.com/PyO3/pyo3/pull/1348) + +### Fixed + +- Stop including `Py_TRACE_REFS` config setting automatically if `Py_DEBUG` is set on Python 3.8 and up. [#1334](https://github.com/PyO3/pyo3/pull/1334) +- Remove `#[deny(warnings)]` attribute (and instead refuse warnings only in CI). [#1340](https://github.com/PyO3/pyo3/pull/1340) +- Fix deprecation warning for missing `__module__` with `#[pyclass]`. [#1343](https://github.com/PyO3/pyo3/pull/1343) +- Correct return type of `PyFrozenSet::empty` to `&PyFrozenSet` (was incorrectly `&PySet`). [#1351](https://github.com/PyO3/pyo3/pull/1351) +- Fix missing `Py_INCREF` on heap type objects on Python versions before 3.8. [#1365](https://github.com/PyO3/pyo3/pull/1365) + +## [0.13.0] - 2020-12-22 + +### Packaging + +- Drop support for Python 3.5 (as it is now end-of-life). [#1250](https://github.com/PyO3/pyo3/pull/1250) +- Bump minimum supported Rust version to 1.45. [#1272](https://github.com/PyO3/pyo3/pull/1272) +- Bump indoc dependency to 1.0. [#1272](https://github.com/PyO3/pyo3/pull/1272) +- Bump paste dependency to 1.0. [#1272](https://github.com/PyO3/pyo3/pull/1272) +- Rename internal crates `pyo3cls` and `pyo3-derive-backend` to `pyo3-macros` and `pyo3-macros-backend` respectively. [#1317](https://github.com/PyO3/pyo3/pull/1317) + +### Added + +- Add support for building for CPython limited API. Opting-in to the limited API enables a single extension wheel built with PyO3 to be installable on multiple Python versions. This required a few minor changes to runtime behavior of of PyO3 `#[pyclass]` types. See the migration guide for full details. [#1152](https://github.com/PyO3/pyo3/pull/1152) + - Add feature flags `abi3-py36`, `abi3-py37`, `abi3-py38` etc. to set the minimum Python version when using the limited API. [#1263](https://github.com/PyO3/pyo3/pull/1263) +- Add argument names to `TypeError` messages generated by pymethod wrappers. [#1212](https://github.com/PyO3/pyo3/pull/1212) +- Add FFI definitions for PEP 587 "Python Initialization Configuration". [#1247](https://github.com/PyO3/pyo3/pull/1247) +- Add FFI definitions for `PyEval_SetProfile` and `PyEval_SetTrace`. [#1255](https://github.com/PyO3/pyo3/pull/1255) +- Add FFI definitions for context.h functions (`PyContext_New`, etc). [#1259](https://github.com/PyO3/pyo3/pull/1259) +- Add `PyAny::is_instance` method. [#1276](https://github.com/PyO3/pyo3/pull/1276) +- Add support for conversion between `char` and `PyString`. [#1282](https://github.com/PyO3/pyo3/pull/1282) +- Add FFI definitions for `PyBuffer_SizeFromFormat`, `PyObject_LengthHint`, `PyObject_CallNoArgs`, `PyObject_CallOneArg`, `PyObject_CallMethodNoArgs`, `PyObject_CallMethodOneArg`, `PyObject_VectorcallDict`, and `PyObject_VectorcallMethod`. [#1287](https://github.com/PyO3/pyo3/pull/1287) +- Add conversions between `u128`/`i128` and `PyLong` for PyPy. [#1310](https://github.com/PyO3/pyo3/pull/1310) +- Add `Python::version` and `Python::version_info` to get the running interpreter version. [#1322](https://github.com/PyO3/pyo3/pull/1322) +- Add conversions for tuples of length 10, 11, and 12. [#1454](https://github.com/PyO3/pyo3/pull/1454) + +### Changed + +- Change return type of `PyType::name` from `Cow` to `PyResult<&str>`. [#1152](https://github.com/PyO3/pyo3/pull/1152) +- `#[pyclass(subclass)]` is now required for subclassing from Rust (was previously just required for subclassing from Python). [#1152](https://github.com/PyO3/pyo3/pull/1152) +- Change `PyIterator` to be consistent with other native types: it is now used as `&PyIterator` instead of `PyIterator<'a>`. [#1176](https://github.com/PyO3/pyo3/pull/1176) +- Change formatting of `PyDowncastError` messages to be closer to Python's builtin error messages. [#1212](https://github.com/PyO3/pyo3/pull/1212) +- Change `Debug` and `Display` impls for `PyException` to be consistent with `PyAny`. [#1275](https://github.com/PyO3/pyo3/pull/1275) +- Change `Debug` impl of `PyErr` to output more helpful information (acquiring the GIL if necessary). [#1275](https://github.com/PyO3/pyo3/pull/1275) +- Rename `PyTypeInfo::is_instance` and `PyTypeInfo::is_exact_instance` to `PyTypeInfo::is_type_of` and `PyTypeInfo::is_exact_type_of`. [#1278](https://github.com/PyO3/pyo3/pull/1278) +- Optimize `PyAny::call0`, `Py::call0` and `PyAny::call_method0` and `Py::call_method0` on Python 3.9 and up. [#1287](https://github.com/PyO3/pyo3/pull/1285) +- Require double-quotes for pyclass name argument e.g `#[pyclass(name = "MyClass")]`. [#1303](https://github.com/PyO3/pyo3/pull/1303) + +### Deprecated + +- Deprecate `Python::is_instance`, `Python::is_subclass`, `Python::release`, and `Python::xdecref`. [#1292](https://github.com/PyO3/pyo3/pull/1292) + +### Removed + +- Remove deprecated ffi definitions `PyUnicode_AsUnicodeCopy`, `PyUnicode_GetMax`, `_Py_CheckRecursionLimit`, `PyObject_AsCharBuffer`, `PyObject_AsReadBuffer`, `PyObject_CheckReadBuffer` and `PyObject_AsWriteBuffer`, which will be removed in Python 3.10. [#1217](https://github.com/PyO3/pyo3/pull/1217) +- Remove unused `python3` feature. [#1235](https://github.com/PyO3/pyo3/pull/1235) + +### Fixed + +- Fix missing field in `PyCodeObject` struct (`co_posonlyargcount`) - caused invalid access to other fields in Python >3.7. [#1260](https://github.com/PyO3/pyo3/pull/1260) +- Fix building for `x86_64-unknown-linux-musl` target from `x86_64-unknown-linux-gnu` host. [#1267](https://github.com/PyO3/pyo3/pull/1267) +- Fix `#[text_signature]` interacting badly with rust `r#raw_identifiers`. [#1286](https://github.com/PyO3/pyo3/pull/1286) +- Fix FFI definitions for `PyObject_Vectorcall` and `PyVectorcall_Call`. [#1287](https://github.com/PyO3/pyo3/pull/1285) +- Fix building with Anaconda python inside a virtualenv. [#1290](https://github.com/PyO3/pyo3/pull/1290) +- Fix definition of opaque FFI types. [#1312](https://github.com/PyO3/pyo3/pull/1312) +- Fix using custom error type in pyclass `#[new]` methods. [#1319](https://github.com/PyO3/pyo3/pull/1319) + +## [0.12.4] - 2020-11-28 + +### Fixed + +- Fix reference count bug in implementation of `From>` for `PyObject`, a regression introduced in PyO3 0.12. [#1297](https://github.com/PyO3/pyo3/pull/1297) + +## [0.12.3] - 2020-10-12 + +### Fixed + +- Fix support for Rust versions 1.39 to 1.44, broken by an incorrect internal update to paste 1.0 which was done in PyO3 0.12.2. [#1234](https://github.com/PyO3/pyo3/pull/1234) + +## [0.12.2] - 2020-10-12 + +### Added + +- Add support for keyword-only arguments without default values in `#[pyfunction]`. [#1209](https://github.com/PyO3/pyo3/pull/1209) +- Add `Python::check_signals` as a safe a wrapper for `PyErr_CheckSignals`. [#1214](https://github.com/PyO3/pyo3/pull/1214) + +### Fixed + +- Fix invalid document for protocol methods. [#1169](https://github.com/PyO3/pyo3/pull/1169) +- Hide docs of PyO3 private implementation details in `pyo3::class::methods`. [#1169](https://github.com/PyO3/pyo3/pull/1169) +- Fix unnecessary rebuild on PATH changes when the python interpreter is provided by PYO3_PYTHON. [#1231](https://github.com/PyO3/pyo3/pull/1231) + +## [0.12.1] - 2020-09-16 + +### Fixed + +- Fix building for a 32-bit Python on 64-bit Windows with a 64-bit Rust toolchain. [#1179](https://github.com/PyO3/pyo3/pull/1179) +- Fix building on platforms where `c_char` is `u8`. [#1182](https://github.com/PyO3/pyo3/pull/1182) + +## [0.12.0] - 2020-09-12 + +### Added + +- Add FFI definitions `Py_FinalizeEx`, `PyOS_getsig`, and `PyOS_setsig`. [#1021](https://github.com/PyO3/pyo3/pull/1021) +- Add `PyString::to_str` for accessing `PyString` as `&str`. [#1023](https://github.com/PyO3/pyo3/pull/1023) +- Add `Python::with_gil` for executing a closure with the Python GIL. [#1037](https://github.com/PyO3/pyo3/pull/1037) +- Add type information to failures in `PyAny::downcast`. [#1050](https://github.com/PyO3/pyo3/pull/1050) +- Implement `Debug` for `PyIterator`. [#1051](https://github.com/PyO3/pyo3/pull/1051) +- Add `PyBytes::new_with` and `PyByteArray::new_with` for initialising `bytes` and `bytearray` objects using a closure. [#1074](https://github.com/PyO3/pyo3/pull/1074) +- Add `#[derive(FromPyObject)]` macro for enums and structs. [#1065](https://github.com/PyO3/pyo3/pull/1065) +- Add `Py::as_ref` and `Py::into_ref` for converting `Py` to `&T`. [#1098](https://github.com/PyO3/pyo3/pull/1098) +- Add ability to return `Result` types other than `PyResult` from `#[pyfunction]`, `#[pymethod]` and `#[pyproto]` functions. [#1106](https://github.com/PyO3/pyo3/pull/1118). +- Implement `ToPyObject`, `IntoPy`, and `FromPyObject` for [hashbrown](https://crates.io/crates/hashbrown)'s `HashMap` and `HashSet` types (requires the `hashbrown` feature). [#1114](https://github.com/PyO3/pyo3/pull/1114) +- Add `#[pyfunction(pass_module)]` and `#[pyfn(pass_module)]` to pass the module object as the first function argument. [#1143](https://github.com/PyO3/pyo3/pull/1143) +- Add `PyModule::add_function` and `PyModule::add_submodule` as typed alternatives to `PyModule::add_wrapped`. [#1143](https://github.com/PyO3/pyo3/pull/1143) +- Add native `PyCFunction` and `PyFunction` types. [#1163](https://github.com/PyO3/pyo3/pull/1163) + +### Changed + +- Rework exception types: [#1024](https://github.com/PyO3/pyo3/pull/1024) [#1115](https://github.com/PyO3/pyo3/pull/1115) + - Rename exception types from e.g. `RuntimeError` to `PyRuntimeError`. The old names continue to exist but are deprecated. + - Exception objects are now accessible as `&T` or `Py`, just like other Python-native types. + - Rename `PyException::py_err` to `PyException::new_err`. + - Rename `PyUnicodeDecodeErr::new_err` to `PyUnicodeDecodeErr::new`. + - Remove `PyStopIteration::stop_iteration`. +- Require `T: Send` for the return value `T` of `Python::allow_threads`. [#1036](https://github.com/PyO3/pyo3/pull/1036) +- Rename `PYTHON_SYS_EXECUTABLE` to `PYO3_PYTHON`. The old name will continue to work (undocumented) but will be removed in a future release. [#1039](https://github.com/PyO3/pyo3/pull/1039) +- Remove `unsafe` from signature of `PyType::as_type_ptr`. [#1047](https://github.com/PyO3/pyo3/pull/1047) +- Change return type of `PyIterator::from_object` to `PyResult` (was `Result`). [#1051](https://github.com/PyO3/pyo3/pull/1051) +- `IntoPy` is no longer implied by `FromPy`. [#1063](https://github.com/PyO3/pyo3/pull/1063) +- Change `PyObject` to be a type alias for `Py`. [#1063](https://github.com/PyO3/pyo3/pull/1063) +- Rework `PyErr` to be compatible with the `std::error::Error` trait: [#1067](https://github.com/PyO3/pyo3/pull/1067) [#1115](https://github.com/PyO3/pyo3/pull/1115) + - Implement `Display`, `Error`, `Send` and `Sync` for `PyErr` and `PyErrArguments`. + - Add `PyErr::instance` for accessing `PyErr` as `&PyBaseException`. + - `PyErr`'s fields are now an implementation detail. The equivalent values can be accessed with `PyErr::ptype`, `PyErr::pvalue` and `PyErr::ptraceback`. + - Change receiver of `PyErr::print` and `PyErr::print_and_set_sys_last_vars` to `&self` (was `self`). + - Remove `PyErrValue`, `PyErr::from_value`, `PyErr::into_normalized`, and `PyErr::normalize`. + - Remove `PyException::into`. + - Remove `Into>` for `PyErr` and `PyException`. +- Change methods generated by `#[pyproto]` to return `NotImplemented` if Python should try a reversed operation. #[1072](https://github.com/PyO3/pyo3/pull/1072) +- Change argument to `PyModule::add` to `impl IntoPy` (was `impl ToPyObject`). #[1124](https://github.com/PyO3/pyo3/pull/1124) + +### Removed + +- Remove many exception and `PyErr` APIs; see the "changed" section above. [#1024](https://github.com/PyO3/pyo3/pull/1024) [#1067](https://github.com/PyO3/pyo3/pull/1067) [#1115](https://github.com/PyO3/pyo3/pull/1115) +- Remove `PyString::to_string` (use new `PyString::to_str`). [#1023](https://github.com/PyO3/pyo3/pull/1023) +- Remove `PyString::as_bytes`. [#1023](https://github.com/PyO3/pyo3/pull/1023) +- Remove `Python::register_any`. [#1023](https://github.com/PyO3/pyo3/pull/1023) +- Remove `GILGuard::acquire` from the public API. Use `Python::acquire_gil` or `Python::with_gil`. [#1036](https://github.com/PyO3/pyo3/pull/1036) +- Remove the `FromPy` trait. [#1063](https://github.com/PyO3/pyo3/pull/1063) +- Remove the `AsPyRef` trait. [#1098](https://github.com/PyO3/pyo3/pull/1098) + +### Fixed + +- Correct FFI definitions `Py_SetProgramName` and `Py_SetPythonHome` to take `*const` arguments (was `*mut`). [#1021](https://github.com/PyO3/pyo3/pull/1021) +- Fix `FromPyObject` for `num_bigint::BigInt` for Python objects with an `__index__` method. [#1027](https://github.com/PyO3/pyo3/pull/1027) +- Correct FFI definition `_PyLong_AsByteArray` to take `*mut c_uchar` argument (was `*const c_uchar`). [#1029](https://github.com/PyO3/pyo3/pull/1029) +- Fix segfault with `#[pyclass(dict, unsendable)]`. [#1058](https://github.com/PyO3/pyo3/pull/1058) [#1059](https://github.com/PyO3/pyo3/pull/1059) +- Fix using `&Self` as an argument type for functions in a `#[pymethods]` block. [#1071](https://github.com/PyO3/pyo3/pull/1071) +- Fix best-effort build against PyPy 3.6. [#1092](https://github.com/PyO3/pyo3/pull/1092) +- Fix many cases of lifetime elision in `#[pyproto]` implementations. [#1093](https://github.com/PyO3/pyo3/pull/1093) +- Fix detection of Python build configuration when cross-compiling. [#1095](https://github.com/PyO3/pyo3/pull/1095) +- Always link against libpython on android with the `extension-module` feature. [#1095](https://github.com/PyO3/pyo3/pull/1095) +- Fix the `+` operator not trying `__radd__` when both `__add__` and `__radd__` are defined in `PyNumberProtocol` (and similar for all other reversible operators). [#1107](https://github.com/PyO3/pyo3/pull/1107) +- Fix building with Anaconda python. [#1175](https://github.com/PyO3/pyo3/pull/1175) + +## [0.11.1] - 2020-06-30 + +### Added + +- `#[pyclass(unsendable)]`. [#1009](https://github.com/PyO3/pyo3/pull/1009) + +### Changed + +- Update `parking_lot` dependency to `0.11`. [#1010](https://github.com/PyO3/pyo3/pull/1010) + +## [0.11.0] - 2020-06-28 + +### Added + +- Support stable versions of Rust (>=1.39). [#969](https://github.com/PyO3/pyo3/pull/969) +- Add FFI definition `PyObject_AsFileDescriptor`. [#938](https://github.com/PyO3/pyo3/pull/938) +- Add `PyByteArray::data`, `PyByteArray::as_bytes`, and `PyByteArray::as_bytes_mut`. [#967](https://github.com/PyO3/pyo3/pull/967) +- Add `GILOnceCell` to use in situations where `lazy_static` or `once_cell` can deadlock. [#975](https://github.com/PyO3/pyo3/pull/975) +- Add `Py::borrow`, `Py::borrow_mut`, `Py::try_borrow`, and `Py::try_borrow_mut` for accessing `#[pyclass]` values. [#976](https://github.com/PyO3/pyo3/pull/976) +- Add `IterNextOutput` and `IterANextOutput` for returning from `__next__` / `__anext__`. [#997](https://github.com/PyO3/pyo3/pull/997) + +### Changed + +- Simplify internals of `#[pyo3(get)]` attribute. (Remove the hidden API `GetPropertyValue`.) [#934](https://github.com/PyO3/pyo3/pull/934) +- Call `Py_Finalize` at exit to flush buffers, etc. [#943](https://github.com/PyO3/pyo3/pull/943) +- Add type parameter to PyBuffer. #[951](https://github.com/PyO3/pyo3/pull/951) +- Require `Send` bound for `#[pyclass]`. [#966](https://github.com/PyO3/pyo3/pull/966) +- Add `Python` argument to most methods on `PyObject` and `Py` to ensure GIL safety. [#970](https://github.com/PyO3/pyo3/pull/970) +- Change signature of `PyTypeObject::type_object` - now takes `Python` argument and returns `&PyType`. [#970](https://github.com/PyO3/pyo3/pull/970) +- Change return type of `PyTuple::slice` and `PyTuple::split_from` from `Py` to `&PyTuple`. [#970](https://github.com/PyO3/pyo3/pull/970) +- Change return type of `PyTuple::as_slice` to `&[&PyAny]`. [#971](https://github.com/PyO3/pyo3/pull/971) +- Rename `PyTypeInfo::type_object` to `type_object_raw`, and add `Python` argument. [#975](https://github.com/PyO3/pyo3/pull/975) +- Update `num-complex` optional dependency from `0.2` to `0.3`. [#977](https://github.com/PyO3/pyo3/pull/977) +- Update `num-bigint` optional dependency from `0.2` to `0.3`. [#978](https://github.com/PyO3/pyo3/pull/978) +- `#[pyproto]` is re-implemented without specialization. [#961](https://github.com/PyO3/pyo3/pull/961) +- `PyClassAlloc::alloc` is renamed to `PyClassAlloc::new`. [#990](https://github.com/PyO3/pyo3/pull/990) +- `#[pyproto]` methods can now have return value `T` or `PyResult` (previously only `PyResult` was supported). [#996](https://github.com/PyO3/pyo3/pull/996) +- `#[pyproto]` methods can now skip annotating the return type if it is `()`. [#998](https://github.com/PyO3/pyo3/pull/998) + +### Removed + +- Remove `ManagedPyRef` (unused, and needs specialization) [#930](https://github.com/PyO3/pyo3/pull/930) + +### Fixed + +- Fix passing explicit `None` to `Option` argument `#[pyfunction]` with a default value. [#936](https://github.com/PyO3/pyo3/pull/936) +- Fix `PyClass.__new__`'s not respecting subclasses when inherited by a Python class. [#990](https://github.com/PyO3/pyo3/pull/990) +- Fix returning `Option` from `#[pyproto]` methods. [#996](https://github.com/PyO3/pyo3/pull/996) +- Fix accepting `PyRef` and `PyRefMut` to `#[getter]` and `#[setter]` methods. [#999](https://github.com/PyO3/pyo3/pull/999) + +## [0.10.1] - 2020-05-14 + +### Fixed + +- Fix deadlock in `Python::acquire_gil` after dropping a `PyObject` or `Py`. [#924](https://github.com/PyO3/pyo3/pull/924) + +## [0.10.0] - 2020-05-13 + +### Added + +- Add FFI definition `_PyDict_NewPresized`. [#849](https://github.com/PyO3/pyo3/pull/849) +- Implement `IntoPy` for `HashSet` and `BTreeSet`. [#864](https://github.com/PyO3/pyo3/pull/864) +- Add `PyAny::dir` method. [#886](https://github.com/PyO3/pyo3/pull/886) +- Gate macros behind a `macros` feature (enabled by default). [#897](https://github.com/PyO3/pyo3/pull/897) +- Add ability to define class attributes using `#[classattr]` on functions in `#[pymethods]`. [#905](https://github.com/PyO3/pyo3/pull/905) +- Implement `Clone` for `PyObject` and `Py`. [#908](https://github.com/PyO3/pyo3/pull/908) +- Implement `Deref` for all builtin types. (`PyList`, `PyTuple`, `PyDict` etc.) [#911](https://github.com/PyO3/pyo3/pull/911) +- Implement `Deref` for `PyCell`. [#911](https://github.com/PyO3/pyo3/pull/911) +- Add `#[classattr]` support for associated constants in `#[pymethods]`. [#914](https://github.com/PyO3/pyo3/pull/914) + +### Changed + +- Panics will now be raised as a Python `PanicException`. [#797](https://github.com/PyO3/pyo3/pull/797) +- Change `PyObject` and `Py` reference counts to decrement immediately upon drop when the GIL is held. [#851](https://github.com/PyO3/pyo3/pull/851) +- Allow `PyIterProtocol` methods to use either `PyRef` or `PyRefMut` as the receiver type. [#856](https://github.com/PyO3/pyo3/pull/856) +- Change the implementation of `FromPyObject` for `Py` to apply to a wider range of `T`, including all `T: PyClass`. [#880](https://github.com/PyO3/pyo3/pull/880) +- Move all methods from the `ObjectProtocol` trait to the `PyAny` struct. [#911](https://github.com/PyO3/pyo3/pull/911) +- Remove need for `#![feature(specialization)]` in crates depending on PyO3. [#917](https://github.com/PyO3/pyo3/pull/917) + +### Removed + +- Remove `PyMethodsProtocol` trait. [#889](https://github.com/PyO3/pyo3/pull/889) +- Remove `num-traits` dependency. [#895](https://github.com/PyO3/pyo3/pull/895) +- Remove `ObjectProtocol` trait. [#911](https://github.com/PyO3/pyo3/pull/911) +- Remove `PyAny::None`. Users should use `Python::None` instead. [#911](https://github.com/PyO3/pyo3/pull/911) +- Remove all `*ProtocolImpl` traits. [#917](https://github.com/PyO3/pyo3/pull/917) + +### Fixed + +- Fix support for `__radd__` and other `__r*__` methods as implementations for Python mathematical operators. [#839](https://github.com/PyO3/pyo3/pull/839) +- Fix panics during garbage collection when traversing objects that were already mutably borrowed. [#855](https://github.com/PyO3/pyo3/pull/855) +- Prevent `&'static` references to Python objects as arguments to `#[pyfunction]` and `#[pymethods]`. [#869](https://github.com/PyO3/pyo3/pull/869) +- Fix lifetime safety bug with `AsPyRef::as_ref`. [#876](https://github.com/PyO3/pyo3/pull/876) +- Fix `#[pyo3(get)]` attribute on `Py` fields. [#880](https://github.com/PyO3/pyo3/pull/880) +- Fix segmentation faults caused by functions such as `PyList::get_item` returning borrowed objects when it was not safe to do so. [#890](https://github.com/PyO3/pyo3/pull/890) +- Fix segmentation faults caused by nested `Python::acquire_gil` calls creating dangling references. [#893](https://github.com/PyO3/pyo3/pull/893) +- Fix segmentatation faults when a panic occurs during a call to `Python::allow_threads`. [#912](https://github.com/PyO3/pyo3/pull/912) + +## [0.9.2] - 2020-04-09 + +### Added + +- `FromPyObject` implementations for `HashSet` and `BTreeSet`. [#842](https://github.com/PyO3/pyo3/pull/842) + +### Fixed + +- Correctly detect 32bit architecture. [#830](https://github.com/PyO3/pyo3/pull/830) + +## [0.9.1] - 2020-03-23 + +### Fixed + +- Error messages for `#[pyclass]`. [#826](https://github.com/PyO3/pyo3/pull/826) +- `FromPyObject` implementation for `PySequence`. [#827](https://github.com/PyO3/pyo3/pull/827) + +## [0.9.0] - 2020-03-19 + +### Added + +- `PyCell`, which has RefCell-like features. [#770](https://github.com/PyO3/pyo3/pull/770) +- `PyClass`, `PyLayout`, `PyClassInitializer`. [#683](https://github.com/PyO3/pyo3/pull/683) +- Implemented `IntoIterator` for `PySet` and `PyFrozenSet`. [#716](https://github.com/PyO3/pyo3/pull/716) +- `FromPyObject` is now automatically implemented for `T: Clone` pyclasses. [#730](https://github.com/PyO3/pyo3/pull/730) +- `#[pyo3(get)]` and `#[pyo3(set)]` will now use the Rust doc-comment from the field for the Python property. [#755](https://github.com/PyO3/pyo3/pull/755) +- `#[setter]` functions may now take an argument of `Pyo3::Python`. [#760](https://github.com/PyO3/pyo3/pull/760) +- `PyTypeInfo::BaseLayout` and `PyClass::BaseNativeType`. [#770](https://github.com/PyO3/pyo3/pull/770) +- `PyDowncastImpl`. [#770](https://github.com/PyO3/pyo3/pull/770) +- Implement `FromPyObject` and `IntoPy` traits for arrays (up to 32). [#778](https://github.com/PyO3/pyo3/pull/778) +- `migration.md` and `types.md` in the guide. [#795](https://github.com/PyO3/pyo3/pull/795), #[802](https://github.com/PyO3/pyo3/pull/802) +- `ffi::{_PyBytes_Resize, _PyDict_Next, _PyDict_Contains, _PyDict_GetDictPtr}`. #[820](https://github.com/PyO3/pyo3/pull/820) + +### Changed + +- `#[new]` does not take `PyRawObject` and can return `Self`. [#683](https://github.com/PyO3/pyo3/pull/683) +- The blanket implementations for `FromPyObject` for `&T` and `&mut T` are no longer specializable. Implement `PyTryFrom` for your type to control the behavior of `FromPyObject::extract` for your types. [#713](https://github.com/PyO3/pyo3/pull/713) +- The implementation for `IntoPy for T` where `U: FromPy` is no longer specializable. Control the behavior of this via the implementation of `FromPy`. [#713](https://github.com/PyO3/pyo3/pull/713) +- Use `parking_lot::Mutex` instead of `spin::Mutex`. [#734](https://github.com/PyO3/pyo3/pull/734) +- Bumped minimum Rust version to `1.42.0-nightly 2020-01-21`. [#761](https://github.com/PyO3/pyo3/pull/761) +- `PyRef` and `PyRefMut` are renewed for `PyCell`. [#770](https://github.com/PyO3/pyo3/pull/770) +- Some new FFI functions for Python 3.8. [#784](https://github.com/PyO3/pyo3/pull/784) +- `PyAny` is now on the top level module and prelude. [#816](https://github.com/PyO3/pyo3/pull/816) + +### Removed + +- `PyRawObject`. [#683](https://github.com/PyO3/pyo3/pull/683) +- `PyNoArgsFunction`. [#741](https://github.com/PyO3/pyo3/pull/741) +- `initialize_type`. To set the module name for a `#[pyclass]`, use the `module` argument to the macro. #[751](https://github.com/PyO3/pyo3/pull/751) +- `AsPyRef::as_mut/with/with_mut/into_py/into_mut_py`. [#770](https://github.com/PyO3/pyo3/pull/770) +- `PyTryFrom::try_from_mut/try_from_mut_exact/try_from_mut_unchecked`. [#770](https://github.com/PyO3/pyo3/pull/770) +- `Python::mut_from_owned_ptr/mut_from_borrowed_ptr`. [#770](https://github.com/PyO3/pyo3/pull/770) +- `ObjectProtocol::get_base/get_mut_base`. [#770](https://github.com/PyO3/pyo3/pull/770) + +### Fixed + +- Fixed unsoundness of subclassing. [#683](https://github.com/PyO3/pyo3/pull/683). +- Clear error indicator when the exception is handled on the Rust side. [#719](https://github.com/PyO3/pyo3/pull/719) +- Usage of raw identifiers with `#[pyo3(set)]`. [#745](https://github.com/PyO3/pyo3/pull/745) +- Usage of `PyObject` with `#[pyo3(get)]`. [#760](https://github.com/PyO3/pyo3/pull/760) +- `#[pymethods]` used in conjunction with `#[cfg]`. #[769](https://github.com/PyO3/pyo3/pull/769) +- `"*"` in a `#[pyfunction()]` argument list incorrectly accepting any number of positional arguments (use `args = "*"` when this behavior is desired). #[792](https://github.com/PyO3/pyo3/pull/792) +- `PyModule::dict`. #[809](https://github.com/PyO3/pyo3/pull/809) +- Fix the case where `DESCRIPTION` is not null-terminated. #[822](https://github.com/PyO3/pyo3/pull/822) + +## [0.8.5] - 2020-01-05 + +### Added + +- Implemented `FromPyObject` for `HashMap` and `BTreeMap` +- Support for `#[name = "foo"]` attribute for `#[pyfunction]` and in `#[pymethods]`. [#692](https://github.com/PyO3/pyo3/pull/692) + +## [0.8.4] - 2019-12-14 + +### Added + +- Support for `#[text_signature]` attribute. [#675](https://github.com/PyO3/pyo3/pull/675) + +## [0.8.3] - 2019-11-23 + +### Removed + +- `#[init]` is removed. [#658](https://github.com/PyO3/pyo3/pull/658) + +### Fixed + +- Now all `&Py~` types have `!Send` bound. [#655](https://github.com/PyO3/pyo3/pull/655) +- Fix a compile error raised by the stabilization of `!` type. [#672](https://github.com/PyO3/pyo3/issues/672). + +## [0.8.2] - 2019-10-27 + +### Added + +- FFI compatibility for PEP 590 Vectorcall. [#641](https://github.com/PyO3/pyo3/pull/641) + +### Fixed + +- Fix PySequenceProtocol::set_item. [#624](https://github.com/PyO3/pyo3/pull/624) +- Fix a corner case of BigInt::FromPyObject. [#630](https://github.com/PyO3/pyo3/pull/630) +- Fix index errors in parameter conversion. [#631](https://github.com/PyO3/pyo3/pull/631) +- Fix handling of invalid utf-8 sequences in `PyString::as_bytes`. [#639](https://github.com/PyO3/pyo3/pull/639) + and `PyString::to_string_lossy` [#642](https://github.com/PyO3/pyo3/pull/642). +- Remove `__contains__` and `__iter__` from PyMappingProtocol. [#644](https://github.com/PyO3/pyo3/pull/644) +- Fix proc-macro definition of PySetAttrProtocol. [#645](https://github.com/PyO3/pyo3/pull/645) + +## [0.8.1] - 2019-10-08 + +### Added + +- Conversion between [num-bigint](https://github.com/rust-num/num-bigint) and Python int. [#608](https://github.com/PyO3/pyo3/pull/608) + +### Fixed + +- Make sure the right Python interpreter is used in OSX builds. [#604](https://github.com/PyO3/pyo3/pull/604) +- Patch specialization being broken by Rust 1.40. [#614](https://github.com/PyO3/pyo3/issues/614) +- Fix a segfault around PyErr. [#597](https://github.com/PyO3/pyo3/pull/597) + +## [0.8.0] - 2019-09-16 + +### Added + +- `module` argument to `pyclass` macro. [#499](https://github.com/PyO3/pyo3/pull/499) +- `py_run!` macro [#512](https://github.com/PyO3/pyo3/pull/512) +- Use existing fields and methods before calling custom **getattr**. [#505](https://github.com/PyO3/pyo3/pull/505) +- `PyBytes` can now be indexed just like `Vec` +- Implement `IntoPy` for `PyRef` and `PyRefMut`. + +### Changed + +- Implementing the Using the `gc` parameter for `pyclass` (e.g. `#[pyclass(gc)]`) without implementing the `class::PyGCProtocol` trait is now a compile-time error. Failing to implement this trait could lead to segfaults. [#532](https://github.com/PyO3/pyo3/pull/532) +- `PyByteArray::data` has been replaced with `PyDataArray::to_vec` because returning a `&[u8]` is unsound. (See [this comment](https://github.com/PyO3/pyo3/issues/373#issuecomment-512332696) for a great write-up for why that was unsound) +- Replace `mashup` with `paste`. +- `GILPool` gained a `Python` marker to prevent it from being misused to release Python objects without the GIL held. + +### Removed + +- `IntoPyObject` was replaced with `IntoPy` +- `#[pyclass(subclass)]` is hidden a `unsound-subclass` feature because it's causing segmentation faults. + +### Fixed + +- More readable error message for generics in pyclass [#503](https://github.com/PyO3/pyo3/pull/503) + +## [0.7.0] - 2019-05-26 + +### Added + +- PyPy support by omerbenamram in [#393](https://github.com/PyO3/pyo3/pull/393) +- Have `PyModule` generate an index of its members (`__all__` list). +- Allow `slf: PyRef` for pyclass(#419) +- Allow to use lifetime specifiers in `pymethods` +- Add `marshal` module. [#460](https://github.com/PyO3/pyo3/pull/460) + +### Changed + +- `Python::run` returns `PyResult<()>` instead of `PyResult<&PyAny>`. +- Methods decorated with `#[getter]` and `#[setter]` can now omit wrapping the + result type in `PyResult` if they don't raise exceptions. + +### Fixed + +- `type_object::PyTypeObject` has been marked unsafe because breaking the contract `type_object::PyTypeObject::init_type` can lead to UB. +- Fixed automatic derive of `PySequenceProtocol` implementation in [#423](https://github.com/PyO3/pyo3/pull/423). +- Capitalization & better wording to README.md. +- Docstrings of properties is now properly set using the doc of the `#[getter]` method. +- Fixed issues with `pymethods` crashing on doc comments containing double quotes. +- `PySet::new` and `PyFrozenSet::new` now return `PyResult<&Py[Frozen]Set>`; exceptions are raised if + the items are not hashable. +- Fixed building using `venv` on Windows. +- `PyTuple::new` now returns `&PyTuple` instead of `Py`. +- Fixed several issues with argument parsing; notable, the `*args` and `**kwargs` + tuple/dict now doesn't contain arguments that are otherwise assigned to parameters. + +## [0.6.0] - 2019-03-28 + +### Regressions + +- Currently, [#341](https://github.com/PyO3/pyo3/issues/341) causes `cargo test` to fail with weird linking errors when the `extension-module` feature is activated. For now you can work around this by making the `extension-module` feature optional and running the tests with `cargo test --no-default-features`: + +```toml +[dependencies.pyo3] +version = "0.6.0" + +[features] +extension-module = ["pyo3/extension-module"] +default = ["extension-module"] +``` + +### Added + +- Added a `wrap_pymodule!` macro similar to the existing `wrap_pyfunction!` macro. Only available on python 3 +- Added support for cross compiling (e.g. to arm v7) by mtp401 in [#327](https://github.com/PyO3/pyo3/pull/327). See the "Cross Compiling" section in the "Building and Distribution" chapter of the guide for more details. +- The `PyRef` and `PyRefMut` types, which allow to differentiate between an instance of a rust struct on the rust heap and an instance that is embedded inside a python object. By kngwyu in [#335](https://github.com/PyO3/pyo3/pull/335) +- Added `FromPy` and `IntoPy` which are equivalent to `From` and `Into` except that they require a gil token. +- Added `ManagedPyRef`, which should eventually replace `ToBorrowedObject`. + +### Changed + +- Renamed `PyObjectRef` to `PyAny` in #388 +- Renamed `add_function` to `add_wrapped` as it now also supports modules. +- Renamed `#[pymodinit]` to `#[pymodule]` +- `py.init(|| value)` becomes `Py::new(value)` +- `py.init_ref(|| value)` becomes `PyRef::new(value)` +- `py.init_mut(|| value)` becomes `PyRefMut::new(value)`. +- `PyRawObject::init` is now infallible, e.g. it returns `()` instead of `PyResult<()>`. +- Renamed `py_exception!` to `create_exception!` and refactored the error macros. +- Renamed `wrap_function!` to `wrap_pyfunction!` +- Renamed `#[prop(get, set)]` to `#[pyo3(get, set)]` +- `#[pyfunction]` now supports the same arguments as `#[pyfn()]` +- Some macros now emit proper spanned errors instead of panics. +- Migrated to the 2018 edition +- `crate::types::exceptions` moved to `crate::exceptions` +- Replace `IntoPyTuple` with `IntoPy>`. +- `IntoPyPointer` and `ToPyPointer` moved into the crate root. +- `class::CompareOp` moved into `class::basic::CompareOp` +- PyTypeObject is now a direct subtrait PyTypeCreate, removing the old cyclical implementation in [#350](https://github.com/PyO3/pyo3/pull/350) +- Add `PyList::{sort, reverse}` by chr1sj0nes in [#357](https://github.com/PyO3/pyo3/pull/357) and [#358](https://github.com/PyO3/pyo3/pull/358) +- Renamed the `typeob` module to `type_object` + +### Removed + +- `PyToken` was removed due to unsoundness (See [#94](https://github.com/PyO3/pyo3/issues/94)). +- Removed the unnecessary type parameter from `PyObjectAlloc` +- `NoArgs`. Just use an empty tuple +- `PyObjectWithGIL`. `PyNativeType` is sufficient now that PyToken is removed. + +### Fixed + +- A soudness hole where every instances of a `#[pyclass]` struct was considered to be part of a python object, even though you can create instances that are not part of the python heap. This was fixed through `PyRef` and `PyRefMut`. +- Fix kwargs support in [#328](https://github.com/PyO3/pyo3/pull/328). +- Add full support for `__dict__` in [#403](https://github.com/PyO3/pyo3/pull/403). + +## [0.5.3] - 2019-01-04 + +### Fixed + +- Fix memory leak in ArrayList by kngwyu [#316](https://github.com/PyO3/pyo3/pull/316) + +## [0.5.2] - 2018-11-25 + +### Fixed + +- Fix indeterministic segfaults when creating many objects by kngwyu in [#281](https://github.com/PyO3/pyo3/pull/281) + +## [0.5.1] - 2018-11-24 + +Yanked + +## [0.5.0] - 2018-11-11 + +### Added + +- `#[pyclass]` objects can now be returned from rust functions +- `PyComplex` by kngwyu in [#226](https://github.com/PyO3/pyo3/pull/226) +- `PyDict::from_sequence`, equivalent to `dict([(key, val), ...])` +- Bindings for the `datetime` standard library types: `PyDate`, `PyTime`, `PyDateTime`, `PyTzInfo`, `PyDelta` with associated `ffi` types, by pganssle [#200](https://github.com/PyO3/pyo3/pull/200). +- `PyString`, `PyUnicode`, and `PyBytes` now have an `as_bytes` method that returns `&[u8]`. +- `PyObjectProtocol::get_type_ptr` by ijl in [#242](https://github.com/PyO3/pyo3/pull/242) + +### Changed + +- Removes the types from the root module and the prelude. They now live in `pyo3::types` instead. +- All exceptions are constructed with `py_err` instead of `new`, as they return `PyErr` and not `Self`. +- `as_mut` and friends take and `&mut self` instead of `&self` +- `ObjectProtocol::call` now takes an `Option<&PyDict>` for the kwargs instead of an `IntoPyDictPointer`. +- `IntoPyDictPointer` was replace by `IntoPyDict` which doesn't convert `PyDict` itself anymore and returns a `PyDict` instead of `*mut PyObject`. +- `PyTuple::new` now takes an `IntoIterator` instead of a slice +- Updated to syn 0.15 +- Split `PyTypeObject` into `PyTypeObject` without the create method and `PyTypeCreate` with requires `PyObjectAlloc + PyTypeInfo + Sized`. +- Ran `cargo edition --fix` which prefixed path with `crate::` for rust 2018 +- Renamed `async` to `pyasync` as async will be a keyword in the 2018 edition. +- Starting to use `NonNull<*mut PyObject>` for Py and PyObject by ijl [#260](https://github.com/PyO3/pyo3/pull/260) + +### Removed + +- Removed most entries from the prelude. The new prelude is small and clear. +- Slowly removing specialization uses +- `PyString`, `PyUnicode`, and `PyBytes` no longer have a `data` method + (replaced by `as_bytes`) and `PyStringData` has been removed. +- The pyobject_extract macro + +### Fixed + +- Added an explanation that the GIL can temporarily be released even while holding a GILGuard. +- Lots of clippy errors +- Fix segfault on calling an unknown method on a PyObject +- Work around a [bug](https://github.com/rust-lang/rust/issues/55380) in the rust compiler by kngwyu [#252](https://github.com/PyO3/pyo3/pull/252) +- Fixed a segfault with subclassing pyo3 create classes and using `__class__` by kngwyu [#263](https://github.com/PyO3/pyo3/pull/263) + +## [0.4.1] - 2018-08-20 + +### Changed + +- PyTryFrom's error is always to `PyDowncastError` + +### Fixed + +- Fixed compilation on nightly since `use_extern_macros` was stabilized + +### Removed + +- The pyobject_downcast macro + +## [0.4.0] - 2018-07-30 + +### Changed + +- Merged both examples into one +- Rustfmt all the things :heavy_check_mark: +- Switched to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) + +### Removed + +- Conversions from tuples to PyDict due to [rust-lang/rust#52050](https://github.com/rust-lang/rust/issues/52050) + +## [0.3.2] - 2018-07-22 + +### Changed + +- Replaced `concat_idents` with mashup + +## [0.3.1] - 2018-07-18 + +### Fixed + +- Fixed scoping bug in pyobject_native_type that would break rust-numpy + +## [0.3.0] - 2018-07-18 + +### Added + +- A few internal macros became part of the public api ([#155](https://github.com/PyO3/pyo3/pull/155), [#186](https://github.com/PyO3/pyo3/pull/186)) +- Always clone in getters. This allows using the get-annotation on all Clone-Types + +### Changed + +- Upgraded to syn 0.14 which means much better error messages :tada: +- 128 bit integer support by [kngwyu](https://github.com/kngwyu) ([#137](https://github.com/PyO3/pyo3/pull/173)) +- `proc_macro` has been stabilized on nightly ([rust-lang/rust#52081](https://github.com/rust-lang/rust/pull/52081)). This means that we can remove the `proc_macro` feature, but now we need the `use_extern_macros` from the 2018 edition instead. +- All proc macro are now prefixed with `py` and live in the prelude. This means you can use `#[pyclass]`, `#[pymethods]`, `#[pyproto]`, `#[pyfunction]` and `#[pymodinit]` directly, at least after a `use pyo3::prelude::*`. They were also moved into a module called `proc_macro`. You shouldn't use `#[pyo3::proc_macro::pyclass]` or other longer paths in attributes because `proc_macro_path_invoc` isn't going to be stabilized soon. +- Renamed the `base` option in the `pyclass` macro to `extends`. +- `#[pymodinit]` uses the function name as module name, unless the name is overridden with `#[pymodinit(name)]` +- The guide is now properly versioned. + +## [0.2.7] - 2018-05-18 + +### Fixed + +- Fix nightly breakage with proc_macro_path + +## [0.2.6] - 2018-04-03 + +### Fixed + +- Fix compatibility with TryFrom trait #137 + +## [0.2.5] - 2018-02-21 + +### Added + +- CPython 3.7 support + +### Fixed + +- Embedded CPython 3.7b1 crashes on initialization #110 +- Generated extension functions are weakly typed #108 +- call_method\* crashes when the method does not exist #113 +- Allow importing exceptions from nested modules #116 + +## [0.2.4] - 2018-01-19 + +### Added + +- Allow to get mutable ref from PyObject #106 +- Drop `RefFromPyObject` trait +- Add Python::register_any method + +### Fixed + +- Fix impl `FromPyObject` for `Py` +- Mark method that work with raw pointers as unsafe #95 + +## [0.2.3] - 11-27-2017 + +### Changed + +- Rustup to 1.23.0-nightly 2017-11-07 + +### Fixed + +- Proper `c_char` usage #93 + +### Removed + +- Remove use of now unneeded 'AsciiExt' trait + +## [0.2.2] - 09-26-2017 + +### Changed + +- Rustup to 1.22.0-nightly 2017-09-30 + +## [0.2.1] - 09-26-2017 + +### Fixed + +- Fix rustc const_fn nightly breakage + +## [0.2.0] - 08-12-2017 + +### Added + +- Added inheritance support #15 +- Added weakref support #56 +- Added subclass support #64 +- Added `self.__dict__` support #68 +- Added `pyo3::prelude` module #70 +- Better `Iterator` support for PyTuple, PyList, PyDict #75 +- Introduce IntoPyDictPointer similar to IntoPyTuple #69 + +### Changed + +- Allow to add gc support without implementing PyGCProtocol #57 +- Refactor `PyErr` implementation. Drop `py` parameter from constructor. + +## [0.1.0] - 07-23-2017 + +### Added + +- Initial release + +[Unreleased]: https://github.com/pyo3/pyo3/compare/v0.29.2...HEAD +[0.29.1]: https://github.com/pyo3/pyo3/compare/v0.29.1...v0.29.2 +[0.29.1]: https://github.com/pyo3/pyo3/compare/v0.29.0...v0.29.1 +[0.29.0]: https://github.com/pyo3/pyo3/compare/v0.28.3...v0.29.0 +[0.28.3]: https://github.com/pyo3/pyo3/compare/v0.28.2...v0.28.3 +[0.28.2]: https://github.com/pyo3/pyo3/compare/v0.28.1...v0.28.2 +[0.28.1]: https://github.com/pyo3/pyo3/compare/v0.28.0...v0.28.1 +[0.28.0]: https://github.com/pyo3/pyo3/compare/v0.27.2...v0.28.0 +[0.27.2]: https://github.com/pyo3/pyo3/compare/v0.27.1...v0.27.2 +[0.27.1]: https://github.com/pyo3/pyo3/compare/v0.27.0...v0.27.1 +[0.27.0]: https://github.com/pyo3/pyo3/compare/v0.26.0...v0.27.0 +[0.26.0]: https://github.com/pyo3/pyo3/compare/v0.25.1...v0.26.0 +[0.25.1]: https://github.com/pyo3/pyo3/compare/v0.25.0...v0.25.1 +[0.25.0]: https://github.com/pyo3/pyo3/compare/v0.24.2...v0.25.0 +[0.24.2]: https://github.com/pyo3/pyo3/compare/v0.24.1...v0.24.2 +[0.24.1]: https://github.com/pyo3/pyo3/compare/v0.24.0...v0.24.1 +[0.24.0]: https://github.com/pyo3/pyo3/compare/v0.23.5...v0.24.0 +[0.23.5]: https://github.com/pyo3/pyo3/compare/v0.23.4...v0.23.5 +[0.23.4]: https://github.com/pyo3/pyo3/compare/v0.23.3...v0.23.4 +[0.23.3]: https://github.com/pyo3/pyo3/compare/v0.23.2...v0.23.3 +[0.23.2]: https://github.com/pyo3/pyo3/compare/v0.23.1...v0.23.2 +[0.23.1]: https://github.com/pyo3/pyo3/compare/v0.23.0...v0.23.1 +[0.23.0]: https://github.com/pyo3/pyo3/compare/v0.22.5...v0.23.0 +[0.22.5]: https://github.com/pyo3/pyo3/compare/v0.22.4...v0.22.5 +[0.22.4]: https://github.com/pyo3/pyo3/compare/v0.22.3...v0.22.4 +[0.22.3]: https://github.com/pyo3/pyo3/compare/v0.22.2...v0.22.3 +[0.22.2]: https://github.com/pyo3/pyo3/compare/v0.22.1...v0.22.2 +[0.22.1]: https://github.com/pyo3/pyo3/compare/v0.22.0...v0.22.1 +[0.22.0]: https://github.com/pyo3/pyo3/compare/v0.21.2...v0.22.0 +[0.21.2]: https://github.com/pyo3/pyo3/compare/v0.21.1...v0.21.2 +[0.21.1]: https://github.com/pyo3/pyo3/compare/v0.21.0...v0.21.1 +[0.21.0]: https://github.com/pyo3/pyo3/compare/v0.20.3...v0.21.0 +[0.21.0-beta.0]: https://github.com/pyo3/pyo3/compare/v0.20.3...v0.21.0-beta.0 +[0.20.3]: https://github.com/pyo3/pyo3/compare/v0.20.2...v0.20.3 +[0.20.2]: https://github.com/pyo3/pyo3/compare/v0.20.1...v0.20.2 +[0.20.1]: https://github.com/pyo3/pyo3/compare/v0.20.0...v0.20.1 +[0.20.0]: https://github.com/pyo3/pyo3/compare/v0.19.2...v0.20.0 +[0.19.2]: https://github.com/pyo3/pyo3/compare/v0.19.1...v0.19.2 +[0.19.1]: https://github.com/pyo3/pyo3/compare/v0.19.0...v0.19.1 +[0.19.0]: https://github.com/pyo3/pyo3/compare/v0.18.3...v0.19.0 +[0.18.3]: https://github.com/pyo3/pyo3/compare/v0.18.2...v0.18.3 +[0.18.2]: https://github.com/pyo3/pyo3/compare/v0.18.1...v0.18.2 +[0.18.1]: https://github.com/pyo3/pyo3/compare/v0.18.0...v0.18.1 +[0.18.0]: https://github.com/pyo3/pyo3/compare/v0.17.3...v0.18.0 +[0.17.3]: https://github.com/pyo3/pyo3/compare/v0.17.2...v0.17.3 +[0.17.2]: https://github.com/pyo3/pyo3/compare/v0.17.1...v0.17.2 +[0.17.1]: https://github.com/pyo3/pyo3/compare/v0.17.0...v0.17.1 +[0.17.0]: https://github.com/pyo3/pyo3/compare/v0.16.6...v0.17.0 +[0.16.6]: https://github.com/pyo3/pyo3/compare/v0.16.5...v0.16.6 +[0.16.5]: https://github.com/pyo3/pyo3/compare/v0.16.4...v0.16.5 +[0.16.4]: https://github.com/pyo3/pyo3/compare/v0.16.3...v0.16.4 +[0.16.3]: https://github.com/pyo3/pyo3/compare/v0.16.2...v0.16.3 +[0.16.2]: https://github.com/pyo3/pyo3/compare/v0.16.1...v0.16.2 +[0.16.1]: https://github.com/pyo3/pyo3/compare/v0.16.0...v0.16.1 +[0.16.0]: https://github.com/pyo3/pyo3/compare/v0.15.1...v0.16.0 +[0.15.2]: https://github.com/pyo3/pyo3/compare/v0.15.1...v0.15.2 +[0.15.1]: https://github.com/pyo3/pyo3/compare/v0.15.0...v0.15.1 +[0.15.0]: https://github.com/pyo3/pyo3/compare/v0.14.5...v0.15.0 +[0.14.5]: https://github.com/pyo3/pyo3/compare/v0.14.4...v0.14.5 +[0.14.4]: https://github.com/pyo3/pyo3/compare/v0.14.3...v0.14.4 +[0.14.3]: https://github.com/pyo3/pyo3/compare/v0.14.2...v0.14.3 +[0.14.2]: https://github.com/pyo3/pyo3/compare/v0.14.1...v0.14.2 +[0.14.1]: https://github.com/pyo3/pyo3/compare/v0.14.0...v0.14.1 +[0.14.0]: https://github.com/pyo3/pyo3/compare/v0.13.2...v0.14.0 +[0.13.2]: https://github.com/pyo3/pyo3/compare/v0.13.1...v0.13.2 +[0.13.1]: https://github.com/pyo3/pyo3/compare/v0.13.0...v0.13.1 +[0.13.0]: https://github.com/pyo3/pyo3/compare/v0.12.4...v0.13.0 +[0.12.4]: https://github.com/pyo3/pyo3/compare/v0.12.3...v0.12.4 +[0.12.3]: https://github.com/pyo3/pyo3/compare/v0.12.2...v0.12.3 +[0.12.2]: https://github.com/pyo3/pyo3/compare/v0.12.1...v0.12.2 +[0.12.1]: https://github.com/pyo3/pyo3/compare/v0.12.0...v0.12.1 +[0.12.0]: https://github.com/pyo3/pyo3/compare/v0.11.1...v0.12.0 +[0.11.1]: https://github.com/pyo3/pyo3/compare/v0.11.0...v0.11.1 +[0.11.0]: https://github.com/pyo3/pyo3/compare/v0.10.1...v0.11.0 +[0.10.1]: https://github.com/pyo3/pyo3/compare/v0.10.0...v0.10.1 +[0.10.0]: https://github.com/pyo3/pyo3/compare/v0.9.2...v0.10.0 +[0.9.2]: https://github.com/pyo3/pyo3/compare/v0.9.1...v0.9.2 +[0.9.1]: https://github.com/pyo3/pyo3/compare/v0.9.0...v0.9.1 +[0.9.0]: https://github.com/pyo3/pyo3/compare/v0.8.5...v0.9.0 +[0.8.5]: https://github.com/pyo3/pyo3/compare/v0.8.4...v0.8.5 +[0.8.4]: https://github.com/pyo3/pyo3/compare/v0.8.3...v0.8.4 +[0.8.3]: https://github.com/pyo3/pyo3/compare/v0.8.2...v0.8.3 +[0.8.2]: https://github.com/pyo3/pyo3/compare/v0.8.1...v0.8.2 +[0.8.1]: https://github.com/pyo3/pyo3/compare/v0.8.0...v0.8.1 +[0.8.0]: https://github.com/pyo3/pyo3/compare/v0.7.0...v0.8.0 +[0.7.0]: https://github.com/pyo3/pyo3/compare/v0.6.0...v0.7.0 +[0.6.0]: https://github.com/pyo3/pyo3/compare/v0.5.3...v0.6.0 +[0.5.3]: https://github.com/pyo3/pyo3/compare/v0.5.2...v0.5.3 +[0.5.2]: https://github.com/pyo3/pyo3/compare/v0.5.1...v0.5.2 +[0.5.1]: https://github.com/pyo3/pyo3/compare/v0.5.0...v0.5.1 +[0.5.0]: https://github.com/pyo3/pyo3/compare/v0.4.1...v0.5.0 +[0.4.1]: https://github.com/pyo3/pyo3/compare/v0.4.0...v0.4.1 +[0.4.0]: https://github.com/pyo3/pyo3/compare/v0.3.2...v0.4.0 +[0.3.2]: https://github.com/pyo3/pyo3/compare/v0.3.1...v0.3.2 +[0.3.1]: https://github.com/pyo3/pyo3/compare/v0.3.0...v0.3.1 +[0.3.0]: https://github.com/pyo3/pyo3/compare/v0.2.7...v0.3.0 +[0.2.7]: https://github.com/pyo3/pyo3/compare/v0.2.6...v0.2.7 +[0.2.6]: https://github.com/pyo3/pyo3/compare/v0.2.5...v0.2.6 +[0.2.5]: https://github.com/pyo3/pyo3/compare/v0.2.4...v0.2.5 +[0.2.4]: https://github.com/pyo3/pyo3/compare/v0.2.3...v0.2.4 +[0.2.3]: https://github.com/pyo3/pyo3/compare/v0.2.2...v0.2.3 +[0.2.2]: https://github.com/pyo3/pyo3/compare/v0.2.1...v0.2.2 +[0.2.1]: https://github.com/pyo3/pyo3/compare/v0.2.0...v0.2.1 +[0.2.0]: https://github.com/pyo3/pyo3/compare/v0.1.0...v0.2.0 +[0.1.0]: https://github.com/PyO3/pyo3/tree/v0.1.0 diff --git a/vendor/pyo3/CITATION.cff b/vendor/pyo3/CITATION.cff new file mode 100644 index 0000000..dfba070 --- /dev/null +++ b/vendor/pyo3/CITATION.cff @@ -0,0 +1,12 @@ +cff-version: 1.2.0 +title: PyO3 +message: >- + If you use this software as part of a publication and wish to cite + it, please use the metadata from this file. +type: software +authors: + - name: PyO3 Project and Contributors + website: https://github.com/PyO3 +license: + - Apache-2.0 + - MIT diff --git a/vendor/pyo3/Cargo.lock b/vendor/pyo3/Cargo.lock new file mode 100644 index 0000000..95c2a79 --- /dev/null +++ b/vendor/pyo3/Cargo.lock @@ -0,0 +1,1738 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aho-corasick" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" +dependencies = [ + "memchr", +] + +[[package]] +name = "android_system_properties" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" +dependencies = [ + "libc", +] + +[[package]] +name = "annotate-snippets" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4" +dependencies = [ + "anstyle", + "unicode-width", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "arrayvec" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" + +[[package]] +name = "assert_approx_eq" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c07dab4369547dbe5114677b33fbbf724971019f3818172d59a97a61c774ffd" + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link", +] + +[[package]] +name = "bigdecimal" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d6867f1565b3aad85681f1015055b087fcfd840d6aeee6eee7f2da317603695" +dependencies = [ + "autocfg", + "libm", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" + +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + +[[package]] +name = "bstr" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f7dc094d718f2e1c1559ad110e27eeaae14a5465d3d56dd6dbd793079fbd530" +dependencies = [ + "memchr", + "regex-automata", + "serde_core", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + +[[package]] +name = "camino" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb1307f12aa967b5a58416e87b3653360e0fd614a016b6e970db08fecbb1b80d" +dependencies = [ + "serde_core", +] + +[[package]] +name = "cargo-platform" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "122ec45a44b270afd1402f351b782c676b173e3c3fb28d86ff7ebfb4d86a4ee4" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef987d17b0a113becdd19d3d0022d04d7ef41f9efe4f3fb63ac44ba61df3ade9" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 2.0.19", +] + +[[package]] +name = "cc" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "chrono-tz" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" +dependencies = [ + "chrono", + "phf", +] + +[[package]] +name = "color-eyre" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5920befb47832a6d61ee3a3a846565cfa39b331331e68a3b1d1116630f2f26d" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8b88ea9df13354b55bc7234ebcce36e6ef896aca2e42a15de9e10edce01b427" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "colored" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "comma" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55b672471b4e9f9e95499ea597ff64941a309b2cdbffcc46f2cc5e2d971fd335" + +[[package]] +name = "console" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c" +dependencies = [ + "encode_unicode", + "libc", + "unicode-width", + "windows-sys", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "crossbeam-channel" +version = "0.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" + +[[package]] +name = "ctrlc" +version = "3.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0b1fab2ae45819af2d0731d60f2afe17227ebb1a1538a236da84c93e9a60162" +dependencies = [ + "dispatch2", + "nix", + "windows-sys", +] + +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror 2.0.19", +] + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" + +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.13.1", + "block2", + "libc", + "objc2", +] + +[[package]] +name = "either" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" + +[[package]] +name = "futures-executor" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a" + +[[package]] +name = "futures-macro" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "futures-sink" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307" + +[[package]] +name = "futures-task" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" + +[[package]] +name = "futures-util" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi 5.3.0", + "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", +] + +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "indenter" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "indicatif" +version = "0.18.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9433806cd6b4ec1aba79c021c7e4c58fb4c3b9977c085062e611ac929998fb0c" +dependencies = [ + "console", + "portable-atomic", + "unicode-width", + "unit-prefix", + "web-time", +] + +[[package]] +name = "inventory" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4f0c30c76f2f4ccee3fe55a2435f691ca00c0e4bd87abe4f4a851b1d4dac39b" +dependencies = [ + "rustversion", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jiff" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" +dependencies = [ + "defmt", + "jiff-core", + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", + "windows-link", +] + +[[package]] +name = "jiff-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", +] + +[[package]] +name = "jiff-static" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" +dependencies = [ + "jiff-core", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + +[[package]] +name = "js-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "levenshtein" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" + +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags 2.13.1", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "num-bigint" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "ordered-float" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e" +dependencies = [ + "num-traits", +] + +[[package]] +name = "owo-colors" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "phf" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "portable-atomic" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3" + +[[package]] +name = "portable-atomic-util" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettydiff" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac17546d82912e64874e3d5b40681ce32eac4e5834344f51efcf689ff1550a65" +dependencies = [ + "owo-colors", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" +dependencies = [ + "bitflags 2.13.1", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "unarray", +] + +[[package]] +name = "pyo3" +version = "0.29.2" +dependencies = [ + "anyhow", + "assert_approx_eq", + "bigdecimal", + "bytes", + "chrono", + "chrono-tz", + "ctrlc", + "either", + "eyre", + "futures", + "hashbrown", + "iana-time-zone", + "indexmap", + "inventory", + "jiff", + "libc", + "lock_api", + "num-bigint", + "num-complex", + "num-rational", + "num-traits", + "once_cell", + "ordered-float", + "parking_lot", + "portable-atomic", + "proptest", + "pyo3-build-config", + "pyo3-ffi", + "pyo3-macros", + "rayon", + "regex", + "rust_decimal", + "send_wrapper", + "serde", + "serde_json", + "smallvec", + "static_assertions", + "tempfile", + "time", + "ui_test", + "uuid", +] + +[[package]] +name = "pyo3-build-config" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f41027e41b4bd03f6e60f9f417fe24a6341a6bb744edd62b6f709f2a52ea30e9" +dependencies = [ + "target-lexicon", +] + +[[package]] +name = "pyo3-ffi" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e591a95526fead067432c3b3a33fc74770b87b1e04e73671090d9c2055a2b327" +dependencies = [ + "libc", + "pyo3-build-config", +] + +[[package]] +name = "pyo3-macros" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73225868fc1cd84eef2c3c230ddb91273bf1de46aeb8a4248da76d32a0924a1c" +dependencies = [ + "proc-macro2", + "pyo3-macros-backend", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "pyo3-macros-backend" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "571575aa3749fa6216757dd47d2a3e7ef360f329a40f0666a9fbd14889024952" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rand" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rayon" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.1", +] + +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "rust_decimal" +version = "1.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be2a24f50780bc85f09cc6ac299bdf1424302742d77221106859c9d8b102126a" +dependencies = [ + "arrayvec", + "num-traits", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustfix" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82fa69b198d894d84e23afde8e9ab2af4400b2cba20d6bf2b428a8b01c222c5a" +dependencies = [ + "serde", + "serde_json", + "thiserror 1.0.69", + "tracing", +] + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags 2.13.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "siphasher" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "spanned" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4b0c055fde758f086eb4a6e73410247df8a3837fd606d2caeeaf72aa566d" +dependencies = [ + "anyhow", + "bstr", + "color-eyre", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.3", + "once_cell", + "rustix", + "windows-sys", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9" +dependencies = [ + "thiserror-impl 2.0.19", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "thread_local" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "sharded-slab", + "thread_local", + "tracing-core", +] + +[[package]] +name = "ui_test" +version = "0.30.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c8811281d587a786747c0c49245925016c07767bc996305bdd34d5ce076786a" +dependencies = [ + "annotate-snippets", + "anyhow", + "bstr", + "cargo-platform", + "cargo_metadata", + "color-eyre", + "colored", + "comma", + "crossbeam-channel", + "indicatif", + "levenshtein", + "prettydiff", + "regex", + "rustc_version", + "rustfix", + "serde", + "serde_json", + "spanned", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + +[[package]] +name = "unit-prefix" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" + +[[package]] +name = "uuid" +version = "1.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239" +dependencies = [ + "getrandom 0.4.3", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.119", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "zerocopy" +version = "0.8.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/vendor/pyo3/Cargo.toml b/vendor/pyo3/Cargo.toml new file mode 100644 index 0000000..5517671 --- /dev/null +++ b/vendor/pyo3/Cargo.toml @@ -0,0 +1,617 @@ +# 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.83" +name = "pyo3" +version = "0.29.2" +authors = ["PyO3 Project and Contributors "] +build = "build.rs" +links = "pyo3-python" +exclude = [ + "/.gitignore", + ".cargo/config", + "/codecov.yml", + "/Makefile", + "/pyproject.toml", + "/noxfile.py", + "/.github", + "/tests/test_compile_error.rs", + "/tests/ui", +] +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Bindings to Python interpreter" +homepage = "https://github.com/pyo3/pyo3" +documentation = "https://docs.rs/crate/pyo3/" +readme = "README.md" +keywords = [ + "pyo3", + "python", + "cpython", + "ffi", +] +categories = [ + "api-bindings", + "development-tools::ffi", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/pyo3/pyo3" + +[package.metadata.docs.rs] +no-default-features = true +features = ["full"] +rustdoc-args = [ + "--cfg", + "docsrs", +] + +[features] +abi3 = ["pyo3-ffi/abi3"] +abi3-py310 = [ + "abi3-py311", + "pyo3-ffi/abi3-py310", +] +abi3-py311 = [ + "abi3-py312", + "pyo3-ffi/abi3-py311", +] +abi3-py312 = [ + "abi3-py313", + "pyo3-ffi/abi3-py312", +] +abi3-py313 = [ + "abi3-py314", + "pyo3-ffi/abi3-py313", +] +abi3-py314 = [ + "abi3-py315", + "pyo3-ffi/abi3-py314", +] +abi3-py315 = [ + "abi3", + "pyo3-ffi/abi3-py315", +] +abi3-py38 = [ + "abi3-py39", + "pyo3-ffi/abi3-py38", +] +abi3-py39 = [ + "abi3-py310", + "pyo3-ffi/abi3-py39", +] +abi3t = ["pyo3-ffi/abi3t"] +abi3t-py315 = [ + "abi3t", + "pyo3-ffi/abi3t-py315", +] +arc_lock = [ + "lock_api", + "lock_api/arc_lock", + "parking_lot?/arc_lock", +] +auto-initialize = [] +bigdecimal = [ + "dep:bigdecimal", + "num-bigint", +] +chrono-local = [ + "chrono/clock", + "dep:iana-time-zone", +] +default = ["macros"] +experimental-async = [ + "macros", + "pyo3-macros/experimental-async", +] +experimental-inspect = ["pyo3-macros/experimental-inspect"] +extension-module = ["pyo3-ffi/extension-module"] +full = [ + "macros", + "anyhow", + "arc_lock", + "bigdecimal", + "bytes", + "chrono", + "chrono-local", + "chrono-tz", + "either", + "experimental-async", + "experimental-inspect", + "eyre", + "hashbrown", + "indexmap", + "jiff-02", + "lock_api", + "num-bigint", + "num-complex", + "num-rational", + "ordered-float", + "parking_lot", + "py-clone", + "rust_decimal", + "serde", + "smallvec", + "time", + "uuid", +] +generate-import-lib = ["pyo3-ffi/generate-import-lib"] +macros = ["pyo3-macros"] +multiple-pymethods = [ + "inventory", + "pyo3-macros/multiple-pymethods", +] +nightly = [] +num-bigint = [ + "dep:num-bigint", + "dep:num-traits", +] +parking_lot = [ + "dep:parking_lot", + "lock_api", +] +py-clone = [] + +[lib] +name = "pyo3" +path = "src/lib.rs" + +[[test]] +name = "test_anyhow" +path = "tests/test_anyhow.rs" +required-features = ["anyhow"] + +[[test]] +name = "test_append_to_inittab" +path = "tests/test_append_to_inittab.rs" +required-features = ["macros"] + +[[test]] +name = "test_arithmetics" +path = "tests/test_arithmetics.rs" +required-features = ["macros"] + +[[test]] +name = "test_buffer" +path = "tests/test_buffer.rs" +required-features = ["macros"] + +[[test]] +name = "test_buffer_protocol" +path = "tests/test_buffer_protocol.rs" +required-features = ["macros"] + +[[test]] +name = "test_bytes" +path = "tests/test_bytes.rs" +required-features = ["macros"] + +[[test]] +name = "test_class_attributes" +path = "tests/test_class_attributes.rs" +required-features = ["macros"] + +[[test]] +name = "test_class_basics" +path = "tests/test_class_basics.rs" +required-features = ["macros"] + +[[test]] +name = "test_class_comparisons" +path = "tests/test_class_comparisons.rs" +required-features = ["macros"] + +[[test]] +name = "test_class_conversion" +path = "tests/test_class_conversion.rs" +required-features = ["macros"] + +[[test]] +name = "test_class_formatting" +path = "tests/test_class_formatting.rs" +required-features = ["macros"] + +[[test]] +name = "test_class_init" +path = "tests/test_class_init.rs" +required-features = ["macros"] + +[[test]] +name = "test_class_new" +path = "tests/test_class_new.rs" +required-features = ["macros"] + +[[test]] +name = "test_coroutine" +path = "tests/test_coroutine.rs" +required-features = ["experimental-async"] + +[[test]] +name = "test_datetime" +path = "tests/test_datetime.rs" + +[[test]] +name = "test_datetime_import" +path = "tests/test_datetime_import.rs" + +[[test]] +name = "test_declarative_module" +path = "tests/test_declarative_module.rs" +required-features = ["macros"] + +[[test]] +name = "test_default_impls" +path = "tests/test_default_impls.rs" +required-features = ["macros"] + +[[test]] +name = "test_enum" +path = "tests/test_enum.rs" +required-features = ["macros"] + +[[test]] +name = "test_exceptions" +path = "tests/test_exceptions.rs" +required-features = ["macros"] + +[[test]] +name = "test_field_cfg" +path = "tests/test_field_cfg.rs" +required-features = ["macros"] + +[[test]] +name = "test_frompy_intopy_roundtrip" +path = "tests/test_frompy_intopy_roundtrip.rs" +required-features = ["macros"] + +[[test]] +name = "test_frompyobject" +path = "tests/test_frompyobject.rs" +required-features = ["macros"] + +[[test]] +name = "test_gc" +path = "tests/test_gc.rs" +required-features = ["macros"] + +[[test]] +name = "test_getter_setter" +path = "tests/test_getter_setter.rs" +required-features = ["macros"] + +[[test]] +name = "test_inheritance" +path = "tests/test_inheritance.rs" +required-features = ["macros"] + +[[test]] +name = "test_init_race" +path = "tests/test_init_race.rs" + +[[test]] +name = "test_intopyobject" +path = "tests/test_intopyobject.rs" +required-features = ["macros"] + +[[test]] +name = "test_macro_docs" +path = "tests/test_macro_docs.rs" +required-features = ["macros"] + +[[test]] +name = "test_macros" +path = "tests/test_macros.rs" +required-features = ["macros"] + +[[test]] +name = "test_mapping" +path = "tests/test_mapping.rs" +required-features = ["macros"] + +[[test]] +name = "test_methods" +path = "tests/test_methods.rs" +required-features = ["macros"] + +[[test]] +name = "test_module" +path = "tests/test_module.rs" +required-features = ["macros"] + +[[test]] +name = "test_multiple_pymethods" +path = "tests/test_multiple_pymethods.rs" +required-features = ["multiple-pymethods"] + +[[test]] +name = "test_proto_methods" +path = "tests/test_proto_methods.rs" +required-features = ["macros"] + +[[test]] +name = "test_pybuffer_drop_without_interpreter" +path = "tests/test_pybuffer_drop_without_interpreter.rs" + +[[test]] +name = "test_pyerr_debug_unformattable" +path = "tests/test_pyerr_debug_unformattable.rs" + +[[test]] +name = "test_pyfunction" +path = "tests/test_pyfunction.rs" +required-features = ["macros"] + +[[test]] +name = "test_pyself" +path = "tests/test_pyself.rs" +required-features = ["macros"] + +[[test]] +name = "test_sequence" +path = "tests/test_sequence.rs" +required-features = ["macros"] + +[[test]] +name = "test_serde" +path = "tests/test_serde.rs" +required-features = ["serde"] + +[[test]] +name = "test_static_slots" +path = "tests/test_static_slots.rs" +required-features = ["macros"] + +[[test]] +name = "test_string" +path = "tests/test_string.rs" +required-features = ["macros"] + +[[test]] +name = "test_super" +path = "tests/test_super.rs" +required-features = ["macros"] + +[[test]] +name = "test_text_signature" +path = "tests/test_text_signature.rs" +required-features = ["macros"] + +[[test]] +name = "test_variable_arguments" +path = "tests/test_variable_arguments.rs" +required-features = ["macros"] + +[[test]] +name = "test_various" +path = "tests/test_various.rs" +required-features = ["macros"] + +[dependencies.anyhow] +version = "1.0.1" +optional = true + +[dependencies.bigdecimal] +version = "0.4.7" +optional = true + +[dependencies.bytes] +version = "1.10" +optional = true + +[dependencies.chrono] +version = "0.4.25" +optional = true +default-features = false + +[dependencies.chrono-tz] +version = ">= 0.10, < 0.11" +optional = true +default-features = false + +[dependencies.either] +version = "1.9" +optional = true + +[dependencies.eyre] +version = ">= 0.6.8, < 0.7" +optional = true + +[dependencies.hashbrown] +version = ">= 0.15.0, < 0.18" +features = ["default-hasher"] +optional = true +default-features = false + +[dependencies.iana-time-zone] +version = "0.1" +features = ["fallback"] +optional = true + +[dependencies.indexmap] +version = ">= 2.5.0, < 3" +optional = true + +[dependencies.inventory] +version = "0.3.5" +optional = true + +[dependencies.jiff-02] +version = "0.2" +optional = true +package = "jiff" + +[dependencies.libc] +version = "0.2.62" + +[dependencies.lock_api] +version = "0.4" +optional = true + +[dependencies.num-bigint] +version = "0.4.4" +optional = true + +[dependencies.num-complex] +version = ">= 0.4.6, < 0.5" +optional = true + +[dependencies.num-rational] +version = "0.4.1" +optional = true + +[dependencies.num-traits] +version = "0.2.16" +optional = true + +[dependencies.once_cell] +version = "1.21" + +[dependencies.ordered-float] +version = "5.0.0" +optional = true +default-features = false + +[dependencies.parking_lot] +version = "0.12" +optional = true + +[dependencies.pyo3-ffi] +version = "=0.29.2" + +[dependencies.pyo3-macros] +version = "=0.29.2" +optional = true + +[dependencies.rust_decimal] +version = "1.15" +optional = true +default-features = false + +[dependencies.serde] +version = "1.0" +optional = true + +[dependencies.smallvec] +version = "1.0" +optional = true + +[dependencies.time] +version = "0.3.38" +optional = true +default-features = false + +[dependencies.uuid] +version = "1.12.0" +optional = true + +[dev-dependencies.assert_approx_eq] +version = "1.1.0" + +[dev-dependencies.chrono] +version = "0.4.25" + +[dev-dependencies.chrono-tz] +version = ">= 0.10, < 0.11" + +[dev-dependencies.futures] +version = "0.3.28" + +[dev-dependencies.parking_lot] +version = "0.12.3" +features = ["arc_lock"] + +[dev-dependencies.proptest] +version = "1.0" +features = ["std"] +default-features = false + +[dev-dependencies.rayon] +version = "1.6.1" + +[dev-dependencies.regex] +version = "1.12.3" + +[dev-dependencies.send_wrapper] +version = "0.6" + +[dev-dependencies.serde] +version = "1.0" +features = ["derive"] + +[dev-dependencies.serde_json] +version = "1.0.61" + +[dev-dependencies.static_assertions] +version = "1.1.0" + +[dev-dependencies.tempfile] +version = "3.12.0" + +[dev-dependencies.ui_test] +version = "0.30.4" + +[dev-dependencies.uuid] +version = "1.10.0" +features = ["v4"] + +[build-dependencies.pyo3-build-config] +version = "=0.29.2" + +[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies.ctrlc] +version = "3.5.2" + +[target.'cfg(not(target_has_atomic = "64"))'.dependencies.portable-atomic] +version = "1.0" + +[lints.clippy] +checked_conversions = "warn" +dbg_macro = "warn" +explicit_into_iter_loop = "warn" +explicit_iter_loop = "warn" +filter_map_next = "warn" +flat_map_option = "warn" +let_unit_value = "warn" +manual_assert = "warn" +manual_ok_or = "warn" +todo = "warn" +undocumented_unsafe_blocks = "warn" +unnecessary_wraps = "warn" +used_underscore_binding = "warn" +useless_transmute = "warn" + +[lints.rust] +elided_lifetimes_in_paths = "warn" +invalid_doc_attributes = "warn" +rust_2021_prelude_collisions = "warn" +unsafe_op_in_unsafe_fn = "warn" +unused_lifetimes = "warn" + +[lints.rust.rust_2018_idioms] +level = "warn" +priority = -1 + +[lints.rust.unexpected_cfgs] +level = "warn" +priority = 0 +check-cfg = [ + "cfg(pyo3_disable_reference_pool)", + "cfg(pyo3_leak_on_drop_without_reference_pool)", + "cfg(pyo3_use_raw_dylib)", + 'cfg(pyo3_dll, values("python3", "python3_d", "python3t", "python3t_d", "python38", "python38_d", "python39", "python39_d", "python310", "python310_d", "python311", "python311_d", "python312", "python312_d", "python313", "python313_d", "python313t", "python313t_d", "python314", "python314_d", "python314t", "python314t_d", "python315", "python315_d", "python315t", "python315t_d", "python316", "python316_d", "python316t", "python316t_d", "libpypy3.11-c"))', +] + +[lints.rustdoc] +bare_urls = "warn" +broken_intra_doc_links = "warn" diff --git a/vendor/pyo3/Cargo.toml.orig b/vendor/pyo3/Cargo.toml.orig new file mode 100644 index 0000000..3f0f054 --- /dev/null +++ b/vendor/pyo3/Cargo.toml.orig @@ -0,0 +1,436 @@ +[package] +name = "pyo3" +version = "0.29.2" +description = "Bindings to Python interpreter" +authors = ["PyO3 Project and Contributors "] +readme = "README.md" +keywords = ["pyo3", "python", "cpython", "ffi"] +homepage = "https://github.com/pyo3/pyo3" +repository = "https://github.com/pyo3/pyo3" +documentation = "https://docs.rs/crate/pyo3/" +categories = ["api-bindings", "development-tools::ffi"] +license = "MIT OR Apache-2.0" +exclude = [ + "/.gitignore", + ".cargo/config", + "/codecov.yml", + "/Makefile", + "/pyproject.toml", + "/noxfile.py", + "/.github", + "/tests/test_compile_error.rs", + "/tests/ui", +] +edition = "2021" +# This allows PyO3 to forward build-config from `pyo3-ffi` to avoid downstream crates +# needing to depend on `pyo3-ffi` directly to use `pyo3-build-config` functionality. +# +# See also https://github.com/rust-lang/cargo/issues/3544 and +# https://github.com/rust-lang/cargo/pull/16436 which may allow this to be +# reverted in the future. +links = "pyo3-python" +rust-version.workspace = true + +[dependencies] +libc = "0.2.62" +once_cell = "1.21" + +# ffi bindings to the python interpreter, split into a separate crate so they can be used independently +pyo3-ffi = { path = "pyo3-ffi", version = "=0.29.2" } + +# support crate for macros feature +pyo3-macros = { path = "pyo3-macros", version = "=0.29.2", optional = true } + +# support crate for multiple-pymethods feature +inventory = { version = "0.3.5", optional = true } + +# crate integrations that can be added using the eponymous features +anyhow = { version = "1.0.1", optional = true } +bigdecimal = { version = "0.4.7", optional = true } +bytes = { version = "1.10", optional = true } +chrono = { version = "0.4.25", default-features = false, optional = true } +chrono-tz = { version = ">= 0.10, < 0.11", default-features = false, optional = true } +either = { version = "1.9", optional = true } +eyre = { version = ">= 0.6.8, < 0.7", optional = true } +hashbrown = { version = ">= 0.15.0, < 0.18", optional = true, default-features = false, features = [ + "default-hasher", +] } +indexmap = { version = ">= 2.5.0, < 3", optional = true } +jiff-02 = { package = "jiff", version = "0.2", optional = true } +num-bigint = { version = "0.4.4", optional = true } +num-complex = { version = ">= 0.4.6, < 0.5", optional = true } +num-rational = { version = "0.4.1", optional = true } +num-traits = { version = "0.2.16", optional = true } +ordered-float = { version = "5.0.0", default-features = false, optional = true } +rust_decimal = { version = "1.15", default-features = false, optional = true } +time = { version = "0.3.38", default-features = false, optional = true } +serde = { version = "1.0", optional = true } +smallvec = { version = "1.0", optional = true } +uuid = { version = "1.12.0", optional = true } +lock_api = { version = "0.4", optional = true } +parking_lot = { version = "0.12", optional = true } +iana-time-zone = { version = "0.1", optional = true, features = ["fallback"]} + +[target.'cfg(not(target_has_atomic = "64"))'.dependencies] +portable-atomic = "1.0" + +[dev-dependencies] +assert_approx_eq = "1.1.0" +chrono = "0.4.25" +chrono-tz = ">= 0.10, < 0.11" +proptest = { version = "1.0", default-features = false, features = ["std"] } +send_wrapper = "0.6" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0.61" +rayon = "1.6.1" +futures = "0.3.28" +tempfile = "3.12.0" +static_assertions = "1.1.0" +uuid = { version = "1.10.0", features = ["v4"] } +parking_lot = { version = "0.12.3", features = ["arc_lock"] } +ui_test = "0.30.4" +regex = "1.12.3" +[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +ctrlc = "3.5.2" + +[build-dependencies] +pyo3-build-config = { path = "pyo3-build-config", version = "=0.29.2" } + +[features] +default = ["macros"] + +# Enables support for `async fn` for `#[pyfunction]` and `#[pymethods]`. +experimental-async = ["macros", "pyo3-macros/experimental-async"] + +# Enables pyo3::inspect module and additional type information on FromPyObject +# and IntoPy traits +experimental-inspect = ["pyo3-macros/experimental-inspect"] + +# Enables macros: #[pyclass], #[pymodule], #[pyfunction] etc. +macros = ["pyo3-macros"] + +# Enables multiple #[pymethods] per #[pyclass] +multiple-pymethods = ["inventory", "pyo3-macros/multiple-pymethods"] + +# Deprecated: use the `PYO3_BUILD_EXTENSION_MODULE` environment variable when +# building a Python extension module (set automatically by `setuptools-rust` and +# `maturin`). +extension-module = ["pyo3-ffi/extension-module"] + +# Use the Python limited API. See https://www.python.org/dev/peps/pep-0384/ for more. +abi3 = ["pyo3-ffi/abi3"] + +# With abi3, we can manually set the minimum Python version. +abi3-py38 = ["abi3-py39", "pyo3-ffi/abi3-py38"] +abi3-py39 = ["abi3-py310", "pyo3-ffi/abi3-py39"] +abi3-py310 = ["abi3-py311", "pyo3-ffi/abi3-py310"] +abi3-py311 = ["abi3-py312", "pyo3-ffi/abi3-py311"] +abi3-py312 = ["abi3-py313", "pyo3-ffi/abi3-py312"] +abi3-py313 = ["abi3-py314", "pyo3-ffi/abi3-py313"] +abi3-py314 = ["abi3-py315", "pyo3-ffi/abi3-py314"] +abi3-py315 = ["abi3", "pyo3-ffi/abi3-py315"] + +abi3t = ["pyo3-ffi/abi3t"] + +# With abi3t, we can manually set the minimum Python version. +abi3t-py315 = ["abi3t", "pyo3-ffi/abi3t-py315"] + +# deprecated: no longer needed, raw-dylib is used instead +generate-import-lib = ["pyo3-ffi/generate-import-lib"] + +# Changes `Python::attach` to automatically initialize the Python interpreter if needed. +auto-initialize = [] + +# Enables `Clone`ing references to Python objects `Py` which panics if the +# thread is not attached to the Python interpreter. +py-clone = [] + +# Adds `OnceExt` and `MutexExt` implementations to the `parking_lot` types +parking_lot = ["dep:parking_lot", "lock_api"] +arc_lock = ["lock_api", "lock_api/arc_lock", "parking_lot?/arc_lock"] + +num-bigint = ["dep:num-bigint", "dep:num-traits"] +bigdecimal = ["dep:bigdecimal", "num-bigint"] + +chrono-local = ["chrono/clock", "dep:iana-time-zone"] + + +# Optimizes PyObject to Vec conversion and so on. +nightly = [] + +# Activates all additional features +# This is mostly intended for testing purposes - activating *all* of these isn't particularly useful. +full = [ + "macros", + # "multiple-pymethods", # Not supported by wasm + "anyhow", + "arc_lock", + "bigdecimal", + "bytes", + "chrono", + "chrono-local", + "chrono-tz", + "either", + "experimental-async", + "experimental-inspect", + "eyre", + "hashbrown", + "indexmap", + "jiff-02", + "lock_api", + "num-bigint", + "num-complex", + "num-rational", + "ordered-float", + "parking_lot", + "py-clone", + "rust_decimal", + "serde", + "smallvec", + "time", + "uuid", +] + +[workspace] +members = [ + "pyo3-ffi", + "pyo3-build-config", + "pyo3-macros", + "pyo3-macros-backend", + "pyo3-introspection", + "tests/ui/base", + "pytests", + "examples", +] +package.rust-version = "1.83" + +[package.metadata.docs.rs] +no-default-features = true +features = ["full"] +rustdoc-args = ["--cfg", "docsrs"] + +[workspace.lints.clippy] +checked_conversions = "warn" +dbg_macro = "warn" +explicit_into_iter_loop = "warn" +explicit_iter_loop = "warn" +filter_map_next = "warn" +flat_map_option = "warn" +let_unit_value = "warn" +manual_assert = "warn" +manual_ok_or = "warn" +todo = "warn" +undocumented_unsafe_blocks = "warn" +unnecessary_wraps = "warn" +useless_transmute = "warn" +used_underscore_binding = "warn" + +[workspace.lints.rust] +elided_lifetimes_in_paths = "warn" +invalid_doc_attributes = "warn" +rust_2018_idioms = { level = "warn", priority = -1 } +rust_2021_prelude_collisions = "warn" +unused_lifetimes = "warn" +unsafe_op_in_unsafe_fn = "warn" + +[workspace.lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = [ + 'cfg(pyo3_disable_reference_pool)', + 'cfg(pyo3_leak_on_drop_without_reference_pool)', + 'cfg(pyo3_use_raw_dylib)', + # this horrible hard-coded list should be kept in sync with the list of possible + # cfgs in pyo3-ffi/src/impl_/macros.rs + # + # for library names outside of this set we don't support raw-dylib and require a + # proper import library + # + # maybe in the future this list will not be necessary, see + # internals.rust-lang.org/t/support-renames-with-link-name-kind-raw-dylib/24415 + 'cfg(pyo3_dll, values("python3", "python3_d", "python3t", "python3t_d", "python38", "python38_d", "python39", "python39_d", "python310", "python310_d", "python311", "python311_d", "python312", "python312_d", "python313", "python313_d", "python313t", "python313t_d", "python314", "python314_d", "python314t", "python314t_d", "python315", "python315_d", "python315t", "python315t_d", "python316", "python316_d", "python316t", "python316t_d", "libpypy3.11-c"))', +] + + +[workspace.lints.rustdoc] +broken_intra_doc_links = "warn" +bare_urls = "warn" + +[lints] +workspace = true + +# Many tests are only relevant on certain feature combinations; +# CI is marginally more efficient if `required-feature` is specified to avoid +# building and launching empty test suites. + +[[test]] +name = "test_anyhow" +required-features = ["anyhow"] + +[[test]] +name = "test_append_to_inittab" +required-features = ["macros"] + +[[test]] +name = "test_arithmetics" +required-features = ["macros"] + +[[test]] +name = "test_buffer" +required-features = ["macros"] + +[[test]] +name = "test_buffer_protocol" +required-features = ["macros"] + +[[test]] +name = "test_bytes" +required-features = ["macros"] + +[[test]] +name = "test_class_attributes" +required-features = ["macros"] + +[[test]] +name = "test_class_basics" +required-features = ["macros"] + +[[test]] +name = "test_class_comparisons" +required-features = ["macros"] + +[[test]] +name = "test_class_conversion" +required-features = ["macros"] + +[[test]] +name = "test_class_formatting" +required-features = ["macros"] + +[[test]] +name = "test_class_init" +required-features = ["macros"] + +[[test]] +name = "test_class_new" +required-features = ["macros"] + +[[test]] +name = "test_compile_error" +required-features = ["macros"] +harness = false + +[[test]] +name = "test_coroutine" +required-features = ["experimental-async"] + +[[test]] +name = "test_declarative_module" +required-features = ["macros"] + +[[test]] +name = "test_default_impls" +required-features = ["macros"] + +[[test]] +name = "test_enum" +required-features = ["macros"] + +[[test]] +name = "test_exceptions" +required-features = ["macros"] + +[[test]] +name = "test_field_cfg" +required-features = ["macros"] + +[[test]] +name = "test_frompy_intopy_roundtrip" +required-features = ["macros"] + +[[test]] +name = "test_frompyobject" +required-features = ["macros"] + +[[test]] +name = "test_gc" +required-features = ["macros"] + +[[test]] +name = "test_getter_setter" +required-features = ["macros"] + +[[test]] +name = "test_inheritance" +required-features = ["macros"] + +[[test]] +name = "test_intopyobject" +required-features = ["macros"] + +[[test]] +name = "test_macro_docs" +required-features = ["macros"] + +[[test]] +name = "test_macros" +required-features = ["macros"] + +[[test]] +name = "test_mapping" +required-features = ["macros"] + +[[test]] +name = "test_methods" +required-features = ["macros"] + +[[test]] +name = "test_module" +required-features = ["macros"] + +[[test]] +name = "test_multiple_pymethods" +required-features = ["multiple-pymethods"] + +[[test]] +name = "test_proto_methods" +required-features = ["macros"] + +[[test]] +name = "test_pyfunction" +required-features = ["macros"] + +[[test]] +name = "test_pyself" +required-features = ["macros"] + +[[test]] +name = "test_sequence" +required-features = ["macros"] + +[[test]] +name = "test_serde" +required-features = ["serde"] + +[[test]] +name = "test_static_slots" +required-features = ["macros"] + +[[test]] +name = "test_string" +required-features = ["macros"] + +[[test]] +name = "test_super" +required-features = ["macros"] + +[[test]] +name = "test_text_signature" +required-features = ["macros"] + +[[test]] +name = "test_variable_arguments" +required-features = ["macros"] + +[[test]] +name = "test_various" +required-features = ["macros"] diff --git a/vendor/pyo3/Code-of-Conduct.md b/vendor/pyo3/Code-of-Conduct.md new file mode 100644 index 0000000..c06c625 --- /dev/null +++ b/vendor/pyo3/Code-of-Conduct.md @@ -0,0 +1,77 @@ +# 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, sex characteristics, 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. 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 + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq + diff --git a/vendor/pyo3/Contributing.md b/vendor/pyo3/Contributing.md new file mode 100644 index 0000000..2d330da --- /dev/null +++ b/vendor/pyo3/Contributing.md @@ -0,0 +1,293 @@ +# Contributing + +Thank you for your interest in contributing to PyO3! All are welcome - please consider reading our [Code of Conduct] to keep our community positive and inclusive. + +If you are searching for ideas how to contribute, proceed to the ["Getting started contributing"](#getting-started-contributing) section. If you have found a specific issue to contribute to and need information about the development process, you may find the section ["Writing pull requests"](#writing-pull-requests) helpful. + +If you want to become familiar with the codebase, see +[Architecture.md](https://github.com/PyO3/pyo3/blob/main/Architecture.md). + +## Getting started contributing + +Please join in with any part of PyO3 which interests you. We use GitHub issues to record all bugs and ideas. Feel free to request an issue to be assigned to you if you want to work on it. + +You can browse the API of the non-public parts of PyO3 [here](https://pyo3.rs/internal/doc/pyo3/index.html). + +The following sections also contain specific ideas on where to start contributing to PyO3. + +## AI Contributions + +In alignment with our [Code of Conduct] we expect contributors using AI to respect the impact of their contributions on the PyO3 community. +A "contribution" includes pull requests, issues, comments, discussions, and any other interaction with the community. +See other projects such as FastAPI which describes ["Human Effort Denial of Service"](https://tiangolo.com/open-source/contributing/#human-effort-denial-of-service) and LLVM's discussion of ["Extractive Contributions"](https://llvm.org/docs/AIToolPolicy.html#extractive-contributions). + +We note that many have strong opinions on the use of AI, and the technical and social landscape is changing rapidly. +As a project PyO3 does not take a position on AI and its merits or issues; we accept that AI is a reality of current software development and wish to prioritise here the best outcomes for the PyO3 community. + +Please abide by the following guidelines for AI contributions: +- Do not submit raw AI output; you are expected to be able to use your own words to explain and reason about any contribution you make to the project. + Submitting raw AI output amplifies the time needed to read and reason about the output from just your own time to many PyO3 community members' time. +- Do not submit AI-generated solutions to issues labelled "easy" or "Good First Issue". + These issues are the best opportunity for new contributors to familiarise with the project and using AI to complete these adds value for nobody. +- Any code which you submit with AI assistance must clearly have sufficient ownership from you that you can assert full copyright in accordance with our MIT and Apache licensing. +- If you are not familiar enough with the project to own your AI-assisted contribution, consider using an issue or discussion to engage constructively with PyO3 maintainers. + We maintainers can always take over development (and use our own AI, if need be), if you do not have the time to build the necessary knowledge to own the solution yourself. + +Any contribution which looks like it was produced by AI without sufficient human effort to ensure its quality may be closed, deleted, and/or hidden at the PyO3 maintainers' discretion. +We will take into consideration (non-exhaustively) factors such as the size of the contribution and whether the GitHub account looks like it is engaging in widespread automated contributions, and whether we need to ban the offending GitHub account. +We prefer that authors disclose if a contribution is generated by AI so we can take that into account without guesswork. + +This policy may be updated in the future to reflect conventions in the open source ecosystem as they evolve. + +## Setting up a development environment + +To work and develop PyO3, you need Python & Rust installed on your system. + +* We encourage the use of [rustup](https://rustup.rs/) to be able to select and choose specific toolchains based on the project. +* [Pyenv](https://github.com/pyenv/pyenv) is also highly recommended for being able to choose a specific Python version. +* [virtualenv](https://virtualenv.pypa.io/en/latest/) can also be used with or without Pyenv to use specific installed Python versions. +* [`nox`][nox] is used to automate many of our CI tasks. + +### Testing, linting, etc. with nox + +[`Nox`][nox] is used to automate many of our CI tasks and can be used locally to handle verification tasks as you code. We recommend running these actions via nox to make use of our preferred configuration options. You can install nox into your global python with pip: `pip install nox` or (recommended) with [`pipx`][pipx] `pip install pipx`, `pipx install nox` + +The main nox commands we have implemented are: + +* `nox -s test` will run the full suite of recommended rust and python tests (>10 minutes) +* `nox -s test-rust -- skip-full` will run a short suite of rust tests (2-3 minutes) +* `nox -s ruff` will check python linting and formatting +* `nox -s rustfmt` will check rust formatting +* `nox -s rumdl` will check the markdown in the guide +* `nox -s clippy` will run clippy to make recommendations on rust style +* `nox -s bench` will benchmark your rust code +* `nox -s codspeed` will run our suite of rust and python performance tests +* `nox -s coverage` will analyse test coverage and output `coverage.json` (alternatively: `nox -s coverage lcov` outputs `lcov.info`) +* `nox -s check-guide` will use [`lychee`][lychee] to check all the links in the guide and doc comments. + +Use `nox -l` to list the full set of subcommands you can run. + +#### UI Tests + +PyO3 uses [`ui_test`][ui_test] to develop UI tests to capture error messages from the Rust compiler for some of the macro functionality. + +The Rust compiler's error output differs depending on whether the `rust-src` component is installed. PyO3's CI has `rust-src` installed, so you need it locally for your UI test output to match: + +```bash +rustup component add rust-src +``` + +Because there are several feature combinations for these UI tests, when updating them all (e.g. for a new Rust compiler version) it may be helpful to use the `update-ui-tests` nox session: +```bash +nox -s update-ui-tests +``` + +## Ways to help + +### Help users identify bugs + +The [PyO3 Discord server](https://discord.gg/33kcChzH7f) is very active with users who are new to PyO3, and often completely new to Rust. Helping them debug is a great way to get experience with the PyO3 codebase. + +Helping others often reveals bugs, documentation weaknesses, and missing APIs. It's a good idea to open GitHub issues for these immediately so the resolution can be designed and implemented! + +### Implement issues ready for development + +Issues where the solution is clear and work is not in progress use the [needs-implementer](https://github.com/PyO3/pyo3/issues?q=is%3Aissue+is%3Aopen+label%3Aneeds-implementer) label. + +Don't be afraid if the solution is not clear to you! The core PyO3 contributors will be happy to mentor you through any questions you have to help you write the solution. + +### Help write great docs + +PyO3 has a user guide (using mdbook) as well as the usual Rust API docs. The aim is for both of these to be detailed, easy to understand, and up-to-date. Pull requests are always welcome to fix typos, change wording, add examples, etc. + +There are some specific areas of focus where help is currently needed for the documentation: + +- Issues requesting documentation improvements are tracked with the [documentation](https://github.com/PyO3/pyo3/issues?q=is%3Aissue+is%3Aopen+label%3Adocumentation) label. +- Not all APIs had docs or examples when they were made. The goal is to have documentation on all PyO3 APIs ([#306](https://github.com/PyO3/pyo3/issues/306)). If you see an API lacking a doc, please write one and open a PR! + +To build the docs (including all features), install [`nox`][nox] and then run + +```shell +nox -s docs -- open +``` + +#### Doctests + +We use lots of code blocks in our docs. Run `cargo test --doc` when making changes to check that +the doctests still work, or `cargo test` to run all the Rust tests including doctests. See +https://doc.rust-lang.org/rustdoc/documentation-tests.html for a guide on doctests. + +#### Building the guide + +You can preview the user guide by building it locally with `mdbook`. + +First, install [`mdbook`][mdbook], the [`mdbook-tabs`][mdbook-tabs] plugin and [`nox`][nox]. Then, run + +```shell +nox -s build-guide -- --open +``` + +To check all links in the guide are valid, also install [`lychee`][lychee] and use the `check-guide` session instead: + +```shell +nox -s check-guide +``` + +### Help design the next PyO3 + +Issues which don't yet have a clear solution use the [needs-design](https://github.com/PyO3/pyo3/issues?q=is%3Aissue+is%3Aopen+label%3Aneeds-design) label. + +If any of these issues interest you, please join in with the conversation on the issue! All opinions are valued, and if you're interested in going further with e.g. draft PRs to experiment with API designs, even better! + +### Review pull requests + +Everybody is welcome to submit comments on open PRs. Please help ensure new PyO3 APIs are safe, performant, tidy, and easy to use! + +## Writing pull requests + +Here are a few things to note when you are writing PRs. + +### Testing and Continuous Integration + +The PyO3 repo uses GitHub Actions. +PRs are blocked from merging if CI is not successful. +Formatting, linting and tests are checked for all Rust and Python code (the pipeline will abort early if formatting fails to save resources). +In addition, all warnings in Rust code are disallowed (using `RUSTFLAGS="-D warnings"`). + +Tests run with all supported Python versions with the latest stable Rust compiler, as well as for the latest Python version with the minimum supported Rust version. + +If you are adding a new feature, you should add it to the `full` feature in our *Cargo.toml** so that it is tested in CI. + +You can run the CI pipeline components yourself with `nox`, see [the testing section above](#testing-linting-etc-with-nox). + +### Documenting changes + +We use [towncrier](https://towncrier.readthedocs.io/en/stable/index.html) to generate a CHANGELOG for each release. + +To include your changes in the release notes, you should create one (or more) news items in the `newsfragments` directory. Valid news items should be saved as `..md` where `` is the pull request number and `` is one of the following: +- `packaging` - for dependency changes and Python / Rust version compatibility changes +- `added` - for new features +- `changed` - for features which already existed but have been altered or deprecated +- `removed` - for features which have been removed +- `fixed` - for "changed" features which were classed as a bugfix + +If your PR is a documentation, refactor, or internal change, prefix your PR title with `docs:`, `refactor:`, or `internal:` to skip this check. + +### Style guide + +#### Generic code + +PyO3 has a lot of generic APIs to increase usability. These can come at the cost of generic code bloat. Where reasonable, try to implement a concrete sub-portion of generic functions. There are two forms of this: + +- If the concrete sub-portion doesn't benefit from re-use by other functions, name it `inner` and keep it as a local to the function. +- If the concrete sub-portion is re-used by other functions, preferably name it `_foo` and place it directly below `foo` in the source code (where `foo` is the original generic function). + +#### FFI calls + +PyO3 makes a lot of FFI calls to Python's C API using raw pointers. Where possible try to avoid using pointers-to-temporaries in expressions: + +```rust +// dangerous +pyo3::ffi::Something(name.into_pyobject(py).as_ptr()); + +// because the following refactoring is a use-after-free error: +let name = name.into_pyobject(py).as_ptr(); +pyo3::ffi::Something(name) +``` + +Instead, prefer to bind the safe owned smart pointer before passing to ffi functions: + +```rust +let name = name.into_pyobject(py); +pyo3::ffi::Something(name.as_ptr()) +// name will automatically be freed when it falls out of scope +``` + +## Python and Rust version support policy + +PyO3 aims to keep sufficient compatibility to make packaging Python extensions built with PyO3 feasible on most common package managers. + +To keep package maintainers' lives simpler, PyO3 will commit, wherever possible, to only adjust minimum supported Rust and Python versions at the same time. This bump will only come in an `0.x` release, roughly once per year, after the oldest supported Python version reaches its end-of-life. (Check https://endoflife.date/python for a clear timetable on these.) + +Below are guidelines on what compatibility all PRs are expected to deliver for each language. + +### Python + +PyO3 supports all officially supported Python versions, as well as the latest PyPy3 and GraalPy releases. All of these versions are tested in CI. + +#### Adding support for new CPython versions + +If you plan to add support for a pre-release version of CPython, here's a (non-exhaustive) checklist: + + - [ ] Wait until the last alpha release (usually alpha7), since ABI is not guaranteed until the first beta release + - [ ] Add prerelease_ver-dev (e.g. `3.14-dev`) to `.github/workflows/ci.yml`, and bump version in `noxfile.py`, `pyo3-ffi/Cargo.toml` under `max-version` within `[package.metadata.cpython]`, and `max` within `pyo3-ffi/build.rs` +- [ ] Add a new abi3-prerelease feature for the version (e.g. `abi3-py314`) + - In `pyo3-build-config/Cargo.toml`, set abi3-most_current_stable to ["abi3-prerelease"] and abi3-prerelease to ["abi3"] + - In `pyo3-ffi/Cargo.toml`, set abi3-most_current_stable to ["abi3-prerelease", "pyo3-build-config/abi3-most_current_stable"] and abi3-prerelease to ["abi3", "pyo3-build-config/abi3-prerelease"] + - In `Cargo.toml`, set abi3-most_current_stable to ["abi3-prerelease", "pyo3-ffi/abi3-most_current_stable"] and abi3-prerelease to ["abi3", "pyo3-ffi/abi3-prerelease"] + - [ ] Use `#[cfg(Py_prerelease])` (e.g. `#[cfg(Py_3_14)]`) and `#[cfg(not(Py_prerelease]))` to indicate changes between the stable branches of CPython and the pre-release + - [ ] Do not add a Rust binding to any function, struct, or global variable prefixed with `_` in CPython's headers + - [ ] Ping @ngoldbaum and @davidhewitt for assistance + +### Rust + +PyO3 aims to make use of up-to-date Rust language features to keep the implementation as efficient as possible. + +The minimum Rust version supported will be decided when the release which bumps Python and Rust versions is made. At the time, the minimum Rust version will be set no higher than the lowest Rust version shipped in the current Debian, RHEL and Alpine Linux distributions. + +CI tests both the most recent stable Rust version and the minimum supported Rust version. Because of Rust's stability guarantees this is sufficient to confirm support for all Rust versions in between. + +## Benchmarking + +PyO3 has two sets of benchmarks for evaluating some aspects of its performance. The benchmark suite is currently very small - please open PRs with new benchmarks if you're interested in helping to expand it! + +First, there are Rust-based benchmarks located in the `pyo3-benches` subdirectory. You can run these benchmarks with: + + nox -s bench + +Second, there is a Python-based benchmark contained in the `pytests` subdirectory. You can read more about it [here](https://github.com/PyO3/pyo3/tree/main/pytests). + +## Code coverage + +You can view what code is and isn't covered by PyO3's tests. We aim to have 100% coverage - please check coverage and add tests if you notice a lack of coverage! + +- First, ensure the llvm-cov cargo plugin is installed. You may need to run the plugin through cargo once before using it with `nox`. +```shell +cargo install cargo-llvm-cov +cargo llvm-cov +``` +- Then, generate an `lcov.info` file with +```shell +nox -s coverage -- --lcov +``` +You can install an IDE plugin to view the coverage. For example, if you use VSCode: +- Add the [coverage-gutters](https://marketplace.visualstudio.com/items?itemName=ryanluker.vscode-coverage-gutters) plugin. +- Add these settings to VSCode's `settings.json`: +```json +{ + "coverage-gutters.coverageFileNames": [ + "lcov.info", + "cov.xml", + "coverage.xml", + ], + "coverage-gutters.showLineCoverage": true +} +``` +- You should now be able to see green highlights for code that is tested, and red highlights for code that is not tested. + +## Sponsor this project + +At the moment there is no official organisation that accepts sponsorship on PyO3's behalf. If you're seeking to provide significant funding to the PyO3 ecosystem, please reach out to us on [GitHub](https://github.com/PyO3/pyo3/issues/new) or [Discord](https://discord.gg/33kcChzH7f) and we can discuss. + +In the meanwhile, some of our maintainers have personal GitHub sponsorship pages and would be grateful for your support: + +- [davidhewitt](https://github.com/sponsors/davidhewitt) +- [messense](https://github.com/sponsors/messense) + +[mdbook]: https://rust-lang.github.io/mdBook/cli/index.html +[mdbook-tabs]: https://mdbook-plugins.rustforweb.org/tabs.html +[lychee]: https://github.com/lycheeverse/lychee +[nox]: https://github.com/theacodes/nox +[pipx]: https://pipx.pypa.io/stable/ +[ui_test]: https://github.com/oli-obk/ui_test +[Code of Conduct]: https://github.com/PyO3/pyo3/blob/main/Code-of-Conduct.md diff --git a/vendor/pyo3/LICENSE-APACHE b/vendor/pyo3/LICENSE-APACHE new file mode 100644 index 0000000..72207b8 --- /dev/null +++ b/vendor/pyo3/LICENSE-APACHE @@ -0,0 +1,178 @@ +Copyright (c) 2017-present PyO3 Project and Contributors. https://github.com/PyO3 + + 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/pyo3/LICENSE-MIT b/vendor/pyo3/LICENSE-MIT new file mode 100644 index 0000000..cd0ad00 --- /dev/null +++ b/vendor/pyo3/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2023-present PyO3 Project and Contributors. https://github.com/PyO3 + +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/pyo3/README.md b/vendor/pyo3/README.md new file mode 100644 index 0000000..c4b6e39 --- /dev/null +++ b/vendor/pyo3/README.md @@ -0,0 +1,290 @@ +# PyO3 + +[![actions status](https://img.shields.io/github/actions/workflow/status/PyO3/pyo3/ci.yml?branch=main&logo=github&style=)](https://github.com/PyO3/pyo3/actions) +[![benchmark](https://img.shields.io/endpoint?url=https://codspeed.io/badge.json)](https://codspeed.io/PyO3/pyo3) +[![codecov](https://img.shields.io/codecov/c/gh/PyO3/pyo3?logo=codecov)](https://codecov.io/gh/PyO3/pyo3) +[![crates.io](https://img.shields.io/crates/v/pyo3?logo=rust)](https://crates.io/crates/pyo3) +[![minimum rustc 1.83](https://img.shields.io/badge/rustc-1.83+-blue?logo=rust)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html) +[![discord server](https://img.shields.io/discord/1209263839632424990?logo=discord)](https://discord.gg/33kcChzH7f) +[![contributing notes](https://img.shields.io/badge/contribute-on%20github-Green?logo=github)](https://github.com/PyO3/pyo3/blob/main/Contributing.md) + +[Rust](https://www.rust-lang.org/) bindings for [Python](https://www.python.org/), including tools for creating native Python extension modules. Running and interacting with Python code from a Rust binary is also supported. + +- User Guide: [stable](https://pyo3.rs) | [main](https://pyo3.rs/main) + +- API Documentation: [stable](https://docs.rs/pyo3/) | [main](https://pyo3.rs/main/doc) + +## Usage + +Requires Rust 1.83 or greater. + +PyO3 supports the following Python distributions: + - CPython 3.8 or greater + - PyPy 7.3 (Python 3.11+) + - GraalPy 25.0 or greater (Python 3.12+) + +You can use PyO3 to write a native Python module in Rust, or to embed Python in a Rust binary. The following sections explain each of these in turn. + +### Using Rust from Python + +PyO3 can be used to generate a native Python module. The easiest way to try this out for the first time is to use [`maturin`](https://github.com/PyO3/maturin). `maturin` is a tool for building and publishing Rust-based Python packages with minimal configuration. The following steps install `maturin`, use it to generate and build a new Python package, and then launch Python to import and execute a function from the package. + +First, follow the commands below to create a new directory containing a new Python `virtualenv`, and install `maturin` into the virtualenv using Python's package manager, `pip`: + +```bash +# (replace string_sum with the desired package name) +$ mkdir string_sum +$ cd string_sum +$ python -m venv .env +$ source .env/bin/activate +$ pip install maturin +``` + +Still inside this `string_sum` directory, now run `maturin init`. This will generate the new package source. When given the choice of bindings to use, select pyo3 bindings: + +```bash +$ maturin init +✔ 🤷 What kind of bindings to use? · pyo3 + ✨ Done! New project created string_sum +``` + +The most important files generated by this command are `Cargo.toml` and `lib.rs`, which will look roughly like the following: + +**`Cargo.toml`** + +```toml +[package] +name = "string_sum" +version = "0.1.0" +edition = "2021" + +[lib] +# The name of the native library. This is the name which will be used in Python to import the +# library (i.e. `import string_sum`). If you change this, you must also change the name of the +# `#[pymodule]` in `src/lib.rs`. +name = "string_sum" +# "cdylib" is necessary to produce a shared library for Python to import from. +# +# Downstream Rust code (including code in `bin/`, `examples/`, and `tests/`) will not be able +# to `use string_sum;` unless the "rlib" or "lib" crate type is also included, e.g.: +# crate-type = ["cdylib", "rlib"] +crate-type = ["cdylib"] + +[dependencies] +pyo3 = "0.29.2" +``` + +**`src/lib.rs`** + +```rust +/// A Python module implemented in Rust. The name of this module must match +/// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to +/// import the module. +#[pyo3::pymodule] +mod string_sum { + use pyo3::prelude::*; + + /// Formats the sum of two numbers as string. + #[pyfunction] + fn sum_as_string(a: usize, b: usize) -> PyResult { + Ok((a + b).to_string()) + } +} +``` + +Finally, run `maturin develop`. This will build the package and install it into the Python virtualenv previously created and activated. The package is then ready to be used from `python`: + +```bash +$ maturin develop +# lots of progress output as maturin runs the compilation... +$ python +>>> import string_sum +>>> string_sum.sum_as_string(5, 20) +'25' +``` + +When checking runtime performance, run `maturin develop --release` to build with optimizations. + +To make changes to the package, just edit the Rust source code and then re-run `maturin develop` to recompile. + +To run this all as a single copy-and-paste, use the bash script below (replace `string_sum` in the first command with the desired package name): + +```bash +mkdir string_sum && cd "$_" +python -m venv .env +source .env/bin/activate +pip install maturin +maturin init --bindings pyo3 +maturin develop +``` + +If you want to be able to run `cargo test` or use this project in a Cargo workspace and are running into linker issues, there are some workarounds in [the FAQ](https://pyo3.rs/latest/faq.html#i-cant-run-cargo-test-or-i-cant-build-in-a-cargo-workspace-im-having-linker-issues-like-symbol-not-found-or-undefined-reference-to-_pyexc_systemerror). + +As well as with `maturin`, it is possible to build using [`setuptools-rust`](https://github.com/PyO3/setuptools-rust) or [manually](https://pyo3.rs/latest/building-and-distribution.html#manual-builds). Both offer more flexibility than `maturin` but require more configuration to get started. + +### Using Python from Rust + +To embed Python into a Rust binary, you need to ensure that your Python installation contains a shared library. The following steps demonstrate how to ensure this (for Ubuntu), and then give some example code which runs an embedded Python interpreter. + +To install the Python shared library on Ubuntu: + +```bash +sudo apt install python3-dev +``` + +To install the Python shared library on RPM based distributions (e.g. Fedora, Red Hat, SuSE), install the `python3-devel` package. + + +Start a new project with `cargo new` and add `pyo3` to the `Cargo.toml` like this: + +```toml +[dependencies.pyo3] +version = "0.29.2" +# Enabling this cargo feature will cause PyO3 to start a Python interpreter on first call to `Python::attach` +features = ["auto-initialize"] +``` + +Example program displaying the value of `sys.version` and the current user name: + +```rust +use pyo3::prelude::*; +use pyo3::types::IntoPyDict; + +fn main() -> PyResult<()> { + Python::attach(|py| { + let sys = py.import("sys")?; + let version: String = sys.getattr("version")?.extract()?; + + let locals = [("os", py.import("os")?)].into_py_dict(py)?; + let code = c"os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'"; + let user: String = py.eval(code, None, Some(&locals))?.extract()?; + + println!("Hello {}, I'm Python {}", user, version); + Ok(()) + }) +} +``` + +The guide has [a section](https://pyo3.rs/latest/python-from-rust.html) with lots of examples +about this topic. + +## Tools and libraries + +- [maturin](https://github.com/PyO3/maturin) _Build and publish crates with pyo3, rust-cpython or cffi bindings as well as rust binaries as python packages_ +- [setuptools-rust](https://github.com/PyO3/setuptools-rust) _Setuptools plugin for Rust support_. +- [pyo3-built](https://github.com/PyO3/pyo3-built) _Simple macro to expose metadata obtained with the [`built`](https://crates.io/crates/built) crate as a [`PyDict`](https://docs.rs/pyo3/*/pyo3/types/struct.PyDict.html)_ +- [rust-numpy](https://github.com/PyO3/rust-numpy) _Rust binding of NumPy C-API_ +- [dict-derive](https://github.com/gperinazzo/dict-derive) _Derive FromPyObject to automatically transform Python dicts into Rust structs_ +- [pyo3-log](https://github.com/vorner/pyo3-log) _Bridge from Rust to Python logging_ +- [pythonize](https://github.com/davidhewitt/pythonize) _Serde serializer for converting Rust objects to JSON-compatible Python objects_ +- [pyo3-async-runtimes](https://github.com/PyO3/pyo3-async-runtimes) _Utilities for interoperability with Python's Asyncio library and Rust's async runtimes._ +- [rustimport](https://github.com/mityax/rustimport) _Directly import Rust files or crates from Python, without manual compilation step. Provides pyo3 integration by default and generates pyo3 binding code automatically._ +- [pyo3-arrow](https://crates.io/crates/pyo3-arrow) _Lightweight [Apache Arrow](https://arrow.apache.org/) integration for pyo3._ +- [pyo3-bytes](https://crates.io/crates/pyo3-bytes) _Integration between [`bytes`](https://crates.io/crates/bytes) and pyo3._ +- [pyo3-object_store](https://github.com/developmentseed/obstore/tree/main/pyo3-object_store) _Integration between [`object_store`](https://docs.rs/object_store) and [`pyo3`](https://github.com/PyO3/pyo3)._ + +## Examples + +- [anise](https://github.com/nyx-space/anise) _A modern, high-performance toolkit for spacecraft mission design, notably used to help softly land Firefly Blue Ghost on the Moon on 02 Feb 2025._ +- [arro3](https://github.com/kylebarron/arro3) _A minimal Python library for Apache Arrow, connecting to the Rust arrow crate._ + - [arro3-compute](https://github.com/kylebarron/arro3/tree/main/arro3-compute) _`arro3-compute`_ + - [arro3-core](https://github.com/kylebarron/arro3/tree/main/arro3-core) _`arro3-core`_ + - [arro3-io](https://github.com/kylebarron/arro3/tree/main/arro3-io) _`arro3-io`_ +- [bed-reader](https://github.com/fastlmm/bed-reader) _Read and write the PLINK BED format, simply and efficiently._ + - Shows Rayon/ndarray::parallel (including capturing errors, controlling thread num), Python types to Rust generics, Github Actions +- [blake3-py](https://github.com/oconnor663/blake3-py) _Python bindings for the [BLAKE3](https://github.com/BLAKE3-team/BLAKE3) cryptographic hash function._ + - Parallelized [builds](https://github.com/oconnor663/blake3-py/blob/master/.github/workflows/dists.yml) on GitHub Actions for MacOS, Linux, Windows, including free-threaded 3.13t wheels. +- [cellular_raza](https://cellular-raza.com) _A cellular agent-based simulation framework for building complex models from a clean slate._ +- [connector-x](https://github.com/sfu-db/connector-x/tree/main/connectorx-python) _Fastest library to load data from DB to DataFrames in Rust and Python._ +- [cryptography](https://github.com/pyca/cryptography/tree/main/src/rust) _Python cryptography library with some functionality in Rust._ +- [css-inline](https://github.com/Stranger6667/css-inline/tree/master/bindings/python) _CSS inlining for Python implemented in Rust._ +- [datafusion-python](https://github.com/apache/arrow-datafusion-python) _A Python library that binds to Apache Arrow in-memory query engine DataFusion._ +- [deltalake-python](https://github.com/delta-io/delta-rs/tree/main/python) _Native Delta Lake Python binding based on delta-rs with Pandas integration._ +- [fastbloom](https://github.com/yankun1992/fastbloom) _A fast [bloom filter](https://github.com/yankun1992/fastbloom#BloomFilter) | [counting bloom filter](https://github.com/yankun1992/fastbloom#countingbloomfilter) implemented by Rust for Rust and Python!_ +- [fastuuid](https://github.com/thedrow/fastuuid/) _Python bindings to Rust's UUID library._ +- [fast-paseto](https://github.com/CodingCogs-OSS/Fast-Paseto) _High-performance PASETO (Platform-Agnostic Security Tokens) implementation with Python bindings._ +- [feos](https://github.com/feos-org/feos) _Lightning fast thermodynamic modeling in Rust with fully developed Python interface._ +- [finalytics](https://github.com/Nnamdi-sys/finalytics) _Investment Analysis library in Rust | Python._ +- [forust](https://github.com/jinlow/forust) _A lightweight gradient boosted decision tree library written in Rust._ +- [geo-index](https://github.com/kylebarron/geo-index) _A Rust crate and [Python library](https://github.com/kylebarron/geo-index/tree/main/python) for packed, immutable, zero-copy spatial indexes._ +- [granian](https://github.com/emmett-framework/granian) _A Rust HTTP server for Python applications._ +- [haem](https://github.com/BooleanCat/haem) _A Python library for working on Bioinformatics problems._ +- [hifitime](https://github.com/nyx-space/hifitime) _A high fidelity time management library for engineering and scientific applications where general relativity and time dilation matter._ +- [html2text-rs](https://github.com/deedy5/html2text_rs) _Python library for converting HTML to markup or plain text._ +- [html-py-ever](https://github.com/PyO3/setuptools-rust/tree/main/examples/html-py-ever) _Using [html5ever](https://github.com/servo/html5ever) through [kuchiki](https://github.com/kuchiki-rs/kuchiki) to speed up html parsing and css-selecting._ +- [hudi-rs](https://github.com/apache/hudi-rs) _The native Rust implementation for Apache Hudi, with C++ & Python API bindings._ +- [inline-python](https://github.com/m-ou-se/inline-python) _Inline Python code directly in your Rust code._ +- [johnnycanencrypt](https://github.com/kushaldas/johnnycanencrypt) OpenPGP library with Yubikey support. +- [jsonschema](https://github.com/Stranger6667/jsonschema/tree/master/crates/jsonschema-py) _A high-performance JSON Schema validator for Python._ +- [mocpy](https://github.com/cds-astro/mocpy) _Astronomical Python library offering data structures for describing any arbitrary coverage regions on the unit sphere._ +- [obstore](https://github.com/developmentseed/obstore) _The simplest, highest-throughput Python interface to Amazon S3, Google Cloud Storage, Azure Storage, & other S3-compliant APIs, powered by Rust._ +- [opendal](https://github.com/apache/opendal/tree/main/bindings/python) _A data access layer that allows users to easily and efficiently retrieve data from various storage services in a unified way._ +- [orjson](https://github.com/ijl/orjson) _Fast Python JSON library._ +- [ormsgpack](https://github.com/aviramha/ormsgpack) _Fast Python msgpack library._ +- [pdfcrate](https://github.com/ratazzi/pdfcrate) _An ergonomic, high-level PDF generation library for Rust and Python — a Prawn-style layout API for composing documents, not low-level PDF plumbing._ +- [polars](https://github.com/pola-rs/polars) _Fast multi-threaded DataFrame library in Rust | Python | Node.js._ +- [pycrdt](https://github.com/jupyter-server/pycrdt) _Python bindings for the Rust CRDT implementation [Yrs](https://github.com/y-crdt/y-crdt)._ +- [pydantic-core](https://github.com/pydantic/pydantic-core) _Core validation logic for pydantic written in Rust._ +- [primp](https://github.com/deedy5/primp) _The fastest python HTTP client that can impersonate web browsers by mimicking their headers and TLS/JA3/JA4/HTTP2 fingerprints._ +- [quebec](https://github.com/ratazzi/quebec) _A database-backed background job queue for Python, inspired by Rails' Solid Queue._ +- [radiate](https://github.com/pkalivas/radiate): _A high-performance evolution engine for genetic programming and evolutionary algorithms._ +- [rateslib](https://github.com/attack68/rateslib) _A fixed income library for Python using Rust extensions._ +- [river](https://github.com/online-ml/river) _Online machine learning in python, the computationally heavy statistics algorithms are implemented in Rust._ +- [robyn](https://github.com/sparckles/Robyn) A Super Fast Async Python Web Framework with a Rust runtime. +- [rust-python-coverage](https://github.com/cjermain/rust-python-coverage) _Example PyO3 project with automated test coverage for Rust and Python._ +- [rnet](https://github.com/0x676e67/rnet) Asynchronous Python HTTP Client with Black Magic +- [sail](https://github.com/lakehq/sail) _Unifying stream, batch, and AI workloads with Apache Spark compatibility._ +- [tibs](https://github.com/scott-griffiths/tibs) _A sleek Python library for binary data._ +- [tiktoken](https://github.com/openai/tiktoken) _A fast BPE tokeniser for use with OpenAI's models._ +- [tokenizers](https://github.com/huggingface/tokenizers/tree/main/bindings/python) _Python bindings to the Hugging Face tokenizers (NLP) written in Rust._ +- [tzfpy](http://github.com/ringsaturn/tzfpy) _A fast package to convert longitude/latitude to timezone name._ +- [toml-rs](https://github.com/lava-sh/toml-rs) _A High-Performance TOML v1.0.0 and v1.1.0 parser for Python written in Rust._ +- [utiles](https://github.com/jessekrubin/utiles) _Fast Python web-map tile utilities_ + +## Articles and other media + +- [(Video) Using Rust in Free-Threaded vs Regular Python 3.13](https://www.youtube.com/watch?v=J7phN_M4GLM) - Jun 4, 2025 +- [(Video) Techniques learned from five years finding the way for Rust in Python](https://www.youtube.com/watch?v=KTQn_PTHNCw) - Feb 26, 2025 +- [(Podcast) Bridging Python and Rust: An Interview with PyO3 Maintainer David Hewitt](https://www.youtube.com/watch?v=P47JUMSQagU) - Aug 30, 2024 +- [(Video) PyO3: From Python to Rust and Back Again](https://www.youtube.com/watch?v=UmL_CA-v3O8) - Jul 3, 2024 +- [Parsing Python ASTs 20x Faster with Rust](https://www.gauge.sh/blog/parsing-python-asts-20x-faster-with-rust) - Jun 17, 2024 +- [(Video) How Python Harnesses Rust through PyO3](https://www.youtube.com/watch?v=UilujdubqVU) - May 18, 2024 +- [(Video) Combining Rust and Python: The Best of Both Worlds?](https://www.youtube.com/watch?v=lyG6AKzu4ew) - Mar 1, 2024 +- [(Video) Extending Python with Rust using PyO3](https://www.youtube.com/watch?v=T45ZEmSR1-s) - Dec 16, 2023 +- [A Week of PyO3 + rust-numpy (How to Speed Up Your Data Pipeline X Times)](https://terencezl.github.io/blog/2023/06/06/a-week-of-pyo3-rust-numpy/) - Jun 6, 2023 +- [(Podcast) PyO3 with David Hewitt](https://rustacean-station.org/episode/david-hewitt/) - May 19, 2023 +- [Making Python 100x faster with less than 100 lines of Rust](https://ohadravid.github.io/posts/2023-03-rusty-python/) - Mar 28, 2023 +- [How Pydantic V2 leverages Rust's Superpowers](https://fosdem.org/2023/schedule/event/rust_how_pydantic_v2_leverages_rusts_superpowers/) - Feb 4, 2023 +- [How we extended the River stats module with Rust using PyO3](https://boring-guy.sh/posts/river-rust/) - Dec 23, 2022 +- [Nine Rules for Writing Python Extensions in Rust](https://towardsdatascience.com/nine-rules-for-writing-python-extensions-in-rust-d35ea3a4ec29?sk=f8d808d5f414154fdb811e4137011437) - Dec 31, 2021 +- [Calling Rust from Python using PyO3](https://saidvandeklundert.net/learn/2021-11-18-calling-rust-from-python-using-pyo3/) - Nov 18, 2021 +- [davidhewitt's 2021 talk at Rust Manchester meetup](https://www.youtube.com/watch?v=-XyWG_klSAw&t=320s) - Aug 19, 2021 +- [Incrementally porting a small Python project to Rust](https://blog.waleedkhan.name/port-python-to-rust/) - Apr 29, 2021 +- [Vortexa - Integrating Rust into Python](https://www.vortexa.com/blog/integrating-rust-into-python) - Apr 12, 2021 +- [Writing and publishing a Python module in Rust](https://blog.yossarian.net/2020/08/02/Writing-and-publishing-a-python-module-in-rust) - Aug 2, 2020 + +## Contributing + +Everyone is welcomed to contribute to PyO3! There are many ways to support the project, such as: + +- help PyO3 users with issues on GitHub and [Discord](https://discord.gg/33kcChzH7f) +- improve documentation +- write features and bugfixes +- publish blogs and examples of how to use PyO3 + +Our [contributing notes](https://github.com/PyO3/pyo3/blob/main/Contributing.md) and [architecture guide](https://github.com/PyO3/pyo3/blob/main/Architecture.md) have more resources if you wish to volunteer time for PyO3 and are searching where to start. + +If you don't have time to contribute yourself but still wish to support the project's future success, some of our maintainers have GitHub sponsorship pages: + +- [davidhewitt](https://github.com/sponsors/davidhewitt) +- [messense](https://github.com/sponsors/messense) + +## License + +PyO3 is licensed under the [Apache-2.0 license](LICENSE-APACHE) or the [MIT license](LICENSE-MIT), at your option. + +Python is licensed under the [Python License](https://docs.python.org/3/license.html). + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in PyO3 by you, as defined in the Apache License, shall be dual-licensed as above, without any additional terms or conditions. + +[![Deploys by Netlify](https://www.netlify.com/assets/badges/netlify-badge-color-accent.svg)](https://www.netlify.com) diff --git a/vendor/pyo3/Releasing.md b/vendor/pyo3/Releasing.md new file mode 100644 index 0000000..d3a1b4c --- /dev/null +++ b/vendor/pyo3/Releasing.md @@ -0,0 +1,58 @@ +# Releasing + +This is notes for the current process of releasing a new PyO3 version. Replace `` in all instructions below with the new version. + +## 1. Prepare the release commit + +Follow the process below to update all required pieces to bump the version. All these changes are done in a single commit because it makes it clear to git readers what happened to bump the version. It also makes it easy to cherry-pick the version bump onto the `main` branch when tidying up branch history at the end of the release process. + +1. Replace all instances of the PyO3 current version and the with the new version to be released. Places to check: + - `Cargo.toml` for all PyO3 crates in the repository. + - Examples in `README.md` + - PyO3 version embedded into documentation like the README. + - `pre-script.rhai` templates for the examples. + - `[towncrier]` section in `pyproject.toml`. + + Some of the above locations may already have the new version with a `-dev` suffix, which needs to be removed. + + **Make sure not to modify the CHANGELOG during this step!** + +2. Run `towncrier build` to generate the CHANGELOG. The version used by `towncrier` should automatically be correct because of the update to `pyproject.toml` in step 1. + +3. Manually edit the CHANGELOG for final notes. Steps to do: + - Adjust wording of any release lines to make them clearer for users / fix typos. + - Add a new link at the bottom for the new version, and update the `Unreleased` link. + +4. Create the commit containing all the above changes, with a message of `release: `. Push to `release-` branch on the main PyO3 repository, where `` depends on whether this is a major or minor release: + - for O.X.0 minor releases, just use `0.X`, e.g. `release-0.17`. This will become the maintenance branch after release. + - for 0.X.Y patch releases, use the full `0.X.Y`, e.g. `release-0.17.1`. This will be deleted after merge. + +## 2. Create the release PR and draft release notes + +Open a PR for the branch, and confirm that it passes CI. For `0.X.0` minor releases, the PR should be merging into `main`, for `0.X.Y` patch releases, the PR should be merging the `release-0.X` maintenance branch. + +On https://github.com/PyO3/pyo3/releases, click "Draft a new release". The tag will be a new tag of `v` (note preceding `v`) and target should be the `release-` branch you just pushed. + +Write release notes which match the style of previous releases. You can get the list of contributors by running `nox -s contributors -- v release-` to get contributors from the previous version tag through to the branch tip you just pushed. (This uses the GitHub API, so you'll need to push the branch first.) + +Save as a draft and wait for now. + +## 3. Leave for a cooling off period + +Wait a couple of days in case anyone wants to hold up the release to add bugfixes etc. + +## 4. Put live + +To put live: +- 1. merge the release PR +- 2. publish a release on GitHub targeting the release branch + +CI will automatically push to `crates.io`. + +## 5. Tidy the main branch + +If the release PR targeted a branch other than main, you will need to cherry-pick the version bumps, CHANGELOG modifications and removal of towncrier `newsfragments` and open another PR to land these on main. + +## 6. Delete the release branch (patch releases only) + +For 0.X.Y patch releases, the release branch is no longer needed, so it should be deleted. diff --git a/vendor/pyo3/assets/script.py b/vendor/pyo3/assets/script.py new file mode 100644 index 0000000..897bd3e --- /dev/null +++ b/vendor/pyo3/assets/script.py @@ -0,0 +1,5 @@ +# Used in PyModule examples. + + +class Blah: + pass diff --git a/vendor/pyo3/branding/favicon/pyo3_16x16.png b/vendor/pyo3/branding/favicon/pyo3_16x16.png new file mode 100644 index 0000000..0d2d77e Binary files /dev/null and b/vendor/pyo3/branding/favicon/pyo3_16x16.png differ diff --git a/vendor/pyo3/branding/favicon/pyo3_32x32.png b/vendor/pyo3/branding/favicon/pyo3_32x32.png new file mode 100644 index 0000000..ff1f97a Binary files /dev/null and b/vendor/pyo3/branding/favicon/pyo3_32x32.png differ diff --git a/vendor/pyo3/branding/pyo3logo.png b/vendor/pyo3/branding/pyo3logo.png new file mode 100644 index 0000000..06cad61 Binary files /dev/null and b/vendor/pyo3/branding/pyo3logo.png differ diff --git a/vendor/pyo3/branding/pyo3logo.svg b/vendor/pyo3/branding/pyo3logo.svg new file mode 100644 index 0000000..0315c63 --- /dev/null +++ b/vendor/pyo3/branding/pyo3logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/vendor/pyo3/branding/pyotr.png b/vendor/pyo3/branding/pyotr.png new file mode 100644 index 0000000..75ab9bb Binary files /dev/null and b/vendor/pyo3/branding/pyotr.png differ diff --git a/vendor/pyo3/branding/pyotr.svg b/vendor/pyo3/branding/pyotr.svg new file mode 100644 index 0000000..52d478e --- /dev/null +++ b/vendor/pyo3/branding/pyotr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/vendor/pyo3/build.rs b/vendor/pyo3/build.rs new file mode 100644 index 0000000..1077d45 --- /dev/null +++ b/vendor/pyo3/build.rs @@ -0,0 +1,62 @@ +use std::env; + +use pyo3_build_config::pyo3_build_script_impl::{ + cargo_env_var, errors::Result, print_feature_cfgs, +}; +use pyo3_build_config::{add_libpython_rpath_link_args, bail, InterpreterConfig}; + +fn ensure_auto_initialize_ok(interpreter_config: &InterpreterConfig) -> Result<()> { + if cargo_env_var("CARGO_FEATURE_AUTO_INITIALIZE").is_some() && !interpreter_config.shared() { + bail!( + "The `auto-initialize` feature is enabled, but your python installation only supports \ + embedding the Python interpreter statically. If you are attempting to run tests, or a \ + binary which is okay to link dynamically, install a Python distribution which ships \ + with the Python shared library.\n\ + \n\ + Embedding the Python interpreter statically does not yet have first-class support in \ + PyO3. If you are sure you intend to do this, disable the `auto-initialize` feature.\n\ + \n\ + For more information, see \ + https://pyo3.rs/v{pyo3_version}/\ + building-and-distribution.html#embedding-python-in-rust", + pyo3_version = env::var("CARGO_PKG_VERSION").unwrap() + ); + } + Ok(()) +} + +/// Prepares the PyO3 crate for compilation. +/// +/// This loads the config from pyo3-build-config and then makes some additional checks to improve UX +/// for users. +/// +/// Emits the cargo configuration based on this config as well as a few checks of the Rust compiler +/// version to enable features which aren't supported on MSRV. +fn configure_pyo3() -> Result<()> { + let interpreter_config = pyo3_build_config::get(); + + ensure_auto_initialize_ok(interpreter_config)?; + + for cfg in interpreter_config.build_script_outputs() { + println!("{cfg}") + } + + print_feature_cfgs(); + + // Forwards interpreter config under the links = "pyo3-python" configuration, + // which allows consumers of `pyo3-build-config` APIs to depend on pyo3 instead of pyo3-ffi. + interpreter_config.to_cargo_dep_env()?; + + // Make `cargo test` etc work with non-system Python installations + add_libpython_rpath_link_args(); + + Ok(()) +} + +fn main() { + pyo3_build_config::print_expected_cfgs(); + if let Err(e) = configure_pyo3() { + eprintln!("error: {}", e.report()); + std::process::exit(1) + } +} diff --git a/vendor/pyo3/guide/book.toml b/vendor/pyo3/guide/book.toml new file mode 100644 index 0000000..25c1dfe --- /dev/null +++ b/vendor/pyo3/guide/book.toml @@ -0,0 +1,19 @@ +[book] +title = "PyO3 user guide" +description = "PyO3 user guide" +authors = ["PyO3 Project and Contributors"] + +[preprocessor.pyo3_version] +command = "python3 pyo3_version.py" + +[preprocessor.glossary_linker] +command = "python3 glossary_linker.py" + +[preprocessor.tabs] + +[output.html] +git-repository-url = "https://github.com/PyO3/pyo3/tree/main/guide" +edit-url-template = "https://github.com/PyO3/pyo3/edit/main/guide/{path}" +playground.runnable = false +additional-css = ["theme/tabs.css"] +additional-js = ["theme/tabs.js"] diff --git a/vendor/pyo3/guide/glossary_linker.py b/vendor/pyo3/guide/glossary_linker.py new file mode 100644 index 0000000..c2c202f --- /dev/null +++ b/vendor/pyo3/guide/glossary_linker.py @@ -0,0 +1,251 @@ +"""mdbook preprocessor to auto-link glossary terms. + +Parses glossary.md for terms defined using definition list syntax: + + term A + : This is a definition of term A. + + term B + : This is a definition of term B. + +For each chapter (except the glossary itself), the first occurrence of each +term is replaced with a link to the glossary entry. + +An HTML comment block at the bottom of glossary.md maps additional +terms to arbitrary URLs (e.g. upstream Python/Rust glossary entries): + +Tested against mdbook 0.5.0. +""" + +import json +import re +import sys + + +def slugify(term): + """Convert a term to a URL-friendly anchor slug.""" + return re.sub(r"[^\w\s-]", "", term.lower()).strip().replace(" ", "-") + + +def parse_glossary(content): + """Parse glossary.md and return (local_terms, external_terms). + + local_terms: dict of {term: url} for definition-list entries (link to glossary anchors). + external_terms: dict of {term: url} from the comment. + """ + local_terms = {} + external_terms = {} + + # Parse definition-list terms: a non-indented line followed by a line + # starting with " : " (the definition). + for m in re.finditer(r"(?m)^([^\s#<>!`\[].+)\n : ", content): + term = m.group(1).strip() + local_terms[term] = f"glossary.md#{slugify(term)}" + + # Parse block for external URLs. + link_block = re.search( + r"", content, re.DOTALL + ) + if not link_block: + raise ValueError("Glossary is missing block") + + for line in link_block.group(1).strip().splitlines(): + line = line.strip() + if not line: + continue + # "term: url" or "term | url" + parts = re.split(r"\s*[:|]\s*", line, maxsplit=1) + if len(parts) == 2: + term, url = parts[0].strip(), parts[1].strip() + if term and url: + external_terms[term] = url + + return local_terms, external_terms + + +# --------------------------------------------------------------------------- +# Replacement logic +# --------------------------------------------------------------------------- + +# Matches fenced code blocks, inline code, and markdown links so we can skip +# them. Everything else is "plain text" we can scan for terms. +_SKIP_PATTERN = re.compile( + r"^```[^\n]*\n[\s\S]*?^```\s*$" # fenced code blocks (``` to ```, multiline) + r"|`[^`\n]+`" # inline code (single line only) + r"|\[[^\]]*\]\([^\)]*\)" # markdown links (entire [...](...)) + r"|<[^>\n]+>" # HTML tags (single line only) + r"|^\s*>.*$" # block quotes (single line) + r"|^.+(?=\n : )" # definition list term lines + r"|^#{1,6}\s+.*$", # headings + re.MULTILINE, +) + + +def link_terms_in_content(content, terms, first_only=True, url_prefix=""): + """Replace occurrences of glossary terms with markdown links. + + If first_only is True (default), only the first occurrence of each term is + linked. If False, every occurrence is linked. + + Skips code blocks, inline code, existing links, and HTML tags. + """ + linked = set() + + # Build a combined pattern matching any term, longest first so that + # multi-word terms match before their sub-terms. + sorted_terms = sorted(terms.keys(), key=len, reverse=True) + if not sorted_terms: + return content + + # Allow optional trailing "s" so plurals like "wheels" match "wheel". + escaped = [re.escape(t) + r"s?" for t in sorted_terms] + term_pattern = re.compile(r"\b(" + "|".join(escaped) + r")\b") + + # Find all protected spans. + protected = [] + for m in _SKIP_PATTERN.finditer(content): + protected.append((m.start(), m.end())) + + # Parse comments to suppress specific terms. + # Maps line number to set of suppressed term names (lowercased). + _suppressed_re = re.compile(r"") + suppressed_at_line = {} + for m in _suppressed_re.finditer(content): + term_name = m.group(1).strip().lower() + # Find the next line after the comment. + next_line_start = content.find("\n", m.end()) + if next_line_start == -1: + continue + next_line_start += 1 + next_line_end = content.find("\n", next_line_start) + if next_line_end == -1: + next_line_end = len(content) + suppressed_at_line.setdefault((next_line_start, next_line_end), set()).add( + term_name + ) + + def in_protected(start, end): + for ps, pe in protected: + if start >= ps and end <= pe: + return True + return False + + def is_suppressed(canonical, start): + """Check if this term is suppressed by a on the same line.""" + for (ls, le), suppressed_terms in suppressed_at_line.items(): + if ls <= start < le and canonical.lower() in suppressed_terms: + return True + return False + + result = [] + last = 0 + + for m in term_pattern.finditer(content): + matched_term = m.group(1) + + # Find the canonical term. Try exact match, then case-insensitive, + # then strip trailing "s" for plural forms. + canonical = None + for candidate in (matched_term, matched_term.rstrip("s")): + if candidate in terms: + canonical = candidate + break + for t in terms: + if t.lower() == candidate.lower(): + canonical = t + break + if canonical is not None: + break + if canonical is None: + continue + + if first_only and canonical in linked: + continue + + if in_protected(m.start(), m.end()): + continue + + if is_suppressed(canonical, m.start()): + continue + + linked.add(canonical) + result.append(content[last : m.start()]) + url = terms[canonical] + if url_prefix and not url.startswith("http"): + url = url_prefix + url + result.append(f"[{matched_term}]({url})") + last = m.end() + + result.append(content[last:]) + return "".join(result) + + +# --------------------------------------------------------------------------- +# mdbook preprocessor interface +# --------------------------------------------------------------------------- + + +def find_glossary_content(items): + """Walk the book items to find and return the glossary chapter content.""" + for item in items: + if not isinstance(item, dict) or "Chapter" not in item: + continue + ch = item["Chapter"] + if ch.get("path") and ch["path"].endswith("glossary.md"): + return ch["content"] + result = find_glossary_content(ch.get("sub_items", [])) + if result is not None: + return result + return None + + +def process_item(item, local_terms, external_terms): + """Recursively process a book item, linking glossary terms.""" + if not isinstance(item, dict) or "Chapter" not in item: + return + + ch = item["Chapter"] + path = ch.get("path", "") + + if path and path.endswith("glossary.md"): + # On the glossary page itself, link external terms (all occurrences). + ch["content"] = link_terms_in_content( + ch["content"], external_terms, first_only=False + ) + elif path: + # Compute relative prefix for local glossary links based on depth. + prefix = "../" * path.count("/") + all_terms = {**local_terms, **external_terms} + ch["content"] = link_terms_in_content( + ch["content"], all_terms, url_prefix=prefix + ) + + for sub in ch.get("sub_items", []): + process_item(sub, local_terms, external_terms) + + +def main(): + for line in sys.stdin: + if not line.strip(): + continue + [context, book] = json.loads(line) + + # Parse glossary terms from the glossary chapter. + glossary_content = find_glossary_content(book["items"]) + if glossary_content is None: + # No glossary found; pass through unchanged. + json.dump(book, fp=sys.stdout) + return + + local_terms, external_terms = parse_glossary(glossary_content) + + # Process all chapters. + for item in book["items"]: + process_item(item, local_terms, external_terms) + + json.dump(book, fp=sys.stdout) + return + + +if __name__ == "__main__": + main() diff --git a/vendor/pyo3/guide/pyclass-parameters.md b/vendor/pyo3/guide/pyclass-parameters.md new file mode 100644 index 0000000..c96082d --- /dev/null +++ b/vendor/pyo3/guide/pyclass-parameters.md @@ -0,0 +1,53 @@ +`#[pyclass]` can be used with the following parameters: + +| Parameter | Description | +| :- | :- | +| `constructor` | This is currently only allowed on [variants of complex enums][params-constructor]. It allows customization of the generated class constructor for each variant. It uses the same syntax and supports the same options as the `signature` attribute of functions and methods. | +| `crate = "some::path"` | Path to import the `pyo3` crate, if it's not accessible at `::pyo3`. | +| `dict` | Gives instances of this class an empty `__dict__` to store custom attributes. | +| `eq` | Implements `__eq__` using the `PartialEq` implementation of the underlying Rust datatype. | +| `eq_int` | Implements `__eq__` using `__int__` for simple enums. | +| `extends = BaseType` | Use a custom baseclass. Defaults to [`PyAny`][params-1] | +| `freelist = N` | Implements a [free list][params-2] of size N. This can improve performance for types that are often created and deleted in quick succession. Profile your code to see whether `freelist` is right for you. | +| `from_py_object` | Implement `FromPyObject` for this pyclass. Requires the pyclass to be `Clone`. | +| `frozen` | Declares that your pyclass is immutable. It removes the borrow checker overhead when retrieving a shared reference to the Rust struct, but disables the ability to get a mutable reference. | +| `generic` | Implements runtime parametrization for the class following [PEP 560](https://peps.python.org/pep-0560/). | +| `get_all` | Generates getters for all fields of the pyclass. | +| `hash` | Implements `__hash__` using the `Hash` implementation of the underlying Rust datatype. *Requires `eq` and `frozen`* | +| `immutable_type` | Makes the type object immutable. Supported on 3.14+ with the `abi3` feature active, or 3.10+ otherwise. | +| `mapping` | Inform PyO3 that this class is a [`Mapping`][params-mapping], and so leave its implementation of sequence C-API slots empty. | +| `module = "module_name"` | Python code will see the class as being defined in this module. Defaults to `builtins`. | +| `name = "python_name"` | Sets the name that Python sees this class as. Defaults to the name of the Rust struct. | +| `ord` | Implements `__lt__`, `__gt__`, `__le__`, & `__ge__` using the `PartialOrd` implementation of the underlying Rust datatype. *Requires `eq`* | +| `rename_all = "renaming_rule"` | Applies renaming rules to every getters and setters of a struct, or every variants of an enum. Possible values are: "camelCase", "kebab-case", "lowercase", "PascalCase", "SCREAMING-KEBAB-CASE", "SCREAMING_SNAKE_CASE", "snake_case", "UPPERCASE". | +| `sequence` | Inform PyO3 that this class is a [`Sequence`][params-sequence], and so leave its C-API mapping length slot empty. | +| `set_all` | Generates setters for all fields of the pyclass. | +| `new = "from_fields"` | Generates a default `__new__` constructor with all fields as parameters in the `new()` method. | +| `skip_from_py_object` | Prevents this PyClass from participating in the `FromPyObject: PyClass + Clone` blanket implementation. This allows a custom `FromPyObject` impl, even if `self` is `Clone`. | +| `str` | Implements `__str__` using the `Display` implementation of the underlying Rust datatype or by passing an optional format string `str=""`. *Note: The optional format string is only allowed for structs. `name` and `rename_all` are incompatible with the optional format string. Additional details can be found in the discussion on this [PR](https://github.com/PyO3/pyo3/pull/4233).* | +| `subclass` | Allows other Python classes and `#[pyclass]` to inherit from this class. Enums cannot be subclassed. | +| `unsendable` | Required if your struct is not [`Send`][params-3]. Rather than using `unsendable`, consider implementing your struct in a thread-safe way by e.g. substituting [`Rc`][params-4] with [`Arc`][params-5]. By using `unsendable`, your class will panic when accessed by another thread. Also note the Python's GC is multi-threaded and while unsendable classes will not be traversed on foreign threads to avoid UB, this can lead to memory leaks. | +| `weakref` | Allows this class to be [weakly referenceable][params-6]. | + +All of these parameters can either be passed directly on the `#[pyclass(...)]` annotation, or as one or more accompanying `#[pyo3(...)]` annotations, e.g.: + +```rust,ignore +// Argument supplied directly to the `#[pyclass]` annotation. +#[pyclass(name = "SomeName", subclass)] +struct MyClass {} + +// Argument supplied as a separate annotation. +#[pyclass] +#[pyo3(name = "SomeName", subclass)] +struct MyClass {} +``` + +[params-1]: https://docs.rs/pyo3/latest/pyo3/types/struct.PyAny.html +[params-2]: https://en.wikipedia.org/wiki/Free_list +[params-3]: https://doc.rust-lang.org/std/marker/trait.Send.html +[params-4]: https://doc.rust-lang.org/std/rc/struct.Rc.html +[params-5]: https://doc.rust-lang.org/std/sync/struct.Arc.html +[params-6]: https://docs.python.org/3/library/weakref.html +[params-constructor]: https://pyo3.rs/latest/class.html#complex-enums +[params-mapping]: https://pyo3.rs/latest/class/protocols.html#mapping--sequence-types +[params-sequence]: https://pyo3.rs/latest/class/protocols.html#mapping--sequence-types diff --git a/vendor/pyo3/guide/pyo3_version.py b/vendor/pyo3/guide/pyo3_version.py new file mode 100644 index 0000000..9fbca56 --- /dev/null +++ b/vendor/pyo3/guide/pyo3_version.py @@ -0,0 +1,53 @@ +"""Simple mdbook preprocessor to inject pyo3 version into the guide. + +It will replace: + - {{#PYO3_VERSION_TAG}} with the contents of the PYO3_VERSION_TAG environment var + - {{#PYO3_DOCS_URL}} with the location of docs (e.g. 'https://docs.rs/pyo3/0.13.2') + - {{#PYO3_CRATE_VERSION}} with a relevant toml snippet (e.g. 'version = "0.13.2"') + + +Tested against mdbook 0.5.0. +""" + +import json +import os +import sys + +# Set PYO3_VERSION in CI to build the correct version into links +PYO3_VERSION_TAG = os.environ.get("PYO3_VERSION_TAG", "main") + +if PYO3_VERSION_TAG == "main": + PYO3_DOCS_URL = "https://pyo3.rs/main/doc" + PYO3_DOCS_VERSION = "latest" + PYO3_CRATE_VERSION = 'git = "https://github.com/pyo3/pyo3"' +else: + # v0.13.2 -> 0.13.2 + version = PYO3_VERSION_TAG.lstrip("v") + PYO3_DOCS_URL = f"https://docs.rs/pyo3/{version}" + PYO3_DOCS_VERSION = version + PYO3_CRATE_VERSION = f'version = "{version}"' + + +def replace_item_content(item): + if not isinstance(item, dict) or "Chapter" not in item: + return + + # Replace raw and url-encoded forms + item["Chapter"]["content"] = ( + item["Chapter"]["content"] + .replace("{{#PYO3_VERSION_TAG}}", PYO3_VERSION_TAG) + .replace("{{#PYO3_DOCS_URL}}", PYO3_DOCS_URL) + .replace("{{#PYO3_DOCS_VERSION}}", PYO3_DOCS_VERSION) + .replace("{{#PYO3_CRATE_VERSION}}", PYO3_CRATE_VERSION) + ) + + for sub_item in item["Chapter"]["sub_items"]: + replace_item_content(sub_item) + + +for line in sys.stdin: + if line: + [context, book] = json.loads(line) + for item in book["items"]: + replace_item_content(item) + json.dump(book, fp=sys.stdout) diff --git a/vendor/pyo3/guide/src/SUMMARY.md b/vendor/pyo3/guide/src/SUMMARY.md new file mode 100644 index 0000000..3e01af7 --- /dev/null +++ b/vendor/pyo3/guide/src/SUMMARY.md @@ -0,0 +1,58 @@ +# Summary + +[Introduction](index.md) + +--- + +- [Getting started](getting-started.md) +- [Using Rust from Python](rust-from-python.md) + - [Python modules](module.md) + - [Python functions](function.md) + - [Function signatures](function/signature.md) + - [Error handling](function/error-handling.md) + - [Python classes](class.md) + - [Class customizations](class/protocols.md) + - [Basic object customization](class/object.md) + - [Emulating numeric types](class/numeric.md) + - [Emulating callable objects](class/call.md) + - [Thread safety](class/thread-safety.md) +- [Calling Python from Rust](python-from-rust.md) + - [Python object types](types.md) + - [Python exceptions](exception.md) + - [Calling Python functions](python-from-rust/function-calls.md) + - [Executing existing Python code](python-from-rust/calling-existing-code.md) +- [Type conversions](conversions.md) + - [Mapping of Rust types to Python types](conversions/tables.md) + - [Conversion traits](conversions/traits.md) +- [Using `async` and `await`](async-await.md) +- [Parallelism](parallelism.md) +- [Supporting Free-Threaded Python](free-threading.md) +- [Debugging](debugging.md) +- [Features reference](features.md) +- [Performance](performance.md) +- [Type stub generation and introspection](type-stub.md) +- [Advanced topics](advanced.md) + - [Sharing types between packages](advanced/sharing-types.md) +- [Building and distribution](building-and-distribution.md) + - [Supporting multiple Python versions](building-and-distribution/multiple-python-versions.md) +- [Useful crates](ecosystem.md) + - [Logging](ecosystem/logging.md) + - [Tracing](ecosystem/tracing.md) + - [Using `async` and `await`](ecosystem/async-await.md) +- [FAQ and troubleshooting](faq.md) + +--- + +[Appendix A: Migration guide](migration.md) + +[Appendix B: Glossary](glossary.md) + +[Appendix B: Trait bounds](trait-bounds.md) + +[Appendix C: Python typing hints](python-typing-hints.md) + +[CHANGELOG](changelog.md) + +--- + +[Contributing](contributing.md) diff --git a/vendor/pyo3/guide/src/advanced.md b/vendor/pyo3/guide/src/advanced.md new file mode 100644 index 0000000..79b6b29 --- /dev/null +++ b/vendor/pyo3/guide/src/advanced.md @@ -0,0 +1,14 @@ +# Advanced topics + +## FFI + +PyO3 exposes much of Python's C API through the `ffi` module. + +The C API is naturally unsafe and requires you to manage reference counts, errors and specific invariants yourself. +Please refer to the [C API Reference Manual](https://docs.python.org/3/c-api/) and [The Rustonomicon](https://doc.rust-lang.org/nightly/nomicon/ffi.html) before using any function from that API. + +## Sharing types between multiple PyO3 modules + +It is possible (but complicated) to share types between multiple PyO3 packages which can be compiled and installed separately. +This allows for ecosystems of functionality to be built similar to the many packages built on top of NumPy. +While PyO3 does not yet have any built-in support for doing this, the next sub-chapter of this guide describes the general approach to doing this, as well as the safety limitations to be aware of. diff --git a/vendor/pyo3/guide/src/advanced/sharing-types.md b/vendor/pyo3/guide/src/advanced/sharing-types.md new file mode 100644 index 0000000..300e6cd --- /dev/null +++ b/vendor/pyo3/guide/src/advanced/sharing-types.md @@ -0,0 +1,454 @@ +# Sharing `#[pyclass]` types between multiple PyO3 extension modules + +> [!WARNING] +> This is an advanced topic which requires reaching deeply into `unsafe` code. +> PyO3 does not have a stable API for doing this, and the approach documented here may break when updating to newer versions of PyO3. +> See [issue #1444](https://github.com/pyo3/pyo3/issues/1444) for ongoing discussion about this topic. + +Some Python extension modules such as NumPy expose a C API which can be consumed by other extension modules to build functionality which directly exchanges native data without needing to go via Python objects. +This allows for higher performance than continually moving data in and out of Python objects. + +It is a common request for PyO3 extension modules to be able to share `#[pyclass]` types (and other native data) across multiple crate/package boundaries in a similar fashion to NumPy. +Because PyO3 extension modules are each compiled as individual `cdylib` binaries, they cannot depend on each other in the typical Rust way of adding a Cargo dependency (which typically just includes the dependency statically inside the final compiled binary). + +Instead, the correct way to share `#[pyclass]` data between separate PyO3 extension modules is to use `#[repr(C)]` Rust types and an FFI-like API to exchange data across the `cdylib` boundaries. +The solution in this subchapter will explain how to do this correctly. + +## Quick summary + +The solution which this subchapter describes shares types across extension module boundaries by defining three Rust crates (see also the [example project] on GitHub). + +1. A crate `base-package-core` contains: + 1. `#[repr(C)]` Rust types and APIs to be shared with downstream extension modules (not `#[pyclass]` types or `#[pymethods]`). + 2. An API struct which contains function pointers to the API functions, version information, and any additional data. + 3. A global static variable which stores the API struct, and a function to initialise this at runtime by importing from the `base_package` Python package. + The implementations of the APIs defined in step 1 will delegate to the function pointers in the API struct. +2. A crate `base-package` which is a PyO3 project containing `#[pyclass]` thin wrappers around the types exposed in `base-package-core`. + 1. Implement the API functionality defined in `base-package-core` and populate the API struct accordingly. + 2. As part of the Python module, export the API struct inside a Python `capsule` object. + The initialisation function defined in `base-package-core` will import this capsule and populate the global static copy of the API struct backing the shared APIs. + +3. A crate `derived-package` which is a PyO3 project depending on `base-package-core` (not `base-package`). + 1. As part of the Python module, import the API struct from the `capule` exposed by the `base_package` Python package and store it in `derived-package`'s copy of the global static variable defined in `base-package-core`. + 2. Use the APIs from `base-package-core` to implement functionality which directly uses the shared types. + +The sections below go into more detail about how to implement various parts of this solution and why the solution is architected this way. + +## Technical background & limitations + +The Python ecosystem provides a well-established mechanism for sharing C APIs between native extension modules using [Python `capsule` objects](#capsules). +This avoids traditional "dynamic linking" between native extension modules, which would rely on system-specific behavior to locate and load `base_package` during import of `derived_package` and to resolve any errors in version mismatch between the two packages. + +The `capsule` mechanism works as follows: + +1. `base_package` defines a `#[repr(C)]` "API" struct which is exported in a Python `capsule` at runtime. +2. `derived_package` delegates to Python's extension loading mechanism to locate `base_package` and load the API from the capsule. +3. `derived_package` then contains its own logic to [check a compatible version](#api-versioning) of `base_package` was loaded; this is necessary to ensure safe exchange of the API struct. + +When sharing types between multiple PyO3 extension modules through a `capsule`, the complexity arises from two main sources: + +- Each Rust extension module may be built with completely separate Rust toolchains and build settings. + - This means anything which is implementation-defined, such as the layout of `#[repr(Rust)] struct`s, the implementation of `std`, and even optimizations, might disagree between the two extension modules. +- Each Rust extension module contains a full statically-linked copy of its own dependencies. + - Any `static` global variables which are compiled in the `base-package` will have a **completely independent** copy in the `derived-package`. + This includes all `std` globals such as the [global allocator] and [panic hook]. + - Any dependency version mismatches might mean that bugs in dependencies of `base-package` may not reproduce in the copy in `derived-package`, (e.g. if the common dependency `base-package-core` depends on `foo` 0.1, it is possible `base-package` will compile with `foo` 0.1.1 and `base-package-core` will compile with `foo` 0.1.2). + +Practically speaking, this introduces the following limitations on extension modules wanting to share data in this way: + +- Extensions must take extreme care to ensure that only `#[repr(C)]` types are shared across the package boundary. + + In particular the default `#[repr(Rust)]` layout has no stability guarantee; _two extension modules sharing a `#[repr(Rust)]` data type is undefined behavior_. + It is also very easy to accidentally share `#[repr(Rust)]` types, see the [safety note on the `PyCapsule` type documentation]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyCapsule.html) for cases to consider when sharing data. + + > [!WARNING] > Beware that PyO3's error type, `PyErr`, is not `#[repr(C)]` and cannot be shared across the package boundary > This is an easy mistake to make when exposing fallible APIs which cross the boundary. > There is a [later section on error handling](#error-handling) which suggests alternative strategies + +- APIs which rely on global variables will not work as expected across the package boundary. + For example: + - The `#[global_allocator]` used by each extension will likely be different - each will need to ensure that any allocations are freed by the same allocator. + - The `std::io` locks (e.g. for `stdout`) will not be shared, so concurrent output from the two extensions may interleave in unexpected ways. + +- PyO3 currently stores `#[pyclass]` types as global variables in static storage in each `cdylib` crate which compiles them. + This means that directly sharing a `#[pyclass]` type across multiple `cdylib` crates will currently silently create multiple distinct Python types. + To avoid this, the shared types cannot be `#[pyclass]`, instead the package exporting the type to Python needs to make private `#[pyclass]` which wraps the shared type. + PyO3 may remove this limitation in future. + +## Using a capsule to create a shared API { #capsules } + +Let's start with the example of NumPy as an extension which wants to offer a C API for other native extensions to consume. +The section above already established that Python native extensions can reuse data using the Python `capsule` type. +It is an opaque wrapper which can be used to exchange arbitrary native data between Python extension modules. +PyO3 provides the [`PyCapsule` type]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyCapsule.html) to create and consume capsules from Rust code. + +NumPy creates a `capsule` which contains a pointer to the structure mapping the implementation of the ["NumPy C API"](https://numpy.org/doc/stable/reference/c-api/index.html). +While the [exact contents of this structure are generated](https://github.com/numpy/numpy/blob/40a1b0283beacb0d723f51e2046c8dc049da6eee/numpy/_core/code_generators/generate_numpy_api.py#L202-L210), the resulting API structure looks something like the following C code: + +```C +// The API is defined as a fully type-erased array of "void pointers". +// +// This copy of the array is not public API, but internal to the NumPy implementation. +void* PyArray_API[] = { + // Some fields contain function pointers, type erased + (void *) PyArray_GetNDArrayCVersion, + // Some fields are empty + NULL, + // Some fields point to Python type objects + (void *) &PyArray_Type, + + // ... the real API is a few hundred elements long. contents and length are version specific. +}; +``` + +To consume this array from downstream C projects, NumPy also defines a C header file which uses C macros to define the downstream API in terms of cast indexing into this API structure: + +```C +static void* PyArray_API[] = NULL; + +// cast function pointers back to their correct type +#define PyArray_GetNDArrayCVersion (*(unsigned int (*)(void))PyArray_API[0]) + +// cast type objects back to `PyTypeObject *` +#define PyArray_Type (* (PyTypeObject *)PyArray_API[2]) + +// downstream packages must call this function before using any of the other APIS +static int PyArray_ImportNumPyAPI(void) +{ + PyArray_API = /* ... */; +} + +``` + +To expose an API from Rust code, we'll need to take a similar approach. +We have the choice of either matching NumPy and using an array of opaque pointers, or using a more typed API `struct` ([as long as it is `#[repr(C)]` - see the safety docs on the [`PyCapsule` type]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyCapsule.html)). +A typed `struct` helps to avoid mistakes in casting fields to the wrong type incorrectly, however additional care needs to be taken to ensure that the layout of the struct does not change incompatibly across non-breaking versions of the API. +This is discussed further in [the next section](#api-versioning). + +The snippets below sketch out what the NumPy approach looks like in Rust, using either an array of opaque pointers or a typed API struct. +In both cases the public API functions are thin wrappers around the function pointers in the API struct, to provide ergonomics similar to the C macros in the NumPy example. + +{{#tabs }} +{{#tab name="Using a pointer array" }} + +If using a pointer array, `base-package-core` will define the pointer array, `BaseApi`, which contains function pointers and other data as opaque `*mut c_void` pointers: + +```rust +// The number of fields in the API will grow over time as future +// versions add more APIs. +const BASE_API_ENTRIES: usize = 2; + +// The pointer array itself +#[repr(transparent)] +pub struct BaseApi([*mut c_void; BASE_API_ENTRIES]); + +// SAFETY: BaseApi never changes once loaded, so it will be shared between threads. +// (Manual implementations necessary due to `*mut c_void` not being `Send` or `Sync`). +// +// (This is likely not necessary if using the typed struct approach, as the compiler can see the real function pointers which are likely `Send` / `Sync`). +unsafe impl Send for BaseApi { } +unsafe impl Sync for BaseApi { } + +/// Global variable which will be used by the API functions +static BASE_API: PyOnceLock = PyOnceLock::new(); + +impl BaseApi { + /// Internal method used by the public methods to read pointers from the API + fn get(py: Python<'_>) -> &'static Self { + BASE_API.get(py).expect("`base_package` not yet imported") + } +} + +/// Version identifiers for the API, returned by `get_api_version`. +#[repr(C)] +pub struct ApiVersion { + /* details omitted for now, see below section regarding API versioning */ +} + +/// Downstream packages must call this method to initialise the library API before +/// calling other functions. +pub fn import_base_package(py: Python<'_>) -> PyResult<()> { + BASE_API.get_or_try_init(py, || /* details of importing omitted for now, see future sections */)?; +} + +// Public functions exported by `base_package-core` are thin wrappers around the function pointers +// in the API struct. + +/// Returns the version of the `base_package` API loaded. `ApiVersion` is a `#[repr(C)]` struct +/// so can be safely shared across package boundaries. +#[inline] +pub fn get_api_version(py: Python<'_>) -> ApiVersion { + // SAFETY: BASE_API slot 0 is known to be the `get_api_version` function (`base_package` will set it). + let get_api_version: extern "C" fn() -> ApiVersion = unsafe { std::mem::transmute(BASE_API.get(py).0[0]) }; + get_api_version() +} +``` + +{{#endtab }} +{{#tab name="Using a typed struct" }} + +If using a typed struct, `base-package-core` will define `BaseApi` as a `#[repr(C)]` struct with typed fields: + +```rust +// The API struct #[repr(C)] to ensure a stable layout across package boundaries. +// IMPORTANT: all fields must also be `repr(C)`, function pointers must be `extern "C"`, +// and fields can only be added to the end of the struct in non-breaking versions of the API. +#[repr(C)] +pub struct BaseApi { + get_api_version: extern "C" fn() -> ApiVersion, +} + +/// Global variable which will be used by the API functions +static BASE_API: PyOnceLock = PyOnceLock::new(); + +impl BaseApi { + /// Internal method used by the public methods to read pointers from the API + fn get(py: Python<'_>) -> &'static Self { + BASE_API.get(py).expect("`base_package` not yet imported") + } +} + +/// Version identifiers for the API, returned by `get_api_version`. +#[repr(C)] +pub struct ApiVersion { + /* details omitted for now, see below section regarding API versioning */ +} + +/// Downstream packages must call this method to initialise the library API before +/// calling other functions. +pub fn import_base_package(py: Python<'_>) -> PyResult<()> { + BASE_API.get_or_try_init(py, || /* details of importing omitted for now, see future sections */)?; +} + +// Public functions exported by `base_package-core` are thin wrappers around the function pointers +// in the API struct. + +/// Returns the version of the `base_package` API loaded. `ApiVersion` is a `#[repr(C)]` struct +/// so can be safely shared across package boundaries. +#[inline] +pub fn get_api_version(py: Python<'_>) -> ApiVersion { + (BASE_API.get(py).get_api_version)() +} +``` + +{{#endtab }} +{{#endtabs }} + +The consumers of the API struct will be compiled against a specific version of the `base-package-core` crate. +It will only be safe to use the API struct if the version in the API struct matches the version expected by the consumer. +Regardless of the choice made, due to backwards compatibility, the API struct can only grow over time, except when the version signals a breaking change. + +The [example project] demonstrates how to do this with Rust. + +## API versioning + +To safely consume the API struct from downstream packages it is first necessary to perform a version check. +This version check needs to establish that the ABI (Application Binary Interface), i.e. the layout of the API struct, matches the expectations of the consumer. + +This means that the `ApiVersion` type exposed by `base-package` in the example uses four fields: the three `major`, `minor`, and `patch` version fields from semver, plus an additional `abi_version` field which is only incremented for breaking changes to the ABI. +Having the `abi_version` field allows for consumers potentially be compatible even across semver-breaking versions of the API. +This means that e.g. `derived-package` compiled with version `0.0.3` of `base-package` could potentially be compatible with `base-package` version `0.0.2` if the API struct layout did not change between these versions, and the `abi_version` field was not incremented. + +To make the version check straightforward, it is recommended to place the version information at the start of the API struct. +This allows the consumer to first read the capsule data as an `ApiVersion` structure, and only if the version check passes, reinterpret the rest of the data as the full API struct. + +To demonstrate, the following code shows the approximate implementation of the `import_base_package` function from the [example project], which performs the version check and if successful reads the API struct from the capsule: + +```rust +#[repr(C)] +pub struct BaseApi { + get_api_version: extern "C" fn() -> ApiVersion, + // real code will contain additional fields to satisfy all functionality +} + +/// Version identifiers for the API, returned by `get_api_version`. +#[repr(C)] +pub struct ApiVersion { + major: u32, + minor: u32, + patch: u32, + abi: u32, +} + +/// Downstream packages must call this method to initialise the library API before +/// calling other functions. +pub fn import_base_package(py: Python<'_>) -> PyResult<()> { + BASE_API.get_or_try_init(|| do_import(py))?; +} + +fn do_import(py: Python<'_>) -> PyResult { + // First: import the capsule as a pointer to retrieve version information. It is necessary to validate the API version + // before attempting to access any of the rest of the API. + // + // SAFETY: The function to get the version info is the first field in the API struct. + let capsule_base = unsafe { PyCapsule::import:: ApiVersion>(py, c"base_package._BASE_API")? }; + + // Read the version information via the function pointer. + let versions = (*capsule_base)(); + + // Use environment variables set by Cargo to validate the API is + // compatible with the version of the base package that is currently running. + let current_major: u32 = env!("CARGO_PKG_VERSION_MAJOR") + .parse() + .expect("invalid cargo package version"); + let current_minor: u32 = env!("CARGO_PKG_VERSION_MINOR") + .parse() + .expect("invalid cargo package version"); + + // Critical: the ABI version must match exactly, otherwise the layout of the API struct + // is not known by this consumer + if versions.abi != BaseApi::CURRENT_ABI_VERSION { + return Err(PyErr::new::(format!( + "base_package ABI version mismatch: expected {}, got {}", + BaseApi::CURRENT_ABI_VERSION, + versions.abi + ))); + } + + // In this example, the consumer allows for newer versions of the API to be used, as long + // as they had a compatible ABI version. Real projects may have different policies on breakage + // and forwards/backwards compatibility they are prepared to maintain. + if (versions.major, versions.minor) < (current_major, current_minor) { + return Err(PyErr::new::(format!( + "base_package API version mismatch: expected at least {}.{}, got {}.{}", + env!("CARGO_PKG_VERSION_MAJOR"), + env!("CARGO_PKG_VERSION_MINOR"), + versions.major, + versions.minor + ))); + } + + // SAFETY: The version fields have been validated, so it is now known it + // is safe to cast the data to the known struct. + // + // The capsule contains a pointer to the full API struct, so this cast is sound. + let api = unsafe { NonNull::from_ref(capsule_base).cast::().as_ref() }; + + Ok(BaseApi { + // all fields in the API are function pointers, so are copied trivially + ..*api + }) +} +``` + +## Creating a shared `#[pyclass]` type + +Once the version checks are complete and the API struct loading is established, this technique can be expanded to share `#[pyclass]` types across the package boundary. + +For a type named `SharedType`, the steps to achieve this are as follows: + +1. `base-package-core` defines a `#[repr(C)]` struct which contains the data to be shared across the boundary. + + +2. The `BaseApi` struct defined in the previous sections is extended to include functions to manipulate this struct (these functions will later be provided by `base-package`). + + At a minimum, this will probably include: + + - `get_shared_type: extern "C" fn() -> Py` - a function to get the `#[pyclass]` Python type object for `SharedType`. + + - `create_shared_type: unsafe extern "C" fn(SharedType) -> Option>` - a function to create a new instance of the `SharedType` struct and return it as a Python object. + + This function is `unsafe` because the caller must ensure that the thread is attached to the interpreter (`Python<'py>` is a zero-sized type and not FFI-safe). + + The return type on this function is wrapped in `Option` to allow for failure - see [the error handling section](#error-handling) for more details. + + - `cast_shared_type: for<'a> extern "C" fn(Borrowed<'a, '_, SharedType>) -> &'a SharedType` - a function to extract a reference to the `SharedType` Rust struct from inside a Python object. + +3. With the API struct extended to include these functions, the `base-package-core` crate can now implement PyO3 traits for `SharedType` in terms of those functions. + + The crucial traits are: + + - `PyTypeInfo` - the `get_type` function can delegate to the `get_shared_type` function pointer in the API struct. + + - `IntoPyPyObject` - the `into_pyobject` function can delegate to the `create_shared_type` function pointer in the API struct. + + - `FromPyObject<'_>` - the `extract` function can delegate to the `cast_shared_type` function pointer in the API struct. + + +4. `base-package` implements a `#[pyclass]` which is a thin wrapper around the `SharedType` struct, defining its Python functionality. + +5. `base-package` implements the functions defined in the API struct to manipulate the `SharedType`, and populates the API struct with pointers to these functions as part of creating the `capsule`. + +6. `derived-package` uses the existing `import_base_package()` function to load the API struct, and then can interact with it as a Python type via PyO3's smart pointers. + +The [example project] demonstrates how to do this with a `Series` type implementing a "mini DataFrame API", to show how to use these stages to perform real work. + +## Practical considerations for sharing data across the package boundary + +As a reminder, there are two key restrictions to data which is shared across the package boundary: + +- Only types with a stable layout, such as `#[repr(C)]` types, can be shared. +- Global variables are not shared across the boundary, and in particular for data sharing, the `#[global_allocator]` is not shared, so data allocated by one package must be freed by the same package. + +This means that all Rust standard library types, such as `Vec`, `String`, and `Box`, cannot be shared across the boundary. +Even Rust tuples do not have a stable layout and cannot be shared. + +There [is a proposal for a `#[repr(crabi)]` ABI](https://github.com/rust-lang/rust/issues/111423) which would define stable layouts for many Rust types, which would make it easier to share data. +This would still not solve types which contain heap allocations. + +For now, a practical solution is to use the [`abi_stable`] crate, which provides many equivalents to Rust standard library types with stable internal layouts. +It uses vtables to allow for heap-allocated data to be shared, automatically ensuring the same allocator is used to free data as was used to allocate it. +This is the solution used in the [example project] to share `Vec`-like and `String`-like data across the boundary. + +Using vtables introduces overhead (e.g. prevents inlining), however this is a necessary consequence of the limitations of sharing data across the package boundary. + +### Error handling across the boundary { #error-handling } + +Similar to many other types, PyO3's `PyErr` type is not currently `#[repr(C)]`, so cannot be shared across the package boundary. + +The simplest approach to handling errors across the boundary is to use `Option` return types in the API struct, and to return `None` on error. +This is the approach taken in the [example project]. + +The downside of this approach is that `?` does not trivially work in the implementation of the API functions. +The suggested strategy is: + +- Inside the API function implementations, convert `PyResult` to `Option` by using `PyErr::restore` to write the error to the Python thread state, and returning `None` on error. +- The wrappers in `base-package-core` which delegate to the API functions can then convert the `Option` back to `PyResult` by using `PyErr::fetch` to read the error from the Python thread state. + +## Wrap-up, limitations & future work + +This subchapter has attempted to detail how to use `capsule` objects to create an API for sharing Rust data between multiple PyO3 extension modules. +While complex, this is a workable technique for projects which need to have this functionality. + +PyO3 does not yet offer any particular support for this use case and will likely be unable to provide a fully safe API to achieve this while data exchange is limited to `#[repr(C)]` types with pitfalls such as duplicate global variables. +Over time PyO3 might accumulate utilities for common pieces of this process. + +Some places where this process process easier in the future include: + +### Better `#[pyclass]` support + +At the moment the `base-package-core` Rust API cannot use PyO3's `#[pyclass]` macro, because of the global variable backing the `#[pyclass]` implementation being a problem when duplicated into `base-package` and `derived-package`. + +A possible solution is that PyO3 could have an option like `#[pyclass(shareable)]`, which could automatically generate the kind of `PyTypeInfo` / `IntoPyObject` / `FromPyObject` implementations which need to be hand-rolled at present. + +To make this work, PyO3 would probably need to support [module state](https://github.com/PyO3/pyo3/pull/5600), and require the `base-package` which exports the shared type to manually initialize it and store it in module state. + +There are many open design questions about how to make that work elegantly. + +### `#[repr(C)]` error handling + +At present, PyO3's `PyErr` type is a complex internal state machine which allows for lazy creation of Python exceptions. +This was convenient in early implementations of PyO3 but carried internal complexity and overhead. + +PyO3's APIs have been trending in recent years towards allowing Rust code to use Rust error types for full control of overhead, e.g. the `IntoPyObject` and `FromPyObject` traits have a `type Error`, and the `#[pyfunction]` macros accept any `Result` as long as the error type implements a conversion to `PyErr`. + +It is likely that PyO3 will eventually transition the `PyErr` type to be a thin wrapper around `Py`, which would allow it to have a stable layout and participate in error handling across the boundary. +This primarily requires consideration about how to nudge existing dependents of `PyErr`'s "lazy" internals towards better practices. + +### Better support for stable-layout types + +The restriction of needing `#[repr(C)]` types to achieve a stable ABI for data sharing creates a lot of friction at the boundary. +It can also have implications for both efficiency and implementation of the `base-package-core` types. + +The author's experience is that the Rust compiler doesn't yet have a mechanism to comprehensively lint against accidentally sharing types with unstable layouts across the boundary. +There may be value in an upstream effort to implement this so that projects using this `capsule` mechanism can avoid easy mistakes. + +Outside of the Rust project itself, [`abi_stable`] crate is the most complete solution currently available to have a convenient way to correctly create a stable ABI. +However, `abi_stable` also appears to be largely unmaintained, so users wanting to depend on its functionality may need to consider reviving or forking it. + +Furthermore, PyO3 currently doesn't implement `FromPyObject` or `IntoPyObject` conversions for `abi_stable` types. +This makes working with these types somewhat awkward / inefficient at the Python boundary. +PyO3 _could_ add an optional feature for this, however given the API surface involved it would be better to resolve the question of maintenance of `abi_stable` before adding such functionality to PyO3. + +[global allocator]: https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html +[panic hook]: https://doc.rust-lang.org/stable/std/panic/fn.set_hook.html +[example project]: https://github.com/davidhewitt/pyo3-1444-prototype +[`abi_stable`]: https://github.com/rodrimati1992/abi_stable_crates/ diff --git a/vendor/pyo3/guide/src/async-await.md b/vendor/pyo3/guide/src/async-await.md new file mode 100644 index 0000000..d38b66a --- /dev/null +++ b/vendor/pyo3/guide/src/async-await.md @@ -0,0 +1,110 @@ +# Using `async` and `await` + +*This feature is still in active development.* +*See [the related issue](https://github.com/PyO3/pyo3/issues/1632).* + +`#[pyfunction]` and `#[pymethods]` attributes also support `async fn`. + +```rust,no_run +# #![allow(dead_code)] +# #[cfg(feature = "experimental-async")] { +use std::{thread, time::Duration}; +use futures::channel::oneshot; +use pyo3::prelude::*; + +#[pyfunction] +#[pyo3(signature=(seconds, result=None))] +async fn sleep(seconds: f64, result: Option>) -> Option> { + let (tx, rx) = oneshot::channel(); + thread::spawn(move || { + thread::sleep(Duration::from_secs_f64(seconds)); + tx.send(()).unwrap(); + }); + rx.await.unwrap(); + result +} +# } +``` + +*Python awaitables instantiated with this method can only be awaited in `asyncio` context.* +*Other Python async runtime may be supported in the future.* + +## `Send + 'static` constraint + +Resulting future of an `async fn` decorated by `#[pyfunction]` must be `Send + 'static` to be embedded in a Python object. + +As a consequence, `async fn` parameters and return types must also be `Send + 'static`, so it is not possible to have a signature like `async fn does_not_compile<'py>(arg: Bound<'py, PyAny>) -> Bound<'py, PyAny>`. + +However, there is an exception for method receivers, so async methods can accept `&self`/ `&mut self`. +Note that this means that the class instance is borrowed for as long as the returned future is not completed, even across yield points and while waiting for I/O operations to complete. +Hence, other methods cannot obtain exclusive borrows while the future is still being polled. +This is the same as how async methods in Rust generally work but it is more problematic for Rust code interfacing with Python code due to pervasive shared mutability. +This strongly suggests to prefer shared borrows `&self` over exclusive ones `&mut self` to avoid racy borrow check failures at runtime. + +## Implicitly attached to the interpreter + +Even if it is not possible to pass a `py: Python<'py>` token to an `async fn`, we're still attached to the interpreter during the execution of the future – the same as for a regular `fn` without `Python<'py>`/`Bound<'py, PyAny>` parameter + +It is still possible to get a `Python` marker using [`Python::attach`]({{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#method.attach); because `attach` is reentrant and optimized, the cost will be negligible. + +## Detaching from the interpreter across `.await` + +There is currently no simple way to detach from the interpreter when awaiting a future, *but solutions are currently in development*. + +Here is the advised workaround for now: + +```rust,ignore +use std::{ + future::Future, + pin::{Pin, pin}, + task::{Context, Poll}, +}; +use pyo3::prelude::*; + +struct AllowThreads(F); + +impl Future for AllowThreads +where + F: Future + Unpin + Send, + F::Output: Send, +{ + type Output = F::Output; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let waker = cx.waker(); + Python::attach(|py| { + py.detach(|| pin!(&mut self.0).poll(&mut Context::from_waker(waker))) + }) + } +} +``` + +## Cancellation + +Cancellation on the Python side can be caught using [`CancelHandle`]({{#PYO3_DOCS_URL}}/pyo3/coroutine/struct.CancelHandle.html) type, by annotating a function parameter with `#[pyo3(cancel_handle)]`. + +```rust,no_run +# #![allow(dead_code)] +# #[cfg(feature = "experimental-async")] { +use futures::FutureExt; +use pyo3::prelude::*; +use pyo3::coroutine::CancelHandle; + +#[pyfunction] +async fn cancellable(#[pyo3(cancel_handle)] mut cancel: CancelHandle) { + futures::select! { + /* _ = ... => println!("done"), */ + _ = cancel.cancelled().fuse() => println!("cancelled"), + } +} +# } +``` + +## The `Coroutine` type + +To make a Rust future awaitable in Python, PyO3 defines a [`Coroutine`]({{#PYO3_DOCS_URL}}/pyo3/coroutine/struct.Coroutine.html) type, which implements the Python [coroutine protocol](https://docs.python.org/3/library/collections.abc.html#collections.abc.Coroutine). + +Each `coroutine.send` call is translated to a `Future::poll` call. +If a [`CancelHandle`]({{#PYO3_DOCS_URL}}/pyo3/coroutine/struct.CancelHandle.html) parameter is declared, the exception passed to `coroutine.throw` call is stored in it and can be retrieved with [`CancelHandle::cancelled`]({{#PYO3_DOCS_URL}}/pyo3/coroutine/struct.CancelHandle.html#method.cancelled); otherwise, it cancels the Rust future, and the exception is reraised; + +*The type does not yet have a public constructor until the design is finalized.* diff --git a/vendor/pyo3/guide/src/building-and-distribution.md b/vendor/pyo3/guide/src/building-and-distribution.md new file mode 100644 index 0000000..809c4fc --- /dev/null +++ b/vendor/pyo3/guide/src/building-and-distribution.md @@ -0,0 +1,448 @@ +# Building and distribution + +This chapter of the guide goes into detail on how to build and distribute projects using PyO3. +The way to achieve this is very different depending on whether the project is a Python module implemented in Rust, or a Rust binary embedding Python. +For both types of project there are also common problems such as the Python version to build for and the [linker]() arguments to use. + +The material in this chapter is intended for users who have already read the PyO3 [README](./index.md). +It covers in turn the choices that can be made for Python modules and for Rust binaries. +There is also a section at the end about cross-compiling projects using PyO3. + +There is an additional sub-chapter dedicated to [supporting multiple Python versions](./building-and-distribution/multiple-python-versions.md). + +## Configuring the Python version + +PyO3 uses a build script (backed by the [`pyo3-build-config`] crate) to determine the Python version and set the correct linker arguments. +By default it will attempt to use the following in order: + +- Any active Python virtualenv. +- The `python` executable (if it's a Python 3 interpreter). +- The `python3` executable. + +You can override the Python interpreter by setting the `PYO3_PYTHON` environment variable, e.g. `PYO3_PYTHON=python3.8`, `PYO3_PYTHON=/usr/bin/python3.9`, or even a PyPy interpreter `PYO3_PYTHON=pypy3`. + +Once the Python interpreter is located, `pyo3-build-config` executes it to query the information in the `sysconfig` module which is needed to configure the rest of the compilation. + +To validate the configuration which PyO3 will use, you can run a compilation with the environment variable `PYO3_PRINT_CONFIG=1` set. +An example output of doing this is shown below: + +```console +$ PYO3_PRINT_CONFIG=1 cargo build + Compiling pyo3-ffi v0.29.2 (/Users/goldbaum/Documents/pyo3/pyo3-ffi) +error: failed to run custom build command for `pyo3-ffi v0.29.2 (/Users/goldbaum/Documents/pyo3/pyo3-ffi)` + +Caused by: + process didn't exit successfully: `/Users/goldbaum/Documents/pyo3/target/debug/build/pyo3-ffi-71f0882ba738a1f0/build-script-build` (exit status: 101) + --- stdout + cargo:rustc-check-cfg=cfg(Py_LIMITED_API) + cargo:rustc-check-cfg=cfg(Py_GIL_DISABLED) + cargo:rustc-check-cfg=cfg(PyPy) + cargo:rustc-check-cfg=cfg(GraalPy) + cargo:rustc-check-cfg=cfg(RustPython) + cargo:rustc-check-cfg=cfg(py_sys_config, values("Py_DEBUG", "Py_REF_DEBUG", "Py_TRACE_REFS", "COUNT_ALLOCS")) + cargo:rustc-check-cfg=cfg(Py_3_8) + cargo:rustc-check-cfg=cfg(Py_3_9) + cargo:rustc-check-cfg=cfg(Py_3_10) + cargo:rustc-check-cfg=cfg(Py_3_11) + cargo:rustc-check-cfg=cfg(Py_3_12) + cargo:rustc-check-cfg=cfg(Py_3_13) + cargo:rustc-check-cfg=cfg(Py_3_14) + cargo:rustc-check-cfg=cfg(Py_3_15) + cargo:rustc-check-cfg=cfg(Py_3_16) + cargo:rerun-if-env-changed=PYO3_CONFIG_FILE + cargo:rerun-if-env-changed=PYO3_CROSS + cargo:rerun-if-env-changed=PYO3_CROSS_LIB_DIR + cargo:rerun-if-env-changed=PYO3_CROSS_PYTHON_VERSION + cargo:rerun-if-env-changed=PYO3_CROSS_PYTHON_IMPLEMENTATION + cargo:rerun-if-env-changed=PYO3_NO_PYTHON + cargo:rerun-if-env-changed=PYO3_ENVIRONMENT_SIGNATURE + cargo:rerun-if-env-changed=PYO3_PYTHON + cargo:rerun-if-env-changed=VIRTUAL_ENV + cargo:rerun-if-env-changed=CONDA_PREFIX + cargo:rerun-if-env-changed=PATH + cargo:rerun-if-env-changed=PYO3_PRINT_CONFIG + + -- PYO3_PRINT_CONFIG=1 is set, printing configuration and halting compile -- + implementation=CPython + version=3.14 + shared=true + target_abi=CPython-free_threaded-3.14 + lib_name=python3.14t + lib_dir=/Users/goldbaum/.pyenv/versions/3.14.5t/lib + executable=/Users/goldbaum/.pyenv/versions/3.14.5t/bin/python + pointer_width=64 + build_flags=Py_GIL_DISABLED + python_framework_prefix= + suppress_build_script_link_lines=false + + note: unset the PYO3_PRINT_CONFIG environment variable and retry to compile with the above config +``` + +The `PYO3_ENVIRONMENT_SIGNATURE` environment variable can be used to trigger rebuilds when its value changes, it has no other effect. + +### Advanced: config files + +If you save the above output config from `PYO3_PRINT_CONFIG` to a file, it is possible to manually override the contents and feed it back into PyO3 using the `PYO3_CONFIG_FILE` env var. + +If your build environment is unusual enough that PyO3's regular configuration detection doesn't work, using a config file like this will give you the flexibility to make PyO3 work for you. +To see the full set of options supported, see the documentation for the [`InterpreterConfig` struct](https://docs.rs/pyo3-build-config/{{#PYO3_DOCS_VERSION}}/pyo3_build_config/struct.InterpreterConfig.html). + +## Building Python extension modules + +Python extension modules need to be compiled differently depending on the OS (and architecture) that they are being compiled for. +As well as multiple OSes (and architectures), there are also many different Python versions which are actively supported. +Packages uploaded to [PyPI](https://pypi.org/) usually want to upload prebuilt "wheels" covering many OS/arch/version combinations so that users on all these different platforms don't have to compile the package themselves. +Package vendors can opt-in to the "abi3" limited Python API which allows their wheels to be used on multiple Python versions, reducing the number of wheels they need to compile, but restricts the functionality they can use. + +There are many ways to go about this: it is possible to use `cargo` to build the extension module (along with some manual work, which varies with OS). +The PyO3 ecosystem has two packaging tools, [`maturin`] and [`setuptools-rust`], which abstract over the OS difference and also support building wheels for PyPI upload. + +PyO3 has some functionality for configuring projects when building Python extension modules: + +- The `PYO3_BUILD_EXTENSION_MODULE` environment variable, which must be set when building Python extension modules. `maturin` and `setuptools-rust` set this automatically. +- The `abi3` and `abi3t` Cargo feature and their version-specific `abi3-pyXY` and `abi3t-pyXY` companions, which are used to opt-in to the limited Python API and a flavor of stable ABI in order to support multiple Python versions in a single wheel. + The free-threaded build of CPython cannot load `abi3` wheels but both builds can load `abi3t` wheels. + +This section describes the packaging tools before describing how to build manually without them. +It then proceeds with an explanation of the `PYO3_BUILD_EXTENSION_MODULE` environment variable. +Finally, there is a section describing PyO3's `abi3` features. + +### Packaging tools + +The PyO3 ecosystem has two main choices to abstract the process of developing Python extension modules: + +- [`maturin`] is a command-line tool to build, package and upload Python modules. + It makes opinionated choices about project layout meaning it needs very little configuration. + This makes it a great choice for users who are building a Python extension module from scratch and don't need flexibility. +- [`setuptools-rust`] is an add-on for `setuptools` which adds extra keyword arguments to the `setup.py` configuration file. + It requires more configuration than `maturin`, however this gives additional flexibility for users adding Rust to an existing Python package that can't satisfy `maturin`'s constraints. + +Consult each project's documentation for full details on how to get started using them and how to upload wheels to PyPI. +It should be noted that while `maturin` is able to build [manylinux](https://github.com/pypa/manylinux)-compliant wheels out-of-the-box, `setuptools-rust` requires a bit more effort, [relying on Docker](https://setuptools-rust.readthedocs.io/en/latest/building_wheels.html) for this purpose. + +There are also [`maturin-starter`] and [`setuptools-rust-starter`] examples in the PyO3 repository. + +### Manual builds + +To build a PyO3-based Python extension module manually, start by running `cargo build` as normal in a library project with the [`cdylib` crate type](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-crate-type-field) while the `PYO3_BUILD_EXTENSION_MODULE` environment variable is set. + +Once built, symlink (or copy) and rename the shared library from Cargo's `target/` directory to your desired output directory: + +- on macOS, rename `libyour_module.dylib` to `your_module.so`. +- on Windows, rename `libyour_module.dll` to `your_module.pyd`. +- on Linux, rename `libyour_module.so` to `your_module.so`. + +You can then open a Python shell in the output directory and you'll be able to run `import your_module`. + +If you're packaging your library for redistribution, you should indicate the Python interpreter your library is compiled for by including the [platform tag](#platform-tags) in its name. +This prevents incompatible interpreters from trying to import your library. +If you're compiling for PyPy you _must_ include the platform tag, or PyPy will ignore the module. + +#### Bazel builds + +To use PyO3 with bazel one needs to manually configure PyO3, PyO3-ffi and PyO3-macros. +In particular, one needs to make sure that it is compiled with the right python flags for the version you intend to use. +For example see: + +1. [github.com/abrisco/rules_pyo3](https://github.com/abrisco/rules_pyo3) -- General rules for building extension modules. +2. [github.com/OliverFM/pytorch_with_gazelle](https://github.com/OliverFM/pytorch_with_gazelle) -- for a minimal example of a repo that can use PyO3, PyTorch and Gazelle to generate python Build files. +3. [github.com/TheButlah/rules_pyo3](https://github.com/TheButlah/rules_pyo3) -- is somewhat dated. + +#### Platform tags + +Rather than using just the `.so` or `.pyd` extension suggested above (depending on OS), you can prefix the shared library extension with a platform tag to indicate the interpreter it is compatible with. +You can query your interpreter's platform tag from the `sysconfig` module. +Some example outputs of this are seen below: + +```bash +# CPython 3.10 on macOS +.cpython-310-darwin.so + +# PyPy 7.3 (Python 3.9) on Linux +$ python -c 'import sysconfig; print(sysconfig.get_config_var("EXT_SUFFIX"))' +.pypy39-pp73-x86_64-linux-gnu.so +``` + +So, for example, a valid module library name on CPython 3.10 for macOS is `your_module.cpython-310-darwin.so`, and its equivalent when compiled for PyPy 7.3 on Linux would be `your_module.pypy38-pp73-x86_64-linux-gnu.so`. + +See [PEP 3149](https://peps.python.org/pep-3149/) for more background on platform tags. + +#### macOS + +On macOS, because the `PYO3_BUILD_EXTENSION_MODULE` environment variable disables linking to `libpython` ([see the next section](#the-extension-module-feature)), some additional linker arguments need to be set. `maturin` and `setuptools-rust` both pass these arguments for PyO3 automatically, but projects using manual builds will need to set these directly in order to support macOS. + +The easiest way to set the correct linker arguments is to add a [`build.rs`](https://doc.rust-lang.org/cargo/reference/build-scripts.html) with the following content: + +```rust,ignore +fn main() { + pyo3_build_config::add_extension_module_link_args(); +} +``` + +Remember to also add `pyo3-build-config` to the `build-dependencies` section in `Cargo.toml`. + +An alternative to using `pyo3-build-config` is add the following to a cargo configuration file (e.g. `.cargo/config.toml`): + +```toml +[target.x86_64-apple-darwin] +rustflags = [ + "-C", "link-arg=-undefined", + "-C", "link-arg=dynamic_lookup", +] + +[target.aarch64-apple-darwin] +rustflags = [ + "-C", "link-arg=-undefined", + "-C", "link-arg=dynamic_lookup", +] +``` + +Using the MacOS system python3 (`/usr/bin/python3`, as opposed to python installed via homebrew, pyenv, nix, etc.) may result in runtime errors such as `Library not loaded: @rpath/Python3.framework/Versions/3.8/Python3`. + +The easiest way to set the correct linker arguments is to add a `build.rs` with the following content: + +```rust,ignore +fn main() { + pyo3_build_config::add_python_framework_link_args(); +} +``` + +Alternatively it can be resolved with another addition to `.cargo/config.toml`: + +```toml +[build] +rustflags = [ + "-C", "link-args=-Wl,-rpath,/Library/Developer/CommandLineTools/Library/Frameworks", +] +``` + +For more discussion on and workarounds for MacOS linking problems [see this issue](https://github.com/PyO3/pyo3/issues/1800#issuecomment-906786649). + +Finally, don't forget that on MacOS the `extension-module` feature will cause `cargo test` to fail without the `--no-default-features` flag (see [the FAQ](https://pyo3.rs/main/faq.html#i-cant-run-cargo-test-or-i-cant-build-in-a-cargo-workspace-im-having-linker-issues-like-symbol-not-found-or-undefined-reference-to-_pyexc_systemerror)). + +### The `PYO3_BUILD_EXTENSION_MODULE` environment variable + + + +By default PyO3 links to `libpython`. +This makes binaries, tests, and examples "just work". +However, Python extension modules on Unix must not link to libpython for [manylinux](https://www.python.org/dev/peps/pep-0513/) compliance. + +The downside of not linking to `libpython` is that binaries, tests, and examples (which usually embed Python) will fail to build. +As a result, PyO3 uses an environment variable `PYO3_BUILD_EXTENSION_MODULE` to disable linking to `libpython`. +This should only be set when building a library for distribution. +`maturin >= 1.9.4` and `setuptools-rust >= 1.12` will set this for you automatically. + +> [!NOTE] +> Historically PyO3 used an `extension-module` feature to perform the same function now done by the `PYO3_BUILD_EXTENSION_MODULE` env var. +> This feature caused linking to be disabled for all compile targets, including Rust tests and benchmarks. +> +> Projects are encouraged to migrate off the feature, as it caused [major development pain](faq.md#i-cant-run-cargo-test-or-i-cant-build-in-a-cargo-workspace-im-having-linker-issues-like-symbol-not-found-or-undefined-reference-to-_pyexc_systemerror) due to the lack of linking. + +### The `PYO3_USE_RAW_DYLIB` environment variable + +When targeting Windows, PyO3 will attempt to use [`raw-dylib` linking](https://doc.rust-lang.org/reference/items/external-blocks.html#dylib-versus-raw-dylib) to avoid the need for users to provide an actual import library to link against. + +On occasion the full Python import library may be needed (e.g. mixed C/Rust projects where the C code uses symbols not defined by `pyo3-ffi`). +In these cases, setting `PYO3_USE_RAW_DYLIB=0` can be used to disable `raw-dylib` linking. + +> [!NOTE] +> Historically PyO3 used a `generate-import-lib` feature which needed external machinery to achieve the same result of `raw-dylib` linking. + +### `Py_LIMITED_API`/`abi3`/`abi3t` + +By default, Python extension modules can only be used with the same Python version they were compiled against. +For example, an extension module built for Python 3.5 can't be imported in Python 3.8. +[PEP 384](https://www.python.org/dev/peps/pep-0384/) introduced the idea of the limited Python API, which would have a stable ABI enabling extension modules built with it to be used against multiple Python versions. +The ABI defined by PEP 384 is called `abi3`, since it's stable for all Python 3.X releases. +In 2026, the steering council approved [PEP 803](https://www.python.org/dev/peps/pep-0803/)) which defines a new stable ABI, `abi3t`, that can be used on the free-threaded build of CPython. +Extensions built using the `abit3` ABI are importable on both the GIL-enabled and free-threaded builds of any CPython version newer than the target version. +So, `abi3t` extensions built for the Python 3.15 limited API will be importable on Python 3.15, 3.16, 3.17, and all future Python 3.X versions. + +The advantage of building extension modules using the limited Python API is that package vendors only need to build and distribute a single copy (for each OS / architecture), and users can install it on all Python versions from the [minimum version](#minimum-python-version-for-abi3-and-abi3t-builds) and up. +The downside of this is that PyO3 can't use optimizations which rely on being compiled against a known exact Python version. +It's up to you to decide whether this matters for your extension module. +It's also possible to design your extension module such that you can distribute `abi3` or `abi3t` wheels but allow users compiling from source to benefit from additional optimizations - see the [support for multiple python versions](./building-and-distribution/multiple-python-versions.md) section of this guide, in particular the `#[cfg(Py_LIMITED_API)]` flag. + +There are three steps involved in targeting `abi3` or `abi3t` when building Python packages as wheels: + +1. Enable the `abi3` and/or `abi3t` feature in `pyo3`. + This ensures `pyo3` only calls Python C-API functions which are part of the stable API, and on Windows also ensures that the project links against the correct shared object (no special behavior is required on other platforms): + + ```toml + [dependencies] + pyo3 = { {{#PYO3_CRATE_VERSION}}, features = ["abi3", "abi3t"] } + ``` + + Enabling both the `"abi3"` and `"abi3t"` features will produce an `abi3` extension if targeting Python 3.14 or older and an `abi3t` extension if targeting 3.15 or newer. + If you always want to produce `abi3t` wheels, you can enable just the `"abi3t"` feature, which will produce extensions targeting `abi3t` if the host interpreter is Python 3.15 or newer, but will produce version-specific extensions otherwise. + If you only enable the `"abi3"` feature, you will produce `abi3` extensions if the host interpreter is a GIL-enabled build of CPython and version-specific extensions otherwise. + + We suggest enabling both features and using multiple python interpreters to build several wheels. + You can build an `abi3` wheel for your minimum supported Python version, a `cp314t` version-specific wheel using a free-threaded Python 3.14 interpreter, and an `abi3t` wheel using a Python 3.15 interpreter. + This will produce wheels targeting all versions of CPython that PyO3 supports. + +2. Ensure that the built shared objects are correctly marked as `abi3` and `abi3t`. + This is accomplished by telling your build system that you're using the limited API. + [`maturin`] >= 0.9.0 and [`setuptools-rust`] >= 0.11.4 support `abi3` wheels and [`maturin`] >= 1.14 supports `abi3t` wheels. + +3. Ensure that the `.whl` is correctly marked as `abi3` or `abi3t`. + For projects using `setuptools`, this is accomplished by passing `--py-limited-api=cp3x` (where `x` is the minimum Python version supported by the wheel, e.g. `--py-limited-api=cp35` for Python 3.5) to `setup.py bdist_wheel`. + +#### Minimum Python version for `abi3` and `abi3t` builds + +Because a single `abi3` wheel can be used with many different Python versions, PyO3 has feature flags `abi3-py38`, `abi3-py39`, `abi3-py310` etc. to set the minimum required Python version for your `abi3` wheel. +For example, if you set the `abi3-py38` feature, your wheel can be used on all Python 3 versions from Python 3.8 and up. +`maturin` and `setuptools-rust` will give the wheel a name like `my-extension-1.0-cp38-abi3-manylinux2020_x86_64.whl`. + +Similarly, there is an `abi3t-py315` feature and future PyO3 versions will offer `abi3t-py316` and so on. + +As your extension module may be run with multiple different Python versions you may occasionally find you need to check the Python version at runtime to customize behavior. +See [the relevant section of this guide](./building-and-distribution/multiple-python-versions.md#checking-the-python-version-at-runtime) on supporting multiple Python versions at runtime. + +PyO3 is only able to link your extension module to abi3 version up to and including your host Python version. +E.g., if you set `abi3-py39` and try to compile the crate with a host of Python 3.8, the build will fail. + +> [!NOTE] +> If you set more that one of these `abi3` version feature flags the lowest version always wins. +> For example, with both `abi3-py38` and `abi3-py39` set, PyO3 would build a wheel which supports Python 3.8 and up. + +#### Building stable ABI extension modules without a Python interpreter + +As an advanced feature, you can build a PyO3 wheel without calling Python interpreter with the environment variable `PYO3_NO_PYTHON` set. +Also, if the build host Python interpreter is not found or is too old or otherwise unusable, PyO3 will still attempt to compile stable ABI extension modules after displaying a warning message. + +#### Missing features + +Due to limitations in the Python API, there are a few `pyo3` features that do not work when compiling for the stable ABI. +These are: + +- `#[pyo3(text_signature = "...")]` does not work on classes until Python 3.10 or greater. +- The `dict` and `weakref` options on classes are not supported until Python 3.9 or greater. +- The buffer API is not supported until Python 3.11 or greater. +- Subclassing native types (e.g. `PyException`) is not supported until Python 3.12 or greater. +- Optimizations which rely on knowledge of the exact Python version compiled against. + +## Embedding Python in Rust + +If you want to embed the Python interpreter inside a Rust program, there are two modes in which this can be done: dynamically and statically. +We'll cover each of these modes in the following sections. +Each of them affect how you must distribute your program. +Instead of learning how to do this yourself, you might want to consider using a project like [PyOxidizer] to ship your application and all of its dependencies in a single file. + +PyO3 automatically switches between the two linking modes depending on whether the Python distribution you have configured PyO3 to use ([see above](#configuring-the-python-version)) contains a shared library or a static library. +The static library is most often seen in Python distributions compiled from source without the `--enable-shared` configuration option. + +### Dynamically embedding the Python interpreter + +Embedding the Python interpreter dynamically is much easier than doing so statically. +This is done by linking your program against a Python shared library (such as `libpython.3.9.so` on UNIX, or `python39.dll` on Windows). +The implementation of the Python interpreter resides inside the shared library. +This means that when the OS runs your Rust program it also needs to be able to find the Python shared library. + +This mode of embedding works well for Rust tests which need access to the Python interpreter. +It is also great for Rust software which is installed inside a Python virtualenv, because the virtualenv sets up appropriate environment variables to locate the correct Python shared library. + +For distributing your program to non-technical users, you will have to consider including the Python shared library in your distribution as well as setting up wrapper scripts to set the right environment variables (such as `LD_LIBRARY_PATH` on UNIX, or `PATH` on Windows). + +Note that PyPy cannot be embedded in Rust (or any other software). +Support for this is tracked on the [PyPy issue tracker](https://github.com/pypy/pypy/issues/3836). + +### Statically embedding the Python interpreter + +Embedding the Python interpreter statically means including the contents of a Python static library directly inside your Rust binary. +This means that to distribute your program you only need to ship your binary file: it contains the Python interpreter inside the binary! + +On Windows static linking is almost never done, so Python distributions don't usually include a static library. +The information below applies only to UNIX. + +The Python static library is usually called `libpython.a`. + +Static linking has a lot of complications, listed below. +For these reasons PyO3 does not yet have first-class support for this embedding mode. +See [issue 416 on PyO3's GitHub](https://github.com/PyO3/pyo3/issues/416) for more information and to discuss any issues you encounter. + +The [`auto-initialize`](features.md#auto-initialize) feature is deliberately disabled when embedding the interpreter statically because this is often unintentionally done by new users to PyO3 running test programs. +Trying out PyO3 is much easier using dynamic embedding. + +The known complications are: + +- To import compiled extension modules (such as other Rust extension modules, or those written in C), your binary must have the correct linker flags set during compilation to export the original contents of `libpython.a` so that extensions can use them (e.g. `-Wl,--export-dynamic`). +- The C compiler and flags which were used to create `libpython.a` must be compatible with your Rust compiler and flags, else you will experience compilation failures. + + Significantly different compiler versions may see errors like this: + + ```text + lto1: fatal error: bytecode stream in file 'rust-numpy/target/release/deps/libpyo3-6a7fb2ed970dbf26.rlib' generated with LTO version 6.0 instead of the expected 6.2 + ``` + + Mismatching flags may lead to errors like this: + + ```text + /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libpython3.9.a(zlibmodule.o): relocation R_X86_64_32 against `.data' can not be used when making a PIE object; recompile with -fPIE + ``` + +If you encounter these or other complications when linking the interpreter statically, discuss them on [issue 416 on PyO3's GitHub](https://github.com/PyO3/pyo3/issues/416). +It is hoped that eventually that discussion will contain enough information and solutions that PyO3 can offer first-class support for static embedding. + +### Import your module when embedding the Python interpreter + +When you run your Rust binary with an embedded interpreter, any `#[pymodule]` created modules won't be accessible to import unless added to a table called `PyImport_Inittab` before the embedded interpreter is initialized. +This will cause Python statements in your embedded interpreter such as `import your_new_module` to fail. +You can call the macro [`append_to_inittab`]({{#PYO3_DOCS_URL}}/pyo3/macro.append_to_inittab.html) with your module before initializing the Python interpreter to add the module function into that table. (The Python interpreter will be initialized by calling `Python::initialize`, `with_embedded_python_interpreter`, or `Python::attach` with the [`auto-initialize`](features.md#auto-initialize) feature enabled.) + +## Cross Compiling + +Thanks to Rust's great cross-compilation support, cross-compiling using PyO3 is relatively straightforward. +To get started, you'll need a few pieces of software: + +- A toolchain for your target. +- The appropriate options in your Cargo `.config` for the platform you're targeting and the toolchain you are using. +- A Python interpreter that's already been compiled for your target (optional when building "abi3" extension modules). +- A Python interpreter that is built for your host and available through the `PATH` or setting the [`PYO3_PYTHON`](#configuring-the-python-version) variable (optional when building "abi3" extension modules). + +After you've obtained the above, you can build a cross-compiled PyO3 module by using Cargo's `--target` flag. +PyO3's build script will detect that you are attempting a cross-compile based on your host machine and the desired target. + +When cross-compiling, PyO3's build script cannot execute the target Python interpreter to query the configuration, so there are a few additional environment variables you may need to set: + +- `PYO3_CROSS`: If present this variable forces PyO3 to configure as a cross-compilation. +- `PYO3_CROSS_LIB_DIR`: This variable can be set to the directory containing the target's libpython DSO and the associated `_sysconfigdata*.py` file for Unix-like targets. + This variable is only needed when the output binary must link to libpython explicitly (e.g. when targeting Android, Windows when `raw-dylib` linking is unavailable, or embedding a Python interpreter), or when it is absolutely required to get the interpreter configuration from `_sysconfigdata*.py`. +- `PYO3_CROSS_PYTHON_VERSION`: Major and minor version (e.g. 3.9) of the target Python installation. + This variable is only needed if PyO3 cannot determine the version to target from `abi3-py3*` features, or if `PYO3_CROSS_LIB_DIR` is not set, or if there are multiple versions of Python present in `PYO3_CROSS_LIB_DIR`. +- `PYO3_CROSS_PYTHON_IMPLEMENTATION`: Python implementation name ("CPython" or "PyPy") of the target Python installation. + CPython is assumed by default when this variable is not set, unless `PYO3_CROSS_LIB_DIR` is set for a Unix-like target and PyO3 can get the interpreter configuration from `_sysconfigdata*.py`. + +An example might look like the following (assuming your target's sysroot is at `/home/pyo3/cross/sysroot` and that your target is `armv7`): + +```sh +export PYO3_CROSS_LIB_DIR="/home/pyo3/cross/sysroot/usr/lib" + +cargo build --target armv7-unknown-linux-gnueabihf +``` + +If there are multiple python versions at the cross lib directory and you cannot set a more precise location to include both the `libpython` DSO and `_sysconfigdata*.py` files, you can set the required version: + +```sh +export PYO3_CROSS_PYTHON_VERSION=3.8 +export PYO3_CROSS_LIB_DIR="/home/pyo3/cross/sysroot/usr/lib" + +cargo build --target armv7-unknown-linux-gnueabihf +``` + +Any of the `abi3-py3*` features can be enabled instead of setting `PYO3_CROSS_PYTHON_VERSION` in the above examples. + +`PYO3_CROSS_LIB_DIR` can often be omitted when cross compiling extension modules for Unix, macOS, and Windows targets. + +The following resources may also be useful for cross-compiling: + +- [github.com/japaric/rust-cross](https://github.com/japaric/rust-cross) is a primer on cross compiling Rust. +- [github.com/rust-embedded/cross](https://github.com/rust-embedded/cross) uses Docker to make Rust cross-compilation easier. + +[`pyo3-build-config`]: https://github.com/PyO3/pyo3/tree/main/pyo3-build-config +[`maturin-starter`]: https://github.com/PyO3/pyo3/tree/main/examples/maturin-starter +[`setuptools-rust-starter`]: https://github.com/PyO3/pyo3/tree/main/examples/setuptools-rust-starter +[`maturin`]: https://github.com/PyO3/maturin +[`setuptools-rust`]: https://github.com/PyO3/setuptools-rust +[PyOxidizer]: https://github.com/indygreg/PyOxidizer diff --git a/vendor/pyo3/guide/src/building-and-distribution/multiple-python-versions.md b/vendor/pyo3/guide/src/building-and-distribution/multiple-python-versions.md new file mode 100644 index 0000000..9f9aa99 --- /dev/null +++ b/vendor/pyo3/guide/src/building-and-distribution/multiple-python-versions.md @@ -0,0 +1,133 @@ +# Supporting multiple Python versions + +PyO3 supports all actively-supported Python 3 and PyPy versions. +As much as possible, this is done internally to PyO3 so that your crate's code does not need to adapt to the differences between each version. +However, as Python features grow and change between versions, PyO3 cannot offer a completely identical API for every Python version. +This may require you to add conditional compilation to your crate or runtime checks for the Python version. + +This section of the guide first introduces the `pyo3-build-config` crate, which you can use as a `build-dependency` to add additional `#[cfg]` flags which allow you to support multiple Python versions at compile-time. + +Second, we'll show how to check the Python version at runtime. +This can be useful when building for multiple versions with the `abi3` feature, where the Python API compiled against is not always the same as the one in use. + +## Conditional compilation for different Python versions + +The `pyo3-build-config` exposes multiple [`#[cfg]` flags](https://doc.rust-lang.org/rust-by-example/attribute/cfg.html) which can be used to conditionally compile code for a given Python version. +PyO3 itself depends on this crate, so by using it you can be sure that you are configured correctly for the Python version PyO3 is building against. + +This allows us to write code like the following + +```rust,ignore +#[cfg(Py_3_8)] +fn function_only_supported_on_python_3_8_and_up() {} + +#[cfg(not(Py_3_8))] +fn function_only_supported_before_python_3_8() {} + +#[cfg(not(Py_LIMITED_API))] +fn function_incompatible_with_stable_abi_feature() {} +``` + +The following sections first show how to add these `#[cfg]` flags to your build process, and then cover some common patterns flags in a little more detail. + +To see a full reference of all the `#[cfg]` flags provided, see the [`pyo3-build-cfg` docs](https://docs.rs/pyo3-build-config). + +### Using `pyo3-build-config` + +You can use the `#[cfg]` flags in just two steps: + +1. Add `pyo3-build-config` to your crate's build dependencies in `Cargo.toml`: + + ```toml + [build-dependencies] + pyo3-build-config = {{#PYO3_CRATE_VERSION}} + ``` + +2. Add a [`build.rs`](https://doc.rust-lang.org/cargo/reference/build-scripts.html) file to your crate with the following contents: + + ```rust,ignore + fn main() { + // If you have an existing build.rs file, just add this line to it. + pyo3_build_config::use_pyo3_cfgs(); + } + ``` + +After these steps you are ready to annotate your code! + +### Common usages of `pyo3-build-cfg` flags + +The `#[cfg]` flags added by `pyo3-build-cfg` can be combined with all of Rust's logic in the `#[cfg]` attribute to create very precise conditional code generation. +The following are some common patterns implemented using these flags: + +```text +#[cfg(Py_3_8)] +``` + +This `#[cfg]` marks code that will only be present on Python 3.8 and upwards. +There are similar options `Py_3_9`, `Py_3_10`, `Py_3_11` and so on for each minor version. + +```text +#[cfg(not(Py_3_8))] +``` + +This `#[cfg]` marks code that will only be present on Python versions before (but not including) Python 3.8. + +```text +#[cfg(Py_GIL_DISABLED)] +``` + +This `#[cfg]` marks code that will only be present for free-threaded builds of CPython. +You might use this in situations where the GIL provides thread safety but the free-threaded build needs extra synchronization logic. + +```text +#[cfg(not(Py_LIMITED_API))] +``` + +This `#[cfg]` marks code that is only available when building for the unlimited Python API (i.e. PyO3's `abi3` or `abi3t` features are not enabled). +This might be useful if you want to ship your extension module as an `abi3` or `abi3t` wheel and also allow users to compile it from source to make use of optimizations only possible with the unlimited API. + +```text +#[cfg(any(Py_3_9, not(Py_LIMITED_API)))] +``` + +This `#[cfg]` marks code which is available when running Python 3.9 or newer, or when using the unlimited API with an older Python version. +Patterns like this are commonly seen on Python APIs which were added to the limited Python API in a specific minor version. + +```text +#[cfg(all(Py_GIL_DISABLED, Py_LIMITED_API))] +``` + +This marks code which is available only for the free-threaded `abi3t` stable ABI. +You might use this if you need some sort of custom locking implementation in code that makes strong assumptions about the GIL providing thread safety. + +```text +#[cfg(PyPy)] +``` + +This `#[cfg]` marks code which is running on PyPy. + +## Checking the Python version at runtime + +When building with PyO3's `abi3` or `abi3t` features, your extension module will be compiled against a specific [minimum version](../building-and-distribution.md#minimum-python-version-for-abi3-and-abi3t-builds) of Python, but may be running on newer Python versions. + +For example with PyO3's `abi3-py38` feature, your extension module will be compiled as if it were for Python 3.8. +If you were using `pyo3-build-config`, `#[cfg(Py_3_8)]` would be present. +Your user could freely install and run your abi3 extension module on Python 3.9. + +There's no way to detect your user doing that at compile time, so instead you need to fall back to runtime checks. + +PyO3 provides the APIs [`Python::version()`] and [`Python::version_info()`] to query the running Python version. +This allows you to do the following, for example: + +```rust +use pyo3::Python; + +Python::attach(|py| { + // PyO3 supports Python 3.8 and up. + assert!(py.version_info() >= (3, 8)); + assert!(py.version_info() >= (3, 8, 0)); +}); +``` + +[`Python::version()`]: {{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#method.version +[`Python::version_info()`]: {{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#method.version_info diff --git a/vendor/pyo3/guide/src/changelog.md b/vendor/pyo3/guide/src/changelog.md new file mode 100644 index 0000000..c16cb03 --- /dev/null +++ b/vendor/pyo3/guide/src/changelog.md @@ -0,0 +1 @@ +{{#include ../../CHANGELOG.md}} diff --git a/vendor/pyo3/guide/src/class.md b/vendor/pyo3/guide/src/class.md new file mode 100644 index 0000000..031a2a5 --- /dev/null +++ b/vendor/pyo3/guide/src/class.md @@ -0,0 +1,1589 @@ +# Python classes + +PyO3 exposes a group of attributes powered by Rust's proc macro system for defining Python classes as Rust structs. + +The main attribute is `#[pyclass]`, which is placed upon a Rust `struct` or `enum` to generate a Python type for it. +They will usually also have *one* `#[pymethods]`-annotated `impl` block for the struct, which is used to define Python methods and constants for the generated Python type. (If the [`multiple-pymethods`] feature is enabled, each `#[pyclass]` is allowed to have multiple `#[pymethods]` blocks.) `#[pymethods]` may also have implementations for Python magic methods such as `__str__`. + +This chapter will discuss the functionality and configuration these attributes offer. +Below is a list of links to the relevant section of this chapter for each: + +- [`#[pyclass]`](#defining-a-new-class) + - [`#[pyo3(get, set)]`](#object-properties-using-pyo3get-set) +- [`#[pymethods]`](#instance-methods) + - [`#[new]`](#constructor) + - [`#[getter]`](#object-properties-using-getter-and-setter) + - [`#[setter]`](#object-properties-using-getter-and-setter) + - [`#[deleter]`](#object-properties-using-getter-and-setter) + - [`#[staticmethod]`](#static-methods) + - [`#[classmethod]`](#class-methods) + - [`#[classattr]`](#class-attributes) + - [`#[args]`](#method-arguments) +- [Magic methods and slots](class/protocols.md) +- [Classes as function arguments](#classes-as-function-arguments) + +## Defining a new class + +To define a custom Python class, add the `#[pyclass]` attribute to a Rust struct or enum. + +```rust +# #![allow(dead_code)] +use pyo3::prelude::*; + +#[pyclass] +struct MyClass { + inner: i32, +} + +// A "tuple" struct +#[pyclass] +struct Number(i32); + +// PyO3 supports unit-only enums (which contain only unit variants) +// These simple enums behave similarly to Python's enumerations (enum.Enum) +#[pyclass(eq, eq_int)] +#[derive(PartialEq)] +enum MyEnum { + Variant, + OtherVariant = 30, // PyO3 supports custom discriminants. +} + +// PyO3 supports custom discriminants in unit-only enums +#[pyclass(eq, eq_int)] +#[derive(PartialEq)] +enum HttpResponse { + Ok = 200, + NotFound = 404, + Teapot = 418, + // ... +} + +// PyO3 also supports enums with Struct and Tuple variants +// These complex enums have slightly different behavior from the simple enums above +// They are meant to work with instance checks and match statement patterns +// The variants can be mixed and matched +// Struct variants have named fields while tuple enums generate generic names for fields in order _0, _1, _2, ... +// Apart from this both types are functionally identical +#[pyclass] +enum Shape { + Circle { radius: f64 }, + Rectangle { width: f64, height: f64 }, + RegularPolygon(u32, f64), + Nothing(), +} +``` + +The above example generates implementations for [`PyTypeInfo`] and [`PyClass`] for `MyClass`, `Number`, `MyEnum`, `HttpResponse`, and `Shape`. +To see these generated implementations, refer to the [implementation details](#implementation-details) at the end of this chapter. + +### Restrictions + +To integrate Rust types with Python, PyO3 needs to place some restrictions on the types which can be annotated with `#[pyclass]`. +In particular, they must have no lifetime parameters, no generic parameters, and must be thread-safe. +The reason for each of these is explained below. + +#### No lifetime parameters + +Rust lifetimes are used by the Rust compiler to reason about a program's memory safety. +They are a compile-time only concept; there is no way to access Rust lifetimes at runtime from a dynamic language like Python. + +As soon as Rust data is exposed to Python, there is no guarantee that the Rust compiler can make on how long the data will live. +Python is a reference-counted language and those references can be held for an arbitrarily long time which is untraceable by the Rust compiler. +The only possible way to express this correctly is to require that any `#[pyclass]` does not borrow data for any lifetime shorter than the `'static` lifetime, i.e. the `#[pyclass]` cannot have any lifetime parameters. + +When you need to share ownership of data between Python and Rust, instead of using borrowed references with lifetimes consider using reference-counted smart pointers such as [`Arc`] or [`Py`][`Py`]. + +#### No generic parameters + +A Rust `struct Foo` with a generic parameter `T` generates new compiled implementations each time it is used with a different concrete type for `T`. +These new implementations are generated by the compiler at each usage site. +This is incompatible with wrapping `Foo` in Python, where there needs to be a single compiled implementation of `Foo` which is integrated with the Python interpreter. + +Currently, the best alternative is to write a macro which expands to a new `#[pyclass]` for each instantiation you want: + +```rust +# #![allow(dead_code)] +use pyo3::prelude::*; + +struct GenericClass { + data: T, +} + +macro_rules! create_interface { + ($name: ident, $type: ident) => { + #[pyclass] + pub struct $name { + inner: GenericClass<$type>, + } + #[pymethods] + impl $name { + #[new] + pub fn new(data: $type) -> Self { + Self { + inner: GenericClass { data: data }, + } + } + } + }; +} + +create_interface!(IntClass, i64); +create_interface!(FloatClass, String); +``` + +#### Must be thread-safe + +Python objects are freely shared between threads by the Python interpreter. +This means that: + +- Python objects may be created and destroyed by different Python threads; therefore `#[pyclass]` objects must be `Send`. +- Python objects may be accessed by multiple Python threads simultaneously; therefore `#[pyclass]` objects must be `Sync`. + +For now, don't worry about these requirements; simple classes will already be thread-safe. +There is a [detailed discussion on thread-safety](./class/thread-safety.md) later in the guide. + +## Constructor + +By default, it is not possible to create an instance of a custom class from Python code. +To declare a constructor, you need to define a method and annotate it with the `#[new]` attribute. +A constructor is accessible as Python's `__new__` method. + +```rust +# #![allow(dead_code)] +# use pyo3::prelude::*; +# #[pyclass] +# struct Number(i32); +# +#[pymethods] +impl Number { + #[new] + fn new(value: i32) -> Self { + Number(value) + } +} +``` + +Alternatively, if your `new` method may fail you can return `PyResult`. + +```rust +# #![allow(dead_code)] +# use pyo3::prelude::*; +# use pyo3::exceptions::PyValueError; +# #[pyclass] +# struct Nonzero(i32); +# +#[pymethods] +impl Nonzero { + #[new] + fn py_new(value: i32) -> PyResult { + if value == 0 { + Err(PyValueError::new_err("cannot be zero")) + } else { + Ok(Nonzero(value)) + } + } +} +``` + +If you want to return an existing object (for example, because your `new` method caches the values it returns), `new` can return `pyo3::Py`. + +As you can see, the Rust method name is not important here; this way you can still, use `new()` for a Rust-level constructor. + +If no method marked with `#[new]` is declared, object instances can only be created from Rust, but not from Python. + +For arguments, see the [`Method arguments`](#method-arguments) section below. + +## Initializer + +An initializer implements Python's `__init__` method. + +It may be required when it's needed to control an object initialization flow on the Rust code. +If possible handling this in `__new__` should be preferred, but in some cases, like subclassing native types, overwriting `__init__` might be necessary. +For example, you define a class that extends `PyDict` and don't want that the original `__init__` method of `PyDict` been called. +In this case by defining an own `__init__` method it's possible to stop initialization flow. + +If you declare an `__init__` method you may need to call a super class' `__init__` method explicitly like in Python code. + +To declare an initializer, you need to define the `__init__` method. +Like in Python `__init__` must have the `self` receiver as the first argument, followed by the same arguments as the constructor. +It can either return `()` or `PyResult<()>`. + +```rust +# #![allow(dead_code)] +# use pyo3::prelude::*; +# #[cfg(not(any(Py_LIMITED_API, GraalPy)))] +use pyo3::types::{PyDict, PyTuple, PySuper}; +# #[cfg(not(any(Py_LIMITED_API, GraalPy)))] +use crate::pyo3::PyTypeInfo; + +# #[cfg(not(any(Py_LIMITED_API, GraalPy)))] +#[pyclass(extends = PyDict)] +struct MyDict; + +# #[cfg(not(any(Py_LIMITED_API, GraalPy)))] +#[pymethods] +impl MyDict { +# #[allow(unused_variables)] + #[new] + #[pyo3(signature = (*args, **kwargs))] + fn __new__( + args: &Bound<'_, PyTuple>, + kwargs: Option<&Bound<'_, PyDict>>, + ) -> PyResult { + Ok(Self) + } + + #[pyo3(signature = (*args, **kwargs))] + fn __init__( + slf: &Bound<'_, Self>, + args: &Bound<'_, PyTuple>, + kwargs: Option<&Bound<'_, PyDict>>, + ) -> PyResult<()> { + // call the super types __init__ + PySuper::new(&PyDict::type_object(slf.py()), slf)? + .call_method("__init__", args.to_owned(), kwargs)?; + // Note: if `MyDict` allows further subclassing (i.e. uses the `#[pyclass(subclass)]` option), and + // this is called from such a subclass, then this will not respect any overrides that subclass may + // have defined. Accordingly if `MyDict` allows subclassing it may be preferred to just call + // `slf.set_item` and let Python resolve the correct subclass method. + slf.as_super().set_item("my_key", "always insert this key")?; + Ok(()) + } +} + +# #[cfg(not(any(Py_LIMITED_API, GraalPy)))] +# fn main() { +# Python::attach(|py| { +# let typeobj = py.get_type::(); +# let obj = typeobj.call((), None).unwrap().cast_into::().unwrap(); +# // check __init__ was called +# assert_eq!(obj.get_item("my_key").unwrap().extract::<&str>().unwrap(), "always insert this key"); +# }); +# } +# #[cfg(any(Py_LIMITED_API, GraalPy))] +# fn main() {} +``` + +## Adding the class to a module + +The next step is to create the Python module and add our class to it: + +```rust +# #![allow(dead_code)] +# use pyo3::prelude::*; +# fn main() {} +# #[pyclass] +# struct Number(i32); +# +#[pymodule] +mod my_module { + #[pymodule_export] + use super::Number; +} +``` + +## `Bound` and interior mutability { #bound-and-interior-mutability } + +It is often useful to turn a `#[pyclass]` type `T` into a Python object and access it from Rust code. +The [`Py`] and [`Bound<'py, T>`] smart pointers are the ways to represent a Python object in PyO3's API. +More detail can be found about them [in the Python objects](./types.md#pyo3s-smart-pointers) section of the guide. + +Most Python objects do not offer exclusive (`&mut`) access (see the [section on Python's memory model](./python-from-rust.md#pythons-memory-model)). +However, Rust structs wrapped as Python objects (called `pyclass` types) often *do* need `&mut` access. +However, the Rust borrow checker cannot reason about `&mut` references once an object's ownership has been passed to the Python interpreter. + +To solve this, PyO3 does borrow checking at runtime using a scheme very similar to `std::cell::RefCell`. +This is known as [interior mutability](https://doc.rust-lang.org/book/ch15-05-interior-mutability.html). + +Users who are familiar with `RefCell` can use `Py` and `Bound<'py, T>` just like `RefCell`. + +For users who are not very familiar with `RefCell`, here is a reminder of Rust's rules of borrowing: + +- At any given time, you can have either (but not both of) one mutable reference or any number of immutable references. +- References can never outlast the data they refer to. + +`Py` and `Bound<'py, T>`, like `RefCell`, ensure these borrowing rules by tracking references at runtime. + +```rust +# use pyo3::prelude::*; +#[pyclass] +struct MyClass { + #[pyo3(get)] + num: i32, +} +Python::attach(|py| { + let obj = Bound::new(py, MyClass { num: 3 }).unwrap(); + { + let obj_ref = obj.borrow(); // Get PyRef + assert_eq!(obj_ref.num, 3); + // You cannot get PyRefMut unless all PyRefs are dropped + assert!(obj.try_borrow_mut().is_err()); + } + { + let mut obj_mut = obj.borrow_mut(); // Get PyRefMut + obj_mut.num = 5; + // You cannot get any other refs until the PyRefMut is dropped + assert!(obj.try_borrow().is_err()); + assert!(obj.try_borrow_mut().is_err()); + } + + // You can convert `Bound` to a Python object + pyo3::py_run!(py, obj, "assert obj.num == 5"); +}); +``` + +A `Bound<'py, T>` is restricted to the Python lifetime `'py`. +To make the object longer lived (for example, to store it in a struct on the Rust side), use `Py`. +`Py` needs a `Python<'_>` token to allow access: + +```rust +# use pyo3::prelude::*; +#[pyclass] +struct MyClass { + num: i32, +} + +fn return_myclass() -> Py { + Python::attach(|py| Py::new(py, MyClass { num: 1 }).unwrap()) +} + +let obj = return_myclass(); + +Python::attach(move |py| { + let bound = obj.bind(py); // Py::bind returns &Bound<'py, MyClass> + let obj_ref = bound.borrow(); // Get PyRef + assert_eq!(obj_ref.num, 1); +}); +``` + +### frozen classes: Opting out of interior mutability + +As detailed above, runtime borrow checking is currently enabled by default. +But a class can opt of out it by declaring itself `frozen`. +It can still use interior mutability via standard Rust types like `RefCell` or `Mutex`, but it is not bound to the implementation provided by PyO3 and can choose the most appropriate strategy on field-by-field basis. + +Classes which are `frozen` and also `Sync`, e.g. they do use `Mutex` but not `RefCell`, can be accessed without needing a `Python` token via the `Bound::get` and `Py::get` methods: + +```rust +use std::sync::atomic::{AtomicUsize, Ordering}; +# use pyo3::prelude::*; + +#[pyclass(frozen)] +struct FrozenCounter { + value: AtomicUsize, +} + +let py_counter: Py = Python::attach(|py| { + let counter = FrozenCounter { + value: AtomicUsize::new(0), + }; + + Py::new(py, counter).unwrap() +}); + +py_counter.get().value.fetch_add(1, Ordering::Relaxed); + +Python::attach(move |_py| drop(py_counter)); +``` + +Frozen classes are likely to become the default thereby guiding the PyO3 ecosystem towards a more deliberate application of interior mutability. +Eventually, this should enable further optimizations of PyO3's internals and avoid downstream code paying the cost of interior mutability when it is not actually required. + +## Customizing the class + +{{#include ../pyclass-parameters.md}} + +These parameters are covered in various sections of this guide. + +### Return type + +Generally, `#[new]` methods have to return `T: Into>` or `PyResult where T: Into>`. + +For constructors that may fail, you should wrap the return type in a PyResult as well. +Consult the table below to determine which type your constructor should return: + +| | **Cannot fail** | **May fail** | +|-----------------------------|---------------------------|-----------------------------------| +|**No inheritance** | `T` | `PyResult` | +|**Inheritance** | [`PyClassInitializer`] | `PyResult>` | + +## Inheritance + +By default, `object`, i.e. `PyAny` is used as the base class. +To override this default, use the `extends` parameter for `pyclass` with the full path to the base class. +Currently, only classes defined in Rust and builtins provided by PyO3 can be inherited from; inheriting from other classes defined in Python is not yet supported ([#991](https://github.com/PyO3/pyo3/issues/991)). + +To initialize a class, which inherits from another class, use the `PyClassInitializer` API. + +To get a parent class from a child, use [`PyRef`] instead of `&self` for methods, or [`PyRefMut`] instead of `&mut self`. +Then you can access a parent class by `self_.as_super()` as `&PyRef`, or by `self_.into_super()` as `PyRef` (and similar for the `PyRefMut` case). +For convenience, `self_.as_ref()` can also be used to get `&Self::BaseClass` directly; however, this approach does not let you access base classes higher in the inheritance hierarchy, for which you would need to chain multiple `as_super` or `into_super` calls. + +```rust +# use pyo3::prelude::*; + +#[pyclass(subclass)] +struct BaseClass { + val1: usize, +} + +#[pymethods] +impl BaseClass { + #[new] + fn new() -> Self { + BaseClass { val1: 10 } + } + + pub fn method1(&self) -> PyResult { + Ok(self.val1) + } +} + +#[pyclass(extends=BaseClass, subclass)] +struct SubClass { + val2: usize, +} + +#[pymethods] +impl SubClass { + #[new] + fn new() -> PyClassInitializer { + PyClassInitializer::from(BaseClass::new()) + .add_subclass(SubClass { val2: 15 }) + } + + fn method2(self_: PyRef<'_, Self>) -> PyResult { + let super_ = self_.as_super(); // Get &PyRef + super_.method1().map(|x| x * self_.val2) + } +} + +#[pyclass(extends=SubClass)] +struct SubSubClass { + val3: usize, +} + +#[pymethods] +impl SubSubClass { + #[new] + fn new() -> PyClassInitializer { + PyClassInitializer::from(SubClass::new()).add_subclass(SubSubClass { val3: 20 }) + } + + fn method3(self_: PyRef<'_, Self>) -> PyResult { + let base = self_.as_super().as_super(); // Get &PyRef<'_, BaseClass> + base.method1().map(|x| x * self_.val3) + } + + fn method4(self_: PyRef<'_, Self>) -> PyResult { + let v = self_.val3; + let super_ = self_.into_super(); // Get PyRef<'_, SubClass> + SubClass::method2(super_).map(|x| x * v) + } + + fn get_values(self_: PyRef<'_, Self>) -> (usize, usize, usize) { + let val1 = self_.as_super().as_super().val1; + let val2 = self_.as_super().val2; + (val1, val2, self_.val3) + } + + fn double_values(mut self_: PyRefMut<'_, Self>) { + self_.as_super().as_super().val1 *= 2; + self_.as_super().val2 *= 2; + self_.val3 *= 2; + } + + #[staticmethod] + fn factory_method(py: Python<'_>, val: usize) -> PyResult> { + let base = PyClassInitializer::from(BaseClass::new()); + let sub = base.add_subclass(SubClass { val2: val }); + if val % 2 == 0 { + Ok(Py::new(py, sub)?.into_any()) + } else { + let sub_sub = sub.add_subclass(SubSubClass { val3: val }); + Ok(Py::new(py, sub_sub)?.into_any()) + } + } +} +# Python::attach(|py| { +# let subsub = pyo3::Py::new(py, SubSubClass::new()).unwrap(); +# pyo3::py_run!(py, subsub, "assert subsub.method1() == 10"); +# pyo3::py_run!(py, subsub, "assert subsub.method2() == 150"); +# pyo3::py_run!(py, subsub, "assert subsub.method3() == 200"); +# pyo3::py_run!(py, subsub, "assert subsub.method4() == 3000"); +# pyo3::py_run!(py, subsub, "assert subsub.get_values() == (10, 15, 20)"); +# pyo3::py_run!(py, subsub, "assert subsub.double_values() == None"); +# pyo3::py_run!(py, subsub, "assert subsub.get_values() == (20, 30, 40)"); +# let subsub = SubSubClass::factory_method(py, 2).unwrap(); +# let subsubsub = SubSubClass::factory_method(py, 3).unwrap(); +# let cls = py.get_type::(); +# pyo3::py_run!(py, subsub cls, "assert not isinstance(subsub, cls)"); +# pyo3::py_run!(py, subsubsub cls, "assert isinstance(subsubsub, cls)"); +# }); +``` + +You can inherit native types such as `PyDict`, if they implement [`PySizedLayout`]({{#PYO3_DOCS_URL}}/pyo3/type_object/trait.PySizedLayout.html). +This is not supported when building for the Python limited API (aka the `abi3` feature of PyO3). + +To convert between the Rust type and its native base class, you can take `slf` as a Python object. +To access the Rust fields use `slf.borrow()` or `slf.borrow_mut()`, and to access the base class use `slf.cast::()`. + +```rust +# #[cfg(any(not(Py_LIMITED_API), Py_3_12))] { +# use pyo3::prelude::*; +use pyo3::types::PyDict; +use std::collections::HashMap; + +#[pyclass(extends=PyDict)] +#[derive(Default)] +struct DictWithCounter { + counter: HashMap, +} + +#[pymethods] +impl DictWithCounter { + #[new] + fn new() -> Self { + Self::default() + } + + fn set(slf: &Bound<'_, Self>, key: String, value: Bound<'_, PyAny>) -> PyResult<()> { + slf.borrow_mut().counter.entry(key.clone()).or_insert(0); + let dict = slf.cast::()?; + dict.set_item(key, value) + } +} +# Python::attach(|py| { +# let cnt = pyo3::Py::new(py, DictWithCounter::new()).unwrap(); +# pyo3::py_run!(py, cnt, "cnt.set('abc', 10); assert cnt['abc'] == 10") +# }); +# } +``` + +If `SubClass` does not provide a base class initialization, the compilation fails. + +```rust,compile_fail +# use pyo3::prelude::*; + +#[pyclass] +struct BaseClass { + val1: usize, +} + +#[pyclass(extends=BaseClass)] +struct SubClass { + val2: usize, +} + +#[pymethods] +impl SubClass { + #[new] + fn new() -> Self { + SubClass { val2: 15 } + } +} +``` + +The `__new__` constructor of a native base class is called implicitly when creating a new instance from Python. +Be sure to accept arguments in the `#[new]` method that you want the base class to get, even if they are not used in that `fn`: + +```rust +# #[allow(dead_code)] +# #[cfg(any(not(Py_LIMITED_API), Py_3_12))] { +# use pyo3::prelude::*; +use pyo3::types::PyDict; + +#[pyclass(extends=PyDict)] +struct MyDict { + private: i32, +} + +#[pymethods] +impl MyDict { + #[new] + #[pyo3(signature = (*args, **kwargs))] + fn new(args: &Bound<'_, PyAny>, kwargs: Option<&Bound<'_, PyAny>>) -> Self { + Self { private: 0 } + } + + // some custom methods that use `private` here... +} +# Python::attach(|py| { +# let cls = py.get_type::(); +# pyo3::py_run!(py, cls, "cls(a=1, b=2)") +# }); +# } +``` + +Here, the `args` and `kwargs` allow creating instances of the subclass passing initial items, such as `MyDict(item_sequence)` or `MyDict(a=1, b=2)`. + +## Object properties + +PyO3 supports two ways to add properties to your `#[pyclass]`: + +- For simple struct fields with no side effects, a `#[pyo3(get, set)]` attribute can be added directly to the field definition in the `#[pyclass]`. +- For properties which require computation you can define `#[getter]`, `#[setter]` and `#[deleter]` functions in the [`#[pymethods]`](#instance-methods) block. + +We'll cover each of these in the following sections. + +### Object properties using `#[pyo3(get, set)]` + +For simple cases where a member variable is just read and written with no side effects, you can declare getters and setters in your `#[pyclass]` field definition using the `pyo3` attribute, like in the example below: + +```rust +# use pyo3::prelude::*; +# #[allow(dead_code)] +#[pyclass] +struct MyClass { + #[pyo3(get, set)] + num: i32, +} +``` + +The above would make the `num` field available for reading and writing as a `self.num` Python property. +To expose the property with a different name to the field, specify this alongside the rest of the options, e.g. `#[pyo3(get, set, name = "custom_name")]`. + +Properties can be readonly or writeonly by using just `#[pyo3(get)]` or `#[pyo3(set)]` respectively. + +To use these annotations, your field type must implement some conversion traits: + +- For `get` the field type `T` must implement either `&T: IntoPyObject` or `T: IntoPyObject + Clone`. +- For `set` the field type must implement `FromPyObject`. + +For example, implementations of those traits are provided for the `Cell` type, if the inner type also implements the trait. +This means you can use `#[pyo3(get, set)]` on fields wrapped in a `Cell`. + +### Object properties using `#[getter]` and `#[setter]` + +For cases which don't satisfy the `#[pyo3(get, set)]` trait requirements, or need side effects, descriptor methods can be defined in a `#[pymethods]` `impl` block. + +This is done using the `#[getter]` and `#[setter]` attributes, like in the example below: + +```rust +# use pyo3::prelude::*; +#[pyclass] +struct MyClass { + num: i32, +} + +#[pymethods] +impl MyClass { + #[getter] + fn num(&self) -> PyResult { + Ok(self.num) + } + + #[setter] + fn set_num(&mut self, num: i32) { + self.num = num; + } +} +``` + +The `#[deleter]` attribute is also available to delete the property. +This corresponds to the `del my_object.my_property` python operation. + +```rust +# use pyo3::prelude::*; +# use pyo3::exceptions::PyAttributeError; +#[pyclass] +struct MyClass { + num: Option, +} + +#[pymethods] +impl MyClass { + #[getter] + fn num(&self) -> PyResult { + self.num.ok_or_else(|| PyAttributeError::new_err("num has been deleted")) + } + + #[deleter] + fn delete_num(&mut self) { + self.num = None; + } +} +``` + +A getter, setter or deleters's function name is used as the property name by default. +There are several ways how to override the name. + +If a function name starts with `get_`, `set_` or `delete_` for getter, setter or deleter, respectively, the descriptor name becomes the function name with this prefix removed. +This is also useful in case of Rust keywords like `type` ([raw identifiers](https://doc.rust-lang.org/edition-guide/rust-2018/module-system/raw-identifiers.html) can be used since Rust 2018). + +```rust +# use pyo3::prelude::*; +# #[pyclass] +# struct MyClass { +# num: i32, +# } +#[pymethods] +impl MyClass { + #[getter] + fn get_num(&self) -> PyResult { + Ok(self.num) + } + + #[setter] + fn set_num(&mut self, value: i32) -> PyResult<()> { + self.num = value; + Ok(()) + } +} +``` + +In this case, a property `num` is defined and available from Python code as `self.num`. + +The `#[getter]`, `#[setter]` and `#[deleter]` attributes accept one parameter. +If this parameter is specified, it is used as the property name, i.e. + +```rust +# use pyo3::prelude::*; +# #[pyclass] +# struct MyClass { +# num: i32, +# } +#[pymethods] +impl MyClass { + #[getter(number)] + fn num(&self) -> PyResult { + Ok(self.num) + } + + #[setter(number)] + fn set_num(&mut self, value: i32) -> PyResult<()> { + self.num = value; + Ok(()) + } +} +``` + +In this case, the property `number` is defined and available from Python code as `self.number`. + +## Instance methods + +To define a Python compatible method, an `impl` block for your struct has to be annotated with the `#[pymethods]` attribute. +PyO3 generates Python compatible wrappers for all functions in this block with some variations, like descriptors, class method static methods, etc. + +Since Rust allows any number of `impl` blocks, you can easily split methods between those accessible to Python (and Rust) and those accessible only to Rust. +However to have multiple `#[pymethods]`-annotated `impl` blocks for the same struct you must enable the [`multiple-pymethods`] feature of PyO3. + +```rust +# use pyo3::prelude::*; +# #[pyclass] +# struct MyClass { +# num: i32, +# } +#[pymethods] +impl MyClass { + fn method1(&self) -> PyResult { + Ok(10) + } + + fn set_method(&mut self, value: i32) -> PyResult<()> { + self.num = value; + Ok(()) + } +} +``` + +Both `&self` and `&mut self` can be used, due to the use of [runtime borrow checking](#bound-and-interior-mutability). + +The return type must be `PyResult` or `T` for some `T` that implements `IntoPyObject`; the latter is allowed if the method cannot raise Python exceptions. + +A `Python` parameter can be specified as part of method signature, in this case the `py` argument gets injected by the method wrapper, e.g. + +```rust +# use pyo3::prelude::*; +# #[pyclass] +# struct MyClass { +# #[allow(dead_code)] +# num: i32, +# } +#[pymethods] +impl MyClass { + fn method2(&self, py: Python<'_>) -> PyResult { + Ok(10) + } +} +``` + +From the Python perspective, the `method2` in this example does not accept any arguments. + +## Class methods + +To create a class method for a custom class, the method needs to be annotated with the `#[classmethod]` attribute. +This is the equivalent of the Python decorator `@classmethod`. + +```rust +# use pyo3::prelude::*; +# use pyo3::types::PyType; +# #[pyclass] +# struct MyClass { +# #[allow(dead_code)] +# num: i32, +# } +#[pymethods] +impl MyClass { + #[classmethod] + fn cls_method(cls: &Bound<'_, PyType>) -> PyResult { + Ok(10) + } +} +``` + +Declares a class method callable from Python. + +- The first parameter is the type object of the class on which the method is called. + This may be the type object of a derived class. +- The first parameter implicitly has type `&Bound<'_, PyType>`. +- For details on `parameter-list`, see the documentation of `Method arguments` section. +- The return type must be `PyResult` or `T` for some `T` that implements `IntoPyObject`. + +### Constructors which accept a class argument + +To create a constructor which takes a positional class argument, you can combine the `#[classmethod]` and `#[new]` modifiers: + +```rust +# #![allow(dead_code)] +# use pyo3::prelude::*; +# use pyo3::types::PyType; +# #[pyclass] +# struct BaseClass(Py); +# +#[pymethods] +impl BaseClass { + #[new] + #[classmethod] + fn py_new(cls: &Bound<'_, PyType>) -> PyResult { + // Get an abstract attribute (presumably) declared on a subclass of this class. + let subclass_attr: Bound<'_, PyAny> = cls.getattr("a_class_attr")?; + Ok(Self(subclass_attr.unbind())) + } +} +``` + +## Static methods + +To create a static method for a custom class, the method needs to be annotated with the `#[staticmethod]` attribute. +The return type must be `T` or `PyResult` for some `T` that implements `IntoPyObject`. + +```rust +# use pyo3::prelude::*; +# #[pyclass] +# struct MyClass { +# #[allow(dead_code)] +# num: i32, +# } +#[pymethods] +impl MyClass { + #[staticmethod] + fn static_method(param1: i32, param2: &str) -> PyResult { + Ok(10) + } +} +``` + +## Class attributes + +To create a class attribute (also called [class variable][classattr]), an associated constant can be annotated with the `#[classattr]` attribute. + +```rust,no_run +# use pyo3::prelude::*; +# #[pyclass] +# struct MyClass {} +#[pymethods] +impl MyClass { + #[classattr] + const MY_ATTRIBUTE: &'static str = "foobar"; +} +# +# Python::attach(|py| { +# let my_class = py.get_type::(); +# pyo3::py_run!(py, my_class, "assert my_class.MY_ATTRIBUTE == 'foobar'") +# }); +``` + +If `const` code is too limiting, a method without any arguments can be annotated with the `#[classattr]` attribute. + +> [!NOTE] +> Here too, the class attribute value is computed once during the class creation and not each time the attribute is accessed. + +```rust,no_run +# use pyo3::prelude::*; +# #[pyclass] +# struct MyClass {} +#[pymethods] +impl MyClass { + #[classattr] + fn my_attribute() -> String { + "hello".to_string() + } +} +# +# Python::attach(|py| { +# let my_class = py.get_type::(); +# pyo3::py_run!(py, my_class, "assert my_class.my_attribute == 'hello'") +# }); +``` + +> [!NOTE] +> If the method has a `Result` return type and returns an `Err`, PyO3 will panic during +class creation. + +> [!NOTE] +> `#[classattr]` does not work with [`#[pyo3(warn(...))]`](./function.md#warn) attribute. + +## Classes as function arguments + +Class objects can be used as arguments to `#[pyfunction]`s and `#[pymethods]` in the same way as the self parameters of instance methods, i.e. they can be passed as: + +- `Py` or `Bound<'py, T>` smart pointers to the class Python object, +- `&T` or `&mut T` references to the Rust data contained in the Python object, or +- `PyRef` and `PyRefMut` reference wrappers. + +Examples of each of these below: + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +#[pyclass] +struct MyClass { + my_field: i32, +} + +// Take a reference to Rust data when the Python object is irrelevant. +#[pyfunction] +fn increment_field(my_class: &mut MyClass) { + my_class.my_field += 1; +} + +// Take a reference wrapper when borrowing should be automatic, +// but access to the Python object is still needed +#[pyfunction] +fn print_field_and_return_me(my_class: PyRef<'_, MyClass>) -> PyRef<'_, MyClass> { + println!("{}", my_class.my_field); + my_class +} + +// Take (a reference to) a Python object smart pointer when borrowing needs to be managed manually. +#[pyfunction] +fn increment_then_print_field(my_class: &Bound<'_, MyClass>) { + my_class.borrow_mut().my_field += 1; + + println!("{}", my_class.borrow().my_field); +} + +// When the Python object smart pointer needs to be stored elsewhere prefer `Py` over `Bound<'py, T>` +// to avoid the lifetime restrictions. +#[pyfunction] +fn print_is_none(my_class: Py, py: Python<'_>) { + println!("{}", my_class.is_none(py)); +} +``` + +Classes can also be passed by value if they can be cloned, i.e. they automatically implement `FromPyObject` if they implement `Clone`, e.g. via `#[derive(Clone)]`: + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +#[pyclass(from_py_object)] +#[derive(Clone)] +struct MyClass { + my_field: Box, +} + +#[pyfunction] +fn disassemble_clone(my_class: MyClass) { + let MyClass { mut my_field } = my_class; + *my_field += 1; +} +``` + +Note that `#[derive(FromPyObject)]` on a class is usually not useful as it tries to construct a new Rust value by filling in the fields by looking up attributes of any given Python value. + +## Method arguments + +Similar to `#[pyfunction]`, the `#[pyo3(signature = (...))]` attribute can be used to specify the way that `#[pymethods]` accept arguments. +Consult the documentation for [`function signatures`](./function/signature.md) to see the parameters this attribute accepts. + +The following example defines a class `MyClass` with a method `method`. +This method has a signature that sets default values for `num` and `name`, and indicates that `py_args` should collect all extra positional arguments and `py_kwargs` all extra keyword arguments: + +```rust,no_run +# use pyo3::prelude::*; +use pyo3::types::{PyDict, PyTuple}; +# +# #[pyclass] +# struct MyClass { +# num: i32, +# } +#[pymethods] +impl MyClass { + #[new] + #[pyo3(signature = (num=-1))] + fn new(num: i32) -> Self { + MyClass { num } + } + + #[pyo3(signature = (num=10, *py_args, name="Hello", **py_kwargs))] + fn method( + &mut self, + num: i32, + py_args: &Bound<'_, PyTuple>, + name: &str, + py_kwargs: Option<&Bound<'_, PyDict>>, + ) -> String { + let num_before = self.num; + self.num = num; + format!( + "num={} (was previously={}), py_args={:?}, name={}, py_kwargs={:?} ", + num, num_before, py_args, name, py_kwargs, + ) + } +} +``` + +In Python, this might be used like: + +```python +>>> import mymodule +>>> mc = mymodule.MyClass() +>>> print(mc.method(44, False, "World", 666, x=44, y=55)) +py_args=('World', 666), py_kwargs=Some({'x': 44, 'y': 55}), name=Hello, num=44, num_before=-1 +>>> print(mc.method(num=-1, name="World")) +py_args=(), py_kwargs=None, name=World, num=-1, num_before=44 +``` + +The [`#[pyo3(text_signature = "...")`](./function/signature.md#overriding-the-generated-signature) option for `#[pyfunction]` also works for `#[pymethods]`. + +```rust +# #![allow(dead_code)] +use pyo3::prelude::*; +use pyo3::types::PyType; + +#[pyclass] +struct MyClass {} + +#[pymethods] +impl MyClass { + #[new] + #[pyo3(text_signature = "(c, d)")] + fn new(c: i32, d: &str) -> Self { + Self {} + } + // the self argument should be written $self + #[pyo3(text_signature = "($self, e, f)")] + fn my_method(&self, e: i32, f: i32) -> i32 { + e + f + } + // similarly for classmethod arguments, use $cls + #[classmethod] + #[pyo3(text_signature = "($cls, e, f)")] + fn my_class_method(cls: &Bound<'_, PyType>, e: i32, f: i32) -> i32 { + e + f + } + #[staticmethod] + #[pyo3(text_signature = "(e, f)")] + fn my_static_method(e: i32, f: i32) -> i32 { + e + f + } +} +# +# fn main() -> PyResult<()> { +# Python::attach(|py| { +# let inspect = PyModule::import(py, "inspect")?.getattr("signature")?; +# let module = PyModule::new(py, "my_module")?; +# module.add_class::()?; +# let class = module.getattr("MyClass")?; +# +# if cfg!(not(Py_LIMITED_API)) || py.version_info() >= (3, 10) { +# let doc: String = class.getattr("__doc__")?.extract()?; +# assert_eq!(doc, ""); +# +# let sig: String = inspect +# .call1((&class,))? +# .call_method0("__str__")? +# .extract()?; +# assert_eq!(sig, "(c, d)"); +# } else { +# let doc: String = class.getattr("__doc__")?.extract()?; +# assert_eq!(doc, ""); +# +# inspect.call1((&class,)).expect_err("`text_signature` on classes is not compatible with compilation in `abi3` mode until Python 3.10 or greater"); +# } +# +# { +# let method = class.getattr("my_method")?; +# +# assert!(method.getattr("__doc__")?.is_none()); +# +# let sig: String = inspect +# .call1((method,))? +# .call_method0("__str__")? +# .extract()?; +# assert_eq!(sig, "(self, /, e, f)"); +# } +# +# { +# let method = class.getattr("my_class_method")?; +# +# assert!(method.getattr("__doc__")?.is_none()); +# +# let sig: String = inspect +# .call1((method,))? +# .call_method0("__str__")? +# .extract()?; +# assert_eq!(sig, "(e, f)"); // inspect.signature skips the $cls arg +# } +# +# { +# let method = class.getattr("my_static_method")?; +# +# assert!(method.getattr("__doc__")?.is_none()); +# +# let sig: String = inspect +# .call1((method,))? +# .call_method0("__str__")? +# .extract()?; +# assert_eq!(sig, "(e, f)"); +# } +# +# Ok(()) +# }) +# } +``` + +Note that `text_signature` on `#[new]` is not compatible with compilation in `abi3` mode until Python 3.10 or greater. + +### Method receivers and lifetime elision + +PyO3 supports writing instance methods using the normal method receivers for shared `&self` and unique `&mut self` references. +This interacts with [lifetime elision][lifetime-elision] insofar as the lifetime of a such a receiver is assigned to all elided output lifetime parameters. + +This is a good default for general Rust code where return values are more likely to borrow from the receiver than from the other arguments, if they contain any lifetimes at all. +However, when returning bound references `Bound<'py, T>` in PyO3-based code, the Python lifetime `'py` should usually be derived from a `py: Python<'py>` token passed as an argument instead of the receiver. + +Specifically, signatures like + +```rust,ignore +fn frobnicate(&self, py: Python) -> Bound; +``` + +will not work as they are inferred as + +```rust,ignore +fn frobnicate<'a, 'py>(&'a self, py: Python<'py>) -> Bound<'a, Foo>; +``` + +instead of the intended + +```rust,ignore +fn frobnicate<'a, 'py>(&'a self, py: Python<'py>) -> Bound<'py, Foo>; +``` + +and should usually be written as + +```rust,ignore +fn frobnicate<'py>(&self, py: Python<'py>) -> Bound<'py, Foo>; +``` + +The same problem does not exist for `#[pyfunction]`s as the special case for receiver lifetimes does not apply and indeed a signature like + +```rust,ignore +fn frobnicate(bar: &Bar, py: Python) -> Bound; +``` + +will yield compiler error [E0106 "missing lifetime specifier"][compiler-error-e0106]. + +## `#[pyclass]` enums + +Enum support in PyO3 comes in two flavors, depending on what kind of variants the enum has: simple and complex. + +### Simple enums + +A simple enum (a.k.a. +C-like enum) has only unit variants. + +PyO3 adds a class attribute for each variant, so you can access them in Python without defining `#[new]`. +PyO3 also provides default implementations of `__richcmp__` and `__int__`, so they can be compared using `==`: + +```rust +# use pyo3::prelude::*; +#[pyclass(eq, eq_int)] +#[derive(PartialEq)] +enum MyEnum { + Variant, + OtherVariant, +} + +Python::attach(|py| { + let x = Py::new(py, MyEnum::Variant).unwrap(); + let y = Py::new(py, MyEnum::OtherVariant).unwrap(); + let cls = py.get_type::(); + pyo3::py_run!(py, x y cls, r#" + assert x == cls.Variant + assert y == cls.OtherVariant + assert x != y + "#) +}) +``` + +You can also convert your simple enums into `int`: + +```rust +# use pyo3::prelude::*; +#[pyclass(eq, eq_int)] +#[derive(PartialEq)] +enum MyEnum { + Variant, + OtherVariant = 10, +} + +Python::attach(|py| { + let cls = py.get_type::(); + let x = MyEnum::Variant as i32; // The exact value is assigned by the compiler. + pyo3::py_run!(py, cls x, r#" + assert int(cls.Variant) == x + assert int(cls.OtherVariant) == 10 + "#) +}) +``` + +PyO3 also provides `__repr__` for enums: + +```rust +# use pyo3::prelude::*; +#[pyclass(eq, eq_int)] +#[derive(PartialEq)] +enum MyEnum{ + Variant, + OtherVariant, +} + +Python::attach(|py| { + let cls = py.get_type::(); + let x = Py::new(py, MyEnum::Variant).unwrap(); + pyo3::py_run!(py, cls x, r#" + assert repr(x) == 'MyEnum.Variant' + assert repr(cls.OtherVariant) == 'MyEnum.OtherVariant' + "#) +}) +``` + +All methods defined by PyO3 can be overridden. +For example here's how you override `__repr__`: + +```rust +# use pyo3::prelude::*; +#[pyclass(eq, eq_int)] +#[derive(PartialEq)] +enum MyEnum { + Answer = 42, +} + +#[pymethods] +impl MyEnum { + fn __repr__(&self) -> &'static str { + "42" + } +} + +Python::attach(|py| { + let cls = py.get_type::(); + pyo3::py_run!(py, cls, "assert repr(cls.Answer) == '42'") +}) +``` + +Enums and their variants can also be renamed using `#[pyo3(name)]`. + +```rust +# use pyo3::prelude::*; +#[pyclass(eq, eq_int, name = "RenamedEnum")] +#[derive(PartialEq)] +enum MyEnum { + #[pyo3(name = "UPPERCASE")] + Variant, +} + +Python::attach(|py| { + let x = Py::new(py, MyEnum::Variant).unwrap(); + let cls = py.get_type::(); + pyo3::py_run!(py, x cls, r#" + assert repr(x) == 'RenamedEnum.UPPERCASE' + assert x == cls.UPPERCASE + "#) +}) +``` + +Ordering of enum variants is optionally added using `#[pyo3(ord)]`. +*Note: Implementation of the `PartialOrd` trait is required when passing the `ord` argument.* +*If not implemented, a compile time error is raised.* + +```rust +# use pyo3::prelude::*; +#[pyclass(eq, ord)] +#[derive(PartialEq, PartialOrd)] +enum MyEnum{ + A, + B, + C, +} + +Python::attach(|py| { + let cls = py.get_type::(); + let a = Py::new(py, MyEnum::A).unwrap(); + let b = Py::new(py, MyEnum::B).unwrap(); + let c = Py::new(py, MyEnum::C).unwrap(); + pyo3::py_run!(py, cls a b c, r#" + assert (a < b) == True + assert (c <= b) == False + assert (c > a) == True + "#) +}) +``` + +You may not use enums as a base class or let enums inherit from other classes. + +```rust,compile_fail +# use pyo3::prelude::*; +#[pyclass(subclass)] +enum BadBase { + Var1, +} +``` + +```rust,compile_fail +# use pyo3::prelude::*; + +#[pyclass(subclass)] +struct Base; + +#[pyclass(extends=Base)] +enum BadSubclass { + Var1, +} +``` + +`#[pyclass]` enums are currently not interoperable with `IntEnum` in Python. + +### Complex enums + +An enum is complex if it has any non-unit (struct or tuple) variants. + +PyO3 supports only struct and tuple variants in a complex enum. +Unit variants aren't supported at present (the recommendation is to use an empty tuple enum instead). + +PyO3 adds a class attribute for each variant, which may be used to construct values and in match patterns. +PyO3 also provides getter methods for all fields of each variant. + +```rust +# use pyo3::prelude::*; +#[pyclass] +enum Shape { + Circle { radius: f64 }, + Rectangle { width: f64, height: f64 }, + RegularPolygon(u32, f64), + Nothing { }, +} + +# #[cfg(Py_3_10)] +Python::attach(|py| { + let circle = Shape::Circle { radius: 10.0 }.into_pyobject(py)?; + let square = Shape::RegularPolygon(4, 10.0).into_pyobject(py)?; + let cls = py.get_type::(); + pyo3::py_run!(py, circle square cls, r#" + assert isinstance(circle, cls) + assert isinstance(circle, cls.Circle) + assert circle.radius == 10.0 + + assert isinstance(square, cls) + assert isinstance(square, cls.RegularPolygon) + assert square[0] == 4 # Gets _0 field + assert square[1] == 10.0 # Gets _1 field + + def count_vertices(cls, shape): + match shape: + case cls.Circle(): + return 0 + case cls.Rectangle(): + return 4 + case cls.RegularPolygon(n): + return n + case cls.Nothing(): + return 0 + + assert count_vertices(cls, circle) == 0 + assert count_vertices(cls, square) == 4 + "#); +# Ok::<_, PyErr>(()) +}) +# .unwrap(); +``` + +WARNING: `Py::new` and `.into_pyobject` are currently inconsistent. +Note how the constructed value is *not* an instance of the specific variant. +For this reason, constructing values is only recommended using `.into_pyobject`. + +```rust +# use pyo3::prelude::*; +#[pyclass] +enum MyEnum { + Variant { i: i32 }, +} + +Python::attach(|py| { + let x = Py::new(py, MyEnum::Variant { i: 42 }).unwrap(); + let cls = py.get_type::(); + pyo3::py_run!(py, x cls, r#" + assert isinstance(x, cls) + assert not isinstance(x, cls.Variant) + "#) +}) +``` + +The constructor of each generated class can be customized using the `#[pyo3(constructor = (...))]` attribute. +This uses the same syntax as the [`#[pyo3(signature = (...))]`](function/signature.md) attribute on function and methods and supports the same options. +To apply this attribute simply place it on top of a variant in a `#[pyclass]` complex enum as shown below: + +```rust +# use pyo3::prelude::*; +#[pyclass] +enum Shape { + #[pyo3(constructor = (radius=1.0))] + Circle { radius: f64 }, + #[pyo3(constructor = (*, width, height))] + Rectangle { width: f64, height: f64 }, + #[pyo3(constructor = (side_count, radius=1.0))] + RegularPolygon { side_count: u32, radius: f64 }, + Nothing { }, +} + +# #[cfg(Py_3_10)] +Python::attach(|py| { + let cls = py.get_type::(); + pyo3::py_run!(py, cls, r#" + circle = cls.Circle() + assert isinstance(circle, cls) + assert isinstance(circle, cls.Circle) + assert circle.radius == 1.0 + + square = cls.Rectangle(width = 1, height = 1) + assert isinstance(square, cls) + assert isinstance(square, cls.Rectangle) + assert square.width == 1 + assert square.height == 1 + + hexagon = cls.RegularPolygon(6) + assert isinstance(hexagon, cls) + assert isinstance(hexagon, cls.RegularPolygon) + assert hexagon.side_count == 6 + assert hexagon.radius == 1 + "#) +}) +``` + +## Implementation details + +The `#[pyclass]` macros rely on a lot of conditional code generation: each `#[pyclass]` can optionally have a `#[pymethods]` block. + +To support this flexibility the `#[pyclass]` macro expands to a blob of boilerplate code which sets up the structure for ["dtolnay specialization"](https://github.com/dtolnay/case-studies/blob/master/autoref-specialization/README.md). +This implementation pattern enables the Rust compiler to use `#[pymethods]` implementations when they are present, and fall back to default (empty) definitions when they are not. + +This simple technique works for the case when there is zero or one implementations. +To support multiple `#[pymethods]` for a `#[pyclass]` (in the [`multiple-pymethods`] feature), a registry mechanism provided by the [`inventory`](https://github.com/dtolnay/inventory) crate is used instead. +This collects `impl`s at library load time, but isn't supported on all platforms. +See [inventory: how it works](https://github.com/dtolnay/inventory#how-it-works) for more details. + +The `#[pyclass]` macro expands to roughly the code seen below. +The `PyClassImplCollector` is the type used internally by PyO3 for dtolnay specialization: + +```rust +# #[cfg(not(feature = "multiple-pymethods"))] { +# use pyo3::prelude::*; +// Note: the implementation differs slightly with the `multiple-pymethods` feature enabled. +# #[allow(dead_code)] +struct MyClass { + # #[allow(dead_code)] + num: i32, +} + +impl pyo3::types::DerefToPyAny for MyClass {} + +unsafe impl pyo3::type_object::PyTypeInfo for MyClass { + const NAME: &'static str = "MyClass"; + const MODULE: ::std::option::Option<&'static str> = ::std::option::Option::None; + + #[inline] + fn type_object_raw(py: pyo3::Python<'_>) -> *mut pyo3::ffi::PyTypeObject { + ::lazy_type_object() + .get_or_try_init(py) + .unwrap_or_else(|e| pyo3::impl_::pyclass::type_object_init_failed( + py, + e, + ::NAME + )) + .as_type_ptr() + } +} + +impl pyo3::PyClass for MyClass { + const NAME: &str = "MyClass"; + type Frozen = pyo3::pyclass::boolean_struct::False; +} + +impl pyo3::impl_::pyclass::PyClassImpl for MyClass { + const MODULE: Option<&str> = None; + const IS_BASETYPE: bool = false; + const IS_SUBCLASS: bool = false; + const IS_MAPPING: bool = false; + const IS_SEQUENCE: bool = false; + type Layout = ::Layout; + type BaseType = PyAny; + type ThreadChecker = pyo3::impl_::pyclass::NoopThreadChecker; + type PyClassMutability = <::PyClassMutability as pyo3::impl_::pycell::PyClassMutability>::MutableChild; + type Dict = pyo3::impl_::pyclass::PyClassDummySlot; + type WeakRef = pyo3::impl_::pyclass::PyClassDummySlot; + type BaseNativeType = pyo3::PyAny; + + const RAW_DOC: &'static std::ffi::CStr = c"..."; + const DOC: &'static std::ffi::CStr = c"..."; + + fn items_iter() -> pyo3::impl_::pyclass::PyClassItemsIter { + use pyo3::impl_::pyclass::*; + let collector = PyClassImplCollector::::new(); + static INTRINSIC_ITEMS: PyClassItems = PyClassItems { slots: &[], methods: &[] }; + PyClassItemsIter::new(&INTRINSIC_ITEMS, collector.py_methods()) + } + + fn lazy_type_object() -> &'static pyo3::impl_::pyclass::LazyTypeObject { + use pyo3::impl_::pyclass::LazyTypeObject; + static TYPE_OBJECT: LazyTypeObject = LazyTypeObject::new(); + &TYPE_OBJECT + } +} + +# Python::attach(|py| { +# let cls = py.get_type::(); +# pyo3::py_run!(py, cls, "assert cls.__name__ == 'MyClass'") +# }); +# } +``` + +[`PyTypeInfo`]: {{#PYO3_DOCS_URL}}/pyo3/type_object/trait.PyTypeInfo.html + +[`Py`]: {{#PYO3_DOCS_URL}}/pyo3/struct.Py.html +[`Bound<'py, T>`]: {{#PYO3_DOCS_URL}}/pyo3/struct.Bound.html +[`PyClass`]: {{#PYO3_DOCS_URL}}/pyo3/pyclass/trait.PyClass.html +[`PyRef`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRef.html +[`PyRefMut`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRefMut.html +[`PyClassInitializer`]: {{#PYO3_DOCS_URL}}/pyo3/pyclass_init/struct.PyClassInitializer.html + +[`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html + +[classattr]: https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables + +[`multiple-pymethods`]: features.md#multiple-pymethods + +[lifetime-elision]: https://doc.rust-lang.org/reference/lifetime-elision.html +[compiler-error-e0106]: https://doc.rust-lang.org/error_codes/E0106.html diff --git a/vendor/pyo3/guide/src/class/call.md b/vendor/pyo3/guide/src/class/call.md new file mode 100644 index 0000000..672a9fa --- /dev/null +++ b/vendor/pyo3/guide/src/class/call.md @@ -0,0 +1,126 @@ +# Emulating callable objects + +Classes can be callable if they have a `#[pymethod]` named `__call__`. +This allows instances of a class to behave similar to functions. + +This method's signature must look like `__call__(, ...) -> object` - here, any argument list can be defined as for normal pymethods + +## Example: Implementing a call counter + +The following pyclass is a basic decorator - its constructor takes a Python object as argument and calls that object when called. +An equivalent Python implementation is linked at the end. + +An example crate containing this pyclass can be found [in the PyO3 GitHub repository](https://github.com/PyO3/pyo3/tree/main/examples/decorator) + +```rust,ignore +{{#include ../../../examples/decorator/src/lib.rs}} +``` + +Python code: + +```python +{{#include ../../../examples/decorator/tests/example.py}} +``` + +Output: + +```text +say_hello has been called 1 time(s). +hello +say_hello has been called 2 time(s). +hello +say_hello has been called 3 time(s). +hello +say_hello has been called 4 time(s). +hello +``` + +### Pure Python implementation + +A Python implementation of this looks similar to the Rust version: + +```python +class Counter: + def __init__(self, wraps): + self.count = 0 + self.wraps = wraps + + def __call__(self, *args, **kwargs): + self.count += 1 + print(f"{self.wraps.__name__} has been called {self.count} time(s)") + self.wraps(*args, **kwargs) +``` + +Note that it can also be implemented as a higher order function: + +```python +def Counter(wraps): + count = 0 + def call(*args, **kwargs): + nonlocal count + count += 1 + print(f"{wraps.__name__} has been called {count} time(s)") + return wraps(*args, **kwargs) + return call +``` + +### What is the `AtomicU64` for? + +A [previous implementation] used a normal `u64`, which meant it required a `&mut self` receiver to update the count: + +```rust,ignore +#[pyo3(signature = (*args, **kwargs))] +fn __call__( + &mut self, + py: Python<'_>, + args: &Bound<'_, PyTuple>, + kwargs: Option<&Bound<'_, PyDict>>, +) -> PyResult> { + self.count += 1; + let name = self.wraps.getattr(py, "__name__")?; + + println!("{} has been called {} time(s).", name, self.count); + + // After doing something, we finally forward the call to the wrapped function + let ret = self.wraps.call(py, args, kwargs)?; + + // We could do something with the return value of + // the function before returning it + Ok(ret) +} +``` + +The problem with this is that the `&mut self` receiver means PyO3 has to borrow it exclusively, and hold this borrow across the `self.wraps.call(py, args, kwargs)` call. +This call returns control to the user's Python code which is free to call arbitrary things, *including* the decorated function. +If that happens PyO3 is unable to create a second unique borrow and will be forced to raise an exception. + +As a result, something innocent like this will raise an exception: + +```py +@Counter +def say_hello(): + if say_hello.count < 2: + print(f"hello from decorator") + +say_hello() +# RuntimeError: Already borrowed +``` + +The implementation in this chapter fixes that by never borrowing exclusively; all the methods take `&self` as receivers, of which multiple may exist simultaneously. +This requires a shared counter and the most straightforward way to implement thread-safe interior mutability (e.g. the type does not need to accept `&mut self` to modify the "interior" state) for a `u64` is to use [`AtomicU64`], so that's what is used here. + +This shows the dangers of running arbitrary Python code - note that "running arbitrary Python code" can be far more subtle than the example above: + +- Python's asynchronous executor may park the current thread in the middle of Python code, even in Python code that *you* control, and let other Python code run. +- Dropping arbitrary Python objects may invoke destructors defined in Python (`__del__` methods). +- Calling Python's C-api (most PyO3 apis call C-api functions internally) may raise exceptions, which may allow Python code in signal handlers to run. +- On the free-threaded build, users might use Python's `threading` module to work with your types simultaneously from multiple OS threads. + +This is especially important if you are writing unsafe code; Python code must never be able to cause undefined behavior. +You must ensure that your Rust code is in a consistent state before doing any of the above things. + + + +[previous implementation]: "Thread Safe Decorator · Discussion #2598 · PyO3/pyo3" +[`AtomicU64`]: "AtomicU64 in std::sync::atomic - Rust" + diff --git a/vendor/pyo3/guide/src/class/numeric.md b/vendor/pyo3/guide/src/class/numeric.md new file mode 100644 index 0000000..8957838 --- /dev/null +++ b/vendor/pyo3/guide/src/class/numeric.md @@ -0,0 +1,451 @@ +# Emulating numeric types + +At this point we have a `Number` class that we can't actually do any math on! + +Before proceeding, we should think about how we want to handle overflows. +There are three obvious solutions: + +- We can have infinite precision just like Python's `int`. + + However that would be quite boring - we'd be reinventing the wheel. +- We can raise exceptions whenever `Number` overflows, but that makes the API painful to use. +- We can wrap around the boundary of `i32`. + This is the approach we'll take here. + To do that we'll just forward to `i32`'s `wrapping_*` methods. + +## Fixing our constructor + +Let's address the first overflow, in `Number`'s constructor: + +```python +from my_module import Number + +n = Number(1 << 1337) +``` + +```text +Traceback (most recent call last): + File "example.py", line 3, in + n = Number(1 << 1337) +OverflowError: Python int too large to convert to C long +``` + +Instead of relying on the default [`FromPyObject`] extraction to parse arguments, we can specify our own extraction function, using the `#[pyo3(from_py_with = ...)]` attribute. +Unfortunately PyO3 doesn't provide a way to wrap Python integers out of the box, but we can do a Python call to mask it and cast it to an `i32`. + +```rust,no_run +# #![allow(dead_code)] +use pyo3::prelude::*; + +fn wrap(obj: &Bound<'_, PyAny>) -> PyResult { + let val = obj.call_method1("__and__", (0xFFFFFFFF_u32,))?; + let val: u32 = val.extract()?; + // 👇 This intentionally overflows! + Ok(val as i32) +} +``` + +We also add documentation, via `///` comments, which are visible to Python users. + +```rust,no_run +# #![allow(dead_code)] +use pyo3::prelude::*; + +fn wrap(obj: &Bound<'_, PyAny>) -> PyResult { + let val = obj.call_method1("__and__", (0xFFFFFFFF_u32,))?; + let val: u32 = val.extract()?; + Ok(val as i32) +} + +/// Did you ever hear the tragedy of Darth Signed The Overfloweth? I thought not. +/// It's not a story C would tell you. It's a Rust legend. +#[pyclass(module = "my_module")] +struct Number(i32); + +#[pymethods] +impl Number { + #[new] + fn new(#[pyo3(from_py_with = wrap)] value: i32) -> Self { + Self(value) + } +} +``` + +With that out of the way, let's implement some operators: + +```rust,no_run +use pyo3::exceptions::{PyZeroDivisionError, PyValueError}; + +# use pyo3::prelude::*; +# +# #[pyclass] +# struct Number(i32); +# +#[pymethods] +impl Number { + fn __add__(&self, other: &Self) -> Self { + Self(self.0.wrapping_add(other.0)) + } + + fn __sub__(&self, other: &Self) -> Self { + Self(self.0.wrapping_sub(other.0)) + } + + fn __mul__(&self, other: &Self) -> Self { + Self(self.0.wrapping_mul(other.0)) + } + + fn __truediv__(&self, other: &Self) -> PyResult { + match self.0.checked_div(other.0) { + Some(i) => Ok(Self(i)), + None => Err(PyZeroDivisionError::new_err("division by zero")), + } + } + + fn __floordiv__(&self, other: &Self) -> PyResult { + match self.0.checked_div(other.0) { + Some(i) => Ok(Self(i)), + None => Err(PyZeroDivisionError::new_err("division by zero")), + } + } + + fn __rshift__(&self, other: &Self) -> PyResult { + match other.0.try_into() { + Ok(rhs) => Ok(Self(self.0.wrapping_shr(rhs))), + Err(_) => Err(PyValueError::new_err("negative shift count")), + } + } + + fn __lshift__(&self, other: &Self) -> PyResult { + match other.0.try_into() { + Ok(rhs) => Ok(Self(self.0.wrapping_shl(rhs))), + Err(_) => Err(PyValueError::new_err("negative shift count")), + } + } +} +``` + +### Unary arithmetic operations + +```rust,no_run +# use pyo3::prelude::*; +# +# #[pyclass] +# struct Number(i32); +# +#[pymethods] +impl Number { + fn __pos__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { + slf + } + + fn __neg__(&self) -> Self { + Self(-self.0) + } + + fn __abs__(&self) -> Self { + Self(self.0.abs()) + } + + fn __invert__(&self) -> Self { + Self(!self.0) + } +} +``` + +### Support for the `complex()`, `int()` and `float()` built-in functions + +```rust,no_run +# use pyo3::prelude::*; +# +# #[pyclass] +# struct Number(i32); +# +use pyo3::types::PyComplex; + +#[pymethods] +impl Number { + fn __int__(&self) -> i32 { + self.0 + } + + fn __float__(&self) -> f64 { + self.0 as f64 + } + + fn __complex__<'py>(&self, py: Python<'py>) -> Bound<'py, PyComplex> { + PyComplex::from_doubles(py, self.0 as f64, 0.0) + } +} +``` + +We do not implement the in-place operations like `__iadd__` because we do not wish to mutate `Number`. +Similarly we're not interested in supporting operations with different types, so we do not implement the reflected operations like `__radd__` either. + +Now Python can use our `Number` class: + +```python +from my_module import Number + +def hash_djb2(s: str): + ''' + A version of Daniel J. Bernstein's djb2 string hashing algorithm + Like many hashing algorithms, it relies on integer wrapping. + ''' + + n = Number(0) + five = Number(5) + + for x in s: + n = Number(ord(x)) + ((n << five) - n) + return n + +assert hash_djb2('l50_50') == Number(-1152549421) +``` + +### Final code + +```rust +use std::collections::hash_map::DefaultHasher; +use std::hash::{Hash, Hasher}; + +use pyo3::exceptions::{PyValueError, PyZeroDivisionError}; +use pyo3::prelude::*; +use pyo3::class::basic::CompareOp; +use pyo3::types::{PyComplex, PyString}; + +fn wrap(obj: &Bound<'_, PyAny>) -> PyResult { + let val = obj.call_method1("__and__", (0xFFFFFFFF_u32,))?; + let val: u32 = val.extract()?; + Ok(val as i32) +} +/// Did you ever hear the tragedy of Darth Signed The Overfloweth? I thought not. +/// It's not a story C would tell you. It's a Rust legend. +#[pyclass(module = "my_module")] +struct Number(i32); + +#[pymethods] +impl Number { + #[new] + fn new(#[pyo3(from_py_with = wrap)] value: i32) -> Self { + Self(value) + } + + fn __repr__(slf: &Bound<'_, Self>) -> PyResult { + // Get the class name dynamically in case `Number` is subclassed + let class_name: Bound<'_, PyString> = slf.get_type().qualname()?; + Ok(format!("{}({})", class_name, slf.borrow().0)) + } + + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __hash__(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.0.hash(&mut hasher); + hasher.finish() + } + + fn __richcmp__(&self, other: &Self, op: CompareOp) -> PyResult { + match op { + CompareOp::Lt => Ok(self.0 < other.0), + CompareOp::Le => Ok(self.0 <= other.0), + CompareOp::Eq => Ok(self.0 == other.0), + CompareOp::Ne => Ok(self.0 != other.0), + CompareOp::Gt => Ok(self.0 > other.0), + CompareOp::Ge => Ok(self.0 >= other.0), + } + } + + fn __bool__(&self) -> bool { + self.0 != 0 + } + + fn __add__(&self, other: &Self) -> Self { + Self(self.0.wrapping_add(other.0)) + } + + fn __sub__(&self, other: &Self) -> Self { + Self(self.0.wrapping_sub(other.0)) + } + + fn __mul__(&self, other: &Self) -> Self { + Self(self.0.wrapping_mul(other.0)) + } + + fn __truediv__(&self, other: &Self) -> PyResult { + match self.0.checked_div(other.0) { + Some(i) => Ok(Self(i)), + None => Err(PyZeroDivisionError::new_err("division by zero")), + } + } + + fn __floordiv__(&self, other: &Self) -> PyResult { + match self.0.checked_div(other.0) { + Some(i) => Ok(Self(i)), + None => Err(PyZeroDivisionError::new_err("division by zero")), + } + } + + fn __rshift__(&self, other: &Self) -> PyResult { + match other.0.try_into() { + Ok(rhs) => Ok(Self(self.0.wrapping_shr(rhs))), + Err(_) => Err(PyValueError::new_err("negative shift count")), + } + } + + fn __lshift__(&self, other: &Self) -> PyResult { + match other.0.try_into() { + Ok(rhs) => Ok(Self(self.0.wrapping_shl(rhs))), + Err(_) => Err(PyValueError::new_err("negative shift count")), + } + } + + fn __xor__(&self, other: &Self) -> Self { + Self(self.0 ^ other.0) + } + + fn __or__(&self, other: &Self) -> Self { + Self(self.0 | other.0) + } + + fn __and__(&self, other: &Self) -> Self { + Self(self.0 & other.0) + } + + fn __int__(&self) -> i32 { + self.0 + } + + fn __float__(&self) -> f64 { + self.0 as f64 + } + + fn __complex__<'py>(&self, py: Python<'py>) -> Bound<'py, PyComplex> { + PyComplex::from_doubles(py, self.0 as f64, 0.0) + } +} + +#[pymodule] +mod my_module { + #[pymodule_export] + use super::Number; +} +# const SCRIPT: &'static std::ffi::CStr = cr#" +# def hash_djb2(s: str): +# n = Number(0) +# five = Number(5) +# +# for x in s: +# n = Number(ord(x)) + ((n << five) - n) +# return n +# +# assert hash_djb2('l50_50') == Number(-1152549421) +# assert hash_djb2('logo') == Number(3327403) +# assert hash_djb2('horizon') == Number(1097468315) +# +# +# assert Number(2) + Number(2) == Number(4) +# assert Number(2) + Number(2) != Number(5) +# +# assert Number(13) - Number(7) == Number(6) +# assert Number(13) - Number(-7) == Number(20) +# +# assert Number(13) / Number(7) == Number(1) +# assert Number(13) // Number(7) == Number(1) +# +# assert Number(13) * Number(7) == Number(13*7) +# +# assert Number(13) > Number(7) +# assert Number(13) < Number(20) +# assert Number(13) == Number(13) +# assert Number(13) >= Number(7) +# assert Number(13) <= Number(20) +# assert Number(13) == Number(13) +# +# +# assert (True if Number(1) else False) +# assert (False if Number(0) else True) +# +# +# assert int(Number(13)) == 13 +# assert float(Number(13)) == 13 +# assert Number.__doc__ == "Did you ever hear the tragedy of Darth Signed The Overfloweth? I thought not.\nIt's not a story C would tell you. It's a Rust legend." +# assert Number(12345234523452) == Number(1498514748) +# try: +# import inspect +# assert inspect.signature(Number).__str__() == '(value)' +# except ValueError: +# # Not supported with `abi3` before Python 3.10 +# pass +# assert Number(1337).__str__() == '1337' +# assert Number(1337).__repr__() == 'Number(1337)' +"#; + +# +# use pyo3::PyTypeInfo; +# +# fn main() -> PyResult<()> { +# Python::attach(|py| -> PyResult<()> { +# let globals = PyModule::import(py, "__main__")?.dict(); +# globals.set_item("Number", Number::type_object(py))?; +# +# py.run(SCRIPT, Some(&globals), None)?; +# Ok(()) +# }) +# } +``` + +## Appendix: Writing some unsafe code + +At the beginning of this chapter we said that PyO3 doesn't provide a way to wrap Python integers out of the box but that's a half truth. +There's not a PyO3 API for it, but there's a Python C API function that does: + +```c +unsigned long PyLong_AsUnsignedLongMask(PyObject *obj) +``` + +We can call this function from Rust by using [`pyo3::ffi::PyLong_AsUnsignedLongMask`]. +This is an *unsafe* function, which means we have to use an unsafe block to call it and take responsibility for upholding the contracts of this function. +Let's review those contracts: + +- We must be attached to the interpreter. + If we're not, calling this function causes a data race. +- The pointer must be valid, i.e. it must be properly aligned and point to a valid Python object. + +Let's create that helper function. +The signature has to be `fn(&Bound<'_, PyAny>) -> PyResult`. + +- `&Bound<'_, PyAny>` represents a checked bound reference, so the pointer derived from it is valid (and not null). +- Whenever we have bound references to Python objects in scope, it is guaranteed that we're attached to the interpreter. + This reference is also where we can get a [`Python`] token to use in our call to [`PyErr::take`]. + +```rust,no_run +# #![allow(dead_code)] +use std::ffi::c_ulong; +use pyo3::prelude::*; +use pyo3::ffi; + +fn wrap(obj: &Bound<'_, PyAny>) -> Result { + let py: Python<'_> = obj.py(); + + unsafe { + let ptr = obj.as_ptr(); + + let ret: c_ulong = ffi::PyLong_AsUnsignedLongMask(ptr); + if ret == c_ulong::MAX { + if let Some(err) = PyErr::take(py) { + return Err(err); + } + } + + Ok(ret as i32) + } +} +``` + +[`PyErr::take`]: {{#PYO3_DOCS_URL}}/pyo3/prelude/struct.PyErr.html#method.take +[`Python`]: {{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html +[`FromPyObject`]: {{#PYO3_DOCS_URL}}/pyo3/conversion/trait.FromPyObject.html +[`pyo3::ffi::PyLong_AsUnsignedLongMask`]: {{#PYO3_DOCS_URL}}/pyo3/ffi/fn.PyLong_AsUnsignedLongMask.html diff --git a/vendor/pyo3/guide/src/class/object.md b/vendor/pyo3/guide/src/class/object.md new file mode 100644 index 0000000..22eb810 --- /dev/null +++ b/vendor/pyo3/guide/src/class/object.md @@ -0,0 +1,394 @@ +# Basic object customization + +Recall the `Number` class from the previous chapter: + +```rust,no_run +# #![allow(dead_code)] +# fn main() {} +use pyo3::prelude::*; + +#[pyclass] +struct Number(i32); + +#[pymethods] +impl Number { + #[new] + fn new(value: i32) -> Self { + Self(value) + } +} + +#[pymodule] +mod my_module { + #[pymodule_export] + use super::Number; +} +``` + +At this point Python code can import the module, access the class and create class instances - but nothing else. + +```python +from my_module import Number + +n = Number(5) +print(n) +``` + +```text + +``` + +## String representations + +It can't even print an user-readable representation of itself! +We can fix that by defining the `__repr__` and `__str__` methods inside a `#[pymethods]` block. +We do this by accessing the value contained inside `Number`. + +```rust,no_run +# use pyo3::prelude::*; +# +# #[pyclass] +# struct Number(i32); +# +#[pymethods] +impl Number { + // For `__repr__` we want to return a string that Python code could use to recreate + // the `Number`, like `Number(5)` for example. + fn __repr__(&self) -> String { + // We use the `format!` macro to create a string. Its first argument is a + // format string, followed by any number of parameters which replace the + // `{}`'s in the format string. + // + // 👇 Tuple field access in Rust uses a dot + format!("Number({})", self.0) + } + // `__str__` is generally used to create an "informal" representation, so we + // just forward to `i32`'s `ToString` trait implementation to print a bare number. + fn __str__(&self) -> String { + self.0.to_string() + } +} +``` + +To automatically generate the `__str__` implementation using a `Display` trait implementation, pass the `str` argument to `pyclass`. + +```rust,no_run +# use std::fmt::{Display, Formatter}; +# use pyo3::prelude::*; +# +# #[allow(dead_code)] +#[pyclass(str)] +struct Coordinate { + x: i32, + y: i32, + z: i32, +} + +impl Display for Coordinate { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "({}, {}, {})", self.x, self.y, self.z) + } +} +``` + +For convenience, a shorthand format string can be passed to `str` as `str=""` for **structs only**. +It expands and is passed into the `format!` macro in the following ways: + +- `"{x}"` -> `"{}", self.x` +- `"{0}"` -> `"{}", self.0` +- `"{x:?}"` -> `"{:?}", self.x` + +*Note: Depending upon the format string you use, this may require implementation of the `Display` or `Debug` traits for the given Rust types.* +*Note: the pyclass args `name` and `rename_all` are incompatible with the shorthand format string and will raise a compile time error.* + +```rust,no_run +# use pyo3::prelude::*; +# +# #[allow(dead_code)] +#[pyclass(str="({x}, {y}, {z})")] +struct Coordinate { + x: i32, + y: i32, + z: i32, +} +``` + +### Accessing the class name + +In the `__repr__`, we used a hard-coded class name. +This is sometimes not ideal, because if the class is subclassed in Python, we would like the repr to reflect the subclass name. +This is typically done in Python code by accessing `self.__class__.__name__`. +In order to be able to access the Python type information *and* the Rust struct, we need to use a `Bound` as the `self` argument. + +```rust,no_run +# use pyo3::prelude::*; +# use pyo3::types::PyString; +# +# #[allow(dead_code)] +# #[pyclass] +# struct Number(i32); +# +#[pymethods] +impl Number { + fn __repr__(slf: &Bound<'_, Self>) -> PyResult { + // This is the equivalent of `self.__class__.__name__` in Python. + let class_name: Bound<'_, PyString> = slf.get_type().qualname()?; + // To access fields of the Rust struct, we need to borrow from the Bound object. + Ok(format!("{}({})", class_name, slf.borrow().0)) + } +} +``` + +### Hashing + +Let's also implement hashing. +We'll just hash the `i32`. +For that we need a [`Hasher`]. +The one provided by `std` is [`DefaultHasher`], which uses the [SipHash] algorithm. + +```rust,no_run +use std::collections::hash_map::DefaultHasher; + +// Required to call the `.hash` and `.finish` methods, which are defined on traits. +use std::hash::{Hash, Hasher}; + +# use pyo3::prelude::*; +# +# #[allow(dead_code)] +# #[pyclass] +# struct Number(i32); +# +#[pymethods] +impl Number { + fn __hash__(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.0.hash(&mut hasher); + hasher.finish() + } +} +``` + +To implement `__hash__` using the Rust [`Hash`] trait implementation, the `hash` option can be used. +This option is only available for `frozen` classes to prevent accidental hash changes from mutating the object. +If you need an `__hash__` implementation for a mutable class, use the manual method from above. +This option also requires `eq`: According to the [Python docs](https://docs.python.org/3/reference/datamodel.html#object.__hash__) "If a class does not define an `__eq__()` method it should not define a `__hash__()` operation either" + +```rust,no_run +# use pyo3::prelude::*; +# +# #[allow(dead_code)] +#[pyclass(frozen, eq, hash)] +#[derive(PartialEq, Hash)] +struct Number(i32); +``` + +> [!NOTE] +> When implementing `__hash__` and comparisons, it is important that the following property holds: +> +> ```text +> k1 == k2 -> hash(k1) == hash(k2) +> ``` +> +> In other words, if two keys are equal, their hashes must also be equal. In addition you must take +> care that your classes' hash doesn't change during its lifetime. In this tutorial we do that by not +> letting Python code change our `Number` class. In other words, it is immutable. +> +> By default, all `#[pyclass]` types have a default hash implementation from Python. +> Types which should not be hashable can override this by setting `__hash__` to None. +> This is the same mechanism as for a pure-Python class. This is done like so: +> +> ```rust,no_run +> # use pyo3::prelude::*; +> #[pyclass] +> struct NotHashable {} +> +> #[pymethods] +> impl NotHashable { +> #[classattr] +> const __hash__: Option> = None; +> } +> ``` + +### Comparisons + +PyO3 supports the usual magic comparison methods available in Python such as `__eq__`, `__lt__` and so on. +It is also possible to support all six operations at once with `__richcmp__`. +This method will be called with a value of `CompareOp` depending on the operation. + +```rust,no_run +use pyo3::class::basic::CompareOp; + +# use pyo3::prelude::*; +# +# #[allow(dead_code)] +# #[pyclass] +# struct Number(i32); +# +#[pymethods] +impl Number { + fn __richcmp__(&self, other: &Self, op: CompareOp) -> PyResult { + match op { + CompareOp::Lt => Ok(self.0 < other.0), + CompareOp::Le => Ok(self.0 <= other.0), + CompareOp::Eq => Ok(self.0 == other.0), + CompareOp::Ne => Ok(self.0 != other.0), + CompareOp::Gt => Ok(self.0 > other.0), + CompareOp::Ge => Ok(self.0 >= other.0), + } + } +} +``` + +If you obtain the result by comparing two Rust values, as in this example, you can take a shortcut using `CompareOp::matches`: + +```rust,no_run +use pyo3::class::basic::CompareOp; + +# use pyo3::prelude::*; +# +# #[allow(dead_code)] +# #[pyclass] +# struct Number(i32); +# +#[pymethods] +impl Number { + fn __richcmp__(&self, other: &Self, op: CompareOp) -> bool { + op.matches(self.0.cmp(&other.0)) + } +} +``` + +It checks that the `std::cmp::Ordering` obtained from Rust's `Ord` matches the given `CompareOp`. + +Alternatively, you can implement just equality using `__eq__`: + +```rust +# use pyo3::prelude::*; +# +# #[pyclass] +# struct Number(i32); +# +#[pymethods] +impl Number { + fn __eq__(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +# fn main() -> PyResult<()> { +# Python::attach(|py| { +# let x = &Bound::new(py, Number(4))?; +# let y = &Bound::new(py, Number(4))?; +# assert!(x.eq(y)?); +# assert!(!x.ne(y)?); +# Ok(()) +# }) +# } +``` + +To implement `__eq__` using the Rust [`PartialEq`] trait implementation, the `eq` option can be used. + +```rust,no_run +# use pyo3::prelude::*; +# +# #[allow(dead_code)] +#[pyclass(eq)] +#[derive(PartialEq)] +struct Number(i32); +``` + +To implement `__lt__`, `__le__`, `__gt__`, & `__ge__` using the Rust `PartialOrd` trait implementation, the `ord` option can be used. +*Note: Requires `eq`.* + +```rust,no_run +# use pyo3::prelude::*; +# +# #[allow(dead_code)] +#[pyclass(eq, ord)] +#[derive(PartialEq, PartialOrd)] +struct Number(i32); +``` + +### Truthyness + +We'll consider `Number` to be `True` if it is nonzero: + +```rust,no_run +# use pyo3::prelude::*; +# +# #[allow(dead_code)] +# #[pyclass] +# struct Number(i32); +# +#[pymethods] +impl Number { + fn __bool__(&self) -> bool { + self.0 != 0 + } +} +``` + +### Final code + +```rust,no_run +# fn main() {} +use std::collections::hash_map::DefaultHasher; +use std::hash::{Hash, Hasher}; + +use pyo3::prelude::*; +use pyo3::class::basic::CompareOp; +use pyo3::types::PyString; + +#[pyclass] +struct Number(i32); + +#[pymethods] +impl Number { + #[new] + fn new(value: i32) -> Self { + Self(value) + } + + fn __repr__(slf: &Bound<'_, Self>) -> PyResult { + let class_name: Bound<'_, PyString> = slf.get_type().qualname()?; + Ok(format!("{}({})", class_name, slf.borrow().0)) + } + + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __hash__(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.0.hash(&mut hasher); + hasher.finish() + } + + fn __richcmp__(&self, other: &Self, op: CompareOp) -> PyResult { + match op { + CompareOp::Lt => Ok(self.0 < other.0), + CompareOp::Le => Ok(self.0 <= other.0), + CompareOp::Eq => Ok(self.0 == other.0), + CompareOp::Ne => Ok(self.0 != other.0), + CompareOp::Gt => Ok(self.0 > other.0), + CompareOp::Ge => Ok(self.0 >= other.0), + } + } + + fn __bool__(&self) -> bool { + self.0 != 0 + } +} + +#[pymodule] +mod my_module { + #[pymodule_export] + use super::Number; +} +``` + +[`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html +[`Hasher`]: https://doc.rust-lang.org/std/hash/trait.Hasher.html +[`DefaultHasher`]: https://doc.rust-lang.org/std/collections/hash_map/struct.DefaultHasher.html +[SipHash]: https://en.wikipedia.org/wiki/SipHash +[`PartialEq`]: https://doc.rust-lang.org/stable/std/cmp/trait.PartialEq.html diff --git a/vendor/pyo3/guide/src/class/protocols.md b/vendor/pyo3/guide/src/class/protocols.md new file mode 100644 index 0000000..a0d73fb --- /dev/null +++ b/vendor/pyo3/guide/src/class/protocols.md @@ -0,0 +1,502 @@ +# Class customizations + +Python's object model defines several protocols for different object behavior, such as the sequence, mapping, and number protocols. +Python classes support these protocols by implementing "magic" methods, such as `__str__` or `__repr__`. +Because of the double-underscores surrounding their name, these are also known as "dunder" methods. + +PyO3 makes it possible for every magic method to be implemented in `#[pymethods]` just as they would be done in a regular Python class, with a few notable differences: + +- `__new__` is replaced by the [`#[new]` attribute](../class.md#constructor). +- `__del__` is not yet supported, but may be in the future. +- `__buffer__` and `__release_buffer__` are currently not supported and instead PyO3 supports [`__getbuffer__` and `__releasebuffer__`](#buffer-objects) methods (these predate [PEP 688](https://peps.python.org/pep-0688/#python-level-buffer-protocol)), again this may change in the future. +- PyO3 adds [`__traverse__` and `__clear__`](#garbage-collector-integration) methods for controlling garbage collection. +- The Python C-API which PyO3 is implemented upon requires many magic methods to have a specific function signature in C and be placed into special "slots" on the class type object. + This limits the allowed argument and return types for these methods. + They are listed in detail in the section below. + +If a magic method is not on the list above (for example `__init_subclass__`), then it should just work in PyO3. +If this is not the case, please file a bug report. + +## Magic Methods handled by PyO3 + +If a function name in `#[pymethods]` is a magic method which is known to need special handling, it will be automatically placed into the correct slot in the Python type object. +The function name is taken from the usual rules for naming `#[pymethods]`: the `#[pyo3(name = "...")]` attribute is used if present, otherwise the Rust function name is used. + +The magic methods handled by PyO3 are very similar to the standard Python ones on [this page](https://docs.python.org/3/reference/datamodel.html#special-method-names) - in particular they are the subset which have slots as [defined here](https://docs.python.org/3/c-api/typeobj.html). + +When PyO3 handles a magic method, a couple of changes apply compared to other `#[pymethods]`: + +- The Rust function signature is restricted to match the magic method. +- The `#[pyo3(signature = (...)]` and `#[pyo3(text_signature = "...")]` attributes are not allowed. + +The following sections list all magic methods for which PyO3 implements the necessary special handling. +The given signatures should be interpreted as follows: + +- All methods take a receiver as first argument, shown as ``. + It can be `&self`, `&mut self` or a `Bound` reference like `self_: PyRef<'_, Self>` and `self_: PyRefMut<'_, Self>`, as described [in the parent section](../class.md#inheritance). +- An optional `Python<'py>` argument is always allowed as the first argument. +- Return values can be optionally wrapped in `PyResult`. +- `object` means that any type is allowed that can be extracted from a Python + object (if argument) or converted to a Python object (if return value). +- Other types must match what's given, e.g. `pyo3::basic::CompareOp` for + `__richcmp__`'s second argument. +- For the comparison and arithmetic methods, extraction errors are not + propagated as exceptions, but lead to a return of `NotImplemented`. +- For some magic methods, the return values are not restricted by PyO3, but checked by the Python interpreter. + For example, `__str__` needs to return a string object. + This is indicated by `object (Python type)`. + +### Basic object customization + +- `__str__() -> object (str)` +- `__repr__() -> object (str)` + + + +- `__hash__() -> isize` + + Objects that compare equal must have the same hash value. + Any type up to 64 bits may be returned instead of `isize`, PyO3 will convert to an isize automatically (wrapping unsigned types like `u64` and `usize`). + +
+ Disabling Python's default hash + + By default, all `#[pyclass]` types have a default hash implementation from Python. + Types which should not be hashable can override this by setting `__hash__` to `None`. + This is the same mechanism as for a pure-Python class. + This is done like so: + + ```rust,no_run + # use pyo3::prelude::*; + # + #[pyclass] + struct NotHashable {} + + #[pymethods] + impl NotHashable { + #[classattr] + const __hash__: Option> = None; + } + ``` + +
+ + + +- `__lt__(, object) -> object` +- `__le__(, object) -> object` +- `__eq__(, object) -> object` +- `__ne__(, object) -> object` +- `__gt__(, object) -> object` +- `__ge__(, object) -> object` + + The implementations of Python's "rich comparison" operators `<`, `<=`, `==`, `!=`, `>` and `>=` respectively. + + *Note that implementing any of these methods will cause Python not to generate a default `__hash__` implementation, so consider also implementing `__hash__`.* + +
+ Return type + + The return type will normally be `bool` or `PyResult`, however any Python object can be returned. +
+ + + + +- `__richcmp__(, object, pyo3::basic::CompareOp) -> object` + + Implements Python comparison operations (`==`, `!=`, `<`, `<=`, `>`, and `>=`) in a single method. + The `CompareOp` argument indicates the comparison operation being performed. + You can use [`CompareOp::matches`] to adapt a Rust `std::cmp::Ordering` result to the requested comparison. + + *This method cannot be implemented in combination with any of `__lt__`, `__le__`, `__eq__`, `__ne__`, `__gt__`, or `__ge__`.* + + *Note that implementing `__richcmp__` will cause Python not to generate a default `__hash__` implementation, so consider implementing `__hash__` when implementing `__richcmp__`.* + +
+ Return type + + The return type will normally be `PyResult`, but any Python object can be returned. + + If you want to leave some operations unimplemented, you can return `py.NotImplemented()` + for some of the operations: + + ```rust,no_run + use pyo3::class::basic::CompareOp; + use pyo3::types::PyNotImplemented; + + # use pyo3::prelude::*; + # use pyo3::BoundObject; + # + # #[pyclass] + # struct Number(i32); + # + #[pymethods] + impl Number { + fn __richcmp__<'py>(&self, other: &Self, op: CompareOp, py: Python<'py>) -> PyResult> { + match op { + CompareOp::Eq => Ok((self.0 == other.0).into_pyobject(py)?.into_any()), + CompareOp::Ne => Ok((self.0 != other.0).into_pyobject(py)?.into_any()), + _ => Ok(PyNotImplemented::get(py).into_any()), + } + } + } + ``` + + If the second argument `object` is not of the type specified in the signature, the generated code will automatically `return NotImplemented`. +
+ + + +- `__getattr__(, object) -> object` +- `__getattribute__(, object) -> object` + +
+ Differences between __getattr__ and __getattribute__ + + As in Python, `__getattr__` is only called if the attribute is not found + by normal attribute lookup. `__getattribute__`, on the other hand, is + called for *every* attribute access. If it wants to access existing + attributes on `self`, it needs to be very careful not to introduce + infinite recursion, and use `baseclass.__getattribute__()`. +
+ +- `__setattr__(, value: object) -> ()` +- `__delattr__(, object) -> ()` + + Overrides attribute access. + +- `__bool__() -> bool` + + Determines the "truthyness" of an object. + +- `__call__(, ...) -> object` - here, any argument list can be defined + as for normal `pymethods` + +### Iterable objects + +Iterators can be defined using these methods: + +- `__iter__() -> object` +- `__next__() -> Option or IterNextOutput` ([see details](#returning-a-value-from-iteration)) + +Returning `None` from `__next__` indicates that that there are no further items. + +Example: + +```rust,no_run +use pyo3::prelude::*; + +use std::sync::Mutex; + +#[pyclass] +struct MyIterator { + iter: Mutex> + Send>>, +} + +#[pymethods] +impl MyIterator { + fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { + slf + } + fn __next__(slf: PyRefMut<'_, Self>) -> Option> { + slf.iter.lock().unwrap().next() + } +} +``` + +In many cases you'll have a distinction between the type being iterated over (i.e. the *iterable*) and the iterator it provides. +In this case, the iterable only needs to implement `__iter__()` while the iterator must implement both `__iter__()` and `__next__()`. +For example: + +```rust,no_run +# use pyo3::prelude::*; + +#[pyclass] +struct Iter { + inner: std::vec::IntoIter, +} + +#[pymethods] +impl Iter { + fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { + slf + } + + fn __next__(mut slf: PyRefMut<'_, Self>) -> Option { + slf.inner.next() + } +} + +#[pyclass] +struct Container { + iter: Vec, +} + +#[pymethods] +impl Container { + fn __iter__(slf: PyRef<'_, Self>) -> PyResult> { + let iter = Iter { + inner: slf.iter.clone().into_iter(), + }; + Py::new(slf.py(), iter) + } +} + +# Python::attach(|py| { +# let container = Container { iter: vec![1, 2, 3, 4] }; +# let inst = pyo3::Py::new(py, container).unwrap(); +# pyo3::py_run!(py, inst, "assert list(inst) == [1, 2, 3, 4]"); +# pyo3::py_run!(py, inst, "assert list(iter(iter(inst))) == [1, 2, 3, 4]"); +# }); +``` + +For more details on Python's iteration protocols, check out [the "Iterator Types" section of the library documentation](https://docs.python.org/library/stdtypes.html#iterator-types). + +#### Returning a value from iteration + +This guide has so far shown how to use `Option` to implement yielding values during iteration. +In Python a generator can also return a value. +This is done by raising a `StopIteration` exception. +To express this in Rust, return `PyResult::Err` with a `PyStopIteration` as the error. + +### Awaitable objects + +- `__await__() -> object` +- `__aiter__() -> object` +- `__anext__() -> Option` + +### Mapping & Sequence types + +The magic methods in this section can be used to implement Python container types. +They are two main categories of container in Python: "mappings" such as `dict`, with arbitrary keys, and "sequences" such as `list` and `tuple`, with integer keys. + +The Python C-API which PyO3 is built upon has separate "slots" for sequences and mappings. +When writing a `class` in pure Python, there is no such distinction in the implementation - a `__getitem__` implementation will fill the slots for both the mapping and sequence forms, for example. + +By default PyO3 reproduces the Python behaviour of filling both mapping and sequence slots. +This makes sense for the "simple" case which matches Python, and also for sequences, where the mapping slot is used anyway to implement slice indexing. + +Mapping types usually will not want the sequence slots filled. +Having them filled will lead to outcomes which may be unwanted, such as: + +- The mapping type will successfully cast to [`PySequence`]. + This may lead to consumers of the type handling it incorrectly. +- Python provides a default implementation of `__iter__` for sequences, which calls `__getitem__` with consecutive positive integers starting from 0 until an `IndexError` is returned. + Unless the mapping only contains consecutive positive integer keys, this `__iter__` implementation will likely not be the intended behavior. + +Use the `#[pyclass(mapping)]` annotation to instruct PyO3 to only fill the mapping slots, leaving the sequence ones empty. +This will apply to `__getitem__`, `__setitem__`, and `__delitem__`. + +Use the `#[pyclass(sequence)]` annotation to instruct PyO3 to fill the `sq_length` slot instead of the `mp_length` slot for `__len__`. +This will help libraries such as `numpy` recognise the class as a sequence, however will also cause CPython to automatically add the sequence length to any negative indices before passing them to `__getitem__`. (`__getitem__`, `__setitem__` and `__delitem__` mapping slots are still used for sequences, for slice operations.) + +- `__len__() -> usize` + + Implements the built-in function `len()`. + + + + +- `__contains__(, object) -> bool` + + Implements membership test operators. + Should return true if `item` is in `self`, false otherwise. + For objects that don’t define `__contains__()`, the membership test simply traverses the sequence until it finds a match. + +
+ Disabling Python's default contains + + By default, all `#[pyclass]` types with an `__iter__` method support a + default implementation of the `in` operator. Types which do not want this + can override this by setting `__contains__` to `None`. This is the same + mechanism as for a pure-Python class. This is done like so: + + ```rust,no_run + # use pyo3::prelude::*; + # + #[pyclass] + struct NoContains {} + + #[pymethods] + impl NoContains { + #[classattr] + const __contains__: Option> = None; + } + ``` + +
+ + + +- `__getitem__(, object) -> object` + + Implements retrieval of the `self[a]` element. + + *Note:* Negative integer indexes are not handled specially by PyO3. + However, for classes with `#[pyclass(sequence)]`, when a negative index is accessed via `PySequence::get_item`, the underlying C API already adjusts the index to be positive. + +- `__setitem__(, object, object) -> ()` + + Implements assignment to the `self[a]` element. + Should only be implemented if elements can be replaced. + + Same behavior regarding negative indices as for `__getitem__`. + +- `__delitem__(, object) -> ()` + + Implements deletion of the `self[a]` element. + Should only be implemented if elements can be deleted. + + Same behavior regarding negative indices as for `__getitem__`. + +- `fn __concat__(&self, other: impl FromPyObject) -> PyResult` + + Concatenates two sequences. + Used by the `+` operator, after trying the numeric addition via the `__add__` and `__radd__` methods. + +- `fn __repeat__(&self, count: isize) -> PyResult` + + Repeats the sequence `count` times. + Used by the `*` operator, after trying the numeric multiplication via the `__mul__` and `__rmul__` methods. + +- `fn __inplace_concat__(&self, other: impl FromPyObject) -> PyResult` + + Concatenates two sequences. + Used by the `+=` operator, after trying the numeric addition via the `__iadd__` method. + +- `fn __inplace_repeat__(&self, count: isize) -> PyResult` + + Concatenates two sequences. + Used by the `*=` operator, after trying the numeric multiplication via the `__imul__` method. + +### Descriptors + +- `__get__(, object, object) -> object` +- `__set__(, object, object) -> ()` +- `__delete__(, object) -> ()` + +### Numeric types + +Binary arithmetic operations (`+`, `-`, `*`, `@`, `/`, `//`, `%`, `divmod()`, `pow()` and `**`, `<<`, `>>`, `&`, `^`, and `|`) and their reflected versions: + +(If the `object` is not of the type specified in the signature, the generated code will automatically `return NotImplemented`.) + +- `__add__(, object) -> object` +- `__radd__(, object) -> object` +- `__sub__(, object) -> object` +- `__rsub__(, object) -> object` +- `__mul__(, object) -> object` +- `__rmul__(, object) -> object` +- `__matmul__(, object) -> object` +- `__rmatmul__(, object) -> object` +- `__floordiv__(, object) -> object` +- `__rfloordiv__(, object) -> object` +- `__truediv__(, object) -> object` +- `__rtruediv__(, object) -> object` +- `__divmod__(, object) -> object` +- `__rdivmod__(, object) -> object` +- `__mod__(, object) -> object` +- `__rmod__(, object) -> object` +- `__lshift__(, object) -> object` +- `__rlshift__(, object) -> object` +- `__rshift__(, object) -> object` +- `__rrshift__(, object) -> object` +- `__and__(, object) -> object` +- `__rand__(, object) -> object` +- `__xor__(, object) -> object` +- `__rxor__(, object) -> object` +- `__or__(, object) -> object` +- `__ror__(, object) -> object` +- `__pow__(, object, object) -> object` +- `__rpow__(, object, object) -> object` + +In-place assignment operations (`+=`, `-=`, `*=`, `@=`, `/=`, `//=`, `%=`, `**=`, `<<=`, `>>=`, `&=`, `^=`, `|=`): + +- `__iadd__(, object) -> ()` +- `__isub__(, object) -> ()` +- `__imul__(, object) -> ()` +- `__imatmul__(, object) -> ()` +- `__itruediv__(, object) -> ()` +- `__ifloordiv__(, object) -> ()` +- `__imod__(, object) -> ()` +- `__ipow__(, object, object) -> ()` +- `__ilshift__(, object) -> ()` +- `__irshift__(, object) -> ()` +- `__iand__(, object) -> ()` +- `__ixor__(, object) -> ()` +- `__ior__(, object) -> ()` + +Unary operations (`-`, `+`, `abs()` and `~`): + +- `__pos__() -> object` +- `__neg__() -> object` +- `__abs__() -> object` +- `__invert__() -> object` + +Coercions: + +- `__index__() -> object (int)` +- `__int__() -> object (int)` +- `__float__() -> object (float)` + +### Buffer objects + +- `__getbuffer__(, *mut ffi::Py_buffer, flags) -> ()` +- `__releasebuffer__(, *mut ffi::Py_buffer) -> ()` Errors returned from `__releasebuffer__` will be sent to `sys.unraiseablehook`. + It is strongly advised to never return an error from `__releasebuffer__`, and if it really is necessary, to make best effort to perform any required freeing operations before returning. + `__releasebuffer__` will not be called a second time; anything not freed will be leaked. + +### Garbage Collector Integration + +If your type owns references to other Python objects, you will need to integrate with Python's garbage collector so that the GC is aware of those references. +To do this, implement the two methods `__traverse__` and `__clear__`. +These correspond to the slots `tp_traverse` and `tp_clear` in the Python C API. +`__traverse__` must call `visit.call()` for each reference to another Python object. +`__clear__` must clear out any mutable references to other Python objects (thus breaking reference cycles). +Immutable references do not have to be cleared, as every cycle must contain at least one mutable reference. + +- `__traverse__(, pyo3::class::gc::PyVisit<'_>) -> Result<(), pyo3::class::gc::PyTraverseError>` +- `__clear__() -> ()` + +> [!NOTE] +> `__traverse__` does not work with [`#[pyo3(warn(...))]`](../function.md#warn). + +Example: + +```rust,no_run +use pyo3::prelude::*; +use pyo3::PyTraverseError; +use pyo3::gc::PyVisit; + +#[pyclass] +struct ClassWithGCSupport { + obj: Option>, +} + +#[pymethods] +impl ClassWithGCSupport { + fn __traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError> { + visit.call(&self.obj)?; + Ok(()) + } + + fn __clear__(&mut self) { + // Clear reference, this decrements ref counter. + self.obj = None; + } +} +``` + +> [!NOTE] +> When a class inherits from either a Python builtins type or another type declared in Rust and implement either or both `__traverse__` and `__clear__`, the parent class `__traverse__` and `__clear__` is called automatically. +> There is no need to explicitly call it from inside the class implementation. + +Usually, an implementation of `__traverse__` should do nothing but calls to `visit.call`. +Most importantly, safe access to the interpreter is prohibited inside implementations of `__traverse__`, i.e. `Python::attach` will panic. + +> [!NOTE] +> These methods are part of the C API, PyPy does not necessarily honor them. If you are building for PyPy you should measure memory consumption to make sure you do not have runaway memory growth. See [this issue on the PyPy bug tracker](https://github.com/pypy/pypy/issues/3848). + +[`PySequence`]: {{#PYO3_DOCS_URL}}/pyo3/types/struct.PySequence.html +[`CompareOp::matches`]: {{#PYO3_DOCS_URL}}/pyo3/pyclass/enum.CompareOp.html#method.matches diff --git a/vendor/pyo3/guide/src/class/thread-safety.md b/vendor/pyo3/guide/src/class/thread-safety.md new file mode 100644 index 0000000..eb2b029 --- /dev/null +++ b/vendor/pyo3/guide/src/class/thread-safety.md @@ -0,0 +1,121 @@ +# `#[pyclass]` thread safety + +Python objects are freely shared between threads by the Python interpreter. +This means that: + +- there is no control which thread might eventually drop the `#[pyclass]` object, meaning `Send` is required. +- multiple threads can potentially be reading the `#[pyclass]` data simultaneously, meaning `Sync` is required. + +This section of the guide discusses various data structures which can be used to make types satisfy these requirements. + +In special cases where it is known that your Python application is never going to use threads (this is rare!), these thread-safety requirements can be opted-out with [`#[pyclass(unsendable)]`](../class.md#customizing-the-class), at the cost of making concurrent access to the Rust data be runtime errors. +This is only for very specific use cases; it is almost always better to make proper thread-safe types. + +## Making `#[pyclass]` types thread-safe + +The general challenge with thread-safety is to make sure that two threads cannot produce a data race, i.e. unsynchronized writes to the same data at the same time. +A data race produces an unpredictable result and is forbidden by Rust. + +By default, `#[pyclass]` employs an ["interior mutability" pattern](../class.md#bound-and-interior-mutability) to allow for either multiple `&T` references or a single exclusive `&mut T` reference to access the data. +This allows for simple `#[pyclass]` types to be thread-safe automatically, at the cost of runtime checking for concurrent access. +Errors will be raised if the usage overlaps. + +For example, the below simple class is thread-safe: + +```rust,no_run +# use pyo3::prelude::*; + +#[pyclass] +struct MyClass { + x: i32, + y: i32, +} + +#[pymethods] +impl MyClass { + fn get_x(&self) -> i32 { + self.x + } + + fn set_y(&mut self, value: i32) { + self.y = value; + } +} +``` + +In the above example, if calls to `get_x` and `set_y` overlap (from two different threads) then at least one of those threads will experience a runtime error indicating that the data was "already borrowed". + +To avoid these errors, you can take control of the interior mutability yourself in one of the following ways. + +### Using atomic data structures + +To remove the possibility of having overlapping `&self` and `&mut self` references produce runtime errors, consider using `#[pyclass(frozen)]` and use [atomic data structures](https://doc.rust-lang.org/std/sync/atomic/) to control modifications directly. + +For example, a thread-safe version of the above `MyClass` using atomic integers would be as follows: + +```rust,no_run +# use pyo3::prelude::*; +use std::sync::atomic::{AtomicI32, Ordering}; + +#[pyclass(frozen)] +struct MyClass { + x: AtomicI32, + y: AtomicI32, +} + +#[pymethods] +impl MyClass { + fn get_x(&self) -> i32 { + self.x.load(Ordering::Relaxed) + } + + fn set_y(&self, value: i32) { + self.y.store(value, Ordering::Relaxed) + } +} +``` + +### Using locks + +An alternative to atomic data structures is to use [locks](https://doc.rust-lang.org/std/sync/struct.Mutex.html) to make threads wait for access to shared data. + +For example, a thread-safe version of the above `MyClass` using locks would be as follows: + +```rust,no_run +# use pyo3::prelude::*; +use std::sync::Mutex; + +struct MyClassInner { + x: i32, + y: i32, +} + +#[pyclass(frozen)] +struct MyClass { + inner: Mutex +} + +#[pymethods] +impl MyClass { + fn get_x(&self) -> i32 { + self.inner.lock().expect("lock not poisoned").x + } + + fn set_y(&self, value: i32) { + self.inner.lock().expect("lock not poisoned").y = value; + } +} +``` + +If you need to lock around state stored in the Python interpreter or otherwise call into the Python C API while a lock is held, you might find the `MutexExt` trait useful. +It provides a `lock_py_attached` method for `std::sync::Mutex` that avoids deadlocks with the GIL or other global synchronization events in the interpreter. +Additionally, support for the `parking_lot` and `lock_api` synchronization libraries is gated behind the `parking_lot` and `lock_api` features. +You can also enable the `arc_lock` feature if you need the `arc_lock` features of either library. + +### Wrapping unsynchronized data + +In some cases, the data structures stored within a `#[pyclass]` may themselves not be thread-safe. +Rust will therefore not implement `Send` and `Sync` on the `#[pyclass]` type. + +To achieve thread-safety, a manual `Send` and `Sync` implementation is required which is `unsafe` and should only be done following careful review of the soundness of the implementation. +Doing this for PyO3 types is no different than for any other Rust code, [the Rustonomicon](https://doc.rust-lang.org/nomicon/send-and-sync.html) has a great discussion on this. diff --git a/vendor/pyo3/guide/src/contributing.md b/vendor/pyo3/guide/src/contributing.md new file mode 100644 index 0000000..aa08bca --- /dev/null +++ b/vendor/pyo3/guide/src/contributing.md @@ -0,0 +1 @@ +{{#include ../../Contributing.md}} diff --git a/vendor/pyo3/guide/src/conversions.md b/vendor/pyo3/guide/src/conversions.md new file mode 100644 index 0000000..ee8dfdd --- /dev/null +++ b/vendor/pyo3/guide/src/conversions.md @@ -0,0 +1,5 @@ +# Type conversions + +In this portion of the guide we'll talk about the mapping of Python types to Rust types offered by PyO3, as well as the traits available to perform conversions between them. + +See also the conversion [tables](conversions/tables.md) and [traits](conversions/traits.md). diff --git a/vendor/pyo3/guide/src/conversions/tables.md b/vendor/pyo3/guide/src/conversions/tables.md new file mode 100644 index 0000000..d62ae5a --- /dev/null +++ b/vendor/pyo3/guide/src/conversions/tables.md @@ -0,0 +1,129 @@ +# Mapping of Rust types to Python types + +When writing functions callable from Python (such as a `#[pyfunction]` or in a `#[pymethods]` block), the trait `FromPyObject` is required for function arguments, and `IntoPyObject` is required for function return values. + +Consult the tables in the following section to find the Rust types provided by PyO3 which implement these traits. + +## Argument Types + +When accepting a function argument, it is possible to either use Rust library types or PyO3's Python-native types. (See the next section for discussion on when to use each.) + +The table below contains the Python type and the corresponding function argument types that will accept them: + +| Python | Rust | Rust (Python-native) | +| ------------- |:-------------------------------:|:--------------------:| +| `object` | - | `PyAny` | +| `str` | `String`, `Cow`, `&str`, `char`, `OsString`, `PathBuf`, `Path` | `PyString` | +| `bytes` | `Vec`, `&[u8]`, `Cow<[u8]>` | `PyBytes` | +| `bool` | `bool` | `PyBool` | +| `int` | `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`, `num_bigint::BigInt`[^1], `num_bigint::BigUint`[^1] | `PyInt` | +| `float` | `f32`, `f64`, `ordered_float::NotNan`[^2], `ordered_float::OrderedFloat`[^2] | `PyFloat` | +| `complex` | `num_complex::Complex`[^3] | `PyComplex` | +| `fractions.Fraction`| `num_rational::Ratio`[^4] | - | +| `list[T]` | `Vec` | `PyList` | +| `dict[K, V]` | `HashMap`, `BTreeMap`, `hashbrown::HashMap`[^5], `indexmap::IndexMap`[^6] | `PyDict` | +| `tuple[T, U]` | `(T, U)`, `Vec` | `PyTuple` | +| `set[T]` | `HashSet`, `BTreeSet`, `hashbrown::HashSet`[^5] | `PySet` | +| `frozenset[T]` | `HashSet`, `BTreeSet`, `hashbrown::HashSet`[^5] | `PyFrozenSet` | +| `bytearray` | `Vec`, `Cow<[u8]>` | `PyByteArray` | +| `slice` | - | `PySlice` | +| `type` | - | `PyType` | +| `module` | - | `PyModule` | +| `collections.abc.Buffer` | - | `PyBuffer` | +| `datetime.datetime` | `SystemTime`, `chrono::DateTime`[^7], `chrono::NaiveDateTime`[^7] | `PyDateTime` | +| `datetime.date` | `chrono::NaiveDate`[^7] | `PyDate` | +| `datetime.time` | `chrono::NaiveTime`[^7] | `PyTime` | +| `datetime.tzinfo` | `chrono::FixedOffset`[^7], `chrono::Utc`[^7], `chrono_tz::TimeZone`[^8] | `PyTzInfo` | +| `datetime.timedelta` | `Duration`, `chrono::Duration`[^7] | `PyDelta` | +| `decimal.Decimal` | `rust_decimal::Decimal`[^9] | - | +| `decimal.Decimal` | `bigdecimal::BigDecimal`[^10] | - | +| `ipaddress.IPv4Address` | `std::net::IpAddr`, `std::net::Ipv4Addr` | - | +| `ipaddress.IPv6Address` | `std::net::IpAddr`, `std::net::Ipv6Addr` | - | +| `os.PathLike` | `PathBuf`, `Path` | `PyString` | +| `pathlib.Path` | `PathBuf`, `Path` | `PyString` | +| `typing.Optional[T]` | `Option` | - | +| `typing.Sequence[T]` | `Vec` | `PySequence` | +| `typing.Mapping[K, V]` | `HashMap`, `BTreeMap`, `hashbrown::HashMap`[^5], `indexmap::IndexMap`[^6] | `&PyMapping` | +| `typing.Iterator[Any]` | - | `PyIterator` | +| `typing.Union[...]` | See [`#[derive(FromPyObject)]`](traits.md#deriving-frompyobject-for-enums) | - | + +It is also worth remembering the following special types: + +| What | Description | +| ---------------- | ------------------------------------- | +| `Python<'py>` | A token used to prove attachment to the Python interpreter. | +| `Bound<'py, T>` | A Python object with a lifetime which binds it to the attachment to the Python interpreter. This provides access to most of PyO3's APIs. | +| `Py` | A Python object not connected to any lifetime of attachment to the Python interpreter. This can be sent to other threads. | +| `PyRef` | A `#[pyclass]` borrowed immutably. | +| `PyRefMut` | A `#[pyclass]` borrowed mutably. | + +For more detail on accepting `#[pyclass]` values as function arguments, see [the section of this guide on Python Classes](../class.md). + +### Using Rust library types vs Python-native types + +Using Rust library types as function arguments will incur a conversion cost compared to using the Python-native types. +Using the Python-native types is almost zero-cost (they just require a type check similar to the Python builtin function `isinstance()`). + +However, once that conversion cost has been paid, the Rust standard library types offer a number of benefits: + +- You can write functionality in native-speed Rust code (free of Python's runtime costs). +- You get better interoperability with the rest of the Rust ecosystem. +- You can use `Python::detach` to detach from the interpreter and let other Python threads make progress while your Rust code is executing. +- You also benefit from stricter type checking. + For example you can specify `Vec`, which will only accept a Python `list` containing integers. + The Python-native equivalent, `&PyList`, would accept a Python `list` containing Python objects of any type. + +For most PyO3 usage the conversion cost is worth paying to get these benefits. +As always, if you're not sure it's worth it in your case, benchmark it! + +## Returning Rust values to Python + +When returning values from functions callable from Python, PyO3's smart pointers (`Py`, `Bound<'py, T>`, and `Borrowed<'a, 'py, T>`) can be used with zero cost. + +Because `Bound<'py, T>` and `Borrowed<'a, 'py, T>` have lifetime parameters, the Rust compiler may ask for lifetime annotations to be added to your function. +See the [section of the guide dedicated to this](../types.md#function-argument-lifetimes). + +If your function is fallible, it should return `PyResult` or `Result` where `E` implements `From for PyErr`. +This will raise a `Python` exception if the `Err` variant is returned. + +Finally, the following Rust types are also able to convert to Python as return values: + +| Rust type | Resulting Python Type | +| ------------- |:-------------------------------:| +| `String` | `str` | +| `&str` | `str` | +| `bool` | `bool` | +| Any integer type (`i32`, `u32`, `usize`, etc) | `int` | +| `f32`, `f64` | `float` | +| `Option` | `Optional[T]` | +| `(T, U)` | `Tuple[T, U]` | +| `Vec` | `List[T]` | +| `Cow<[u8]>` | `bytes` | +| `HashMap` | `Dict[K, V]` | +| `BTreeMap` | `Dict[K, V]` | +| `HashSet` | `Set[T]` | +| `BTreeSet` | `Set[T]` | +| `Py` | `T` | +| `Bound` | `T` | +| `PyRef` | `T` | +| `PyRefMut` | `T` | + +[^1]: Requires the `num-bigint` optional feature. + +[^2]: Requires the `ordered-float` optional feature. + +[^3]: Requires the `num-complex` optional feature. + +[^4]: Requires the `num-rational` optional feature. + +[^5]: Requires the `hashbrown` optional feature. + +[^6]: Requires the `indexmap` optional feature. + +[^7]: Requires the `chrono` (and maybe `chrono-local`) optional feature(s). + +[^8]: Requires the `chrono-tz` optional feature. + +[^9]: Requires the `rust_decimal` optional feature. + +[^10]: Requires the `bigdecimal` optional feature. diff --git a/vendor/pyo3/guide/src/conversions/traits.md b/vendor/pyo3/guide/src/conversions/traits.md new file mode 100644 index 0000000..83e958a --- /dev/null +++ b/vendor/pyo3/guide/src/conversions/traits.md @@ -0,0 +1,763 @@ +# Conversion traits + +PyO3 provides some handy traits to convert between Python types and Rust types. + +## `.extract()` and the `FromPyObject` trait + +The easiest way to convert a Python object to a Rust value is using `.extract()`. +It returns a `PyResult` with a type error if the conversion fails, so usually you will use something like + +```rust +# use pyo3::prelude::*; +# use pyo3::types::PyList; +# fn main() -> PyResult<()> { +# Python::attach(|py| { +# let list = PyList::new(py, b"foo")?; +let v: Vec = list.extract()?; +# assert_eq!(&v, &[102, 111, 111]); +# Ok(()) +# }) +# } +``` + +This method is available for many Python object types, and can produce a wide variety of Rust types, which you can check out in the implementor list of [`FromPyObject`]. + +[`FromPyObject`] is also implemented for your own Rust types wrapped as Python objects (see [the chapter about classes](../class.md)). +There, in order to both be able to operate on mutable references *and* satisfy Rust's rules of non-aliasing mutable references, you have to extract the PyO3 reference wrappers [`PyRef`] and [`PyRefMut`]. +They work like the reference wrappers of `std::cell::RefCell` and ensure (at runtime) that Rust borrows are allowed. + +### Deriving [`FromPyObject`] + +[`FromPyObject`] can be automatically derived for many kinds of structs and enums if the member types themselves implement `FromPyObject`. +This even includes members with a generic type `T: FromPyObject`. +Derivation for empty enums, enum variants and structs is not supported. + +### Deriving [`FromPyObject`] for structs + +The derivation generates code that will attempt to access the attribute `my_string` on the Python object, i.e. `obj.getattr("my_string")`, and call `extract()` on the attribute. + +```rust +use pyo3::prelude::*; + +#[derive(FromPyObject)] +struct RustyStruct { + my_string: String, +} +# +# fn main() -> PyResult<()> { +# Python::attach(|py| -> PyResult<()> { +# let module = PyModule::from_code( +# py, +# c"class Foo: +# def __init__(self): +# self.my_string = 'test'", +# c"", +# c"", +# )?; +# +# let class = module.getattr("Foo")?; +# let instance = class.call0()?; +# let rustystruct: RustyStruct = instance.extract()?; +# assert_eq!(rustystruct.my_string, "test"); +# Ok(()) +# }) +# } +``` + +By setting the `#[pyo3(item)]` attribute on the field, PyO3 will attempt to extract the value by calling the `get_item` method on the Python object. + +```rust +use pyo3::prelude::*; + +#[derive(FromPyObject)] +struct RustyStruct { + #[pyo3(item)] + my_string: String, +} +# +# use pyo3::types::PyDict; +# fn main() -> PyResult<()> { +# Python::attach(|py| -> PyResult<()> { +# let dict = PyDict::new(py); +# dict.set_item("my_string", "test")?; +# +# let rustystruct: RustyStruct = dict.extract()?; +# assert_eq!(rustystruct.my_string, "test"); +# Ok(()) +# }) +# } +``` + +The argument passed to `getattr` and `get_item` can also be configured: + +```rust +use pyo3::prelude::*; + +#[derive(FromPyObject)] +struct RustyStruct { + #[pyo3(item("key"))] + string_in_mapping: String, + #[pyo3(attribute("name"))] + string_attr: String, +} +# +# fn main() -> PyResult<()> { +# Python::attach(|py| -> PyResult<()> { +# let module = PyModule::from_code( +# py, +# c"class Foo(dict): +# def __init__(self): +# self.name = 'test' +# self['key'] = 'test2'", +# c"", +# c"", +# )?; +# +# let class = module.getattr("Foo")?; +# let instance = class.call0()?; +# let rustystruct: RustyStruct = instance.extract()?; +# assert_eq!(rustystruct.string_attr, "test"); +# assert_eq!(rustystruct.string_in_mapping, "test2"); +# +# Ok(()) +# }) +# } +``` + +This tries to extract `string_attr` from the attribute `name` and `string_in_mapping` from a mapping with the key `"key"`. +The arguments for `attribute` are restricted to non-empty string literals while `item` can take any valid literal that implements `ToBorrowedObject`. + +You can use `#[pyo3(from_item_all)]` on a struct to extract every field with `get_item` method. +In this case, you can't use `#[pyo3(attribute)]` or barely use `#[pyo3(item)]` on any field. +However, using `#[pyo3(item("key"))]` to specify the key for a field is still allowed. + +```rust +use pyo3::prelude::*; + +#[derive(FromPyObject)] +#[pyo3(from_item_all)] +struct RustyStruct { + foo: String, + bar: String, + #[pyo3(item("foobar"))] + baz: String, +} +# +# fn main() -> PyResult<()> { +# Python::attach(|py| -> PyResult<()> { +# let py_dict = py.eval(c"{'foo': 'foo', 'bar': 'bar', 'foobar': 'foobar'}", None, None)?; +# let rustystruct: RustyStruct = py_dict.extract()?; +# assert_eq!(rustystruct.foo, "foo"); +# assert_eq!(rustystruct.bar, "bar"); +# assert_eq!(rustystruct.baz, "foobar"); +# +# Ok(()) +# }) +# } +``` + +### Deriving [`FromPyObject`] for tuple structs + +Tuple structs are also supported but do not allow customizing the extraction. +The input is always assumed to be a Python tuple with the same length as the Rust type, the `n`th field is extracted from the `n`th item in the Python tuple. + +```rust +use pyo3::prelude::*; + +#[derive(FromPyObject)] +struct RustyTuple(String, String); + +# use pyo3::types::PyTuple; +# fn main() -> PyResult<()> { +# Python::attach(|py| -> PyResult<()> { +# let tuple = PyTuple::new(py, vec!["test", "test2"])?; +# +# let rustytuple: RustyTuple = tuple.extract()?; +# assert_eq!(rustytuple.0, "test"); +# assert_eq!(rustytuple.1, "test2"); +# +# Ok(()) +# }) +# } +``` + +Tuple structs with a single field are treated as wrapper types which are described in the following section. +To override this behaviour and ensure that the input is in fact a tuple, specify the struct as + +```rust +use pyo3::prelude::*; + +#[derive(FromPyObject)] +struct RustyTuple((String,)); + +# use pyo3::types::PyTuple; +# fn main() -> PyResult<()> { +# Python::attach(|py| -> PyResult<()> { +# let tuple = PyTuple::new(py, vec!["test"])?; +# +# let rustytuple: RustyTuple = tuple.extract()?; +# assert_eq!((rustytuple.0).0, "test"); +# +# Ok(()) +# }) +# } +``` + +### Deriving [`FromPyObject`] for wrapper types + +The `pyo3(transparent)` attribute can be used on structs with exactly one field. +This results in extracting directly from the input object, i.e. `obj.extract()`, rather than trying to access an item or attribute. +This behaviour is enabled per default for newtype structs and tuple-variants with a single field. + +```rust +use pyo3::prelude::*; + +#[derive(FromPyObject)] +struct RustyTransparentTupleStruct(String); + +#[derive(FromPyObject)] +#[pyo3(transparent)] +struct RustyTransparentStruct { + inner: String, +} + +# use pyo3::types::PyString; +# fn main() -> PyResult<()> { +# Python::attach(|py| -> PyResult<()> { +# let s = PyString::new(py, "test"); +# +# let tup: RustyTransparentTupleStruct = s.extract()?; +# assert_eq!(tup.0, "test"); +# +# let stru: RustyTransparentStruct = s.extract()?; +# assert_eq!(stru.inner, "test"); +# +# Ok(()) +# }) +# } +``` + +### Deriving [`FromPyObject`] for enums + +The `FromPyObject` derivation for enums generates code that tries to extract the variants in the order of the fields. +As soon as a variant can be extracted successfully, that variant is returned. +This makes it possible to extract Python union types like `str | int`. + +The same customizations and restrictions described for struct derivations apply to enum variants, i.e. a tuple variant assumes that the input is a Python tuple, and a struct variant defaults to extracting fields as attributes but can be configured in the same manner. +The `transparent` attribute can be applied to single-field-variants. + +```rust +use pyo3::prelude::*; + +#[derive(FromPyObject)] +# #[derive(Debug)] +enum RustyEnum<'py> { + Int(usize), // input is a positive int + String(String), // input is a string + IntTuple(usize, usize), // input is a 2-tuple with positive ints + StringIntTuple(String, usize), // input is a 2-tuple with String and int + Coordinates3d { + // needs to be in front of 2d + x: usize, + y: usize, + z: usize, + }, + Coordinates2d { + // only gets checked if the input did not have `z` + #[pyo3(attribute("x"))] + a: usize, + #[pyo3(attribute("y"))] + b: usize, + }, + #[pyo3(transparent)] + CatchAll(Bound<'py, PyAny>), // This extraction never fails +} +# +# use pyo3::types::{PyBytes, PyString}; +# fn main() -> PyResult<()> { +# Python::attach(|py| -> PyResult<()> { +# { +# let thing = 42_u8.into_pyobject(py)?; +# let rust_thing: RustyEnum<'_> = thing.extract()?; +# +# assert_eq!( +# 42, +# match rust_thing { +# RustyEnum::Int(i) => i, +# other => unreachable!("Error extracting: {:?}", other), +# } +# ); +# } +# { +# let thing = PyString::new(py, "text"); +# let rust_thing: RustyEnum<'_> = thing.extract()?; +# +# assert_eq!( +# "text", +# match rust_thing { +# RustyEnum::String(i) => i, +# other => unreachable!("Error extracting: {:?}", other), +# } +# ); +# } +# { +# let thing = (32_u8, 73_u8).into_pyobject(py)?; +# let rust_thing: RustyEnum<'_> = thing.extract()?; +# +# assert_eq!( +# (32, 73), +# match rust_thing { +# RustyEnum::IntTuple(i, j) => (i, j), +# other => unreachable!("Error extracting: {:?}", other), +# } +# ); +# } +# { +# let thing = ("foo", 73_u8).into_pyobject(py)?; +# let rust_thing: RustyEnum<'_> = thing.extract()?; +# +# assert_eq!( +# (String::from("foo"), 73), +# match rust_thing { +# RustyEnum::StringIntTuple(i, j) => (i, j), +# other => unreachable!("Error extracting: {:?}", other), +# } +# ); +# } +# { +# let module = PyModule::from_code( +# py, +# c"class Foo(dict): +# def __init__(self): +# self.x = 0 +# self.y = 1 +# self.z = 2", +# c"", +# c"", +# )?; +# +# let class = module.getattr("Foo")?; +# let instance = class.call0()?; +# let rust_thing: RustyEnum<'_> = instance.extract()?; +# +# assert_eq!( +# (0, 1, 2), +# match rust_thing { +# RustyEnum::Coordinates3d { x, y, z } => (x, y, z), +# other => unreachable!("Error extracting: {:?}", other), +# } +# ); +# } +# +# { +# let module = PyModule::from_code( +# py, +# c"class Foo(dict): +# def __init__(self): +# self.x = 3 +# self.y = 4", +# c"", +# c"", +# )?; +# +# let class = module.getattr("Foo")?; +# let instance = class.call0()?; +# let rust_thing: RustyEnum<'_> = instance.extract()?; +# +# assert_eq!( +# (3, 4), +# match rust_thing { +# RustyEnum::Coordinates2d { a, b } => (a, b), +# other => unreachable!("Error extracting: {:?}", other), +# } +# ); +# } +# +# { +# let thing = PyBytes::new(py, b"text"); +# let rust_thing: RustyEnum<'_> = thing.extract()?; +# +# assert_eq!( +# b"text", +# match rust_thing { +# RustyEnum::CatchAll(ref i) => i.cast::()?.as_bytes(), +# other => unreachable!("Error extracting: {:?}", other), +# } +# ); +# } +# Ok(()) +# }) +# } +``` + +If none of the enum variants match, a `PyTypeError` containing the names of the tested variants is returned. +The names reported in the error message can be customized through the `#[pyo3(annotation = "name")]` attribute, e.g. to use conventional Python type names: + +```rust +use pyo3::prelude::*; + +#[derive(FromPyObject)] +# #[derive(Debug)] +enum RustyEnum { + #[pyo3(transparent, annotation = "str")] + String(String), + #[pyo3(transparent, annotation = "int")] + Int(isize), +} +# +# fn main() -> PyResult<()> { +# Python::attach(|py| -> PyResult<()> { +# { +# let thing = 42_u8.into_pyobject(py)?; +# let rust_thing: RustyEnum = thing.extract()?; +# +# assert_eq!( +# 42, +# match rust_thing { +# RustyEnum::Int(i) => i, +# other => unreachable!("Error extracting: {:?}", other), +# } +# ); +# } +# +# { +# let thing = "foo".into_pyobject(py)?; +# let rust_thing: RustyEnum = thing.extract()?; +# +# assert_eq!( +# "foo", +# match rust_thing { +# RustyEnum::String(i) => i, +# other => unreachable!("Error extracting: {:?}", other), +# } +# ); +# } +# +# { +# let thing = b"foo".into_pyobject(py)?; +# let error = thing.extract::().unwrap_err(); +# assert!(error.is_instance_of::(py)); +# } +# +# Ok(()) +# }) +# } +``` + +If the input is neither a string nor an integer, the error message will be: `"'' is not an instance of 'str | int'"`. + +### `#[derive(FromPyObject)]` Container Attributes + +- `pyo3(transparent)` + - extract the field directly from the object as `obj.extract()` instead of `get_item()` or + `getattr()` + - Newtype structs and tuple-variants are treated as transparent per default. + - only supported for single-field structs and enum variants +- `pyo3(annotation = "name")` + - changes the name of the failed variant in the generated error message in case of failure. + - e.g. `pyo3("int")` reports the variant's type as `int`. + - only supported for enum variants +- `pyo3(rename_all = "...")` + - renames all attributes/item keys according to the specified renaming rule + - Possible values are: "camelCase", "kebab-case", "lowercase", "PascalCase", "SCREAMING-KEBAB-CASE", "SCREAMING_SNAKE_CASE", "snake_case", "UPPERCASE". + - fields with an explicit renaming via `attribute(...)`/`item(...)` are not affected + +### `#[derive(FromPyObject)]` Field Attributes + +- `pyo3(attribute)`, `pyo3(attribute("name"))` + - retrieve the field from an attribute, possibly with a custom name specified as an argument + - argument must be a string-literal. +- `pyo3(item)`, `pyo3(item("key"))` + - retrieve the field from a mapping, possibly with the custom key specified as an argument. + - can be any literal that implements `ToBorrowedObject` +- `pyo3(from_py_with = ...)` + - apply a custom function to convert the field from Python the desired Rust type. + - the argument must be the path to the function. + - the function signature must be `fn(&Bound) -> PyResult` where `T` is the Rust type of the argument. +- `pyo3(default)`, `pyo3(default = ...)` + - if the argument is set, uses the given default value. + - in this case, the argument must be a Rust expression returning a value of the desired Rust type. + - if the argument is not set, [`Default::default`](https://doc.rust-lang.org/std/default/trait.Default.html#tymethod.default) is used. + - note that the default value is only used if the field is not set. + If the field is set and the conversion function from Python to Rust fails, an exception is raised and the default value is not used. + - this attribute is only supported on named fields. + +For example, the code below applies the given conversion function on the `"value"` dict item to compute its length or fall back to the type default value (0): + +```rust +use pyo3::prelude::*; + +#[derive(FromPyObject)] +struct RustyStruct { + #[pyo3(item("value"), default, from_py_with = Bound::<'_, PyAny>::len)] + len: usize, + #[pyo3(item)] + other: usize, +} +# +# use pyo3::types::PyDict; +# fn main() -> PyResult<()> { +# Python::attach(|py| -> PyResult<()> { +# // Filled case +# let dict = PyDict::new(py); +# dict.set_item("value", (1,)).unwrap(); +# dict.set_item("other", 1).unwrap(); +# let result = dict.extract::()?; +# assert_eq!(result.len, 1); +# assert_eq!(result.other, 1); +# +# // Empty case +# let dict = PyDict::new(py); +# dict.set_item("other", 1).unwrap(); +# let result = dict.extract::()?; +# assert_eq!(result.len, 0); +# assert_eq!(result.other, 1); +# Ok(()) +# }) +# } +``` + +### ⚠ Phase-Out of `FromPyObject` blanket implementation for cloneable PyClasses ⚠ + +Historically PyO3 has provided a blanket implementation for `#[pyclass]` types that also implement `Clone`, to allow extraction of such types by value. +Over time this has turned out problematic for a few reasons, the major one being the prevention of custom conversions by downstream crates if their type is `Clone`. +Over the next few releases the blanket implementation is gradually phased out, and eventually replaced by an opt-in option. +As a first step of this migration a new `skip_from_py_object` option for `#[pyclass]` was introduced, to opt-out of the blanket implementation and allow downstream users to provide their own implementation: + +```rust +# #![allow(dead_code)] +# use pyo3::prelude::*; + +#[pyclass(skip_from_py_object)] // opt-out of the PyO3 FromPyObject blanket +#[derive(Clone)] +struct Number(i32); + +impl<'py> FromPyObject<'_, 'py> for Number { + type Error = PyErr; + + fn extract(obj: pyo3::Borrowed<'_, 'py, pyo3::PyAny>) -> Result { + if let Ok(obj) = obj.cast::() { // first try extraction via class object + Ok(obj.borrow().clone()) + } else { + obj.extract::().map(Self) // otherwise try integer directly + } + } +} +``` + +As a second step the `from_py_object` option was introduced. +This option also opts-out of the blanket implementation and instead generates a custom `FromPyObject` implementation for the pyclass which is functionally equivalent to the blanket. + +## `IntoPyObject` + +The [`IntoPyObject`] trait defines the to-python conversion for a Rust type. +All types in PyO3 implement this trait, as does a `#[pyclass]` which doesn't use `extends`. + +This trait defines a single method, `into_pyobject()`, which returns a [`Result`] with `Ok` and `Err` types depending on the input value. +For convenience, there is a companion [`IntoPyObjectExt`] trait which adds methods such as `into_py_any()` which converts the `Ok` and `Err` types to commonly used types (in the case of `into_py_any()`, `Py` and `PyErr` respectively). + +Occasionally you may choose to implement this for custom types which are mapped to Python types *without* having a unique python type. + +### derive macro + +`IntoPyObject` can be implemented using our derive macro. +Both `struct`s and `enum`s are supported. + +`struct`s will turn into a `PyDict` using the field names as keys, tuple `struct`s will turn convert into `PyTuple` with the fields in declaration order. + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +# use std::collections::HashMap; +# use std::hash::Hash; + +// structs convert into `PyDict` with field names as keys +#[derive(IntoPyObject)] +struct Struct { + count: usize, + obj: Py, +} + +// tuple structs convert into `PyTuple` +// lifetimes and generics are supported, the impl will be bounded by +// `K: IntoPyObject, V: IntoPyObject` +#[derive(IntoPyObject)] +struct Tuple<'a, K: Hash + Eq, V>(&'a str, HashMap); +``` + +For structs with a single field (newtype pattern) the `#[pyo3(transparent)]` option can be used to forward the implementation to the inner type. + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; + +// newtype tuple structs are implicitly `transparent` +#[derive(IntoPyObject)] +struct TransparentTuple(Py); + +#[derive(IntoPyObject)] +#[pyo3(transparent)] +struct TransparentStruct<'py> { + inner: Bound<'py, PyAny>, // `'py` lifetime will be used as the Python lifetime +} +``` + +For `enum`s each variant is converted according to the rules for `struct`s above. + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +# use std::collections::HashMap; +# use std::hash::Hash; + +#[derive(IntoPyObject)] +enum Enum<'a, 'py, K: Hash + Eq, V> { // enums are supported and convert using the same + TransparentTuple(Py), // rules on the variants as the structs above + #[pyo3(transparent)] + TransparentStruct { inner: Bound<'py, PyAny> }, + Tuple(&'a str, HashMap), + Struct { count: usize, obj: Py } +} +``` + +Additionally `IntoPyObject` can be derived for a reference to a struct or enum using the `IntoPyObjectRef` derive macro. +All the same rules from above apply as well. + +#### `#[derive(IntoPyObject)]`/`#[derive(IntoPyObjectRef)]` Field Attributes + +- `pyo3(into_py_with = ...)` + - apply a custom function to convert the field from Rust into Python. + - the argument must be the function identifier + - the function signature must be `fn(Cow<'_, T>, Python<'py>) -> PyResult>` where `T` is the Rust type of the argument. + - `#[derive(IntoPyObject)]` will invoke the function with `Cow::Owned` + - `#[derive(IntoPyObjectRef)]` will invoke the function with `Cow::Borrowed` + + ```rust,no_run + # use pyo3::prelude::*; + # use pyo3::IntoPyObjectExt; + # use std::borrow::Cow; + #[derive(Clone)] + struct NotIntoPy(usize); + + #[derive(IntoPyObject, IntoPyObjectRef)] + struct MyStruct { + #[pyo3(into_py_with = convert)] + not_into_py: NotIntoPy, + } + + /// Convert `NotIntoPy` into Python + fn convert<'py>(not_into_py: Cow<'_, NotIntoPy>, py: Python<'py>) -> PyResult> { + not_into_py.0.into_bound_py_any(py) + } + ``` + +### manual implementation + +If the derive macro is not suitable for your use case, `IntoPyObject` can be implemented manually as demonstrated below. + +```rust,no_run +# use pyo3::prelude::*; +# #[allow(dead_code)] +struct MyPyObjectWrapper(Py); + +impl<'py> IntoPyObject<'py> for MyPyObjectWrapper { + type Target = PyAny; // the Python type + type Output = Bound<'py, Self::Target>; // in most cases this will be `Bound` + type Error = std::convert::Infallible; // the conversion error type, has to be convertible to `PyErr` + + fn into_pyobject(self, py: Python<'py>) -> Result { + Ok(self.0.into_bound(py)) + } +} + +// equivalent to former `ToPyObject` implementations +impl<'a, 'py> IntoPyObject<'py> for &'a MyPyObjectWrapper { + type Target = PyAny; + type Output = Borrowed<'a, 'py, Self::Target>; // `Borrowed` can be used to optimized reference counting + type Error = std::convert::Infallible; + + fn into_pyobject(self, py: Python<'py>) -> Result { + Ok(self.0.bind_borrowed(py)) + } +} +``` + +### `BoundObject` for conversions that may be `Bound` or `Borrowed` + +`IntoPyObject::into_py_object` returns either `Bound` or `Borrowed` depending on the implementation for a concrete type. +For example, the `IntoPyObject` implementation for `u32` produces a `Bound<'py, PyInt>` and the `bool` implementation produces a `Borrowed<'py, 'py, PyBool>`: + +```rust,no_run +use pyo3::prelude::*; +use pyo3::IntoPyObject; +use pyo3::types::{PyBool, PyInt}; + +let ints: Vec = vec![1, 2, 3, 4]; +let bools = vec![true, false, false, true]; + +Python::attach(|py| { + let ints_as_pyint: Vec> = ints + .iter() + .map(|x| Ok(x.into_pyobject(py)?)) + .collect::>() + .unwrap(); + + let bools_as_pybool: Vec> = bools + .iter() + .map(|x| Ok(x.into_pyobject(py)?)) + .collect::>() + .unwrap(); +}); +``` + +In this example if we wanted to combine `ints_as_pyints` and `bools_as_pybool` into a single `Vec>` to return from the `Python::attach` closure, we would have to manually convert the concrete types for the smart pointers and the python types. + +Instead, we can write a function that generically converts vectors of either integers or bools into a vector of `Py` using the [`BoundObject`] trait: + +```rust,no_run +# use pyo3::prelude::*; +# use pyo3::BoundObject; +# use pyo3::IntoPyObject; + +# let bools = vec![true, false, false, true]; +# let ints = vec![1, 2, 3, 4]; + +fn convert_to_vec_of_pyobj<'py, T>(py: Python<'py>, the_vec: Vec) -> PyResult>> +where + T: IntoPyObject<'py> + Copy +{ + the_vec.iter() + .map(|x| { + Ok( + // Note: the below is equivalent to `x.into_py_any()` + // from the `IntoPyObjectExt` trait + x.into_pyobject(py) + .map_err(Into::into)? + .into_any() + .unbind() + ) + }) + .collect() +} + +let vec_of_pyobjs: Vec> = Python::attach(|py| { + let mut bools_as_pyany = convert_to_vec_of_pyobj(py, bools).unwrap(); + let mut ints_as_pyany = convert_to_vec_of_pyobj(py, ints).unwrap(); + let mut result: Vec> = vec![]; + result.append(&mut bools_as_pyany); + result.append(&mut ints_as_pyany); + result +}); +``` + +In the example above we used `BoundObject::into_any` and `BoundObject::unbind` to manipulate the python types and smart pointers into the result type we wanted to produce from the function. + +[`FromPyObject`]: {{#PYO3_DOCS_URL}}/pyo3/conversion/trait.FromPyObject.html +[`IntoPyObject`]: {{#PYO3_DOCS_URL}}/pyo3/conversion/trait.IntoPyObject.html +[`IntoPyObjectExt`]: {{#PYO3_DOCS_URL}}/pyo3/conversion/trait.IntoPyObjectExt.html + +[`PyRef`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRef.html +[`PyRefMut`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRefMut.html +[`BoundObject`]: {{#PYO3_DOCS_URL}}/pyo3/instance/trait.BoundObject.html + +[`Result`]: https://doc.rust-lang.org/stable/std/result/enum.Result.html diff --git a/vendor/pyo3/guide/src/debugging.md b/vendor/pyo3/guide/src/debugging.md new file mode 100644 index 0000000..ad818a4 --- /dev/null +++ b/vendor/pyo3/guide/src/debugging.md @@ -0,0 +1,381 @@ +# Debugging + +## Macros + +PyO3's attributes (`#[pyclass]`, `#[pymodule]`, etc.) are [procedural macros](https://doc.rust-lang.org/reference/procedural-macros.html), which means that they rewrite the source of the annotated item. +You can view the generated source with the following command, which also expands a few other things: + +```bash +cargo rustc --profile=check -- -Z unstable-options --pretty=expanded > expanded.rs; rustfmt expanded.rs +``` + +(You might need to install [rustfmt](https://github.com/rust-lang-nursery/rustfmt) if you don't already have it.) + +You can also debug classic `!`-macros by adding `-Z trace-macros`: + +```bash +cargo rustc --profile=check -- -Z unstable-options --pretty=expanded -Z trace-macros > expanded.rs; rustfmt expanded.rs +``` + +Note that those commands require using the nightly build of rust and may occasionally have bugs. +See [cargo expand](https://github.com/dtolnay/cargo-expand) for a more elaborate and stable version of those commands. + +## Running with Valgrind + +Valgrind is a tool to detect memory management bugs such as memory leaks. + +You first need to install a debug build of Python, otherwise Valgrind won't produce usable results. +In Ubuntu there's e.g. a `python3-dbg` package. + +Activate an environment with the debug interpreter and recompile. +If you're on Linux, use `ldd` with the name of your binary and check that you're linking e.g. `libpython3.8d.so.1.0` instead of `libpython3.8.so.1.0`. + +[Download the suppressions file for CPython](https://raw.githubusercontent.com/python/cpython/master/Misc/valgrind-python.supp). + +Run Valgrind with `valgrind --suppressions=valgrind-python.supp ./my-command --with-options` + +## Getting a stacktrace + +The best start to investigate a crash such as an segmentation fault is a backtrace. +You can set `RUST_BACKTRACE=1` as an environment variable to get the stack trace on a `panic!`. +Alternatively you can use a debugger such as `gdb` to explore the issue. +Rust provides a wrapper, `rust-gdb`, which has pretty-printers for inspecting Rust variables. +Since PyO3 uses `cdylib` for Python shared objects, it does not receive the pretty-print debug hooks in `rust-gdb` ([rust-lang/rust#96365](https://github.com/rust-lang/rust/issues/96365)). +The mentioned issue contains a workaround for enabling pretty-printers in this case. + +- Link against a debug build of python as described in the previous chapter +- Run `rust-gdb ` +- Set a breakpoint (`b`) on `rust_panic` if you are investigating a `panic!` +- Enter `r` to run +- After the crash occurred, enter `bt` or `bt full` to print the stacktrace + +Often it is helpful to run a small piece of Python code to exercise a section of Rust. + +```console +rust-gdb --args python -c "import my_package; my_package.sum_to_string(1, 2)" +``` + +## Setting breakpoints in your Rust code + +One of the preferred ways by developers to debug their code is by setting breakpoints. +This can be achieved in PyO3 by using a debugger like `rust-gdb` or `rust-lldb` with your Python interpreter. + +For more information about how to use both `lldb` and `gdb` you can read the [gdb to lldb command map](https://lldb.llvm.org/use/map.html) from the lldb documentation. + +### Common setup + +1. Compile your extension module with debug symbols: + + ```bash + # Debug is the default for maturin, but you can explicitly ensure debug symbols with: + RUSTFLAGS="-g" maturin develop + + # For setuptools-rust users: + pip install -e . + ``` + + > **Note**: When using debuggers, make sure that `python` resolves to an actual Python binary or symlink and not a shim script. + > Some tools like pyenv use shim scripts which can interfere with debugging. + +### Debugger specific setup + +Depending on your OS and your preferences you can use two different debuggers, `rust-gdb` or `rust-lldb`. + +{{#tabs }} +{{#tab name="Using rust-gdb" }} + +1. Launch rust-gdb with the Python interpreter: + + ```bash + rust-gdb --args python + ``` + +2. Once in gdb, set a breakpoint in your Rust code: + + ```bash + (gdb) break your_module.rs:42 + ``` + +3. Run your Python script that imports and uses your Rust extension module: + + ```bash + # Option 1: Run an inline Python command + (gdb) run -c "import your_module; your_module.your_function()" + + # Option 2: Run a Python script + (gdb) run your_script.py + + # Option 3: Run pytest tests + (gdb) run -m pytest tests/test_something.py::TestName + ``` + +{{#endtab }} +{{#tab name="Using rust-lldb (for macOS users)" }} + +1. Start rust-lldb with Python: + + ```bash + rust-lldb -- python + ``` + +2. Set breakpoints in your Rust code: + + ```bash + (lldb) breakpoint set --file your_module.rs --line 42 + ``` + +3. Run your Python script: + + ```bash + # Option 1: Run an inline Python command + (lldb) run -c "import your_module; your_module.your_function()" + + # Option 2: Run a Python script + (lldb) run your_script.py + + # Option 3: Run pytest tests + (lldb) run -m pytest tests/test_something.py::TestName + ``` + +{{#endtab }} +{{#endtabs }} + +### Using VS Code + +VS Code with the Rust and Python extensions provides an integrated debugging experience: + +1. First, install the necessary VS Code extensions: + - [Rust Analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) + - [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb) + - [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) + +2. Create a `.vscode/launch.json` file with a configuration that uses the LLDB Debug Launcher: + + ```json + { + "version": "0.2.0", + "configurations": [ + { + "name": "Debug PyO3", + "type": "lldb", + "request": "attach", + "program": "${workspaceFolder}/.venv/bin/python", + "pid": "${command:pickProcess}", + "sourceLanguages": ["rust"] + }, + { + "name": "Launch Python with PyO3", + "type": "lldb", + "request": "launch", + "program": "${workspaceFolder}/.venv/bin/python", + "args": ["${file}"], + "cwd": "${workspaceFolder}", + "sourceLanguages": ["rust"] + }, + { + "name": "Debug PyO3 with Args", + "type": "lldb", + "request": "launch", + "program": "${workspaceFolder}/.venv/bin/python", + "args": ["path/to/your/script.py", "arg1", "arg2"], + "cwd": "${workspaceFolder}", + "sourceLanguages": ["rust"] + }, + { + "name": "Debug PyO3 Tests", + "type": "lldb", + "request": "launch", + "program": "${workspaceFolder}/.venv/bin/python", + "args": ["-m", "pytest", "tests/your_test.py::test_function", "-v"], + "cwd": "${workspaceFolder}", + "sourceLanguages": ["rust"] + } + ] + } + ``` + + This configuration supports multiple debugging scenarios: + - Attaching to a running Python process + - Launching the currently open Python file + - Running a specific script with command-line arguments + - Running pytest tests + +3. Set breakpoints in your Rust code by clicking in the gutter next to line numbers. + +4. Start debugging: + - For attaching to a running Python process: First start the process, then select the "Debug PyO3" configuration and click Start Debugging (F5). + You'll be prompted to select the Python process to attach to. + - For launching a Python script: Open your Python script, select the "Launch Python with PyO3" configuration and click Start Debugging (F5). + - For running with arguments: Select "Debug PyO3 with Args" (remember to edit the configuration with your actual script path and arguments). + - For running tests: Select "Debug PyO3 Tests" (edit the test path as needed). + +5. When debugging PyO3 code: + - You can inspect Rust variables and data structures + - Use the debug console to evaluate expressions + - Step through Rust code line by line using the step controls + - Set conditional breakpoints for more complex debugging scenarios + +### Advanced Debugging Configurations + +For advanced debugging scenarios, you might want to add environment variables or enable specific Rust debug flags: + +```json +{ + "name": "Debug PyO3 with Environment", + "type": "lldb", + "request": "launch", + "program": "${workspaceFolder}/.venv/bin/python", + "args": ["${file}"], + "env": { + "RUST_BACKTRACE": "1", + "PYTHONPATH": "${workspaceFolder}" + }, + "sourceLanguages": ["rust"] +} +``` + +### Debugging from Jupyter Notebooks + +For Jupyter Notebooks run from VS Code, you can use the following helper functions to automate the launch configuration: + +```python +from pathlib import Path +import os +import json +import sys + + +def update_launch_json(vscode_config_file_path=None): + """Update VSCode launch.json with the correct Jupyter kernel PID. + + Args: + vscode_config_file_path (str, optional): Path to the .vscode/launch.json file. + If not provided, will use the current working directory. + """ + pid = get_jupyter_kernel_pid() + if not pid: + print("Could not determine Jupyter kernel PID.") + return + + # Determine launch.json path + if vscode_config_file_path: + launch_json_path = vscode_config_file_path + else: + launch_json_path = os.path.join(Path(os.getcwd()), ".vscode", "launch.json") + + # Get Python interpreter path + python_path = sys.executable + + # Default debugger config + debug_config = { + "version": "0.2.0", + "configurations": [ + { + "name": "Debug PyO3 (Jupyter)", + "type": "lldb", + "request": "attach", + "program": python_path, + "pid": pid, + "sourceLanguages": ["rust"], + }, + { + "name": "Launch Python with PyO3", + "type": "lldb", + "request": "launch", + "program": python_path, + "args": ["${file}"], + "cwd": "${workspaceFolder}", + "sourceLanguages": ["rust"] + } + ], + } + + # Create .vscode directory if it doesn't exist + try: + os.makedirs(os.path.dirname(launch_json_path), exist_ok=True) + + # If launch.json already exists, try to update it instead of overwriting + if os.path.exists(launch_json_path): + try: + with open(launch_json_path, "r") as f: + existing_config = json.load(f) + + # Check if our configuration already exists + config_exists = False + for config in existing_config.get("configurations", []): + if config.get("name") == "Debug PyO3 (Jupyter)": + config["pid"] = pid + config["program"] = python_path + config_exists = True + + if not config_exists: + existing_config.setdefault("configurations", []).append(debug_config["configurations"][0]) + + debug_config = existing_config + except Exception: + # If reading fails, we'll just overwrite with our new configuration + pass + + with open(launch_json_path, "w") as f: + json.dump(debug_config, f, indent=4) + print(f"Updated launch.json with PID: {pid} at {launch_json_path}") + except Exception as e: + print(f"Error updating launch.json: {e}") + + +def get_jupyter_kernel_pid(): + """Find the process ID (PID) of the running Jupyter kernel. + + Returns: + int: The process ID of the Jupyter kernel, or None if not found. + """ + # Check if we're running in a Jupyter environment + if 'ipykernel' in sys.modules: + pid = os.getpid() + print(f"Jupyter kernel PID: {pid}") + return pid + else: + print("Not running in a Jupyter environment.") + return None +``` + +To use these functions: + +1. Run the cell containing these functions in your Jupyter notebook +2. Run `update_launch_json()` in a cell +3. In VS Code, select the "Debug PyO3 (Jupyter)" configuration and start debugging + +## Thread Safety and Compiler Sanitizers + +PyO3 attempts to match the Rust language-level guarantees for thread safety, but that does not preclude other code outside of the control of PyO3 or buggy code managed by a PyO3 extension module from creating a thread safety issue. +Analyzing whether or not a piece of Rust code that uses the CPython C API is thread safe can be quite complicated, since many Python operations can lead to arbitrary Python code execution. +Automated ways to discover thread safety issues can often be more fruitful than code analysis. + +[ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html) is a thread safety checking runtime that can be used to detect data races triggered by thread safety bugs or incorrect use of thread-unsafe data structures. +While it can only detect data races triggered by code at runtime, if it does detect something the reports often point to exactly where the problem is happening. + +To use `ThreadSanitizer` with a library that depends on PyO3, you will need to install a nightly Rust toolchain, along with the `rust-src` component, since you will need to compile the Rust standard library: + +```bash +rustup install nightly +rustup override set nightly +rustup component add rust-src +``` + +You will also need a version of CPython compiled using LLVM/Clang with the same major version of LLVM as is currently used to compile nightly Rust. +As of March 2025, Rust nightly uses LLVM 20. + +The [cpython_sanity docker images](https://github.com/nascheme/cpython_sanity) contain a development environment with a pre-compiled version of CPython 3.13 or 3.14 as well as optionally NumPy and SciPy, all compiled using LLVM 20 and ThreadSanitizer. + +After activating a nightly Rust toolchain, you can build your project using `ThreadSanitizer` with the following command: + +```bash +RUSTFLAGS="-Zsanitizer=thread" maturin develop -Zbuild-std --target x86_64-unknown-linux-gnu +``` + +If you are not running on an x86_64 Linux machine, you should replace `x86_64-unknown-linux-gnu` with the [target triple](https://doc.rust-lang.org/rustc/platform-support.html#tier-1-with-host-tools) that is appropriate for your system. +You can also replace `maturin develop` with `cargo test` to run `cargo` tests. +Note that `cargo` runs tests in a thread pool, so `cargo` tests can be a good way to find thread safety issues. + +You can also replace `-Zsanitizer=thread` with `-Zsanitizer=address` or any of the other sanitizers that are [supported by Rust](https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html). +Note that you'll need to build CPython from source with the appropriate [configure script flags](https://docs.python.org/3/using/configure.html#cmdoption-with-address-sanitizer) to use the same sanitizer environment as you want to use for your Rust code. diff --git a/vendor/pyo3/guide/src/ecosystem.md b/vendor/pyo3/guide/src/ecosystem.md new file mode 100644 index 0000000..6c0297e --- /dev/null +++ b/vendor/pyo3/guide/src/ecosystem.md @@ -0,0 +1,5 @@ +# The PyO3 ecosystem + +This portion of the guide is dedicated to crates which are external to the main PyO3 project and provide additional functionality you might find useful. + +Because these projects evolve independently of the PyO3 repository the content of these articles may fall out of date over time; please file issues on the PyO3 GitHub to alert maintainers when this is the case. diff --git a/vendor/pyo3/guide/src/ecosystem/async-await.md b/vendor/pyo3/guide/src/ecosystem/async-await.md new file mode 100644 index 0000000..4b291d6 --- /dev/null +++ b/vendor/pyo3/guide/src/ecosystem/async-await.md @@ -0,0 +1,15 @@ +# Using `async` and `await` + +*`async`/`await` support is currently being integrated in PyO3.* +*See the [dedicated documentation](../async-await.md)* + +If you are working with a Python library that makes use of async functions or wish to provide Python bindings for an async Rust library, [`pyo3-async-runtimes`](https://github.com/PyO3/pyo3-async-runtimes) likely has the tools you need. +It provides conversions between async functions in both Python and Rust and was designed with first-class support for popular Rust runtimes such as [`tokio`](https://tokio.rs/) and [`async-std`](https://docs.rs/async-std/latest/async_std/). +In addition, all async Python code runs on the default `asyncio` event loop, so `pyo3-async-runtimes` should work just fine with existing Python libraries. + +## Additional Information + +- Managing event loop references can be tricky with `pyo3-async-runtimes`. + See [Event Loop References](https://docs.rs/pyo3-async-runtimes/#event-loop-references-and-contextvars) in the API docs to get a better intuition for how event loop references are managed in this library. +- Testing `pyo3-async-runtimes` libraries and applications requires a custom test harness since Python requires control over the main thread. + You can find a testing guide in the [API docs for the `testing` module](https://docs.rs/pyo3-async-runtimes/latest/pyo3_async_runtimes/testing) diff --git a/vendor/pyo3/guide/src/ecosystem/logging.md b/vendor/pyo3/guide/src/ecosystem/logging.md new file mode 100644 index 0000000..3b8a3f3 --- /dev/null +++ b/vendor/pyo3/guide/src/ecosystem/logging.md @@ -0,0 +1,93 @@ +# Logging + +It is desirable if both the Python and Rust parts of the application end up logging using the same configuration into the same place. + +This section of the guide briefly discusses how to connect the two languages' logging ecosystems together. +The recommended way for Python extension modules is to configure Rust's logger to send log messages to Python using the `pyo3-log` crate. +For users who want to do the opposite and send Python log messages to Rust, see the note at the end of this guide. + +## Using `pyo3-log` to send Rust log messages to Python + +The [pyo3-log] crate allows sending the messages from the Rust side to Python's [logging] system. +This is mostly suitable for writing extension modules to consume from Python programs. + +Use [`pyo3_log::init`][init] to install the logger in its default configuration. +It's also possible to tweak its configuration (mostly to tune its performance). + +```rust,no_run +#[pyo3::pymodule] +mod my_module { + use log::info; + use pyo3::prelude::*; + + #[pyfunction] + fn log_something() { + // This will use the logger installed in `my_module` to send the `info` + // message to the Python logging facilities. + info!("Something!"); + } + + #[pymodule_init] + fn init(m: &Bound<'_, PyModule>) -> PyResult<()> { + // A good place to install the Rust -> Python logger. + pyo3_log::init(); + } +} +``` + +Then it is up to the Python side to actually output the messages somewhere. + +```python +import logging +import my_module + +FORMAT = '%(levelname)s %(name)s %(asctime)-15s %(filename)s:%(lineno)d %(message)s' +logging.basicConfig(format=FORMAT) +logging.getLogger().setLevel(logging.INFO) +my_module.log_something() +``` + +It is important to initialize the Python loggers first, before calling any Rust functions that may log. +This limitation can be worked around if it is not possible to satisfy, read the documentation about [caching]. + +## The Python to Rust direction + +To have python logs be handled by Rust, one need only register a rust function to handle logs emitted from the core python logging module. + +This has been implemented within the [pyo3-pylogger] crate. + +```rust,no_run +use log::{info, warn}; +use pyo3::prelude::*; + +fn main() -> PyResult<()> { + // register the host handler with python logger, providing a logger target + // set the name here to something appropriate for your application + pyo3_pylogger::register("example_application_py_logger"); + + // initialize up a logger + env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("trace")).init(); + + // Log some messages from Rust. + info!("Just some normal information!"); + warn!("Something spooky happened!"); + + // Log some messages from Python + Python::attach(|py| { + py.run( + " +import logging +logging.error('Something bad happened') +", + None, + None, + ) + }) +} +``` + +[logging]: https://docs.python.org/3/library/logging.html +[pyo3-log]: https://crates.io/crates/pyo3-log +[init]: https://docs.rs/pyo3-log/*/pyo3_log/fn.init.html +[caching]: https://docs.rs/pyo3-log/*/pyo3_log/#performance-filtering-and-caching +[pyo3-pylogger]: https://crates.io/crates/pyo3-pylogger diff --git a/vendor/pyo3/guide/src/ecosystem/tracing.md b/vendor/pyo3/guide/src/ecosystem/tracing.md new file mode 100644 index 0000000..bac29e5 --- /dev/null +++ b/vendor/pyo3/guide/src/ecosystem/tracing.md @@ -0,0 +1,96 @@ +# Tracing + +Python projects that write extension modules for performance reasons may want to tap into [Rust's `tracing` ecosystem] to gain insight into the performance of their extension module. + +This section of the guide describes a few crates that provide ways to do that. +They build on [`tracing_subscriber`][tracing-subscriber] and require code changes in both Python and Rust to integrate. +Note that each extension module must configure its own `tracing` integration; one extension module will not see `tracing` data from a different module. + +## `pyo3-tracing-subscriber` ([documentation][pyo3-tracing-subscriber-docs]) + +[`pyo3-tracing-subscriber`][pyo3-tracing-subscriber] provides a way for Python projects to configure `tracing_subscriber`. +It exposes a few `tracing_subscriber` layers: + +- `tracing_subscriber::fmt` for writing human-readable output to file or stdout +- `opentelemetry-stdout` for writing OTLP output to file or stdout +- `opentelemetry-otlp` for writing OTLP output to an OTLP endpoint + +The extension module must call [`pyo3_tracing_subscriber::add_submodule`][add-submodule] to export the Python classes needed to configure and initialize `tracing`. + +On the Python side, use the `Tracing` context manager to initialize tracing and run Rust code inside the context manager's block. `Tracing` takes a `GlobalTracingConfig` instance describing the layers to be used. + +See [the README on crates.io][pyo3-tracing-subscriber] for example code. + +## `pyo3-python-tracing-subscriber` ([documentation][pyo3-python-tracing-subscriber-docs]) + +The similarly-named [`pyo3-python-tracing-subscriber`][pyo3-python-tracing-subscriber] implements a shim in Rust that forwards `tracing` data to a `Layer` implementation defined in and passed in from Python. + +There are many ways an extension module could integrate `pyo3-python-tracing-subscriber` but a simple one may look something like this: + +```rust,no_run +#[tracing::instrument] +#[pyfunction] +fn fibonacci(index: usize, use_memoized: bool) -> PyResult { + // ... +} + +#[pyfunction] +pub fn initialize_tracing(py_impl: Bound<'_, PyAny>) { + tracing_subscriber::registry() + .with(pyo3_python_tracing_subscriber::PythonCallbackLayerBridge::new(py_impl)) + .init(); +} +``` + +The extension module must provide some way for Python to pass in one or more Python objects that implement [the `Layer` interface]. +Then it should construct [`pyo3_python_tracing_subscriber::PythonCallbackLayerBridge`][PythonCallbackLayerBridge] instances with each of those Python objects and initialize `tracing_subscriber` as shown above. + +The Python objects implement a modified version of the `Layer` interface: + +- `on_new_span()` may return some state that will stored inside the Rust span +- other callbacks will be given that state as an additional positional argument + +A dummy `Layer` implementation may look like this: + +```python +import rust_extension + +class MyPythonLayer: + def __init__(self): + pass + + # `on_new_span` can return some state + def on_new_span(self, span_attrs: str, span_id: str) -> int: + print(f"[on_new_span]: {span_attrs} | {span_id}") + return random.randint(1, 1000) + + # The state from `on_new_span` is passed back into other trait methods + def on_event(self, event: str, state: int): + print(f"[on_event]: {event} | {state}") + + def on_close(self, span_id: str, state: int): + print(f"[on_close]: {span_id} | {state}") + + def on_record(self, span_id: str, values: str, state: int): + print(f"[on_record]: {span_id} | {values} | {state}") + +def main(): + rust_extension.initialize_tracing(MyPythonLayer()) + + print("10th fibonacci number: ", rust_extension.fibonacci(10, True)) +``` + +`pyo3-python-tracing-subscriber` has [working examples] showing both the Rust side and the Python side of an integration. + +[pyo3-tracing-subscriber]: https://crates.io/crates/pyo3-tracing-subscriber +[pyo3-tracing-subscriber-docs]: https://docs.rs/pyo3-tracing-subscriber +[add-submodule]: https://docs.rs/pyo3-tracing-subscriber/*/pyo3_tracing_subscriber/fn.add_submodule.html + +[pyo3-python-tracing-subscriber]: https://crates.io/crates/pyo3-python-tracing-subscriber +[pyo3-python-tracing-subscriber-docs]: https://docs.rs/pyo3-python-tracing-subscriber +[PythonCallbackLayerBridge]: https://docs.rs/pyo3-python-tracing-subscriber/*/pyo3_python_tracing_subscriber/struct.PythonCallbackLayerBridge.html +[working examples]: https://github.com/getsentry/pyo3-python-tracing-subscriber/tree/main/demo + +[Rust's `tracing` ecosystem]: https://crates.io/crates/tracing +[tracing-subscriber]: https://docs.rs/tracing-subscriber/*/tracing_subscriber/ +[the `Layer` interface]: https://docs.rs/tracing-subscriber/*/tracing_subscriber/layer/trait.Layer.html diff --git a/vendor/pyo3/guide/src/exception.md b/vendor/pyo3/guide/src/exception.md new file mode 100644 index 0000000..b46655f --- /dev/null +++ b/vendor/pyo3/guide/src/exception.md @@ -0,0 +1,180 @@ +# Python exceptions + +## Defining a new exception + +Use the [`create_exception!`] macro: + +```rust +use pyo3::create_exception; + +create_exception!(module, MyError, pyo3::exceptions::PyException); +``` + +- `module` is the name of the containing module. +- `MyError` is the name of the new exception type. + +For example: + +```rust +use pyo3::prelude::*; +use pyo3::create_exception; +use pyo3::types::IntoPyDict; +use pyo3::exceptions::PyException; + +create_exception!(mymodule, CustomError, PyException); + +# fn main() -> PyResult<()> { +Python::attach(|py| { + let ctx = [("CustomError", py.get_type::())].into_py_dict(py)?; + pyo3::py_run!( + py, + *ctx, + "assert str(CustomError) == \"\"" + ); + pyo3::py_run!(py, *ctx, "assert CustomError('oops').args == ('oops',)"); +# Ok(()) +}) +# } +``` + +When using PyO3 to create an extension module, you can add the new exception to the module like this, so that it is importable from Python: + +```rust,no_run +# fn main() {} +use pyo3::prelude::*; +use pyo3::exceptions::PyException; + +pyo3::create_exception!(mymodule, CustomError, PyException); + +#[pymodule] +mod mymodule { + #[pymodule_export] + use super::CustomError; + + // ... other elements added to module ... +} +``` + +## Raising an exception + +As described in the [function error handling](./function/error-handling.md) chapter, to raise an exception from a `#[pyfunction]` or `#[pymethods]`, return an `Err(PyErr)`. +PyO3 will automatically raise this exception for you when returning the result to Python. + +You can also manually write and fetch errors in the Python interpreter's global state: + +```rust +use pyo3::{Python, PyErr}; +use pyo3::exceptions::PyTypeError; + +Python::attach(|py| { + PyTypeError::new_err("Error").restore(py); + assert!(PyErr::occurred(py)); + drop(PyErr::fetch(py)); +}); +``` + +## Checking exception types + +Python has an [`isinstance`](https://docs.python.org/3/library/functions.html#isinstance) method to check an object's type. +In PyO3 every object has the [`PyAny::is_instance`] and [`PyAny::is_instance_of`] methods which do the same thing. + +```rust,no_run +use pyo3::prelude::*; +use pyo3::types::{PyBool, PyList}; + +# fn main() -> PyResult<()> { +Python::attach(|py| { + assert!(PyBool::new(py, true).is_instance_of::()); + let list = PyList::new(py, &[1, 2, 3, 4])?; + assert!(!list.is_instance_of::()); + assert!(list.is_instance_of::()); +# Ok(()) +}) +# } +``` + +To check the type of an exception, you can similarly do: + +```rust,no_run +# use pyo3::exceptions::PyTypeError; +# use pyo3::prelude::*; +# Python::attach(|py| { +# let err = PyTypeError::new_err(()); +err.is_instance_of::(py); +# }); +``` + +## Using exceptions defined in Python code + +It is possible to use an exception defined in Python code as a native Rust type. +The [`import_exception!`] macro allows importing a specific exception class and defines a Rust type for that exception. + +```rust,no_run +#![allow(dead_code)] +use pyo3::prelude::*; + +mod io { + pyo3::import_exception!(io, UnsupportedOperation); +} + +fn tell(file: &Bound<'_, PyAny>) -> PyResult { + match file.call_method0("tell") { + Err(_) => Err(io::UnsupportedOperation::new_err("not supported: tell")), + Ok(x) => x.extract::(), + } +} +``` + +[`pyo3::exceptions`]({{#PYO3_DOCS_URL}}/pyo3/exceptions/index.html) defines exceptions for several standard library modules. + +## Creating more complex exceptions + +If you need to create an exception with more complex behavior, you can also manually create a subclass of `PyException`: + +```rust +#![allow(dead_code)] +# #[cfg(any(not(Py_LIMITED_API), Py_3_12))] { +use pyo3::prelude::*; +use pyo3::types::IntoPyDict; +use pyo3::exceptions::PyException; + +#[pyclass(extends=PyException)] +struct CustomError { + #[pyo3(get)] + url: String, + + #[pyo3(get)] + message: String, +} + +#[pymethods] +impl CustomError { + #[new] + fn new(url: String, message: String) -> Self { + Self { url, message } + } +} + +# fn main() -> PyResult<()> { +Python::attach(|py| { + let ctx = [("CustomError", py.get_type::())].into_py_dict(py)?; + pyo3::py_run!( + py, + *ctx, + "assert str(CustomError) == \"\", repr(CustomError)" + ); + pyo3::py_run!(py, *ctx, "assert CustomError('https://example.com', 'something went bad').args == ('https://example.com', 'something went bad')"); + pyo3::py_run!(py, *ctx, "assert CustomError('https://example.com', 'something went bad').url == 'https://example.com'"); +# Ok(()) +}) +# } +# } + +``` + +Note that when the `abi3` feature is enabled, subclassing `PyException` is only possible on Python 3.12 or greater. + +[`create_exception!`]: {{#PYO3_DOCS_URL}}/pyo3/macro.create_exception.html +[`import_exception!`]: {{#PYO3_DOCS_URL}}/pyo3/macro.import_exception.html +[`PyAny::is_instance`]: {{#PYO3_DOCS_URL}}/pyo3/types/trait.PyAnyMethods.html#tymethod.is_instance +[`PyAny::is_instance_of`]: {{#PYO3_DOCS_URL}}/pyo3/types/trait.PyAnyMethods.html#tymethod.is_instance_of diff --git a/vendor/pyo3/guide/src/faq.md b/vendor/pyo3/guide/src/faq.md new file mode 100644 index 0000000..c167607 --- /dev/null +++ b/vendor/pyo3/guide/src/faq.md @@ -0,0 +1,199 @@ +# Frequently Asked Questions and troubleshooting + +Sorry that you're having trouble using PyO3. +If you can't find the answer to your problem in the list below, you can also reach out for help on [GitHub Discussions](https://github.com/PyO3/pyo3/discussions) and on [Discord](https://discord.gg/33kcChzH7f). + +## I'm experiencing deadlocks using PyO3 with `std::sync::OnceLock`, `std::sync::LazyLock`, `lazy_static`, and `once_cell` + +`OnceLock`, `LazyLock`, and their thirdparty predecessors use blocking to ensure only one thread ever initializes them. +Because the Python interpreter can introduce additional locks (the Python GIL and GC can both require all other threads to pause) this can lead to deadlocks in the following way: + +1. A thread (thread A) which is attached to the Python interpreter starts initialization of a `OnceLock` value. +2. The initialization code calls some Python API which temporarily detaches from the interpreter e.g. `Python::import`. +3. Another thread (thread B) attaches to the Python interpreter and attempts to access the same `OnceLock` value. +4. Thread B is blocked, because it waits for `OnceLock`'s initialization to lock to release. +5. On GIL-enabled Python, thread A is now also blocked, because it waits to re-attach to the interpreter (by taking the GIL which thread B still holds). +6. Deadlock. + +PyO3 provides a struct [`PyOnceLock`] which implements a single-initialization API based on these types that avoids deadlocks. +You can also make use of the [`OnceExt`] and [`OnceLockExt`] extension traits that enable using the standard library types for this purpose by providing new methods for these types that avoid the risk of deadlocking with the Python interpreter. +This means they can be used in place of other choices when you are experiencing the deadlock described above. +See the documentation for [`PyOnceLock`] and [`OnceExt`] for further details and an example how to use them. + +[`PyOnceLock`]: {{#PYO3_DOCS_URL}}/pyo3/sync/struct.PyOnceLock.html +[`OnceExt`]: {{#PYO3_DOCS_URL}}/pyo3/sync/trait.OnceExt.html +[`OnceLockExt`]: {{#PYO3_DOCS_URL}}/pyo3/sync/trait.OnceLockExt.html + +## I can't run `cargo test`; or I can't build in a Cargo workspace: I'm having linker issues like "Symbol not found" or "Undefined reference to _PyExc_SystemError" + +The `extension-module` feature (now deprecated) disables linking to `libpython`. +This breaks binaries and tests which need to load symbols from `libpython` to execute. + +Remove the `extension-module` feature and upgrade to `maturin >= 1.9.4` or `setuptools-rust 1.12`. + +If building manually, see the [`PYO3_BUILD_EXTENSION_MODULE` environment variable](./building-and-distribution.md#the-pyo3_build_extension_module-environment-variable). + +## I can't run `cargo test`: my crate cannot be found for tests in `tests/` directory + +The Rust book suggests to [put integration tests inside a `tests/` directory](https://doc.rust-lang.org/book/ch11-03-test-organization.html#integration-tests). + +For a PyO3 project where the `crate-type` is set to `"cdylib"` in your `Cargo.toml`, the compiler won't be able to find your crate and will display errors such as `E0432` or `E0463`: + +```text +error[E0432]: unresolved import `my_crate` + --> tests/test_my_crate.rs:1:5 + | +1 | use my_crate; + | ^^^^^^^^^^^^ no external crate `my_crate` +``` + +The best solution is to make your crate types include both `rlib` and `cdylib`: + +```toml +# Cargo.toml +[lib] +crate-type = ["cdylib", "rlib"] +``` + +## Ctrl-C doesn't do anything while my Rust code is executing + +This is because Ctrl-C raises a SIGINT signal, which is handled by the calling Python process by simply setting a flag to action upon later. +This flag isn't checked while Rust code called from Python is executing, only once control returns to the Python interpreter. + +You can give the Python interpreter a chance to process the signal properly by calling `Python::check_signals`. +It's good practice to call this function regularly if you have a long-running Rust function so that your users can cancel it. + +## `#[pyo3(get)]` clones my field + +You may have a nested struct similar to this: + +```rust,no_run +# use pyo3::prelude::*; +#[pyclass(from_py_object)] +#[derive(Clone)] +struct Inner {/* fields omitted */} + +#[pyclass] +struct Outer { + #[pyo3(get)] + inner: Inner, +} + +#[pymethods] +impl Outer { + #[new] + fn __new__() -> Self { + Self { inner: Inner {} } + } +} +``` + +When Python code accesses `Outer`'s field, PyO3 will return a new object on every access (note that their addresses are different): + +```python +outer = Outer() + +a = outer.inner +b = outer.inner + +assert a is b, f"a: {a}\nb: {b}" +``` + +```text +AssertionError: a: +b: +``` + +This can be especially confusing if the field is mutable, as getting the field and then mutating it won't persist - you'll just get a fresh clone of the original on the next access. +Unfortunately Python and Rust don't agree about ownership - if PyO3 gave out references to (possibly) temporary Rust objects to Python code, Python code could then keep that reference alive indefinitely. +Therefore returning Rust objects requires cloning. + +If you don't want that cloning to happen, a workaround is to allocate the field on the Python heap and store a reference to that, by using [`Py<...>`]({{#PYO3_DOCS_URL}}/pyo3/struct.Py.html): + +```rust,no_run +# use pyo3::prelude::*; +#[pyclass] +struct Inner {/* fields omitted */} + +#[pyclass] +struct Outer { + inner: Py, +} + +#[pymethods] +impl Outer { + #[new] + fn __new__(py: Python<'_>) -> PyResult { + Ok(Self { + inner: Py::new(py, Inner {})?, + }) + } + + #[getter] + fn inner(&self, py: Python<'_>) -> Py { + self.inner.clone_ref(py) + } +} +``` + +This time `a` and `b` *are* the same object: + +```python +outer = Outer() + +a = outer.inner +b = outer.inner + +assert a is b, f"a: {a}\nb: {b}" +print(f"a: {a}\nb: {b}") +``` + +```text +a: +b: +``` + +The downside to this approach is that any Rust code working on the `Outer` struct potentially has to attach to the Python interpreter to do anything with the `inner` field. (If `Inner` is `#[pyclass(frozen)]` and implements `Sync`, then `Py::get` may be used to access the `Inner` contents from `Py` without needing to attach to the interpreter.) + +## I want to use the `pyo3` crate re-exported from dependency but the proc-macros fail + +All PyO3 proc-macros (`#[pyclass]`, `#[pyfunction]`, `#[derive(FromPyObject)]` and so on) expect the `pyo3` crate to be available under that name in your crate root, which is the normal situation when `pyo3` is a direct dependency of your crate. + +However, when the dependency is renamed, or your crate only indirectly depends on `pyo3`, you need to let the macro code know where to find the crate. +This is done with the `crate` attribute: + +```rust,no_run +# use pyo3::prelude::*; +# pub extern crate pyo3; +# mod reexported { pub use ::pyo3; } +# #[allow(dead_code)] +#[pyclass] +#[pyo3(crate = "reexported::pyo3")] +struct MyClass; +``` + +## I'm trying to call Python from Rust but I get `STATUS_DLL_NOT_FOUND` or `STATUS_ENTRYPOINT_NOT_FOUND` + +This happens on Windows when linking to the python DLL fails or the wrong one is linked. +The Python DLL on Windows will usually be called something like: + +- `python3X.dll` for Python 3.X, e.g. `python310.dll` for Python 3.10 +- `python3.dll` when using PyO3's `abi3` feature +- `python3t.dll` when using PyO3's `abi3t` feature + +The DLL needs to be locatable using the [Windows DLL search order](https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#standard-search-order-for-unpackaged-apps). +Some ways to achieve this are: + +- Put the Python DLL in the same folder as your build artifacts +- Add the directory containing the Python DLL to your `PATH` environment variable, for example `C:\Users\\AppData\Local\Programs\Python\Python310` +- If this happens when you are *distributing* your program, consider using [PyOxidizer](https://github.com/indygreg/PyOxidizer) to package it with your binary. +- The legacy MSI Python installer for Python 3.15 installs `python3t.dll` into an `abi3t_compat` subfolder of the main Python installation. + Add that folder to your PATH as well if you are using `abi3t` features on Python 3.15. + +If the wrong DLL is linked it is possible that this happened because another program added itself and its own Python DLLs to `PATH`. +Rearrange your `PATH` variables to give the correct DLL priority. + +> [!NOTE] +> Changes to `PATH` (or any other environment variable) are not visible to existing shells. Restart it for changes to take effect. + +For advanced troubleshooting, [Dependency Walker](https://www.dependencywalker.com/) can be used to diagnose linking errors. diff --git a/vendor/pyo3/guide/src/features.md b/vendor/pyo3/guide/src/features.md new file mode 100644 index 0000000..ce60be8 --- /dev/null +++ b/vendor/pyo3/guide/src/features.md @@ -0,0 +1,325 @@ +# Features reference + +PyO3 provides a number of Cargo features to customize functionality. +This chapter of the guide provides detail on each of them. + +By default, only the `macros` feature is enabled. + +## Features to select the target ABI + +Each version of CPython exposes an ABI corresponding to the C API that is particular to that version. +Extensions built for this "version-specific" ABI can only be imported by Python interpreters with the same major version, since the Python C API and ABI are subject to change in every major release. +Python also supports a [limited API](https://docs.python.org/3/c-api/stable.html#limited-c-api) and [stable ABI](https://docs.python.org/3/c-api/stable.html#stable-abi). +Extensions targeting the stable ABI defined by Python 3.X can be imported by any subsequent Python version newer than Python 3.X, but not older versions. + +There are two "flavors" of stable ABI: `abi3`, supported on Python 3.2 and newer but *not* the free-threaded builds and `abi3t`, supported on Python 3.15 and newer for both the GIL-enabled and free-threaded builds of Python. +PyO3 supports building extensions targeting both flavors of stable ABI. + +When PyO3 finds a "host" python interpreter and no `abi3` or `abi3t` feature is active, it will generate extensions targeting the version-specific ABI for the host Python version. +For example, when ``pip`` or ``uv`` installs a Python package that includes Rust dependencies that depend on PyO3, the host interpreter is the interpreter running ``pip`` or the interpreter from the activated ``uv`` environment. + +To build for the stable ABIs, you must activate an `abi3` and/or an `abi3t` feature. +You can simultaneously activate both features. +This will produce an `abi3` extension on the GIL-enabled and a version-specific extension on Python 3.14 and an `abi3t` extension on Python 3.15 and newer. + +### `abi3` + +This feature is used when building Python extension modules to create wheels which are compatible with multiple Python versions but not the free-threaded build. + +It restricts PyO3's API to a subset of the full Python API which is guaranteed by [PEP 384](https://www.python.org/dev/peps/pep-0384/) to be forwards-compatible with future Python versions. + +Since no particular "target" Python version is implied by this feature, it will generate an `abi3` extension targeting the stable ABI defined by the "host" Python interpreter. +As such, this feature requires a host Python interpreter is present and cannot be used for cross-compilation. + +If you are using this feature to distribute extensions, you should ensure your minimum supported Python version is installed to do the build. +However, see the description of the `abi3-pyXY` feature if you would like to generate extensions targeting an older Python version using a recent Python interpreter. + +See the [building and distribution](building-and-distribution.md#py_limited_apiabi3abi3t) section for further detail. + +### The `abi3-pyXY` features + +(`abi3-py38`, `abi3-py39`, `abi3-py310`, `abi3-py311`, `abi3-py312`, `abi3-py313` and `abi3-py314`) + +These features are extensions of the `abi3` feature to specify the exact minimum Python version which the multiple-version-wheel will support. + +They can be used to target versions of the ABI defined by Python versions released before the "host" python interpreter. +They can also be used without any host interpreter at all to cross-compile. + +See the [building and distribution](building-and-distribution.md#minimum-python-version-for-abi3-and-abi3t-builds) section for further detail. + +### `abi3t` + +This feature is used when building Python extension modules to create wheels which are compatible with Python 3.15 or newer, targeting both the free-threaded and GIL-enabled build with a single extension module. + +It restricts PyO3's API to a subset of the full Python API which is guaranteed by [PEP 384](https://www.python.org/dev/peps/pep-0384/) and [PEP 803](https://www.python.org/dev/peps/pep-0803/) to be forwards-compatible with future Python versions and be importable by the free-threaded and GIL-enabled interpreter. + +Since no particular "target" Python version is implied by this feature, it will generate an `abi3` extension targeting the stable ABI defined by the "host" Python interpreter. +As such, this feature requires a host Python interpreter is present and cannot be used for cross-compilation. + +If you are using this feature to distribute extensions, you should ensure your minimum supported Python version is installed to do the build. +However, see the description of the `abi3t-pyXY` feature if you would like to generate extensions targeting an older Python version using a recent Python interpreter. + +Activating an `abi3t` and targeting Python 3.14 and older is a no-op: the build will produce an extension but it will not be an `abi3t` extension, since `abi3t` is unsupported before Python 3.15. + +See the [building and distribution](building-and-distribution.md#py_limited_apiabi3abi3t) section for further detail. + +### The `abi3t-pyXY` features + +(`abi3t-py315`) + +These features are extensions of the `abi3t` feature to specify the exact minimum Python version which the multiple-version-wheel will support. + +They can be used to target versions of the ABI defined by Python versions released before the "host" python interpreter. +They can also be used without any host interpreter at all to cross-compile. + +Activating an `abi3t` and targeting Python 3.14 and older is a no-op: the build will produce an extension but it will not be an `abi3t` extension, since `abi3t` is unsupported before Python 3.15. + +See the [building and distribution](building-and-distribution.md#minimum-python-version-for-abi3-and-abi3t-builds) section for further detail. + +## Features for embedding Python in Rust + +### `auto-initialize` + +This feature changes [`Python::attach`]({{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#method.attach) to automatically initialize a Python interpreter (by calling [`Python::initialize`]({{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#method.initialize)) if needed. + +If you do not enable this feature, you should call `Python::initialize()` before attempting to call any other Python APIs. + +## Advanced Features + +### `experimental-async` + +This feature adds support for `async fn` in `#[pyfunction]` and `#[pymethods]`. + +The feature has some unfinished refinements and performance improvements. +To help finish this off, see [issue #1632](https://github.com/PyO3/pyo3/issues/1632) and its associated draft PRs. + +### `experimental-inspect` + +This feature adds to the built binaries introspection data that can be then retrieved using the `pyo3-introspection` crate to generate [type stubs](https://typing.readthedocs.io/en/latest/source/stubs.html). + +Also, this feature adds the `pyo3::inspect` module, as well as `IntoPy::type_output` and `FromPyObject::type_input` APIs to produce Python type "annotations" for Rust types. + +This is a first step towards adding first-class support for generating type annotations automatically in PyO3, however work is needed to finish this off. +All feedback and offers of help welcome on [issue #2454](https://github.com/PyO3/pyo3/issues/2454). + +### `py-clone` + +This feature was introduced to ease migration. +It was found that delayed reference counting (which PyO3 used historically) could not be made sound and hence `Clone`-ing an instance of `Py` is impossible when not attached to Python interpreter (it will panic). +To avoid migrations introducing new panics without warning, the `Clone` implementation itself is now gated behind this feature. + +### `pyo3_disable_reference_pool` + +This is a performance-oriented conditional compilation flag, e.g. [set via `$RUSTFLAGS`][set-configuration-options], which disabled the global reference pool and the associated overhead for the crossing the Python-Rust boundary. +However, if enabled, `Drop`ping an instance of `Py` when not attached to the Python interpreter will abort the process. + +### `macros` + +This feature enables a dependency on the `pyo3-macros` crate, which provides the procedural macros portion of PyO3's API: + +- `#[pymodule]` +- `#[pyfunction]` +- `#[pyclass]` +- `#[pymethods]` +- `#[derive(FromPyObject)]` + +It also provides the `py_run!` macro. + +These macros require a number of dependencies which may not be needed by users who just need PyO3 for Python FFI. +Disabling this feature enables faster builds for those users, as these dependencies will not be built if this feature is disabled. + +> [!NOTE] +> This feature is enabled by default. +> To disable it, set `default-features = false` for the `pyo3` entry in your Cargo.toml. + +### `multiple-pymethods` + +This feature enables each `#[pyclass]` to have more than one `#[pymethods]` block. + +Most users should only need a single `#[pymethods]` per `#[pyclass]`. +In addition, not all platforms (e.g. Wasm) are supported by `inventory`, which is used in the implementation of the feature. +For this reason this feature is not enabled by default, meaning fewer dependencies and faster compilation for the majority of users. + +See [the `#[pyclass]` implementation details](class.md#implementation-details) for more information. + +### `nightly` + +The `nightly` feature needs the nightly Rust compiler. +This allows PyO3 to use the `auto_traits` and `negative_impls` features to fix the `Python::detach` function. + +## Optional Dependencies + +These features enable conversions between Python types and types from other Rust crates, enabling easy access to the rest of the Rust ecosystem. + +### `anyhow` + +Adds a dependency on [anyhow](https://docs.rs/anyhow). +Enables a conversion from [anyhow](https://docs.rs/anyhow)’s [`Error`](https://docs.rs/anyhow/latest/anyhow/struct.Error.html) type to [`PyErr`]({{#PYO3_DOCS_URL}}/pyo3/struct.PyErr.html), for easy error handling. + +### `arc_lock` + +Enables Pyo3's `MutexExt` trait for all Mutexes that extend on [`lock_api::Mutex`](https://docs.rs/lock_api/latest/lock_api/struct.Mutex.html) or [`parking_lot::ReentrantMutex`](https://docs.rs/lock_api/latest/lock_api/struct.ReentrantMutex.html) and are wrapped in an [`Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html) type. +Like [`Arc`](https://docs.rs/parking_lot/latest/parking_lot/type.Mutex.html#method.lock_arc) + +### `bigdecimal` + +Adds a dependency on [bigdecimal](https://docs.rs/bigdecimal) and enables conversions into its [`BigDecimal`](https://docs.rs/bigdecimal/latest/bigdecimal/struct.BigDecimal.html) type. + +### `bytes` + +Adds a dependency on [bytes](https://docs.rs/bytes/latest/bytes) and enables conversions into its [`Bytes`](https://docs.rs/bytes/latest/bytes/struct.Bytes.html) type. + +### `chrono` + +Adds a dependency on [chrono](https://docs.rs/chrono). +Enables a conversion from [chrono](https://docs.rs/chrono)'s types to python: + +- [TimeDelta](https://docs.rs/chrono/latest/chrono/struct.TimeDelta.html) -> [`PyDelta`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDelta.html) +- [FixedOffset](https://docs.rs/chrono/latest/chrono/offset/struct.FixedOffset.html) -> [`PyDelta`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDelta.html) +- [Utc](https://docs.rs/chrono/latest/chrono/offset/struct.Utc.html) -> [`PyTzInfo`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyTzInfo.html) +- [NaiveDate](https://docs.rs/chrono/latest/chrono/naive/struct.NaiveDate.html) -> [`PyDate`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDate.html) +- [NaiveTime](https://docs.rs/chrono/latest/chrono/naive/struct.NaiveTime.html) -> [`PyTime`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyTime.html) +- [DateTime](https://docs.rs/chrono/latest/chrono/struct.DateTime.html) -> [`PyDateTime`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDateTime.html) + +### `chrono-local` + +Enables conversion from and to [Local](https://docs.rs/chrono/latest/chrono/struct.Local.html) timezones. +The current system timezone as determined by [`iana_time_zone::get_timezone()`](https://docs.rs/iana-time-zone/latest/iana_time_zone/fn.get_timezone.html) will be used for conversions. + +`chrono::DateTime` will convert from either of: + +- `datetime` objects with `tzinfo` equivalent to the current system timezone. +- "naive" `datetime` objects (those without a `tzinfo`), as it is a convention that naive datetime objects should be treated as using the system timezone. + +When converting to Python, `Local` tzinfo is converted to a `zoneinfo.ZoneInfo` matching the current system timezone. + +### `chrono-tz` + +Adds a dependency on [chrono-tz](https://docs.rs/chrono-tz). +Enables conversion from and to [`Tz`](https://docs.rs/chrono-tz/latest/chrono_tz/enum.Tz.html). + +### `either` + +Adds a dependency on [either](https://docs.rs/either). +Enables a conversions into [either](https://docs.rs/either)’s [`Either`](https://docs.rs/either/latest/either/enum.Either.html) type. + +### `eyre` + +Adds a dependency on [eyre](https://docs.rs/eyre). +Enables a conversion from [eyre](https://docs.rs/eyre)’s [`Report`](https://docs.rs/eyre/latest/eyre/struct.Report.html) type to [`PyErr`]({{#PYO3_DOCS_URL}}/pyo3/struct.PyErr.html), for easy error handling. + +### `hashbrown` + +Adds a dependency on [hashbrown](https://docs.rs/hashbrown) and enables conversions into its [`HashMap`](https://docs.rs/hashbrown/latest/hashbrown/struct.HashMap.html) and [`HashSet`](https://docs.rs/hashbrown/latest/hashbrown/struct.HashSet.html) types. + +### `indexmap` + +Adds a dependency on [indexmap](https://docs.rs/indexmap) and enables conversions into its [`IndexMap`](https://docs.rs/indexmap/latest/indexmap/map/struct.IndexMap.html) type. + +### `jiff-02` + +Adds a dependency on [jiff@0.2](https://docs.rs/jiff/0.2). +Enables a conversion from [jiff](https://docs.rs/jiff)'s types to python: + +- [SignedDuration](https://docs.rs/jiff/0.2/jiff/struct.SignedDuration.html) -> [`PyDelta`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDelta.html) +- [TimeZone](https://docs.rs/jiff/0.2/jiff/tz/struct.TimeZone.html) -> [`PyTzInfo`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyTzInfo.html) +- [Offset](https://docs.rs/jiff/0.2/jiff/tz/struct.Offset.html) -> [`PyTzInfo`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyTzInfo.html) +- [Date](https://docs.rs/jiff/0.2/jiff/civil/struct.Date.html) -> [`PyDate`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDate.html) +- [Time](https://docs.rs/jiff/0.2/jiff/civil/struct.Time.html) -> [`PyTime`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyTime.html) +- [DateTime](https://docs.rs/jiff/0.2/jiff/civil/struct.DateTime.html) -> [`PyDateTime`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDateTime.html) +- [Zoned](https://docs.rs/jiff/0.2/jiff/struct.Zoned.html) -> [`PyDateTime`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDateTime.html) +- [Timestamp](https://docs.rs/jiff/0.2/jiff/struct.Timestamp.html) -> [`PyDateTime`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDateTime.html) +- [ISOWeekDate](https://docs.rs/jiff/0.2/jiff/civil/struct.ISOWeekDate.html) -> [`PyDate`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDate.html) + +### `lock_api` + +Adds a dependency on [lock_api](https://docs.rs/lock_api) and enables Pyo3's `MutexExt` trait for all mutexes that extend on [`lock_api::Mutex`](https://docs.rs/lock_api/latest/lock_api/struct.Mutex.html) and [`parking_lot::ReentrantMutex`](https://docs.rs/lock_api/latest/lock_api/struct.ReentrantMutex.html) (like `parking_lot` or `spin`). + +### `num-bigint` + +Adds a dependency on [num-bigint](https://docs.rs/num-bigint) and enables conversions into its [`BigInt`](https://docs.rs/num-bigint/latest/num_bigint/struct.BigInt.html) and [`BigUint`](https://docs.rs/num-bigint/latest/num_bigint/struct.BigUint.html) types. + +### `num-complex` + +Adds a dependency on [num-complex](https://docs.rs/num-complex) and enables conversions into its [`Complex`](https://docs.rs/num-complex/latest/num_complex/struct.Complex.html) type. + +### `num-rational` + +Adds a dependency on [num-rational](https://docs.rs/num-rational) and enables conversions into its [`Ratio`](https://docs.rs/num-rational/latest/num_rational/struct.Ratio.html) type. + +### `ordered-float` + +Adds a dependency on [ordered-float](https://docs.rs/ordered-float) and enables conversions between [ordered-float](https://docs.rs/ordered-float)'s types and Python: + +- [NotNan](https://docs.rs/ordered-float/latest/ordered_float/struct.NotNan.html) -> [`PyFloat`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyFloat.html) +- [OrderedFloat](https://docs.rs/ordered-float/latest/ordered_float/struct.OrderedFloat.html) -> [`PyFloat`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyFloat.html) + +### `parking-lot` + +Adds a dependency on [parking_lot](https://docs.rs/parking_lot) and enables Pyo3's `OnceExt` & `MutexExt` traits for [`parking_lot::Once`](https://docs.rs/parking_lot/latest/parking_lot/struct.Once.html) [`parking_lot::Mutex`](https://docs.rs/parking_lot/latest/parking_lot/type.Mutex.html) and [`parking_lot::ReentrantMutex`](https://docs.rs/parking_lot/latest/parking_lot/type.ReentrantMutex.html) types. + +### `rust_decimal` + +Adds a dependency on [rust_decimal](https://docs.rs/rust_decimal) and enables conversions into its [`Decimal`](https://docs.rs/rust_decimal/latest/rust_decimal/struct.Decimal.html) type. + +### `time` + +Adds a dependency on [time](https://docs.rs/time). +Enables conversions between [time](https://docs.rs/time)'s types and Python: + +- [Date](https://docs.rs/time/0.3.38/time/struct.Date.html) -> [`PyDate`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDate.html) +- [Time](https://docs.rs/time/0.3.38/time/struct.Time.html) -> [`PyTime`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyTime.html) +- [OffsetDateTime](https://docs.rs/time/0.3.38/time/struct.OffsetDateTime.html) -> [`PyDateTime`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDateTime.html) +- [PrimitiveDateTime](https://docs.rs/time/0.3.38/time/struct.PrimitiveDateTime.html) -> [`PyDateTime`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDateTime.html) +- [Duration](https://docs.rs/time/0.3.38/time/struct.Duration.html) -> [`PyDelta`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDelta.html) +- [UtcOffset](https://docs.rs/time/0.3.38/time/struct.UtcOffset.html) -> [`PyTzInfo`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyTzInfo.html) +- [UtcDateTime](https://docs.rs/time/0.3.38/time/struct.UtcDateTime.html) -> [`PyDateTime`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyDateTime.html) + +### `serde` + +Enables (de)serialization of `Py` objects via [serde](https://serde.rs/). +This allows to use [`#[derive(Serialize, Deserialize)`](https://serde.rs/derive.html) on structs that hold references to `#[pyclass]` instances + +```rust,no_run +# #[cfg(feature = "serde")] +# #[allow(dead_code)] +# mod serde_only { +# use pyo3::prelude::*; +# use serde::{Deserialize, Serialize}; + +#[pyclass] +#[derive(Serialize, Deserialize)] +struct Permission { + name: String, +} + +#[pyclass] +#[derive(Serialize, Deserialize)] +struct User { + username: String, + permissions: Vec>, +} +# } +``` + +### `smallvec` + +Adds a dependency on [smallvec](https://docs.rs/smallvec) and enables conversions into its [`SmallVec`](https://docs.rs/smallvec/latest/smallvec/struct.SmallVec.html) type. + +[set-configuration-options]: https://doc.rust-lang.org/reference/conditional-compilation.html#set-configuration-options + +### `uuid` + +Adds a dependency on [uuid](https://docs.rs/uuid) and enables conversions into its [`Uuid`](https://docs.rs/uuid/latest/uuid/struct.Uuid.html) type. + +## Deprecated features for extension module authors + +### `extension-module` + +Deprecated, users should remove this feature and upgrade to `maturin >= 1.9.4` or `setuptools-rust >= 1.12`. + +See the [building and distribution](building-and-distribution.md#the-extension-module-feature) section for further detail. + +### `generate-import-lib` + +This feature is deprecated and has no effect. diff --git a/vendor/pyo3/guide/src/free-threading.md b/vendor/pyo3/guide/src/free-threading.md new file mode 100644 index 0000000..c802d40 --- /dev/null +++ b/vendor/pyo3/guide/src/free-threading.md @@ -0,0 +1,295 @@ +# Supporting Free-Threaded CPython + +CPython 3.14 declared support for the "free-threaded" build of CPython that does not rely on the global interpreter lock (often referred to as the GIL) for thread safety. +Since version 0.23, PyO3 supports building Rust extension modules for the free-threaded Python build and calling into free-threaded Python from Rust. + +If you want more background on free-threaded Python in general, see the [what's new](https://docs.python.org/3/whatsnew/3.13.html#whatsnew313-free-threaded-cpython) entry in the 3.13 release notes (when the "free-threaded" build was first added as an experimental mode), the [free-threading HOWTO guide](https://docs.python.org/3/howto/free-threading-extensions.html#freethreading-extensions-howto) in the CPython docs, the [extension module porting guide](https://py-free-threading.github.io/porting-extensions/) in the community-maintained Python free-threading guide, and [PEP 703](https://peps.python.org/pep-0703/), which provides the technical background for the free-threading implementation in CPython. + +In the GIL-enabled build (the only choice before the "free-threaded" build was introduced), the global interpreter lock serializes access to the Python runtime. +The GIL is therefore a fundamental limitation to parallel scaling of multithreaded Python workflows, due to [Amdahl's law](https://en.wikipedia.org/wiki/Amdahl%27s_law), because any time spent executing a parallel processing task on only one execution context fundamentally cannot be sped up using parallelism. + +The free-threaded build removes this limit on multithreaded Python scaling. +This means it's much more straightforward to achieve parallelism using the Python [`threading`] module. +If you have ever needed to use [`multiprocessing`](https://docs.python.org/3/library/multiprocessing.html) to achieve a parallel speedup for some Python code, free-threading will likely allow the use of Python threads instead for the same workflow. + +PyO3's support for free-threaded Python will enable authoring native Python extension modules that are thread-safe by construction, with much stronger safety guarantees than C extension modules. +Our goal is to enable ["fearless concurrency"](https://doc.rust-lang.org/book/ch16-00-concurrency.html) in the native Python runtime by building on the Rust [`Send` and `Sync`](https://doc.rust-lang.org/nomicon/send-and-sync.html) traits. + +This document provides advice for porting Rust code using PyO3 to run under free-threaded Python. + +## Supporting free-threaded Python with PyO3 + +Since PyO3 0.28, PyO3 defaults to assuming Python modules created with it are thread-safe. +This will be the case except for Rust code which has used `unsafe` to assume thread-safety incorrectly. +An example of this is `unsafe` code which was written with the historical assumption that Python was single-threaded due to the GIL, and so the `Python<'py>` token used by PyO3 could be used to guarantee thread-safety. +A module can opt-out of supporting free-threaded Python until it has audited its `unsafe` code for correctness by declaring the module with `#[pymodule(gil_used = true)]` (see below). + +Complicated `#[pyclass]` types may need to deal with thread-safety directly; there is [a dedicated section of the guide](./class/thread-safety.md) to discuss this. + +At a low-level, annotating a module sets the `Py_MOD_GIL` slot on modules defined by an extension to `Py_MOD_GIL_NOT_USED`, which allows the interpreter to see at runtime that the author of the extension module attests it is thread-safe. + +By opting-out of supporting free-threaded Python, the Python interpreter will re-enable the GIL at runtime while importing your module and print a `RuntimeWarning` with a message containing the name of the module causing it to re-enable the GIL. +You can force the GIL to remain disabled by setting the `PYTHON_GIL=0` as an environment variable or passing `-Xgil=0` when starting Python (`0` means the GIL is turned off). + +If you are sure that all data structures exposed in a `PyModule` are thread-safe, then pass `gil_used = false` as a parameter to the `pymodule` procedural macro declaring the module or call `PyModule::gil_used` on a `PyModule` instance. +For example: + +### Example opting-in + +(Note: for PyO3 versions 0.23 through 0.27, the default was `gil_used = true` and so the opposite was needed; modules needed to opt-in to free-threaded Python support with `gil_used = false`.) + +```rust,no_run +/// This module relies on the GIL for thread safety +#[pyo3::pymodule(gil_used = true)] +mod my_extension { + use pyo3::prelude::*; + + // this type is not thread-safe + #[pyclass] + struct MyNotThreadSafeType { + // insert not thread-safe code + } +} +``` + +Or for a module that is set up without using the `pymodule` macro: + +```rust,no_run +use pyo3::prelude::*; + +# #[allow(dead_code)] +fn register_child_module(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { + let child_module = PyModule::new(parent_module.py(), "child_module")?; + child_module.gil_used(true)?; + parent_module.add_submodule(&child_module) +} + +``` + +See the [`string-sum`](https://github.com/PyO3/pyo3/tree/main/pyo3-ffi/examples/string-sum) example for how to declare free-threaded support using raw FFI calls for modules using single-phase initialization and the [`sequential`](https://github.com/PyO3/pyo3/tree/main/pyo3-ffi/examples/sequential) example for modules using multi-phase initialization. + +If you would like to use conditional compilation to trigger different code paths under the free-threaded build, you can use the `Py_GIL_DISABLED` attribute once you have configured your crate to generate the necessary build configuration data. +See [the guide section](./building-and-distribution/multiple-python-versions.md) for more details about supporting multiple different Python versions, including the free-threaded build. + +## Special considerations for the free-threaded build + +The free-threaded interpreter does not have a GIL. +Many existing extension modules providing mutable data structures relied on the GIL to lock Python objects and make interior mutability thread-safe. + +Calling into the CPython C API is only legal when an OS thread is explicitly attached to the interpreter runtime. +In the GIL-enabled build, this happens when the GIL is acquired. +In the free-threaded build there is no GIL, but the same C macros that release or acquire the GIL in the GIL-enabled build instead ask the interpreter to attach the thread to the Python runtime, and there can be many threads simultaneously attached. +See [PEP 703](https://peps.python.org/pep-0703/#thread-states) for more background about how threads can be attached and detached from the interpreter runtime, in a manner analogous to releasing and acquiring the GIL in the GIL-enabled build. + +In the GIL-enabled build, PyO3 uses the [`Python<'py>`] type and the `'py` lifetime to signify that the global interpreter lock is held. +In the freethreaded build, holding a `'py` lifetime means only that the thread is currently attached to the Python interpreter -- other threads can be simultaneously interacting with the interpreter. + +### Attaching to the runtime + +You still need to obtain a `'py` lifetime to interact with Python objects or call into the CPython C API. +If you are not yet attached to the Python runtime, you can register a thread using the [`Python::attach`] function. +Threads created via the Python [`threading`] module do not need to do this, and pyo3 will handle setting up the [`Python<'py>`] token when CPython calls into your extension module. + +### Detaching to avoid hangs and deadlocks + +The free-threaded build triggers global synchronization events in the following situations: + +- During garbage collection in order to get a globally consistent view of + reference counts and references between objects +- In Python 3.13, when the first background thread is started in + order to mark certain objects as immortal +- When either `sys.settrace` or `sys.setprofile` are called in order to + instrument running code objects and threads +- During a call to `os.fork()`, to ensure a process-wide consistent state. + +This is a non-exhaustive list and there may be other situations in future Python versions that can trigger global synchronization events. + +This means that you should detach from the interpreter runtime using [`Python::detach`] in exactly the same situations as you should detach from the runtime in the GIL-enabled build: when doing long-running tasks that do not require the CPython runtime or when doing any task that needs to re-attach to the runtime (see the [guide section](parallelism.md#sharing-python-objects-between-rust-threads) that covers this). +In the former case, you would observe a hang on threads that are waiting on the long-running task to complete, and in the latter case you would see a deadlock while a thread tries to attach after the runtime triggers a global synchronization event, but the spawning thread prevents the synchronization event from completing. + +### Exceptions and panics for multithreaded access of mutable `pyclass` instances + +Data attached to `pyclass` instances is protected from concurrent access by a `RefCell`-like pattern of runtime borrow checking. +Like a `RefCell`, PyO3 will raise exceptions (or in some cases panic) to enforce exclusive access for mutable borrows. +It was always possible to generate panics like this in PyO3 in code that releases the GIL with [`Python::detach`] or calling a python method accepting `&self` from a `&mut self` (see [the docs on interior mutability](./class.md#bound-and-interior-mutability),) but now in free-threaded Python there are more opportunities to trigger these panics from Python because there is no GIL to lock concurrent access to mutably borrowed data from Python. + +The most straightforward way to trigger this problem is to use the Python [`threading`] module to simultaneously call a rust function that mutably borrows a [`pyclass`]({{#PYO3_DOCS_URL}}/pyo3/attr.pyclass.html) in multiple threads. +For example, consider the following implementation: + +```rust,no_run +# use pyo3::prelude::*; +#[pyclass] +#[derive(Default)] +struct ThreadIter { + count: usize, +} + +#[pymethods] +impl ThreadIter { + #[new] + pub fn new() -> Self { + Default::default() + } + + fn __next__(&mut self, py: Python<'_>) -> usize { + self.count += 1; + self.count + } +} +``` + +And then if we do something like this in Python: + +```python +import concurrent.futures +from my_module import ThreadIter + +i = ThreadIter() + +def increment(): + next(i) + +with concurrent.futures.ThreadPoolExecutor(max_workers=16) as tpe: + futures = [tpe.submit(increment) for _ in range(100)] + [f.result() for f in futures] +``` + +We will see an exception: + +```text +Traceback (most recent call last) + File "example.py", line 5, in + next(i) +RuntimeError: Already borrowed +``` + +We may allow user-selectable semantics for mutable pyclass definitions in a future version of PyO3, allowing some form of opt-in locking to emulate the GIL if that is needed. +For now you should explicitly add locking, possibly using conditional compilation or using the critical section API, to avoid creating deadlocks with the GIL. + +### Cannot build extension modules using the limited API + +The free-threaded build uses a completely new ABI and there is not yet an equivalent to the limited API for the free-threaded ABI. +That means if your crate depends on PyO3 using the `abi3` feature or an an `abi3-pyxx` feature, PyO3 will print a warning and ignore that setting when building extension modules using the free-threaded interpreter. + +This means that if your package makes use of the ABI forward compatibility provided by the limited API to upload only one wheel for each release of your package, you will need to update your release procedure to also upload a version-specific free-threaded wheel. + +See [the guide section](./building-and-distribution/multiple-python-versions.md) for more details about supporting multiple different Python versions, including the free-threaded build. + +### Thread-safe single initialization + +To initialize data exactly once, use the [`PyOnceLock`] type, which is a close equivalent to [`std::sync::OnceLock`][`OnceLock`] that also helps avoid deadlocks by detaching from the Python interpreter when threads are blocking waiting for another thread to complete initialization. +If already using [`OnceLock`] and it is impractical to replace with a [`PyOnceLock`], there is the [`OnceLockExt`] extension trait which adds [`OnceLockExt::get_or_init_py_attached`] to detach from the interpreter when blocking in the same fashion as [`PyOnceLock`]. +Here is an example using [`PyOnceLock`] to single-initialize a runtime cache holding a `Py`: + +```rust +# use pyo3::prelude::*; +use pyo3::sync::PyOnceLock; +use pyo3::types::PyDict; + +let cache: PyOnceLock> = PyOnceLock::new(); + +Python::attach(|py| { + // guaranteed to be called once and only once + cache.get_or_init(py, || PyDict::new(py).unbind()) +}); +``` + +In cases where a function must run exactly once, you can bring the [`OnceExt`] trait into scope. +The [`OnceExt`] trait adds [`OnceExt::call_once_py_attached`] and [`OnceExt::call_once_force_py_attached`] functions to the api of `std::sync::Once`, enabling use of [`Once`] in contexts where the thread is attached to the Python interpreter. +These functions are analogous to [`Once::call_once`], [`Once::call_once_force`] except they accept a [`Python<'py>`] token in addition to an `FnOnce`. +All of these functions detach from the interpreter before blocking and re-attach before executing the function, avoiding deadlocks that are possible without using the PyO3 extension traits. +Here the same example as above built using a [`Once`] instead of a +[`PyOnceLock`]: + +```rust +# use pyo3::prelude::*; +use std::sync::Once; +use pyo3::sync::OnceExt; +use pyo3::types::PyDict; + +struct RuntimeCache { + once: Once, + cache: Option> +} + +let mut cache = RuntimeCache { + once: Once::new(), + cache: None +}; + +Python::attach(|py| { + // guaranteed to be called once and only once + cache.once.call_once_py_attached(py, || { + cache.cache = Some(PyDict::new(py).unbind()); + }); +}); +``` + +### `GILProtected` has been removed + +[`GILProtected`] was a PyO3 type that allowed mutable access to static data by leveraging the GIL to lock concurrent access from other threads. +In free-threaded Python there is no GIL, so this type had to be replaced with alternative forms of locking. +In many cases, a type from [`std::sync::atomic`](https://doc.rust-lang.org/std/sync/atomic/) or a [`std::sync::Mutex`](https://doc.rust-lang.org/std/sync/struct.Mutex.html) was sufficient. + +Before: + +```rust,ignore +# fn main() { +# #[cfg(not(Py_GIL_DISABLED))] { +# use pyo3::prelude::*; +use pyo3::sync::GILProtected; +use pyo3::types::{PyDict, PyNone}; +use std::cell::RefCell; + +static OBJECTS: GILProtected>>> = + GILProtected::new(RefCell::new(Vec::new())); + +Python::attach(|py| { + // stand-in for something that executes arbitrary Python code + let d = PyDict::new(py); + d.set_item(PyNone::get(py), PyNone::get(py)).unwrap(); + OBJECTS.get(py).borrow_mut().push(d.unbind()); +}); +# }} +``` + +After (using a `Mutex`): + +```rust +# use pyo3::prelude::*; +# fn main() { +use pyo3::types::{PyDict, PyNone}; +use std::sync::Mutex; + +static OBJECTS: Mutex>> = Mutex::new(Vec::new()); + +Python::attach(|py| { + // stand-in for something that executes arbitrary Python code + let d = PyDict::new(py); + d.set_item(PyNone::get(py), PyNone::get(py)).unwrap(); + // as with any `Mutex` usage, lock the mutex for as little time as possible + // in this case, we do it just while pushing into the `Vec` + OBJECTS.lock().unwrap().push(d.unbind()); +}); +# } +``` + +If you are executing arbitrary Python code while holding the lock, then you should import the [`MutexExt`] trait and use the `lock_py_attached` method instead of `lock`. +This ensures that global synchronization events started by the Python runtime can proceed, avoiding possible deadlocks with the interpreter. + +[`GILProtected`]: https://docs.rs/pyo3/0.22/pyo3/sync/struct.GILProtected.html +[`MutexExt`]: {{#PYO3_DOCS_URL}}/pyo3/sync/trait.MutexExt.html +[`Once`]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html +[`Once::call_once`]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.call_once +[`Once::call_once_force`]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.call_once_force +[`OnceExt`]: {{#PYO3_DOCS_URL}}/pyo3/sync/trait.OnceExt.html +[`OnceExt::call_once_py_attached`]: {{#PYO3_DOCS_URL}}/pyo3/sync/trait.OnceExt.html#tymethod.call_once_py_attached +[`OnceExt::call_once_force_py_attached`]: {{#PYO3_DOCS_URL}}/pyo3/sync/trait.OnceExt.html#tymethod.call_once_force_py_attached +[`OnceLockExt`]: {{#PYO3_DOCS_URL}}/pyo3/sync/trait.OnceLockExt.html +[`OnceLockExt::get_or_init_py_attached`]: {{#PYO3_DOCS_URL}}/pyo3/sync/trait.OnceLockExt.html#tymethod.get_or_init_py_attached +[`OnceLock`]: https://doc.rust-lang.org/stable/std/sync/struct.OnceLock.html +[`Python::detach`]: {{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#method.detach +[`Python::attach`]: {{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#method.attach +[`Python<'py>`]: {{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html +[`PyOnceLock`]: {{#PYO3_DOCS_URL}}/pyo3/sync/struct.PyOnceLock.html +[`threading`]: https://docs.python.org/3/library/threading.html diff --git a/vendor/pyo3/guide/src/function-calls.md b/vendor/pyo3/guide/src/function-calls.md new file mode 100644 index 0000000..e5c9c1e --- /dev/null +++ b/vendor/pyo3/guide/src/function-calls.md @@ -0,0 +1 @@ +# Calling Python functions diff --git a/vendor/pyo3/guide/src/function.md b/vendor/pyo3/guide/src/function.md new file mode 100644 index 0000000..644d6da --- /dev/null +++ b/vendor/pyo3/guide/src/function.md @@ -0,0 +1,272 @@ +# Python functions + +The `#[pyfunction]` attribute is used to define a Python function from a Rust function. +Once defined, the function needs to be added to a [module](./module.md). + +The following example defines a function called `double` in a Python module called `my_extension`: + +```rust,no_run +#[pyo3::pymodule] +mod my_extension { + use pyo3::prelude::*; + + #[pyfunction] + fn double(x: usize) -> usize { + x * 2 + } +} +``` + +This chapter of the guide explains full usage of the `#[pyfunction]` attribute. +In this first section, the following topics are covered: + +- [Function options](#function-options) + - [`#[pyo3(name = "...")]`](#name) + - [`#[pyo3(signature = (...))]`](#signature) + - [`#[pyo3(text_signature = "...")]`](#text_signature) + - [`#[pyo3(pass_module)]`](#pass_module) + - [`#[pyo3(warn(message = "...", category = ...))]`](#warn) +- [Per-argument options](#per-argument-options) +- [Advanced function patterns](#advanced-function-patterns) + +There are also additional sections on the following topics: + +- [Function Signatures](./function/signature.md) +- [Error Handling](./function/error-handling.md) + +## Function options + +The `#[pyo3]` attribute can be used to modify properties of the generated Python function. +It can take any combination of the following options: + +- `#[pyo3(name = "...")]` + + Overrides the name exposed to Python. + + In the following example, the Rust function `no_args_py` will be added to the Python module `module_with_functions` as the Python function `no_args`: + + ```rust + # use pyo3::prelude::*; + #[pyo3::pymodule] + mod module_with_functions { + use pyo3::prelude::*; + + #[pyfunction] + #[pyo3(name = "no_args")] + fn no_args_py() -> usize { + 42 + } + } + + # Python::attach(|py| { + # let m = pyo3::wrap_pymodule!(module_with_functions)(py); + # assert!(m.getattr(py, "no_args").is_ok()); + # assert!(m.getattr(py, "no_args_py").is_err()); + # }); + ``` + +- `#[pyo3(signature = (...))]` + + Defines the function signature in Python. + See [Function Signatures](./function/signature.md). + +- `#[pyo3(text_signature = "...")]` + + Overrides the PyO3-generated function signature visible in Python tooling (such as via [`inspect.signature`]). + See the [corresponding topic in the Function Signatures subchapter](./function/signature.md#making-the-function-signature-available-to-python). + +- `#[pyo3(pass_module)]` + + Set this option to make PyO3 pass the containing module as the first argument to the function. + It is then possible to use the module in the function body. + The first argument **must** be of type `&Bound<'_, PyModule>`, `Bound<'_, PyModule>`, or `Py`. + + The following example creates a function `pyfunction_with_module` which returns the containing module's name (i.e. `module_with_fn`): + + ```rust,no_run + #[pyo3::pymodule] + mod module_with_fn { + use pyo3::prelude::*; + use pyo3::types::PyString; + + #[pyfunction] + #[pyo3(pass_module)] + fn pyfunction_with_module<'py>( + module: &Bound<'py, PyModule>, + ) -> PyResult> { + module.name() + } + } + ``` + +- `#[pyo3(warn(message = "...", category = ...))]` + + This option is used to display a warning when the function is used in Python. + It is equivalent to [`warnings.warn(message, category)`](https://docs.python.org/3/library/warnings.html#warnings.warn). + The `message` parameter is a string that will be displayed when the function is called, and the `category` parameter is optional and has to be a subclass of [`Warning`](https://docs.python.org/3/library/exceptions.html#Warning). + When the `category` parameter is not provided, the warning will be defaulted to [`UserWarning`](https://docs.python.org/3/library/exceptions.html#UserWarning). + + > Note: when used with `#[pymethods]`, this attribute does not work with `#[classattr]` nor `__traverse__` magic method. + + The following are examples of using the `#[pyo3(warn)]` attribute: + + ```rust + use pyo3::prelude::*; + + #[pymodule] + mod raising_warning_fn { + use pyo3::prelude::pyfunction; + use pyo3::exceptions::PyFutureWarning; + + #[pyfunction] + #[pyo3(warn(message = "This is a warning message"))] + fn function_with_warning() -> usize { + 42 + } + + #[pyfunction] + #[pyo3(warn(message = "This function is warning with FutureWarning", category = PyFutureWarning))] + fn function_with_warning_and_custom_category() -> usize { + 42 + } + } + + # use pyo3::exceptions::{PyFutureWarning, PyUserWarning}; + # use pyo3::types::{IntoPyDict, PyList}; + # use pyo3::PyTypeInfo; + # + # fn catch_warning(py: Python<'_>, f: impl FnOnce(&Bound<'_, PyList>) -> ()) -> PyResult<()> { + # let warnings = py.import("warnings")?; + # let kwargs = [("record", true)].into_py_dict(py)?; + # let catch_warnings = warnings + # .getattr("catch_warnings")? + # .call((), Some(&kwargs))?; + # let list = catch_warnings.call_method0("__enter__")?.cast_into()?; + # warnings.getattr("simplefilter")?.call1(("always",))?; // show all warnings + # f(&list); + # catch_warnings + # .call_method1("__exit__", (py.None(), py.None(), py.None())) + # .unwrap(); + # Ok(()) + # } + # + # macro_rules! assert_warnings { + # ($py:expr, $body:expr, [$(($category:ty, $message:literal)),+] $(,)? ) => { + # catch_warning($py, |list| { + # $body; + # let expected_warnings = [$((<$category as PyTypeInfo>::type_object($py), $message)),+]; + # assert_eq!(list.len(), expected_warnings.len()); + # for (warning, (category, message)) in list.iter().zip(expected_warnings) { + # assert!(warning.getattr("category").unwrap().is(&category)); + # assert_eq!( + # warning.getattr("message").unwrap().str().unwrap().to_string_lossy(), + # message + # ); + # } + # }).unwrap(); + # }; + # } + # + # Python::attach(|py| { + # assert_warnings!( + # py, + # { + # let m = pyo3::wrap_pymodule!(raising_warning_fn)(py); + # let f1 = m.getattr(py, "function_with_warning").unwrap(); + # let f2 = m.getattr(py, "function_with_warning_and_custom_category").unwrap(); + # f1.call0(py).unwrap(); + # f2.call0(py).unwrap(); + # }, + # [ + # (PyUserWarning, "This is a warning message"), + # ( + # PyFutureWarning, + # "This function is warning with FutureWarning" + # ) + # ] + # ); + # }); + ``` + + When the functions are called as the following, warnings will be displayed. + + ```python + import warnings + from raising_warning_fn import function_with_warning, function_with_warning_and_custom_category + + function_with_warning() + function_with_warning_and_custom_category() + ``` + + The warning output will be: + + ```plaintext + UserWarning: This is a warning message + FutureWarning: This function is warning with FutureWarning + ``` + +## Per-argument options + +The `#[pyo3]` attribute can be used on individual arguments to modify properties of them in the generated function. +It can take any combination of the following options: + +- `#[pyo3(from_py_with = ...)]` + + Set this on an option to specify a custom function to convert the function argument from Python to the desired Rust type, instead of using the default `FromPyObject` extraction. + The function signature must be `fn(&Bound<'_, PyAny>) -> PyResult` where `T` is the Rust type of the argument. + + The following example uses `from_py_with` to convert the input Python object to its length: + + ```rust + use pyo3::prelude::*; + + fn get_length(obj: &Bound<'_, PyAny>) -> PyResult { + obj.len() + } + + #[pyfunction] + fn object_length(#[pyo3(from_py_with = get_length)] argument: usize) -> usize { + argument + } + + # Python::attach(|py| { + # let f = pyo3::wrap_pyfunction!(object_length)(py).unwrap(); + # assert_eq!(f.call1((vec![1, 2, 3],)).unwrap().extract::().unwrap(), 3); + # }); + ``` + +## Advanced function patterns + +### Calling Python functions in Rust + +You can pass Python `def`'d functions and built-in functions to Rust functions [`PyFunction`] corresponds to regular Python functions while [`PyCFunction`] describes built-ins such as `repr()`. + +You can also use [`Bound<'_, PyAny>::is_callable`] to check if you have a callable object. +`is_callable` will return `true` for functions (including lambdas), methods and objects with a `__call__` method. +You can call the object with [`Bound<'_, PyAny>::call`] with the args as first parameter and the kwargs (or `None`) as second parameter. +There are also [`Bound<'_, PyAny>::call0`] with no args and [`Bound<'_, PyAny>::call1`] with only positional args. + +### Calling Rust functions in Python + +The ways to convert a Rust function into a Python object vary depending on the function: + +- Named functions, e.g. `fn foo()`: add `#[pyfunction]` and then use [`wrap_pyfunction!`] to get the corresponding [`PyCFunction`]; see [`wrap_pyfunction!`] for an example. +- Anonymous functions (or closures), e.g. `foo: fn()` either: + - use a `#[pyclass]` struct which stores the function as a field and implement `__call__` to call the stored function. + - use `PyCFunction::new_closure` to create an object directly from the function. + +### Accessing the FFI functions + +In order to make Rust functions callable from Python, PyO3 generates an `extern "C"` function whose exact signature depends on the Rust signature. (PyO3 chooses the optimal Python argument passing convention.) It then embeds the call to the Rust function inside this FFI-wrapper function. +This wrapper handles extraction of the regular arguments and the keyword arguments from the input `PyObject`s. + +The `wrap_pyfunction` macro can be used to directly get a `Bound` given a `#[pyfunction]` and a `Bound`: `wrap_pyfunction!(rust_fun, module)`. + +[`Bound<'_, PyAny>::is_callable`]: {{#PYO3_DOCS_URL}}/pyo3/prelude/trait.PyAnyMethods.html#tymethod.is_callable +[`Bound<'_, PyAny>::call`]: {{#PYO3_DOCS_URL}}/pyo3/prelude/trait.PyAnyMethods.html#tymethod.call +[`Bound<'_, PyAny>::call0`]: {{#PYO3_DOCS_URL}}/pyo3/prelude/trait.PyAnyMethods.html#tymethod.call0 +[`Bound<'_, PyAny>::call1`]: {{#PYO3_DOCS_URL}}/pyo3/prelude/trait.PyAnyMethods.html#tymethod.call1 +[`wrap_pyfunction!`]: {{#PYO3_DOCS_URL}}/pyo3/macro.wrap_pyfunction.html +[`PyFunction`]: {{#PYO3_DOCS_URL}}/pyo3/types/struct.PyFunction.html +[`PyCFunction`]: {{#PYO3_DOCS_URL}}/pyo3/types/struct.PyCFunction.html +[`inspect.signature`]: https://docs.python.org/3/library/inspect.html#inspect.signature diff --git a/vendor/pyo3/guide/src/function/error-handling.md b/vendor/pyo3/guide/src/function/error-handling.md new file mode 100644 index 0000000..5db344b --- /dev/null +++ b/vendor/pyo3/guide/src/function/error-handling.md @@ -0,0 +1,251 @@ +# Error handling + +This chapter contains a little background of error handling in Rust and how PyO3 integrates this with Python exceptions. + +This covers enough detail to create a `#[pyfunction]` which raises Python exceptions from errors originating in Rust. + +There is a later section of the guide on [Python exceptions](../exception.md) which covers exception types in more detail. + +## Representing Python exceptions + +Rust code uses the generic [`Result`] enum to propagate errors. +The error type `E` is chosen by the code author to describe the possible errors which can happen. + +PyO3 has the [`PyErr`] type which represents a Python exception. +If a PyO3 API could result in a Python exception being raised, the return type of that `API` will be [`PyResult`], which is an alias for the type `Result`. + +In summary: + +- When Python exceptions are raised and caught by PyO3, the exception will be stored in the `Err` variant of the `PyResult`. +- Passing Python exceptions through Rust code then uses all the "normal" techniques such as the `?` operator, with `PyErr` as the error type. +- Finally, when a `PyResult` crosses from Rust back to Python via PyO3, if the result is an `Err` variant the contained exception will be raised. + +(There are many great tutorials on Rust error handling and the `?` operator, so this guide will not go into detail on Rust-specific topics.) + +## Raising an exception from a function + +As indicated in the previous section, when a `PyResult` containing an `Err` crosses from Rust to Python, PyO3 will raise the exception contained within. + +Accordingly, to raise an exception from a `#[pyfunction]`, change the return type `T` to `PyResult`. +When the function returns an `Err` it will raise a Python exception. (Other `Result` types can be used as long as the error `E` has a `From` conversion for `PyErr`, see [custom Rust error types](#custom-rust-error-types) below.) + +This also works for functions in `#[pymethods]`. + +For example, the following `check_positive` function raises a `ValueError` when the input is negative: + +```rust +use pyo3::exceptions::PyValueError; +use pyo3::prelude::*; + +#[pyfunction] +fn check_positive(x: i32) -> PyResult<()> { + if x < 0 { + Err(PyValueError::new_err("x is negative")) + } else { + Ok(()) + } +} +# +# fn main(){ +# Python::attach(|py|{ +# let fun = pyo3::wrap_pyfunction!(check_positive, py).unwrap(); +# fun.call1((-1,)).unwrap_err(); +# fun.call1((1,)).unwrap(); +# }); +# } +``` + +All built-in Python exception types are defined in the [`pyo3::exceptions`] module. +They have a `new_err` constructor to directly build a `PyErr`, as seen in the example above. + +## Custom Rust error types + +PyO3 will automatically convert a `Result` returned by a `#[pyfunction]` into a `PyResult` as long as there is an implementation of `std::from::From for PyErr`. +Many error types in the Rust standard library have a [`From`] conversion defined in this way. + +If the type `E` you are handling is defined in a third-party crate, see the section on [foreign rust error types](#foreign-rust-error-types) below for ways to work with this error. + +The following example makes use of the implementation of `From for PyErr` to raise exceptions encountered when parsing strings as integers: + +```rust +# use pyo3::prelude::*; +use std::num::ParseIntError; + +#[pyfunction] +fn parse_int(x: &str) -> Result { + x.parse() +} + +# fn main() { +# Python::attach(|py| { +# let fun = pyo3::wrap_pyfunction!(parse_int, py).unwrap(); +# let value: usize = fun.call1(("5",)).unwrap().extract().unwrap(); +# assert_eq!(value, 5); +# }); +# } +``` + +When passed a string which doesn't contain a floating-point number, the exception raised will look like the below: + +```python +>>> parse_int("bar") +Traceback (most recent call last): + File "", line 1, in +ValueError: invalid digit found in string +``` + +As a more complete example, the following snippet defines a Rust error named `CustomIOError`. +It then defines a `From for PyErr`, which returns a `PyErr` representing Python's `OSError`. +Therefore, it can use this error in the result of a `#[pyfunction]` directly, relying on the conversion if it has to be propagated into a Python exception. + +```rust +use pyo3::exceptions::PyOSError; +use pyo3::prelude::*; +use std::fmt; + +#[derive(Debug)] +struct CustomIOError; + +impl std::error::Error for CustomIOError {} + +impl fmt::Display for CustomIOError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Oh no!") + } +} + +impl std::convert::From for PyErr { + fn from(err: CustomIOError) -> PyErr { + PyOSError::new_err(err.to_string()) + } +} + +pub struct Connection {/* ... */} + +fn bind(addr: String) -> Result { + if &addr == "0.0.0.0" { + Err(CustomIOError) + } else { + Ok(Connection{ /* ... */}) + } +} + +#[pyfunction] +fn connect(s: String) -> Result<(), CustomIOError> { + bind(s)?; + // etc. + Ok(()) +} + +fn main() { + Python::attach(|py| { + let fun = pyo3::wrap_pyfunction!(connect, py).unwrap(); + let err = fun.call1(("0.0.0.0",)).unwrap_err(); + assert!(err.is_instance_of::(py)); + }); +} +``` + +If lazy construction of the Python exception instance is desired, the [`PyErrArguments`]({{#PYO3_DOCS_URL}}/pyo3/trait.PyErrArguments.html) trait can be implemented instead of `From`. +In that case, actual exception argument creation is delayed until the `PyErr` is needed. + +A final note is that any errors `E` which have a `From` conversion can be used with the `?` ("try") operator with them. +An alternative implementation of the above `parse_int` which instead returns `PyResult` is below: + +```rust +use pyo3::prelude::*; + +fn parse_int(s: String) -> PyResult { + let x = s.parse()?; + Ok(x) +} +# +# use pyo3::exceptions::PyValueError; +# +# fn main() { +# Python::attach(|py| { +# assert_eq!(parse_int(String::from("1")).unwrap(), 1); +# assert_eq!(parse_int(String::from("1337")).unwrap(), 1337); +# +# assert!(parse_int(String::from("-1")) +# .unwrap_err() +# .is_instance_of::(py)); +# assert!(parse_int(String::from("foo")) +# .unwrap_err() +# .is_instance_of::(py)); +# assert!(parse_int(String::from("13.37")) +# .unwrap_err() +# .is_instance_of::(py)); +# }) +# } +``` + +## Foreign Rust error types + +The Rust compiler will not permit implementation of traits for types outside of the crate where the type is defined. (This is known as the "orphan rule".) + +Given a type `OtherError` which is defined in third-party code, there are two main strategies available to integrate it with PyO3: + +- Create a newtype wrapper, e.g. `MyOtherError`. + Then implement `From for PyErr` (or `PyErrArguments`), as well as `From` for `MyOtherError`. +- Use Rust's Result combinators such as `map_err` to write code freely to convert `OtherError` into whatever is needed. + This requires boilerplate at every usage however gives unlimited flexibility. + +To detail the newtype strategy a little further, the key trick is to return `Result` from the `#[pyfunction]`. +This means that PyO3 will make use of `From for PyErr` to create Python exceptions while the `#[pyfunction]` implementation can use `?` to convert `OtherError` to `MyOtherError` automatically. + +The following example demonstrates this for some imaginary third-party crate `some_crate` with a function `get_x` returning `Result`: + +```rust +# mod some_crate { +# pub struct OtherError(()); +# impl OtherError { +# pub fn message(&self) -> &'static str { "some error occurred" } +# } +# pub fn get_x() -> Result { Ok(5) } +# } + +use pyo3::prelude::*; +use pyo3::exceptions::PyValueError; +use some_crate::{OtherError, get_x}; + +struct MyOtherError(OtherError); + +impl From for PyErr { + fn from(error: MyOtherError) -> Self { + PyValueError::new_err(error.0.message()) + } +} + +impl From for MyOtherError { + fn from(other: OtherError) -> Self { + Self(other) + } +} + +#[pyfunction] +fn wrapped_get_x() -> Result { + // get_x is a function returning Result + let x: i32 = get_x()?; + Ok(x) +} + +# fn main() { +# Python::attach(|py| { +# let fun = pyo3::wrap_pyfunction!(wrapped_get_x, py).unwrap(); +# let value: usize = fun.call0().unwrap().extract().unwrap(); +# assert_eq!(value, 5); +# }); +# } +``` + +## Notes + +In Python 3.11 and up, notes can be added to Python exceptions to provide additional debugging information when printing the exception. +In PyO3, you can use the `add_note` method on `PyErr` to accomplish this functionality. + +[`From`]: https://doc.rust-lang.org/stable/std/convert/trait.From.html +[`Result`]: https://doc.rust-lang.org/stable/std/result/enum.Result.html +[`PyResult`]: {{#PYO3_DOCS_URL}}/pyo3/prelude/type.PyResult.html +[`PyErr`]: {{#PYO3_DOCS_URL}}/pyo3/struct.PyErr.html +[`pyo3::exceptions`]: {{#PYO3_DOCS_URL}}/pyo3/exceptions/index.html diff --git a/vendor/pyo3/guide/src/function/signature.md b/vendor/pyo3/guide/src/function/signature.md new file mode 100644 index 0000000..b791ae4 --- /dev/null +++ b/vendor/pyo3/guide/src/function/signature.md @@ -0,0 +1,300 @@ +# Function signatures + +The `#[pyfunction]` attribute also accepts parameters to control how the generated Python function accepts arguments. +Just like in Python, arguments can be positional-only, keyword-only, or accept either. +`*args` lists and `**kwargs` dicts can also be accepted. +These parameters also work for `#[pymethods]` which will be introduced in the [Python Classes](../class.md) section of the guide. + +Like Python, by default PyO3 accepts all arguments as either positional or keyword arguments. +All arguments are required by default. +This behaviour can be configured by the `#[pyo3(signature = (...))]` option which allows writing a signature in Python syntax. + +This section of the guide goes into detail about use of the `#[pyo3(signature = (...))]` option and its related option `#[pyo3(text_signature = "...")]` + +## Using `#[pyo3(signature = (...))]` + +For example, below is a function that accepts arbitrary keyword arguments (`**kwargs` in Python syntax) and returns the number that was passed: + +```rust,no_run +#[pyo3::pymodule] +mod module_with_functions { + use pyo3::prelude::*; + use pyo3::types::PyDict; + + #[pyfunction] + #[pyo3(signature = (**kwds))] + fn num_kwds(kwds: Option<&Bound<'_, PyDict>>) -> usize { + kwds.map_or(0, |dict| dict.len()) + } +} +``` + +Just like in Python, the following constructs can be part of the signature:: + +- `/`: positional-only arguments separator, each parameter defined before `/` is a positional-only parameter. +- `*`: var arguments separator, each parameter defined after `*` is a keyword-only parameter. +- `*args`: "args" is var args. + Type of the `args` parameter has to be `&Bound<'_, PyTuple>`. +- `**kwargs`: "kwargs" receives keyword arguments. + The type of the `kwargs` parameter has to be `Option<&Bound<'_, PyDict>>`. +- `arg=Value`: arguments with default value. + If the `arg` argument is defined after var arguments, it is treated as a keyword-only argument. + Note that `Value` has to be valid rust code, PyO3 just inserts it into the generated code unmodified. + +Example: + +```rust,no_run +# use pyo3::prelude::*; +use pyo3::types::{PyDict, PyTuple}; +# +# #[pyclass] +# struct MyClass { +# num: i32, +# } +#[pymethods] +impl MyClass { + #[new] + #[pyo3(signature = (num=-1))] + fn new(num: i32) -> Self { + MyClass { num } + } + + #[pyo3(signature = (num=10, *py_args, name="Hello", **py_kwargs))] + fn method( + &mut self, + num: i32, + py_args: &Bound<'_, PyTuple>, + name: &str, + py_kwargs: Option<&Bound<'_, PyDict>>, + ) -> String { + let num_before = self.num; + self.num = num; + format!( + "num={} (was previously={}), py_args={:?}, name={}, py_kwargs={:?} ", + num, num_before, py_args, name, py_kwargs, + ) + } + + fn make_change(&mut self, num: i32) -> PyResult { + self.num = num; + Ok(format!("num={}", self.num)) + } +} +``` + +Arguments of type `Python` must not be part of the signature: + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +#[pyfunction] +#[pyo3(signature = (lambda))] +pub fn simple_python_bound_function(py: Python<'_>, lambda: Py) -> PyResult<()> { + Ok(()) +} +``` + +N.B. the position of the `/` and `*` arguments (if included) control the system of handling positional and keyword arguments. +In Python: + +```python +import mymodule + +mc = mymodule.MyClass() +print(mc.method(44, False, "World", 666, x=44, y=55)) +print(mc.method(num=-1, name="World")) +print(mc.make_change(44)) +``` + +Produces output: + +```text +num=44 (was previously=-1), py_args=(False, 'World', 666), name=Hello, py_kwargs=Some({'x': 44, 'y': 55}) +num=-1 (was previously=44), py_args=(), name=World, py_kwargs=None +num=44 +``` + +> [!NOTE] +> To use keywords like `struct` as a function argument, use "raw identifier" syntax `r#struct` in both the signature and the function definition: +> +> ```rust,no_run +> # #![allow(dead_code)] +> # use pyo3::prelude::*; +> #[pyfunction(signature = (r#struct = "foo"))] +> fn function_with_keyword(r#struct: &str) { +> # let _ = r#struct; +> /* ... */ +> } +> ``` + +## Making the function signature available to Python + +The function signature is exposed to Python via the `__text_signature__` attribute. +PyO3 automatically generates this for every `#[pyfunction]` and all `#[pymethods]` directly from the Rust function, taking into account any override done with the `#[pyo3(signature = (...))]` option. + +This automatic generation can only display the value of default arguments for strings, integers, boolean types, and `None`. +Any other default arguments will be displayed as `...`. (`.pyi` type stub files commonly also use `...` for default arguments in the same way.) + +In cases where the automatically-generated signature needs adjusting, it can [be overridden](#overriding-the-generated-signature) using the `#[pyo3(text_signature)]` option.) + +The example below creates a function `add` which accepts two positional-only arguments `a` and `b`, where `b` has a default value of zero. + +```rust +use pyo3::prelude::*; + +/// This function adds two unsigned 64-bit integers. +#[pyfunction] +#[pyo3(signature = (a, b=0, /))] +fn add(a: u64, b: u64) -> u64 { + a + b +} +# +# fn main() -> PyResult<()> { +# Python::attach(|py| { +# let fun = pyo3::wrap_pyfunction!(add, py)?; +# +# let doc: String = fun.getattr("__doc__")?.extract()?; +# assert_eq!(doc, "This function adds two unsigned 64-bit integers."); +# +# let inspect = PyModule::import(py, "inspect")?.getattr("signature")?; +# let sig: String = inspect +# .call1((fun,))? +# .call_method0("__str__")? +# .extract()?; +# +# assert_eq!(sig, "(a, b=0, /)"); +# +# Ok(()) +# }) +# } +``` + +The following IPython output demonstrates how this generated signature will be seen from Python tooling: + +```text +>>> pyo3_test.add.__text_signature__ +'(a, b=..., /)' +>>> pyo3_test.add? +Signature: pyo3_test.add(a, b=0, /) +Docstring: This function adds two unsigned 64-bit integers. +Type: builtin_function_or_method +``` + +### Overriding the generated signature + +The `#[pyo3(text_signature = "()")]` attribute can be used to override the default generated signature. + +In the snippet below, the text signature attribute is used to include the default value of `0` for the argument `b`, instead of the automatically-generated default value of `...`: + +```rust +use pyo3::prelude::*; + +/// This function adds two unsigned 64-bit integers. +#[pyfunction] +#[pyo3(signature = (a, b=0, /), text_signature = "(a, b=0, /)")] +fn add(a: u64, b: u64) -> u64 { + a + b +} +# +# fn main() -> PyResult<()> { +# Python::attach(|py| { +# let fun = pyo3::wrap_pyfunction!(add, py)?; +# +# let doc: String = fun.getattr("__doc__")?.extract()?; +# assert_eq!(doc, "This function adds two unsigned 64-bit integers."); +# +# let inspect = PyModule::import(py, "inspect")?.getattr("signature")?; +# let sig: String = inspect +# .call1((fun,))? +# .call_method0("__str__")? +# .extract()?; +# assert_eq!(sig, "(a, b=0, /)"); +# +# Ok(()) +# }) +# } +``` + +PyO3 will include the contents of the annotation unmodified as the `__text_signature__`. +Below shows how IPython will now present this (see the default value of 0 for b): + +```text +>>> pyo3_test.add.__text_signature__ +'(a, b=0, /)' +>>> pyo3_test.add? +Signature: pyo3_test.add(a, b=0, /) +Docstring: This function adds two unsigned 64-bit integers. +Type: builtin_function_or_method +``` + +If no signature is wanted at all, `#[pyo3(text_signature = None)]` will disable the built-in signature. +The snippet below demonstrates use of this: + +```rust +use pyo3::prelude::*; + +/// This function adds two unsigned 64-bit integers. +#[pyfunction] +#[pyo3(signature = (a, b=0, /), text_signature = None)] +fn add(a: u64, b: u64) -> u64 { + a + b +} +# +# fn main() -> PyResult<()> { +# Python::attach(|py| { +# let fun = pyo3::wrap_pyfunction!(add, py)?; +# +# let doc: String = fun.getattr("__doc__")?.extract()?; +# assert_eq!(doc, "This function adds two unsigned 64-bit integers."); +# assert!(fun.getattr("__text_signature__")?.is_none()); +# +# Ok(()) +# }) +# } +``` + +Now the function's `__text_signature__` will be set to `None`, and IPython will not display any signature in the help: + +```text +>>> pyo3_test.add.__text_signature__ == None +True +>>> pyo3_test.add? +Docstring: This function adds two unsigned 64-bit integers. +Type: builtin_function_or_method +``` + +### Type annotations in the signature + +The `signature` attribute can also contain type hints: + +```rust +use pyo3::prelude::*; + +#[pymodule] +pub mod example { + use pyo3::prelude::*; + + #[pyfunction] + #[pyo3(signature = (arg: "list[int]") -> "list[int]")] + fn list_of_int_identity(arg: Bound<'_, PyAny>) -> Bound<'_, PyAny> { + arg + } +} +``` + +It enables the [work-in-progress capacity of PyO3 to autogenerate type stubs](../type-stub.md) to generate a file with the correct type hints: + +```python +def list_of_int_identity(arg: "list[int]") -> "list[int]": ... +``` + +instead of the generic: + +```python +from typing import Any + +def list_of_int_identity(arg: Any) -> Any: ... +``` + +Note that currently type annotations must be written as strings. +Future enhancements of PyO3's typing support may include the ability to parse a limited subset of Python's type expression syntax. diff --git a/vendor/pyo3/guide/src/getting-started.md b/vendor/pyo3/guide/src/getting-started.md new file mode 100644 index 0000000..f8b1d76 --- /dev/null +++ b/vendor/pyo3/guide/src/getting-started.md @@ -0,0 +1,203 @@ +# Installation + +To get started using PyO3 you will need three things: a Rust toolchain, a Python environment, and a way to build. +We'll cover each of these below. + +> [!TIP] +> If you'd like to chat to the PyO3 maintainers and other PyO3 users, consider joining the [PyO3 Discord server](https://discord.gg/33kcChzH7f). We're keen to hear about your experience getting started, so we can make PyO3 as accessible as possible for everyone! + +## Rust + +First, make sure you have Rust installed on your system. +If you haven't already done so, try following the instructions [on the Rust website](https://www.rust-lang.org/tools/install). +PyO3 runs on both the `stable` and `nightly` versions so you can choose whichever one fits you best. +The minimum required Rust version is 1.83. + +If you can run `rustc --version` and the version is new enough you're good to go! + +## Python + +To use PyO3, you need at least Python 3.8. +While you can simply use the default Python interpreter on your system, it is recommended to use a virtual environment. + +## Virtualenvs + +While you can use any virtualenv manager you like, we recommend the use of `pyenv` in particular if you want to develop or test for multiple different Python versions, so that is what the examples in this book will use. +The installation instructions for `pyenv` can be found [in the `pyenv` GitHub repository](https://github.com/pyenv/pyenv#a-getting-pyenv). (Note: To get the `pyenv activate` and `pyenv virtualenv` commands, you will also need to install the [`pyenv-virtualenv`](https://github.com/pyenv/pyenv-virtualenv) plugin. +The [pyenv installer](https://github.com/pyenv/pyenv-installer#installation--update--uninstallation) will install both together.) + +It can be useful to keep the sources used when installing using `pyenv` so that future debugging can see the original source files. +This can be done by passing the `--keep` flag as part of the `pyenv install` command. + +For example: + +```bash +pyenv install 3.12 --keep +``` + +### Building + +There are a number of build and Python package management systems such as [`setuptools-rust`](https://github.com/PyO3/setuptools-rust) or [manually](./building-and-distribution.md#manual-builds). +We recommend the use of `maturin`, which you can install [as per the `maturin` documentation](https://maturin.rs/installation.html). +It is developed to work with PyO3 and provides the most "batteries included" experience, especially if you are aiming to publish to PyPI. +`maturin` is just a Python package, so you can add it in the same way you already install Python packages. + +System Python: + +```bash +pip install maturin --user +``` + +pipx: + +```bash +pipx install maturin +``` + +pyenv: + +```bash +pyenv activate pyo3 +pip install maturin +``` + +poetry: + +```bash +poetry add -G dev maturin +``` + +After installation, you can run `maturin --version` to check that you have correctly installed it. + +## Starting a new project + +First you should create the folder and virtual environment that are going to contain your new project. +Here we will use the recommended `pyenv`: + +```bash +mkdir pyo3-example +cd pyo3-example +pyenv virtualenv pyo3 +pyenv local pyo3 +``` + +After this, you should install your build manager. +In this example, we will use `maturin`. +After you've activated your virtualenv, add `maturin` to it: + +```bash +pip install maturin +``` + +Now you can initialize the new project: + +```bash +maturin init +``` + +If `maturin` is already installed, you can create a new project using that directly as well: + +```bash +maturin new -b pyo3 pyo3-example +cd pyo3-example +pyenv virtualenv pyo3 +pyenv local pyo3 +``` + +## Adding to an existing project + +Sadly, `maturin` cannot currently be run in existing projects, so if you want to use Python in an existing project you basically have two options: + +1. Create a new project as above and move your existing code into that project +2. Manually edit your project configuration as necessary + +If you opt for the second option, here are the things you need to pay attention to: + +## Cargo.toml + +Make sure that the Rust crate you want to be able to access from Python is compiled into a library. +You can have a binary output as well, but the code you want to access from Python has to be in the library part. +Also, make sure that the crate type is `cdylib` and add PyO3 as a dependency as so: + +```toml +# If you already have [package] information in `Cargo.toml`, you can ignore +# this section! +[package] +# `name` here is name of the package. +name = "pyo3_start" +# these are good defaults: +version = "0.1.0" +edition = "2021" + +[lib] +# The name of the native library. This is the name which will be used in Python to import the +# library (i.e. `import string_sum`). If you change this, you must also change the name of the +# `#[pymodule]` in `src/lib.rs`. +name = "pyo3_example" + +# "cdylib" is necessary to produce a shared library for Python to import from. +crate-type = ["cdylib"] + +[dependencies] +pyo3 = { {{#PYO3_CRATE_VERSION}} } +``` + +## pyproject.toml + +You should also create a `pyproject.toml` with the following contents: + +```toml +[build-system] +requires = ["maturin>=1.9.4,<2"] +build-backend = "maturin" + +[project] +name = "pyo3_example" +requires-python = ">=3.8" +classifiers = [ + "Programming Language :: Rust", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] +``` + +## Running code + +After this you can setup Rust code to be available in Python as below; for example, you can place this code in `src/lib.rs`: + +```rust,no_run +/// A Python module implemented in Rust. The name of this function must match +/// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to +/// import the module. +#[pyo3::pymodule] +mod pyo3_example { + use pyo3::prelude::*; + + /// Formats the sum of two numbers as string. + #[pyfunction] + fn sum_as_string(a: usize, b: usize) -> PyResult { + Ok((a + b).to_string()) + } +} +``` + +Now you can run `maturin develop` to prepare the Python package, after which you can use it like so: + +```bash +$ maturin develop +# lots of progress output as maturin runs the compilation... +$ python +>>> import pyo3_example +>>> pyo3_example.sum_as_string(5, 20) +'25' +``` + +By default, `maturin develop` builds your Rust code with Cargo's default [`dev` profile](https://doc.rust-lang.org/cargo/reference/profiles.html#default-profiles), which includes debug information and limited optimizations. +When checking runtime performance, run `maturin develop --release` to build with Cargo's `release` profile and enable optimizations. + +For more instructions on how to use Python code from Rust, see the [Python from Rust](python-from-rust.md) page. + +## Maturin Import Hook + +In development, any changes in the code would require running `maturin develop` before testing. +To streamline the development process, you may want to install [Maturin Import Hook](https://github.com/PyO3/maturin-import-hook) which will run `maturin develop` automatically when the library with code changes is being imported. diff --git a/vendor/pyo3/guide/src/glossary.md b/vendor/pyo3/guide/src/glossary.md new file mode 100644 index 0000000..d3bc866 --- /dev/null +++ b/vendor/pyo3/guide/src/glossary.md @@ -0,0 +1,45 @@ +# Glossary + +Many of the terms used in this guide are common to the Python or Rust ecosystem, and accordingly can be found in the [Python Glossary](https://docs.python.org/3/glossary.html), [Rust Glossary](https://doc.rust-lang.org/reference/glossary.html), or [Cargo Glossary](https://doc.rust-lang.org/cargo/appendix/glossary.html). + +Below are some terms that are particularly relevant to PyO3 and either are not found in the above glossaries or have a specific meaning in the context of PyO3: + +attached + : To call into the Python interpreter from Rust, the Rust thread must have an associated Python thread state which is "attached" to the Python interpreter. + This is a safety invariant required by the Python C API, which ensures that the Python interpreter can handle exceptions, avoid data races with the garbage collector, etc. + The [`Python::attach`]({{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#method.attach) method is used to attach the current thread to the Python interpreter and obtain a `Python` token which can be used to call Python APIs. + +extension module + : A Python module which is implemented using native code (e.g. C, C++ or Rust) instead of Python. + See also [CPython's documentation on creating extension modules](https://docs.python.org/3/extending/extending.html). + +GIL-enabled Python + : The (current, as of Python 3.14) default build of Python, which depends on the GIL for thread safety. + + This was historically the only thread safety strategy before the introduction of free-threaded Python. + +Python token + : PyO3's [`Python<'py>`]({{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html) type, which can only exist when the current thread is [attached](#attached) to the Python interpreter. + This type is used to call Python APIs and ensures that the safety invariants required by the Python C API are upheld. + +smart pointer + : Pointers which automatically manage the memory they point to. + In particular this guide refers to [PyO3's smart pointers](types.md#pyo3s-smart-pointers) `Py`, `Bound<'py, T>`, and `Borrowed<'a, 'py, T>` which point to Python objects and use Python reference counting to ensure correct memory management. + + See also the [Rust book's chapter on smart pointers](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html). + +wheel + : A precompiled Python package format. + Wheels are the standard way to distribute native code in Python packages for common operating systems and Python versions, which avoid the need for users to compile from source. + The alternative is known as the "source distribution", or "sdist", which requires users to compile the code as part of package installation. + + diff --git a/vendor/pyo3/guide/src/index.md b/vendor/pyo3/guide/src/index.md new file mode 100644 index 0000000..309809a --- /dev/null +++ b/vendor/pyo3/guide/src/index.md @@ -0,0 +1,17 @@ +# The PyO3 user guide + +Welcome to the PyO3 user guide! +This book is a companion to [PyO3's API docs](https://docs.rs/pyo3). +It contains examples and documentation to explain all of PyO3's use cases in detail. + +The rough order of material in this user guide is as follows: + 1. Getting started + 2. Wrapping Rust code for use from Python + 3. How to use Python code from Rust + 4. Remaining topics which go into advanced concepts in detail + +Please choose from the chapters on the left to jump to individual topics, or continue below to start with PyO3's README. + +
+ +{{#include ../../README.md}} diff --git a/vendor/pyo3/guide/src/migration.md b/vendor/pyo3/guide/src/migration.md new file mode 100644 index 0000000..c2cdce6 --- /dev/null +++ b/vendor/pyo3/guide/src/migration.md @@ -0,0 +1,2955 @@ +# Migrating from older PyO3 versions + +This guide can help you upgrade code through breaking changes from one PyO3 version to the next. +For a detailed list of all changes, see the [CHANGELOG](changelog.md). + +## from 0.28.* to 0.29 + +### Removed implementations of `From`, `From`, and `From` for `PyErr` + +
+Click to expand + +Previously the implementations of `From`, `From`, `From`, `From`, and `From` failed to construct the correct Python exception class, as reported in . +The implementations for `string::FromUtf8Error` and `ffi::IntoStringError` were fixed in this release. + +For `str::Utf8Error`, the Rust error does not contain the source bytes required to construct the Python exception. +Instead, `PyUnicodeDecodeError::new_err_from_utf8` can be used to convert the error to a `PyErr`. + +Before: + +```rust,ignore +fn bytes_to_str(bytes: &[u8]) -> PyResult<&str> { + Ok(std::str::from_utf8(bytes)?) +} +``` + +After: + +```rust +# use pyo3::prelude::*; +use pyo3::exceptions::PyUnicodeDecodeError; + +# #[expect(dead_code)] +fn bytes_to_str<'a>(py: Python<'_>, bytes: &'a [u8]) -> PyResult<&'a str> { + std::str::from_utf8(bytes).map_err(|e| PyUnicodeDecodeError::new_err_from_utf8(py, bytes, e)) +} +``` + +For `string::FromUtf16Error` and `char::DecodeUtf16Error` the Rust error types do not contain any of the information required to construct a `UnicodeDecodeError`. +To raise a Python `UnicodeDecodeError` a new error should be manually constructed by calling `PyUnicodeDecodeError::new_err(...)`. + +
+ +### `pyo3_build_config` APIs now require a direct dependency on `pyo3` or `pyo3-ffi` + +
+Click to expand + +Prior to PyO3 0.29, `pyo3-build-config` would inline part of the build configuration into the crate in its own build script. +This worked for simple builds but not for cross-compiling; `pyo3-ffi`'s build script would need to re-implement a lot of the same machinery to correctly configure the build for cross-compilation. +There were also edge cases where `pyo3-build-config` would use this inlined configuration incorrectly and misconfigure the build - e.g. [when cross compiling with `buck` or `bazel` build systems](https://github.com/PyO3/pyo3/issues/4579). + +In PyO3 0.29, `pyo3-build-config` no longer inlines any configuration into itself and instead requires a direct dependency on either `pyo3-ffi` or `pyo3` to load the configuration resolved from `pyo3-ffi`'s build script. + +This has upside of faster compilation - `pyo3-build-config` no longer has a build script and never recompiles when changing Python version. +It also guarantees that all builds are based on the single fully-configured build configuration resolved by `pyo3-ffi`. + +### Deprecation of super class initialization from tuples + +Performing superclass initialitation from a subclass via a tuple is deprecated and will be removed in a future PyO3 version. +This also includes the `From<(S, B)> for PyClassInitializer` impl which we can't warn against. +To migrate use `PyClassInitializer` directly: + +Before: + +```rust +# #![allow(deprecated)] +# use pyo3::prelude::*; +#[pyclass(subclass)] +struct Base; + +#[pyclass(extends=Base)] +struct Sub; + +#[pymethods] +impl Sub { + #[new] + fn new() -> (Self, Base) { + (Self, Base) + } +} +``` + +After: + +```rust +# use pyo3::prelude::*; +#[pyclass(subclass)] +struct Base; + +#[pyclass(extends=Base)] +struct Sub; + +#[pymethods] +impl Sub { + #[new] + fn new() -> PyClassInitializer { + PyClassInitializer::from(Base) + .add_subclass(Self) + } +} +``` + +
+ +### Minor API breaks for soundness reasons + +
+Click to expand + +Recent development in LLM-assisted security analysis has enhanced the ability to detect flaws, both for maintainers and attackers. +Such security analysis of PyO3 flagged some APIs with edge cases that could lead to unsoundness. +The PyO3 maintainers took the decision to make small breaking changes to eliminate these edge cases. +Users should not be affected by these changes unless they were inadvertently relying on unsound behavior. + +The changes were: + +- `PyCapsule::new_with_destructor` now requires the destructor to be `'static` to prevent possible use-after-free issues. +- `PyCFunction::new_closure` now requires the closure to be `Sync` to prevent possible thread unsafety. ⚠️ A security advisory will be issued for this, as the thread unsafety could easily go undetected in testing and lead to exploitable issues downstream in production. ⚠️ +- `PyClassGuardMap` has been split into `PyClassGuardMap` and `PyClassGuardMapMut` to prevent possible lifetime variance issues. +- `PyClassGuardMut::as_super` now returns `PyClassGuardMutSuper` instead of `&mut PyClassGuardMut` to prevent possible type confusion issues. +- `with_critical_section_mutex2` now passes an `Option` as the second argument to the closure to avoid possible mutable reference aliasing when both mutexes participating in the critical section are the same address. + +
+ +### PyO3 now uses `raw-dylib` linking on Windows + +
+Click to expand + +The `raw-dylib` linking mode allows PyO3 to no longer need to have link libraries present when building for Windows targets. +This removes the need for the `generate-import-lib` feature (which is now a no-op) and generally simplifies building for Windows. +This is not expected to have negative impact on users, please report if there are issues. + +
+ +## from 0.27.* to 0.28 + +### Default to supporting free-threaded Python + +
+Click to expand + +When PyO3 0.23 added support for free-threaded Python, this was as an opt-in feature for modules by annotating with `#[pymodule(gil_used = false)]`. + +As the support has matured and PyO3's own API has evolved to remove reliance on the GIL, the time is right to switch the default. +Modules now automatically allow use on free-threaded Python, unless they directly state they require the GIL with `#[pymodule(gil_used = true)]`. +
+ +### Deprecation of automatic `FromPyObject` for `#[pyclass]` types which implement `Clone` + +
+Click to expand + +`#[pyclass]` types which implement `Clone` used to also implement `FromPyObject` automatically. +This behavior is being phased out and replaced by an explicit opt-in, which will allow [better error messages and more user control](https://github.com/PyO3/pyo3/issues/5419). +Affected types will by marked by a deprecation message. + +To migrate use either + +- `#[pyclass(from_py_object)]` to keep the automatic derive, or +- `#[pyclass(skip_from_py_object)]` to accept the new behavior. + +Before: + +```rust +# #![allow(deprecated)] +# use pyo3::prelude::*; +#[pyclass] +#[derive(Clone)] +struct PyClass {} +``` + +After: + +```rust +# use pyo3::prelude::*; +// If the automatic implementation of `FromPyObject` is desired, opt in: +#[pyclass(from_py_object)] +#[derive(Clone)] +struct PyClass {} + +// or if the `FromPyObject` implementation is not needed: +#[pyclass(skip_from_py_object)] +#[derive(Clone)] +struct PyClassWithoutFromPyObject {} +``` + +The `#[pyclass(skip_from_py_object)]` option will eventually be deprecated and removed as it becomes the default behavior. + +
+ +### Deprecation of `Py` constructors from raw pointer + +
+Click to expand + +The constructors `Py::from_owned_ptr`, `Py::from_owned_ptr_or_opt`, and `Py::from_owned_ptr_or_err` (and similar "borrowed" variants) perform an unchecked cast to the `Py` target type `T`. +This unchecked cast is a footgun on APIs where the primary concern is about constructing PyO3's safe smart pointer types correctly from the raw pointer value. + +The equivalent constructors on `Bound` always produce a `Bound`, which encourages any subsequent cast to be done explicitly as either checked or unchecked. +These should be used instead. + +Before: + +```rust +# #![allow(deprecated)] +# use pyo3::prelude::*; +# use pyo3::types::PyNone; +# Python::attach(|py| { +let raw_ptr = py.None().into_ptr(); + +let _: Py = unsafe { Py::from_borrowed_ptr(py, raw_ptr) }; +let _: Py = unsafe { Py::from_owned_ptr(py, raw_ptr) }; +# }) +``` + +After: + +```rust +# use pyo3::prelude::*; +# use pyo3::types::PyNone; +# Python::attach(|py| { +let raw_ptr = py.None().into_ptr(); + +// Bound APIs require choice of doing unchecked or checked cast. Optionally `.unbind()` to +// produce `Py` values. +let _: Bound<'_, PyNone> = unsafe { Bound::from_borrowed_ptr(py, raw_ptr).cast_into_unchecked() }; +let _: Bound<'_, PyNone> = unsafe { Bound::from_owned_ptr(py, raw_ptr).cast_into_unchecked() }; +# }) +``` + +
+ +### Removal of `From` and `From> for PyClassInitializer` + +
+Click to expand + +As part of refactoring the initialization code these impls were removed and its functionality was moved into the generated code for `#[new]`. +As a small side side effect the following pattern will not be accepted anymore: + +```rust,ignore +# use pyo3::prelude::*; +# Python::attach(|py| { +# let existing_py: Py = py.None(); +let obj_1 = Py::new(py, existing_py); + +# let existing_bound: Bound<'_, PyAny> = py.None().into_bound(py); +let obj_2 = Bound::new(py, existing_bound); +# }) +``` + +To migrate use `clone` or `clone_ref`: + +```rust +# use pyo3::prelude::*; +# Python::attach(|py| { +# let existing_py: Py = py.None(); +let obj_1 = existing_py.clone_ref(py); + +# let existing_bound: Bound<'_, PyAny> = py.None().into_bound(py); +let obj_2 = existing_bound.clone(); +# }) +``` + +
+ +### Untyped buffer API moved to PyUntypedBuffer + +
+Click to expand + +`PyBuffer` now is a typed wrapper around `PyUntypedBuffer`. +Many methods such as `PyBuffer::format` have been moved to `PyUntypedBuffer::format`. +`PyBuffer` dereferences to `PyUntypedBuffer`, so method call syntax will continue to work as-is. +Users may need to update references to the moved functions. +
+ +### Internal change to use multi-phase initialization + +
+Click to expand + +[PEP 489](https://peps.python.org/pep-0489/) introduced "multi-phase initialization" for extension modules which provides ways to allocate and clean up per-module state. +This is a necessary step towards supporting Python "subinterpreters" which run on their own copy of state. + +Starting in PyO3 0.28, the `#[pymodule]` macro machinery has been reworked to use multi-phase initialization. +The possibility of creating and consuming per-module state (and supporting subinterpreters) is left for a future PyO3 version. +This should not require migration, nor is there expected to be breakage caused by the change. + +Nevertheless, this affects the order of initialization so seemed worth noting in this guide. +
+ +## from 0.26.* to 0.27 + +### `FromPyObject` reworked for flexibility and efficiency + +
+Click to expand + +With the removal of the `gil-ref` API in PyO3 0.23 it is now possible to fully split the Python lifetime `'py` and the input lifetime `'a`. +This allows borrowing from the input data without extending the lifetime of being attached to the interpreter. + +`FromPyObject` now takes an additional lifetime `'a` describing the input lifetime. +The argument type of the `extract` method changed from `&Bound<'py, PyAny>` to `Borrowed<'a, 'py, PyAny>`. +This was done because `&'a Bound<'py, PyAny>` would have an implicit restriction `'py: 'a` due to the reference type. + +This new form was partly implemented already in 0.22 using the internal `FromPyObjectBound` trait and is now extended to all types. + +Most implementations can just add an elided lifetime to migrate. + +Additionally `FromPyObject` gained an associated type `Error`. +This is the error type that can be used in case of a conversion error. +During migration using `PyErr` is a good default, later a custom error type can be introduced to prevent unnecessary creation of Python exception objects and improved type safety. + +Before: + +```rust,ignore +impl<'py> FromPyObject<'py> for IpAddr { + fn extract_bound(obj: &Bound<'py, PyAny>) -> PyResult { + ... + } +} +``` + +After + +```rust,ignore +impl<'py> FromPyObject<'_, 'py> for IpAddr { + type Error = PyErr; + + fn extract(obj: Borrowed<'_, 'py, PyAny>) -> Result { + ... + // since `Borrowed` derefs to `&Bound`, the body often + // needs no changes, or adding an occasional `&` + } +} +``` + +Occasionally, more steps are necessary. +For generic types, the bounds need to be adjusted. +The correct bound depends on how the type is used. + +For simple wrapper types usually it's possible to just forward the bound. + +Before: + +```rust,ignore +struct MyWrapper(T); + +impl<'py, T> FromPyObject<'py> for MyWrapper +where + T: FromPyObject<'py> +{ + fn extract_bound(obj: &Bound<'py, PyAny>) -> PyResult { + ob.extract().map(MyWrapper) + } +} +``` + +After: + +```rust +# use pyo3::prelude::*; +# #[allow(dead_code)] +# pub struct MyWrapper(T); +impl<'a, 'py, T> FromPyObject<'a, 'py> for MyWrapper +where + T: FromPyObject<'a, 'py> +{ + type Error = T::Error; + + fn extract(obj: Borrowed<'a, 'py, PyAny>) -> Result { + obj.extract().map(MyWrapper) + } +} +``` + +Container types that need to create temporary Python references during extraction, for example extracting from a `PyList`, requires a stronger bound. +For these the `FromPyObjectOwned` trait was introduced. +It is automatically implemented for any type that implements `FromPyObject` and does not borrow from the input. +It is intended to be used as a trait bound in these situations. + +Before: + +```rust,ignore +struct MyVec(Vec); +impl<'py, T> FromPyObject<'py> for Vec +where + T: FromPyObject<'py>, +{ + fn extract_bound(obj: &Bound<'py, PyAny>) -> PyResult { + let mut v = MyVec(Vec::new()); + for item in obj.try_iter()? { + v.0.push(item?.extract::()?); + } + Ok(v) + } +} +``` + +After: + +```rust +# use pyo3::prelude::*; +# #[allow(dead_code)] +# pub struct MyVec(Vec); +impl<'py, T> FromPyObject<'_, 'py> for MyVec +where + T: FromPyObjectOwned<'py> // 👈 can only extract owned values, because each `item` below + // is a temporary short lived owned reference +{ + type Error = PyErr; + + fn extract(obj: Borrowed<'_, 'py, PyAny>) -> Result { + let mut v = MyVec(Vec::new()); + for item in obj.try_iter()? { + v.0.push(item?.extract::().map_err(Into::into)?); // `map_err` is needed because `?` uses `From`, not `Into` 🙁 + } + Ok(v) + } +} +``` + +This is very similar to `serde`s [`Deserialize`] and [`DeserializeOwned`] traits, see [the `serde` docs](https://serde.rs/lifetimes.html). + +[`Deserialize`]: https://docs.rs/serde/latest/serde/trait.Deserialize.html +[`DeserializeOwned`]: https://docs.rs/serde/latest/serde/de/trait.DeserializeOwned.html +
+ +### `.downcast()` and `DowncastError` replaced with `.cast()` and `CastError` + +
+Click to expand + +The `.downcast()` family of functions were only available on `Bound`. +In corner cases (particularly related to `.downcast_into()`) this would require use of `.as_any().downcast()` or `.into_any().downcast_into()` chains. +Additionally, `DowncastError` produced Python exception messages which are not very Pythonic due to use of Rust type names in the error messages. + +The `.cast()` family of functions are available on all `Bound` and `Borrowed` smart pointers, whatever the type, and have error messages derived from the actual type at runtime. +This produces a nicer experience for both PyO3 module authors and consumers. + +To migrate, replace `.downcast()` with `.cast()` and `DowncastError` with `CastError` (and similar with `.downcast_into()` / `DowncastIntoError` etc). + +`CastError` requires a Python `type` object (or other "classinfo" object compatible with `isinstance()`) as the second object, so in the rare case where `DowncastError` was manually constructed, small adjustments to code may apply. +
+ +### `PyTypeCheck` is now an `unsafe trait` + +
+Click to expand + +Because `PyTypeCheck` is the trait used to guard the `.cast()` functions to treat Python objects as specific concrete types, the trait is `unsafe` to implement. + +This should always have been the case, it was an unfortunate omission from its original implementation which is being corrected in this release. +
+ +## from 0.25.* to 0.26 + +### Rename of `Python::with_gil`, `Python::allow_threads`, and `pyo3::prepare_freethreaded_python` + +
+Click to expand + +The names for these APIs were created when the global interpreter lock (GIL) was mandatory. +With the introduction of free-threading in Python 3.13 this is no longer the case, and the naming has no universal meaning anymore. +For this reason, we chose to rename these to more modern terminology introduced in free-threading: + +- `Python::with_gil` is now called `Python::attach`, it attaches a Python thread-state to the current thread. + In GIL enabled builds there can only be 1 thread attached to the interpreter, in free-threading there can be more. +- `Python::allow_threads` is now called `Python::detach`, it detaches a previously attached thread-state. +- `pyo3::prepare_freethreaded_python` is now called `Python::initialize`. +
+ +### Deprecation of `PyObject` type alias + +
+Click to expand + +The type alias `PyObject` (aka `Py`) is often confused with the identically named FFI definition `pyo3::ffi::PyObject`. +For this reason we are deprecating its usage. +To migrate simply replace its usage by the target type `Py`. +
+ +### Replacement of `GILOnceCell` with `PyOnceLock` + +
+Click to expand + +Similar to the above renaming of `Python::with_gil` and related APIs, the `GILOnceCell` type was designed for a Python interpreter which was limited by the GIL. +Aside from its name, it allowed for the "once" initialization to race because the racing was mediated by the GIL and was extremely unlikely to manifest in practice. + +With the introduction of free-threaded Python the racy initialization behavior is more likely to be problematic and so a new type `PyOnceLock` has been introduced which performs true single-initialization correctly while attached to the Python interpreter. +It exposes the same API as `GILOnceCell`, so should be a drop-in replacement with the notable exception that if the racy initialization of `GILOnceCell` was inadvertently relied on (e.g. due to circular references) then the stronger once-ever guarantee of `PyOnceLock` may lead to deadlocking which requires refactoring. + +Before: + +```rust,ignore +# use pyo3::prelude::*; +# use pyo3::sync::GILOnceCell; +# use pyo3::types::PyType; +# fn main() -> PyResult<()> { +# Python::attach(|py| { +static DECIMAL_TYPE: GILOnceCell> = GILOnceCell::new(); +DECIMAL_TYPE.import(py, "decimal", "Decimal")?; +# Ok(()) +# }) +# } +``` + +After: + +```rust +# use pyo3::prelude::*; +# use pyo3::sync::PyOnceLock; +# use pyo3::types::PyType; +# fn main() -> PyResult<()> { +# Python::attach(|py| { +static DECIMAL_TYPE: PyOnceLock> = PyOnceLock::new(); +DECIMAL_TYPE.import(py, "decimal", "Decimal")?; +# Ok(()) +# }) +# } +``` + +
+ +### Deprecation of `GILProtected` + +
+Click to expand + +As another cleanup related to concurrency primitives designed for a Python constrained by the GIL, the `GILProtected` type is now deprecated. +Prefer to use concurrency primitives which are compatible with free-threaded Python, such as [`std::sync::Mutex`](https://doc.rust-lang.org/std/sync/struct.Mutex.html) (in combination with PyO3's [`MutexExt`]({{#PYO3_DOCS_URL}}/pyo3/sync/trait.MutexExt.html) trait). + +Before: + +```rust,ignore +# use pyo3::prelude::*; +# fn main() { +# #[cfg(not(Py_GIL_DISABLED))] { +use pyo3::sync::GILProtected; +use std::cell::RefCell; +# Python::attach(|py| { +static NUMBERS: GILProtected>> = GILProtected::new(RefCell::new(Vec::new())); +Python::attach(|py| { + NUMBERS.get(py).borrow_mut().push(42); +}); +# }) +# } +# } +``` + +After: + +```rust +# use pyo3::prelude::*; +use pyo3::sync::MutexExt; +use std::sync::Mutex; +# fn main() { +# Python::attach(|py| { +static NUMBERS: Mutex> = Mutex::new(Vec::new()); +Python::attach(|py| { + NUMBERS.lock_py_attached(py).expect("no poisoning").push(42); +}); +# }) +# } +``` + +
+ +### `PyMemoryError` now maps to `io::ErrorKind::OutOfMemory` when converted to `io::Error` + +
+Click to expand + +Previously, converting a `PyMemoryError` into a Rust `io::Error` would result in an error with kind `Other`. +Now, it produces an error with kind `OutOfMemory`. +Similarly, converting an `io::Error` with kind `OutOfMemory` back into a Python error would previously yield a generic `PyOSError`. +Now, it yields a `PyMemoryError`. + +This change makes error conversions more precise and matches the semantics of out-of-memory errors between Python and Rust. +
+ +## from 0.24.* to 0.25 + +### `AsPyPointer` removal + +
+Click to expand + +The `AsPyPointer` trait is mostly a leftover from the now removed gil-refs API. +The last remaining uses were the GC API, namely `PyVisit::call`, and identity comparison (`PyAnyMethods::is` and `Py::is`). + +`PyVisit::call` has been updated to take `T: Into>>`, which allows for arguments of type `&Py`, `&Option>` and `Option<&Py>`. +It is unlikely any changes are needed here to migrate. + +`PyAnyMethods::is`/ `Py::is` has been updated to take `T: AsRef>>`. +Additionally `AsRef>>` implementations were added for `Py`, `Bound` and `Borrowed`. +Because of the existing `AsRef> for Bound` implementation this may cause inference issues in non-generic code. +This can be easily migrated by switching to `as_any` instead of `as_ref` for these calls. +
+ +## from 0.23.* to 0.24 + +
+Click to expand +There were no significant changes from 0.23 to 0.24 which required documenting in this guide. +
+ +## from 0.22.* to 0.23 + +
+Click to expand + +PyO3 0.23 is a significant rework of PyO3's internals for two major improvements: + +- Support of Python 3.13's new freethreaded build (aka "3.13t") +- Rework of to-Python conversions with a new `IntoPyObject` trait. + +These changes are both substantial and reasonable efforts have been made to allow as much code as possible to continue to work as-is despite the changes. +The impacts are likely to be seen in three places when upgrading: + +- PyO3's data structures [are now thread-safe](#free-threaded-python-support) instead of reliant on the GIL for synchronization. + In particular, `#[pyclass]` types are [now required to be `Sync`](./class/thread-safety.md). +- The [`IntoPyObject` trait](#new-intopyobject-trait-unifies-to-python-conversions) may need to be implemented for types in your codebase. + In most cases this can simply be done with [`#[derive(IntoPyObject)]`](#intopyobject-and-intopyobjectref-derive-macros). + There will be many deprecation warnings from the replacement of `IntoPy` and `ToPyObject` traits. +- There will be many deprecation warnings from the [final removal of the `gil-refs` feature](#gil-refs-feature-removed), which opened up API space for a cleanup and simplification to PyO3's "Bound" API. + +The sections below discuss the rationale and details of each change in more depth. +
+ +### Free-threaded Python Support + +
+Click to expand + +PyO3 0.23 introduces initial support for the new free-threaded build of CPython 3.13, aka "3.13t". + +Because this build allows multiple Python threads to operate simultaneously on underlying Rust data, the `#[pyclass]` macro now requires that types it operates on implement `Sync`. + +Aside from the change to `#[pyclass]`, most features of PyO3 work unchanged, as the changes have been to the internal data structures to make them thread-safe. +An example of this is the `GILOnceCell` type, which used the GIL to synchronize single-initialization. +It now uses internal locks to guarantee that only one write ever succeeds, however it allows for multiple racing runs of the initialization closure. +It may be preferable to instead use `std::sync::OnceLock` in combination with the `pyo3::sync::OnceLockExt` trait which adds `OnceLock::get_or_init_py_attached` for single-initialization where the initialization closure is guaranteed only ever to run once and without deadlocking with the GIL. + +Future PyO3 versions will likely add more traits and data structures to make working with free-threaded Python easier. + +Some features are inaccessible on the free-threaded build: + +- The `GILProtected` type, which relied on the GIL to expose synchronized access to inner contents +- `PyList::get_item_unchecked`, which cannot soundly be used due to races between time-of-check and time-of-use + +If you make use of these features then you will need to account for the unavailability of the API in the free-threaded build. +One way to handle it is via conditional compilation -- extension modules can use `pyo3-build-config` to get access to a `#[cfg(Py_GIL_DISABLED)]` guard. + +See [the guide section on free-threaded Python](free-threading.md) for more details about supporting free-threaded Python in a PyO3 extension module. +
+ +### New `IntoPyObject` trait unifies to-Python conversions + +
+Click to expand + +PyO3 0.23 introduces a new `IntoPyObject` trait to convert Rust types into Python objects which replaces both `IntoPy` and `ToPyObject`. +Notable features of this new trait include: + +- conversions can now return an error +- it is designed to work efficiently for both `T` owned types and `&T` references +- compared to `IntoPy` the generic `T` moved into an associated type, so + - there is now only one way to convert a given type + - the output type is stronger typed and may return any Python type instead of just `PyAny` +- byte collections are specialized to convert into `PyBytes` now, see [below](#to-python-conversions-changed-for-byte-collections-vecu8-u8-n-and-smallvecu8-n) +- `()` (unit) is now only specialized in return position of `#[pyfunction]` and `#[pymethods]` to return `None`, in normal usage it converts into an empty `PyTuple` + +All PyO3 provided types as well as `#[pyclass]`es already implement `IntoPyObject`. +Other types will need to adapt an implementation of `IntoPyObject` to stay compatible with the Python APIs. +In many cases the new [`#[derive(IntoPyObject)]`](#intopyobject-and-intopyobjectref-derive-macros) macro can be used instead of [manual implementations](#intopyobject-manual-implementation). + +Since `IntoPyObject::into_pyobject` may return either a `Bound` or `Borrowed`, you may find the [`BoundObject`](conversions/traits.md#boundobject-for-conversions-that-may-be-bound-or-borrowed) trait to be useful to write code that generically handles either type of smart pointer. + +Together with the introduction of `IntoPyObject` the old conversion traits `ToPyObject` and `IntoPy` are deprecated and will be removed in a future PyO3 version. + +#### `IntoPyObject` and `IntoPyObjectRef` derive macros + +To implement the new trait you may use the new `IntoPyObject` and `IntoPyObjectRef` derive macros as below. + +```rust,no_run +# use pyo3::prelude::*; +#[derive(IntoPyObject, IntoPyObjectRef)] +struct Struct { + count: usize, + obj: Py, +} +``` + +The `IntoPyObjectRef` derive macro derives implementations for references (e.g. for `&Struct` in the example above), which is a replacement for the `ToPyObject` trait. + +#### `IntoPyObject` manual implementation + +Before: + +```rust,ignore +# use pyo3::prelude::*; +# #[allow(dead_code)] +struct MyPyObjectWrapper(PyObject); + +impl IntoPy for MyPyObjectWrapper { + fn into_py(self, py: Python<'_>) -> PyObject { + self.0 + } +} + +impl ToPyObject for MyPyObjectWrapper { + fn to_object(&self, py: Python<'_>) -> PyObject { + self.0.clone_ref(py) + } +} +``` + +After: + +```rust,ignore +# use pyo3::prelude::*; +# #[allow(dead_code)] +# struct MyPyObjectWrapper(PyObject); + +impl<'py> IntoPyObject<'py> for MyPyObjectWrapper { + type Target = PyAny; // the Python type + type Output = Bound<'py, Self::Target>; // in most cases this will be `Bound` + type Error = std::convert::Infallible; + + fn into_pyobject(self, py: Python<'py>) -> Result { + Ok(self.0.into_bound(py)) + } +} + +// `ToPyObject` implementations should be converted to implementations on reference types +impl<'a, 'py> IntoPyObject<'py> for &'a MyPyObjectWrapper { + type Target = PyAny; + type Output = Borrowed<'a, 'py, Self::Target>; // `Borrowed` can be used to optimized reference counting + type Error = std::convert::Infallible; + + fn into_pyobject(self, py: Python<'py>) -> Result { + Ok(self.0.bind_borrowed(py)) + } +} +``` + +
+ +### To-Python conversions changed for byte collections (`Vec`, `[u8; N]` and `SmallVec<[u8; N]>`) + +
+Click to expand + +With the introduction of the `IntoPyObject` trait, PyO3's macros now prefer `IntoPyObject` implementations over `IntoPy` when producing Python values. +This applies to `#[pyfunction]` and `#[pymethods]` return values and also fields accessed via `#[pyo3(get)]`. + +This change has an effect on functions and methods returning _byte_ collections like + +- `Vec` +- `[u8; N]` +- `SmallVec<[u8; N]>` + +In their new `IntoPyObject` implementation these will now turn into `PyBytes` rather than a `PyList`. +All other `T`s are unaffected and still convert into a `PyList`. + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +#[pyfunction] +fn foo() -> Vec { // would previously turn into a `PyList`, now `PyBytes` + vec![0, 1, 2, 3] +} + +#[pyfunction] +fn bar() -> Vec { // unaffected, returns `PyList` + vec![0, 1, 2, 3] +} +``` + +If this conversion is _not_ desired, consider building a list manually using `PyList::new`. + +The following types were previously _only_ implemented for `u8` and now allow other `T`s turn into `PyList`: + +- `&[T]` +- `Cow<[T]>` + +This is purely additional and should just extend the possible return types. + +
+ +### `gil-refs` feature removed + +
+Click to expand + +PyO3 0.23 completes the removal of the "GIL Refs" API in favour of the new "Bound" API introduced in PyO3 0.21. + +With the removal of the old API, many "Bound" API functions which had been introduced with `_bound` suffixes no longer need the suffixes as these names have been freed up. +For example, `PyTuple::new_bound` is now just `PyTuple::new` (the existing name remains but is deprecated). + +Before: + +```rust,ignore +# #![allow(deprecated)] +# use pyo3::prelude::*; +# use pyo3::types::PyTuple; +# fn main() { +# Python::attach(|py| { +// For example, for PyTuple. Many such APIs have been changed. +let tup = PyTuple::new_bound(py, [1, 2, 3]); +# }) +# } +``` + +After: + +```rust +# use pyo3::prelude::*; +# use pyo3::types::PyTuple; +# fn main() { +# Python::attach(|py| { +// For example, for PyTuple. Many such APIs have been changed. +let tup = PyTuple::new(py, [1, 2, 3]); +# }) +# } +``` + +#### `IntoPyDict` trait adjusted for removal of `gil-refs` + +As part of this API simplification, the `IntoPyDict` trait has had a small breaking change: `IntoPyDict::into_py_dict_bound` method has been renamed to `IntoPyDict::into_py_dict`. +It is also now fallible as part of the `IntoPyObject` trait addition. + +If you implemented `IntoPyDict` for your type, you should implement `into_py_dict` instead of `into_py_dict_bound`. +The old name is still available for calling but deprecated. + +Before: + +```rust,ignore +# use pyo3::prelude::*; +# use pyo3::types::{PyDict, IntoPyDict}; +# use std::collections::HashMap; + +struct MyMap(HashMap); + +impl IntoPyDict for MyMap +where + K: ToPyObject, + V: ToPyObject, +{ + fn into_py_dict_bound(self, py: Python<'_>) -> Bound<'_, PyDict> { + let dict = PyDict::new_bound(py); + for (key, value) in self.0 { + dict.set_item(key, value) + .expect("Failed to set_item on dict"); + } + dict + } +} +``` + +After: + +```rust,no_run +# use pyo3::prelude::*; +# use pyo3::types::{PyDict, IntoPyDict}; +# use std::collections::HashMap; + +# #[allow(dead_code)] +struct MyMap(HashMap); + +impl<'py, K, V> IntoPyDict<'py> for MyMap +where + K: IntoPyObject<'py>, + V: IntoPyObject<'py>, +{ + fn into_py_dict(self, py: Python<'py>) -> PyResult> { + let dict = PyDict::new(py); + for (key, value) in self.0 { + dict.set_item(key, value)?; + } + Ok(dict) + } +} +``` + +
+ +## from 0.21.* to 0.22 + +### Deprecation of `gil-refs` feature continues + +
+Click to expand + +Following the introduction of the "Bound" API in PyO3 0.21 and the planned removal of the "GIL Refs" API, all functionality related to GIL Refs is now gated behind the `gil-refs` feature and emits a deprecation warning on use. + +See the 0.21 migration entry for help upgrading. +
+ +### Deprecation of implicit default for trailing optional arguments + +
+Click to expand + +With `pyo3` 0.22 the implicit `None` default for trailing `Option` type argument is deprecated. +To migrate, place a `#[pyo3(signature = (...))]` attribute on affected functions or methods and specify the desired behavior. +The migration warning specifies the corresponding signature to keep the current behavior. +With 0.23 the signature will be required for any function containing `Option` type parameters to prevent accidental and unnoticed changes in behavior. +With 0.24 this restriction will be lifted again and `Option` type arguments will be treated as any other argument _without_ special handling. + +Before: + +```rust,no_run +# #![allow(deprecated, dead_code)] +# use pyo3::prelude::*; +#[pyfunction] +fn increment(x: u64, amount: Option) -> u64 { + x + amount.unwrap_or(1) +} +``` + +After: + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +#[pyfunction] +#[pyo3(signature = (x, amount=None))] +fn increment(x: u64, amount: Option) -> u64 { + x + amount.unwrap_or(1) +} +``` + +
+ +### `Py::clone` is now gated behind the `py-clone` feature + +
+Click to expand + +If you rely on `impl Clone for Py` to fulfil trait requirements imposed by existing Rust code written without PyO3-based code in mind, the newly introduced feature `py-clone` must be enabled. + +However, take care to note that the behaviour is different from previous versions. +If `Clone` was called without the GIL being held, we tried to delay the application of these reference count increments until PyO3-based code would re-acquire it. +This turned out to be impossible to implement in a sound manner and hence was removed. +Now, if `Clone` is called without the GIL being held, we panic instead for which calling code might not be prepared. + +It is advised to migrate off the `py-clone` feature. +The simplest way to remove dependency on `impl Clone for Py` is to wrap `Py` as `Arc>` and use cloning of the arc. + +Related to this, we also added a `pyo3_disable_reference_pool` conditional compilation flag which removes the infrastructure necessary to apply delayed reference count decrements implied by `impl Drop for Py`. +They do not appear to be a soundness hazard as they should lead to memory leaks in the worst case. +However, the global synchronization adds significant overhead to cross the Python-Rust boundary. +Enabling this feature will remove these costs and make the `Drop` implementation abort the process if called without the GIL being held instead. +
+ +### Require explicit opt-in for comparison for simple enums + +
+Click to expand + +With `pyo3` 0.22 the new `#[pyo3(eq)]` options allows automatic implementation of Python equality using Rust's `PartialEq`. +Previously simple enums automatically implemented equality in terms of their discriminants. +To make PyO3 more consistent, this automatic equality implementation is deprecated in favour of having opt-ins for all `#[pyclass]` types. +Similarly, simple enums supported comparison with integers, which is not covered by Rust's `PartialEq` derive, so has been split out into the `#[pyo3(eq_int)]` attribute. + +To migrate, place a `#[pyo3(eq, eq_int)]` attribute on simple enum classes. + +Before: + +```rust,no_run +# #![allow(deprecated, dead_code)] +# use pyo3::prelude::*; +#[pyclass] +enum SimpleEnum { + VariantA, + VariantB = 42, +} +``` + +After: + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +#[pyclass(eq, eq_int)] +#[derive(PartialEq)] +enum SimpleEnum { + VariantA, + VariantB = 42, +} +``` + +
+ +### `PyType::name` reworked to better match Python `__name__` + +
+Click to expand + +This function previously would try to read directly from Python type objects' C API field (`tp_name`), in which case it would return a `Cow::Borrowed`. +However the contents of `tp_name` don't have well-defined semantics. + +Instead `PyType::name()` now returns the equivalent of Python `__name__` and returns `PyResult>`. + +The closest equivalent to PyO3 0.21's version of `PyType::name()` has been introduced as a new function `PyType::fully_qualified_name()`, which is equivalent to `__module__` and `__qualname__` joined as `module.qualname`. + +Before: + +```rust,ignore +# #![allow(deprecated, dead_code)] +# use pyo3::prelude::*; +# use pyo3::types::{PyBool}; +# fn main() -> PyResult<()> { +Python::with_gil(|py| { + let bool_type = py.get_type_bound::(); + let name = bool_type.name()?.into_owned(); + println!("Hello, {}", name); + + let mut name_upper = bool_type.name()?; + name_upper.to_mut().make_ascii_uppercase(); + println!("Hello, {}", name_upper); + + Ok(()) +}) +# } +``` + +After: + +```rust,ignore +# #![allow(dead_code)] +# use pyo3::prelude::*; +# use pyo3::types::{PyBool}; +# fn main() -> PyResult<()> { +Python::with_gil(|py| { + let bool_type = py.get_type_bound::(); + let name = bool_type.name()?; + println!("Hello, {}", name); + + // (if the full dotted path was desired, switch from `name()` to `fully_qualified_name()`) + let mut name_upper = bool_type.fully_qualified_name()?.to_string(); + name_upper.make_ascii_uppercase(); + println!("Hello, {}", name_upper); + + Ok(()) +}) +# } +``` + +
+ +## from 0.20.* to 0.21 + +
+Click to expand + +PyO3 0.21 introduces a new `Bound<'py, T>` smart pointer which replaces the existing "GIL Refs" API to interact with Python objects. +For example, in PyO3 0.20 the reference `&'py PyAny` would be used to interact with Python objects. +In PyO3 0.21 the updated type is `Bound<'py, PyAny>`. +Making this change moves Rust ownership semantics out of PyO3's internals and into user code. +This change fixes [a known soundness edge case of interaction with gevent](https://github.com/PyO3/pyo3/issues/3668) as well as improves CPU and [memory performance](https://github.com/PyO3/pyo3/issues/1056). +For a full history of discussion see . +For a full history of discussion see . + +The "GIL Ref" `&'py PyAny` and similar types such as `&'py PyDict` continue to be available as a deprecated API. +Due to the advantages of the new API it is advised that all users make the effort to upgrade as soon as possible. + +In addition to the major API type overhaul, PyO3 has needed to make a few small breaking adjustments to other APIs to close correctness and soundness gaps. + +The recommended steps to update to PyO3 0.21 is as follows: + +1. Enable the `gil-refs` feature to silence deprecations related to the API change +2. Fix all other PyO3 0.21 migration steps +3. Disable the `gil-refs` feature and migrate off the deprecated APIs + +The following sections are laid out in this order. +
+ +### Enable the `gil-refs` feature + +
+Click to expand + +To make the transition for the PyO3 ecosystem away from the GIL Refs API as smooth as possible, in PyO3 0.21 no APIs consuming or producing GIL Refs have been altered. +Instead, variants using `Bound` smart pointers have been introduced, for example `PyTuple::new_bound` which returns `Bound` is the replacement form of `PyTuple::new`. +The GIL Ref APIs have been deprecated, but to make migration easier it is possible to disable these deprecation warnings by enabling the `gil-refs` feature. + +> [!TIP] +> The one single exception where an existing API was changed in-place is the `pyo3::intern!` macro. Almost all uses of this macro did not need to update code to account it changing to return `&Bound` immediately, and adding an `intern_bound!` replacement was perceived as adding more work for users. + +It is recommended that users do this as a first step of updating to PyO3 0.21 so that the deprecation warnings do not get in the way of resolving the rest of the migration steps. + +Before: + +```toml +# Cargo.toml +[dependencies] +pyo3 = "0.20" +``` + +After: + +```toml +# Cargo.toml +[dependencies] +pyo3 = { version = "0.21", features = ["gil-refs"] } +``` + +
+ +### `PyTypeInfo` and `PyTryFrom` have been adjusted + +
+Click to expand + +The `PyTryFrom` trait has aged poorly, its `try_from` method now conflicts with `TryFrom::try_from` in the 2021 edition prelude. +A lot of its functionality was also duplicated with `PyTypeInfo`. + +To tighten up the PyO3 traits as part of the deprecation of the GIL Refs API the `PyTypeInfo` trait has had a simpler companion `PyTypeCheck`. +The methods `PyAny::downcast` and `PyAny::downcast_exact` no longer use `PyTryFrom` as a bound, instead using `PyTypeCheck` and `PyTypeInfo` respectively. + +To migrate, switch all type casts to use `obj.downcast()` instead of `try_from(obj)` (and similar for `downcast_exact`). + +Before: + +```rust,ignore +# #![allow(deprecated)] +# use pyo3::prelude::*; +# use pyo3::types::{PyInt, PyList}; +# fn main() -> PyResult<()> { +Python::with_gil(|py| { + let list = PyList::new(py, 0..5); + let b = ::try_from(list.get_item(0).unwrap())?; + Ok(()) +}) +# } +``` + +After: + +```rust,ignore +# use pyo3::prelude::*; +# use pyo3::types::{PyInt, PyList}; +# fn main() -> PyResult<()> { +Python::with_gil(|py| { + // Note that PyList::new is deprecated for PyList::new_bound as part of the GIL Refs API removal, + // see the section below on migration to Bound. + #[allow(deprecated)] + let list = PyList::new(py, 0..5); + let b = list.get_item(0).unwrap().downcast::()?; + Ok(()) +}) +# } +``` + +
+ +### `Iter(A)NextOutput` are deprecated + +
+Click to expand + +The `__next__` and `__anext__` magic methods can now return any type convertible into Python objects directly just like all other `#[pymethods]`. +The `IterNextOutput` used by `__next__` and `IterANextOutput` used by `__anext__` are subsequently deprecated. +Most importantly, this change allows returning an awaitable from `__anext__` without non-sensically wrapping it into `Yield` or `Some`. +Only the return types `Option` and `Result, E>` are still handled in a special manner where `Some(val)` yields `val` and `None` stops iteration. + +Starting with an implementation of a Python iterator using `IterNextOutput`, e.g. + +```rust,ignore +use pyo3::prelude::*; +use pyo3::iter::IterNextOutput; + +#[pyclass] +struct PyClassIter { + count: usize, +} + +#[pymethods] +impl PyClassIter { + fn __next__(&mut self) -> IterNextOutput { + if self.count < 5 { + self.count += 1; + IterNextOutput::Yield(self.count) + } else { + IterNextOutput::Return("done") + } + } +} +``` + +If returning `"done"` via `StopIteration` is not really required, this should be written as + +```rust,no_run +use pyo3::prelude::*; + +#[pyclass] +struct PyClassIter { + count: usize, +} + +#[pymethods] +impl PyClassIter { + fn __next__(&mut self) -> Option { + if self.count < 5 { + self.count += 1; + Some(self.count) + } else { + None + } + } +} +``` + +This form also has additional benefits: It has already worked in previous PyO3 versions, it matches the signature of Rust's [`Iterator` trait](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html) and it allows using a fast path in CPython which completely avoids the cost of raising a `StopIteration` exception. +Note that using [`Option::transpose`](https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.transpose) and the `Result, E>` variant, this form can also be used to wrap fallible iterators. + +Alternatively, the implementation can also be done as it would in Python itself, i.e. by "raising" a `StopIteration` exception + +```rust,no_run +use pyo3::prelude::*; +use pyo3::exceptions::PyStopIteration; + +#[pyclass] +struct PyClassIter { + count: usize, +} + +#[pymethods] +impl PyClassIter { + fn __next__(&mut self) -> PyResult { + if self.count < 5 { + self.count += 1; + Ok(self.count) + } else { + Err(PyStopIteration::new_err("done")) + } + } +} +``` + +Finally, an asynchronous iterator can directly return an awaitable without confusing wrapping + +```rust,no_run +use pyo3::prelude::*; + +#[pyclass] +struct PyClassAwaitable { + number: usize, +} + +#[pymethods] +impl PyClassAwaitable { + fn __next__(&self) -> usize { + self.number + } + + fn __await__(slf: Py) -> Py { + slf + } +} + +#[pyclass] +struct PyClassAsyncIter { + number: usize, +} + +#[pymethods] +impl PyClassAsyncIter { + fn __anext__(&mut self) -> PyClassAwaitable { + self.number += 1; + PyClassAwaitable { + number: self.number, + } + } + + fn __aiter__(slf: Py) -> Py { + slf + } +} +``` + +
+ +### `PyType::name` has been renamed to `PyType::qualname` + +
+Click to expand + +`PyType::name` has been renamed to `PyType::qualname` to indicate that it does indeed return the [qualified name](https://docs.python.org/3/glossary.html#term-qualified-name), matching the `__qualname__` attribute. +The newly added `PyType::name` yields the full name including the module name now which corresponds to `__module__.__name__` on the level of attributes. +
+ +### `PyCell` has been deprecated + +
+Click to expand + +Interactions with Python objects implemented in Rust no longer need to go though `PyCell`. +Instead interactions with Python object now consistently go through `Bound` or `Py` independently of whether `T` is native Python object or a `#[pyclass]` implemented in Rust. +Use `Bound::new` or `Py::new` respectively to create and `Bound::borrow(_mut)` / `Py::borrow(_mut)` to borrow the Rust object. +
+ +### Migrating from the GIL Refs API to `Bound` + +
+Click to expand + +To minimise breakage of code using the GIL Refs API, the `Bound` smart pointer has been introduced by adding complements to all functions which accept or return GIL Refs. +This allows code to migrate by replacing the deprecated APIs with the new ones. + +To identify what to migrate, temporarily switch off the `gil-refs` feature to see deprecation warnings on [almost](#cases-where-pyo3-cannot-emit-gil-ref-deprecation-warnings) all uses of APIs accepting and producing GIL Refs . +Over one or more PRs it should be possible to follow the deprecation hints to update code. +Depending on your development environment, switching off the `gil-refs` feature may introduce [some very targeted breakages](#deactivating-the-gil-refs-feature), so you may need to fixup those first. + +For example, the following APIs have gained updated variants: + +- `PyList::new`, `PyTuple::new` and similar constructors have replacements `PyList::new_bound`, `PyTuple::new_bound` etc. +- `FromPyObject::extract` has a new `FromPyObject::extract_bound` (see the section below) +- The `PyTypeInfo` trait has had new `_bound` methods added to accept / return `Bound`. + +Because the new `Bound` API brings ownership out of the PyO3 framework and into user code, there are a few places where user code is expected to need to adjust while switching to the new API: + +- Code will need to add the occasional `&` to borrow the new smart pointer as `&Bound` to pass these types around (or use `.clone()` at the very small cost of increasing the Python reference count) +- `Bound` and `Bound` cannot support indexing with `list[0]`, you should use `list.get_item(0)` instead. +- `Bound::iter_borrowed` is slightly more efficient than `Bound::iter`. + The default iteration of `Bound` cannot return borrowed references because Rust does not (yet) have "lending iterators". + Similarly `Bound::get_borrowed_item` is more efficient than `Bound::get_item` for the same reason. +- `&Bound` does not implement `FromPyObject` (although it might be possible to do this in the future once the GIL Refs API is completely removed). + Use `bound_any.downcast::()` instead of `bound_any.extract::<&Bound>()`. +- `Bound::to_str` now borrows from the `Bound` rather than from the `'py` lifetime, so code will need to store the smart pointer as a value in some cases where previously `&PyString` was just used as a temporary. (There are some more details relating to this in [the section below](#deactivating-the-gil-refs-feature).) +- `.extract::<&str>()` now borrows from the source Python object. + The simplest way to update is to change to `.extract::()`, which retains ownership of the Python reference. + See more information [in the section on deactivating the `gil-refs` feature](#deactivating-the-gil-refs-feature). + +To convert between `&PyAny` and `&Bound` use the `as_borrowed()` method: + +```rust,ignore +let gil_ref: &PyAny = ...; +let bound: &Bound = &gil_ref.as_borrowed(); +``` + +To convert between `Py` and `Bound` use the `bind()` / `into_bound()` methods, and `as_unbound()` / `unbind()` to go back from `Bound` to `Py`. + +```rust,ignore +let obj: Py = ...; +let bound: &Bound<'py, PyList> = obj.bind(py); +let bound: Bound<'py, PyList> = obj.into_bound(py); + +let obj: &Py = bound.as_unbound(); +let obj: Py = bound.unbind(); +``` + +> [!WARNING] +> Dangling pointer trap 💣 +> +> Because of the ownership changes, code which uses `.as_ptr()` to convert `&PyAny` and other GIL Refs to a `*mut pyo3_ffi::PyObject` should take care to avoid creating dangling pointers now that `Bound` carries ownership. +> +> For example, the following pattern with `Option<&PyAny>` can easily create a dangling pointer when migrating to the `Bound` smart pointer: +> +> ```rust,ignore +> let opt: Option<&PyAny> = ...; +> let p: *mut ffi::PyObject = opt.map_or(std::ptr::null_mut(), |any| any.as_ptr()); +> ``` +> +> The correct way to migrate this code is to use `.as_ref()` to avoid dropping the `Bound` in the `map_or` closure: +> +> ```rust,ignore +> let opt: Option> = ...; +> let p: *mut ffi::PyObject = opt.as_ref().map_or(std::ptr::null_mut(), Bound::as_ptr); +> ``` + +#### Migrating `FromPyObject` implementations + +`FromPyObject` has had a new method `extract_bound` which takes `&Bound<'py, PyAny>` as an argument instead of `&PyAny`. +Both `extract` and `extract_bound` have been given default implementations in terms of the other, to avoid breaking code immediately on update to 0.21. + +All implementations of `FromPyObject` should be switched from `extract` to `extract_bound`. + +Before: + +```rust,ignore +impl<'py> FromPyObject<'py> for MyType { + fn extract(obj: &'py PyAny) -> PyResult { + /* ... */ + } +} +``` + +After: + +```rust,ignore +impl<'py> FromPyObject<'py> for MyType { + fn extract_bound(obj: &Bound<'py, PyAny>) -> PyResult { + /* ... */ + } +} +``` + +The expectation is that in 0.22 `extract_bound` will have the default implementation removed and in 0.23 `extract` will be removed. + +#### Cases where PyO3 cannot emit GIL Ref deprecation warnings + +Despite a large amount of deprecations warnings produced by PyO3 to aid with the transition from GIL Refs to the Bound API, there are a few cases where PyO3 cannot automatically warn on uses of GIL Refs. +It is worth checking for these cases manually after the deprecation warnings have all been addressed: + +- Individual implementations of the `FromPyObject` trait cannot be deprecated, so PyO3 cannot warn about uses of code patterns like `.extract<&PyAny>()` which produce a GIL Ref. +- GIL Refs in `#[pyfunction]` arguments emit a warning, but if the GIL Ref is wrapped inside another container such as `Vec<&PyAny>` then PyO3 cannot warn against this. +- The `wrap_pyfunction!(function)(py)` deferred argument form of the `wrap_pyfunction` macro taking `py: Python<'py>` produces a GIL Ref, and due to limitations in type inference PyO3 cannot warn against this specific case. + +
+ +### Deactivating the `gil-refs` feature + +
+Click to expand + +As a final step of migration, deactivating the `gil-refs` feature will set up code for best performance and is intended to set up a forward-compatible API for PyO3 0.22. + +At this point code that needed to manage GIL Ref memory can safely remove uses of `GILPool` (which are constructed by calls to `Python::new_pool` and `Python::with_pool`). +Deprecation warnings will highlight these cases. + +There is just one case of code that changes upon disabling these features: `FromPyObject` trait implementations for types that borrow directly from the input data cannot be implemented by PyO3 without GIL Refs (while the GIL Refs API is in the process of being removed). +The main types affected are `&str`, `Cow<'_, str>`, `&[u8]`, `Cow<'_, u8>`. + +To make PyO3's core functionality continue to work while the GIL Refs API is in the process of being removed, disabling the `gil-refs` feature moves the implementations of `FromPyObject` for `&str`, `Cow<'_, str>`, `&[u8]`, `Cow<'_, u8>` to a new temporary trait `FromPyObjectBound`. +This trait is the expected future form of `FromPyObject` and has an additional lifetime `'a` to enable these types to borrow data from Python objects. + +PyO3 0.21 has introduced the [`PyBackedStr`]({{#PYO3_DOCS_URL}}/pyo3/pybacked/struct.PyBackedStr.html) and [`PyBackedBytes`]({{#PYO3_DOCS_URL}}/pyo3/pybacked/struct.PyBackedBytes.html) types to help with this case. +The easiest way to avoid lifetime challenges from extracting `&str` is to use these. +For more complex types like `Vec<&str>`, is now impossible to extract directly from a Python object and `Vec` is the recommended upgrade path. + +A key thing to note here is because extracting to these types now ties them to the input lifetime, some extremely common patterns may need to be split into multiple Rust lines. +For example, the following snippet of calling `.extract::<&str>()` directly on the result of `.getattr()` needs to be adjusted when deactivating the `gil-refs` feature. + +Before: + +```rust,ignore +# #[cfg(feature = "gil-refs")] { +# use pyo3::prelude::*; +# use pyo3::types::{PyList, PyType}; +# fn example<'py>(py: Python<'py>) -> PyResult<()> { +#[allow(deprecated)] // GIL Ref API +let obj: &'py PyType = py.get_type::(); +let name: &'py str = obj.getattr("__name__")?.extract()?; +assert_eq!(name, "list"); +# Ok(()) +# } +# Python::with_gil(example).unwrap(); +# } +``` + +After: + +```rust,ignore +# #[cfg(any(not(Py_LIMITED_API), Py_3_10))] { +# use pyo3::prelude::*; +# use pyo3::types::{PyList, PyType}; +# fn example<'py>(py: Python<'py>) -> PyResult<()> { +let obj: Bound<'py, PyType> = py.get_type_bound::(); +let name_obj: Bound<'py, PyAny> = obj.getattr("__name__")?; +// the lifetime of the data is no longer `'py` but the much shorter +// lifetime of the `name_obj` smart pointer above +let name: &'_ str = name_obj.extract()?; +assert_eq!(name, "list"); +# Ok(()) +# } +# Python::with_gil(example).unwrap(); +# } +``` + +To avoid needing to worry about lifetimes at all, it is also possible to use the new `PyBackedStr` type, which stores a reference to the Python `str` without a lifetime attachment. +In particular, `PyBackedStr` helps for `abi3` builds for Python older than 3.10. +Due to limitations in the `abi3` CPython API for those older versions, PyO3 cannot offer a `FromPyObjectBound` implementation for `&str` on those versions. +The easiest way to migrate for older `abi3` builds is to replace any cases of `.extract::<&str>()` with `.extract::()`. +Alternatively, use `.extract::>()`, `.extract::()` to copy the data into Rust. + +The following example uses the same snippet as those just above, but this time the final extracted type is `PyBackedStr`: + +```rust,ignore +# use pyo3::prelude::*; +# use pyo3::types::{PyList, PyType}; +# fn example<'py>(py: Python<'py>) -> PyResult<()> { +use pyo3::pybacked::PyBackedStr; +let obj: Bound<'py, PyType> = py.get_type_bound::(); +let name: PyBackedStr = obj.getattr("__name__")?.extract()?; +assert_eq!(&*name, "list"); +# Ok(()) +# } +# Python::with_gil(example).unwrap(); +``` + +
+ +## from 0.19.* to 0.20 + +### Drop support for older technologies + +
+Click to expand + +PyO3 0.20 has increased minimum Rust version to 1.56. +This enables use of newer language features and simplifies maintenance of the project. +
+ +### `PyDict::get_item` now returns a `Result` + +
+Click to expand + +`PyDict::get_item` in PyO3 0.19 and older was implemented using a Python API which would suppress all exceptions and return `None` in those cases. +This included errors in `__hash__` and `__eq__` implementations of the key being looked up. + +Newer recommendations by the Python core developers advise against using these APIs which suppress exceptions, instead allowing exceptions to bubble upwards. `PyDict::get_item_with_error` already implemented this recommended behavior, so that API has been renamed to `PyDict::get_item`. + +Before: + +```rust,ignore +use pyo3::prelude::*; +use pyo3::exceptions::PyTypeError; +use pyo3::types::{PyDict, IntoPyDict}; + +# fn main() { +# let _ = +Python::with_gil(|py| { + let dict: &PyDict = [("a", 1)].into_py_dict(py); + // `a` is in the dictionary, with value 1 + assert!(dict.get_item("a").map_or(Ok(false), |x| x.eq(1))?); + // `b` is not in the dictionary + assert!(dict.get_item("b").is_none()); + // `dict` is not hashable, so this fails with a `TypeError` + assert!(dict + .get_item_with_error(dict) + .unwrap_err() + .is_instance_of::(py)); +}); +# } +``` + +After: + +```rust,ignore +use pyo3::prelude::*; +use pyo3::exceptions::PyTypeError; +use pyo3::types::{PyDict, IntoPyDict}; + +# fn main() { +# let _ = +Python::with_gil(|py| -> PyResult<()> { + let dict: &PyDict = [("a", 1)].into_py_dict(py); + // `a` is in the dictionary, with value 1 + assert!(dict.get_item("a")?.map_or(Ok(false), |x| x.eq(1))?); + // `b` is not in the dictionary + assert!(dict.get_item("b")?.is_none()); + // `dict` is not hashable, so this fails with a `TypeError` + assert!(dict + .get_item(dict) + .unwrap_err() + .is_instance_of::(py)); + + Ok(()) +}); +# } +``` + +
+ +### Required arguments are no longer accepted after optional arguments + +
+Click to expand + +Trailing `Option` arguments have an automatic default of `None`. +To avoid unwanted changes when modifying function signatures, in PyO3 0.18 it was deprecated to have a required argument after an `Option` argument without using `#[pyo3(signature = (...))]` to specify the intended defaults. +In PyO3 0.20, this becomes a hard error. + +Before: + +```rust,ignore +#[pyfunction] +fn x_or_y(x: Option, y: u64) -> u64 { + x.unwrap_or(y) +} +``` + +After: + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; + +#[pyfunction] +#[pyo3(signature = (x, y))] // both x and y have no defaults and are required +fn x_or_y(x: Option, y: u64) -> u64 { + x.unwrap_or(y) +} +``` + +
+ +### Remove deprecated function forms + +
+Click to expand + +In PyO3 0.18 the `#[args]` attribute for `#[pymethods]`, and directly specifying the function signature in `#[pyfunction]`, was deprecated. +This functionality has been removed in PyO3 0.20. + +Before: + +```rust,ignore +#[pyfunction] +#[pyo3(a, b = "0", "/")] +fn add(a: u64, b: u64) -> u64 { + a + b +} +``` + +After: + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; + +#[pyfunction] +#[pyo3(signature = (a, b=0, /))] +fn add(a: u64, b: u64) -> u64 { + a + b +} +``` + +
+ +### `IntoPyPointer` trait removed + +
+Click to expand + +The trait `IntoPyPointer`, which provided the `into_ptr` method on many types, has been removed. `into_ptr` is now available as an inherent method on all types that previously implemented this trait. +
+ +### `AsPyPointer` now `unsafe` trait + +
+Click to expand + +The trait `AsPyPointer` is now `unsafe trait`, meaning any external implementation of it must be marked as `unsafe impl`, and ensure that they uphold the invariant of returning valid pointers. +
+ +## from 0.18.* to 0.19 + +### Access to `Python` inside `__traverse__` implementations are now forbidden + +
+Click to expand + +During `__traverse__` implementations for Python's Garbage Collection it is forbidden to do anything other than visit the members of the `#[pyclass]` being traversed. +This means making Python function calls or other API calls are forbidden. + +Previous versions of PyO3 would allow access to `Python` (e.g. via `Python::with_gil`), which could cause the Python interpreter to crash or otherwise confuse the garbage collection algorithm. + +Attempts to acquire the GIL will now panic. +See [#3165](https://github.com/PyO3/pyo3/issues/3165) for more detail. + +```rust,ignore +# use pyo3::prelude::*; + +#[pyclass] +struct SomeClass {} + +impl SomeClass { + fn __traverse__(&self, pyo3::class::gc::PyVisit<'_>) -> Result<(), pyo3::class::gc::PyTraverseError>` { + Python::with_gil(|| { /*...*/ }) // ERROR: this will panic + } +} +``` + +
+ +### Smarter `anyhow::Error` / `eyre::Report` conversion when inner error is "simple" `PyErr` + +
+Click to expand + +When converting from `anyhow::Error` or `eyre::Report` to `PyErr`, if the inner error is a "simple" `PyErr` (with no source error), then the inner error will be used directly as the `PyErr` instead of wrapping it in a new `PyRuntimeError` with the original information converted into a string. + +```rust,ignore +# #[cfg(feature = "anyhow")] +# #[allow(dead_code)] +# mod anyhow_only { +# use pyo3::prelude::*; +# use pyo3::exceptions::PyValueError; +#[pyfunction] +fn raise_err() -> anyhow::Result<()> { + Err(PyValueError::new_err("original error message").into()) +} + +fn main() { + Python::with_gil(|py| { + let rs_func = wrap_pyfunction!(raise_err, py).unwrap(); + pyo3::py_run!( + py, + rs_func, + r" + try: + rs_func() + except Exception as e: + print(repr(e)) + " + ); + }) +} +# } +``` + +Before, the above code would have printed `RuntimeError('ValueError: original error message')`, which might be confusing. + +After, the same code will print `ValueError: original error message`, which is more straightforward. + +However, if the `anyhow::Error` or `eyre::Report` has a source, then the original exception will still be wrapped in a `PyRuntimeError`. +
+ +### The deprecated `Python::acquire_gil` was removed and `Python::with_gil` must be used instead + +
+Click to expand + +While the API provided by [`Python::acquire_gil`](https://docs.rs/pyo3/0.18.3/pyo3/marker/struct.Python.html#method.acquire_gil) seems convenient, it is somewhat brittle as the design of the [`Python`](https://docs.rs/pyo3/0.18.3/pyo3/marker/struct.Python.html) token relies on proper nesting and panics if not used correctly, e.g. + +```rust,ignore +# #![allow(dead_code, deprecated)] +# use pyo3::prelude::*; + +#[pyclass] +struct SomeClass {} + +struct ObjectAndGuard { + object: Py, + guard: GILGuard, +} + +impl ObjectAndGuard { + fn new() -> Self { + let guard = Python::acquire_gil(); + let object = Py::new(guard.python(), SomeClass {}).unwrap(); + + Self { object, guard } + } +} + +let first = ObjectAndGuard::new(); +let second = ObjectAndGuard::new(); +// Panics because the guard within `second` is still alive. +drop(first); +drop(second); +``` + +The replacement is [`Python::with_gil`](https://docs.rs/pyo3/0.18.3/pyo3/marker/struct.Python.html#method.with_gil) which is more cumbersome but enforces the proper nesting by design, e.g. + +```rust,ignore +# #![allow(dead_code)] +# use pyo3::prelude::*; + +#[pyclass] +struct SomeClass {} + +struct Object { + object: Py, +} + +impl Object { + fn new(py: Python<'_>) -> Self { + let object = Py::new(py, SomeClass {}).unwrap(); + + Self { object } + } +} + +// It either forces us to release the GIL before acquiring it again. +let first = Python::with_gil(|py| Object::new(py)); +let second = Python::with_gil(|py| Object::new(py)); +drop(first); +drop(second); + +// Or it ensures releasing the inner lock before the outer one. +Python::with_gil(|py| { + let first = Object::new(py); + let second = Python::with_gil(|py| Object::new(py)); + drop(first); + drop(second); +}); +``` + +Furthermore, `Python::acquire_gil` provides ownership of a `GILGuard` which can be freely stored and passed around. +This is usually not helpful as it may keep the lock held for a long time thereby blocking progress in other parts of the program. +Due to the generative lifetime attached to the Python token supplied by `Python::with_gil`, the problem is avoided as the Python token can only be passed down the call chain. +Often, this issue can also be avoided entirely as any GIL-bound reference `&'py PyAny` implies access to a Python token `Python<'py>` via the [`PyAny::py`](https://docs.rs/pyo3/0.22.5/pyo3/types/struct.PyAny.html#method.py) method. +
+ +## from 0.17.* to 0.18 + +### Required arguments after `Option<_>` arguments will no longer be automatically inferred + +
+Click to expand + +In `#[pyfunction]` and `#[pymethods]`, if a "required" function input such as `i32` came after an `Option<_>` input, then the `Option<_>` would be implicitly treated as required. (All trailing `Option<_>` arguments were treated as optional with a default value of `None`). + +Starting with PyO3 0.18, this is deprecated and a future PyO3 version will require a [`#[pyo3(signature = (...))]` option](./function/signature.md) to explicitly declare the programmer's intention. + +Before, x in the below example would be required to be passed from Python code: + +```rust,compile_fail,ignore +# #![allow(dead_code)] +# use pyo3::prelude::*; + +#[pyfunction] +fn required_argument_after_option(x: Option, y: i32) {} +``` + +After, specify the intended Python signature explicitly: + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; + +// If x really was intended to be required +#[pyfunction(signature = (x, y))] +fn required_argument_after_option_a(x: Option, y: i32) {} + +// If x was intended to be optional, y needs a default too +#[pyfunction(signature = (x=None, y=0))] +fn required_argument_after_option_b(x: Option, y: i32) {} +``` + +
+ +### `__text_signature__` is now automatically generated for `#[pyfunction]` and `#[pymethods]` + +
+Click to expand + +The [`#[pyo3(text_signature = "...")]` option](./function/signature.md#making-the-function-signature-available-to-python) was previously the only supported way to set the `__text_signature__` attribute on generated Python functions. + +PyO3 is now able to automatically populate `__text_signature__` for all functions automatically based on their Rust signature (or the [new `#[pyo3(signature = (...))]` option](./function/signature.md)). +These automatically-generated `__text_signature__` values will currently only render `...` for all default values. +Many `#[pyo3(text_signature = "...")]` options can be removed from functions when updating to PyO3 0.18, however in cases with default values a manual implementation may still be preferred for now. + +As examples: + +```rust +# use pyo3::prelude::*; + +// The `text_signature` option here is no longer necessary, as PyO3 will automatically +// generate exactly the same value. +#[pyfunction(text_signature = "(a, b, c)")] +fn simple_function(a: i32, b: i32, c: i32) {} + +// The `text_signature` still provides value here as of PyO3 0.18, because the automatically +// generated signature would be "(a, b=..., c=...)". +#[pyfunction(signature = (a, b = 1, c = 2), text_signature = "(a, b=1, c=2)")] +fn function_with_defaults(a: i32, b: i32, c: i32) {} + +# fn main() { +# Python::attach(|py| { +# let simple = wrap_pyfunction!(simple_function, py).unwrap(); +# assert_eq!(simple.getattr("__text_signature__").unwrap().to_string(), "(a, b, c)"); +# let defaulted = wrap_pyfunction!(function_with_defaults, py).unwrap(); +# assert_eq!(defaulted.getattr("__text_signature__").unwrap().to_string(), "(a, b=1, c=2)"); +# }) +# } +``` + +
+ +## from 0.16.* to 0.17 + +### Type checks have been changed for `PyMapping` and `PySequence` types + +
+Click to expand + +Previously the type checks for `PyMapping` and `PySequence` (implemented in `PyTryFrom`) used the Python C-API functions `PyMapping_Check` and `PySequence_Check`. +Unfortunately these functions are not sufficient for distinguishing such types, leading to inconsistent behavior (see [pyo3/pyo3#2072](https://github.com/PyO3/pyo3/issues/2072)). + +PyO3 0.17 changes these downcast checks to explicitly test if the type is a subclass of the corresponding abstract base class `collections.abc.Mapping` or `collections.abc.Sequence`. +Note this requires calling into Python, which may incur a performance penalty over the previous method. +If this performance penalty is a problem, you may be able to perform your own checks and use `try_from_unchecked` (unsafe). + +Another side-effect is that a pyclass defined in Rust with PyO3 will need to be _registered_ with the corresponding Python abstract base class for downcasting to succeed. +`PySequence::register` and `PyMapping:register` have been added to make it easy to do this from Rust code. +These are equivalent to calling `collections.abc.Mapping.register(MappingPyClass)` or `collections.abc.Sequence.register(SequencePyClass)` from Python. + +For example, for a mapping class defined in Rust: + +```rust,compile_fail +use pyo3::prelude::*; +use std::collections::HashMap; + +#[pyclass(mapping)] +struct Mapping { + index: HashMap, +} + +#[pymethods] +impl Mapping { + #[new] + fn new(elements: Option<&PyList>) -> PyResult { + // ... + // truncated implementation of this mapping pyclass - basically a wrapper around a HashMap +} +``` + +You must register the class with `collections.abc.Mapping` before the downcast will work: + +```rust,compile_fail +let m = Py::new(py, Mapping { index }).unwrap(); +assert!(m.as_ref(py).downcast::().is_err()); +PyMapping::register::(py).unwrap(); +assert!(m.as_ref(py).downcast::().is_ok()); +``` + +Note that this requirement may go away in the future when a pyclass is able to inherit from the abstract base class directly (see [pyo3/pyo3#991](https://github.com/PyO3/pyo3/issues/991)). +
+ +### The `multiple-pymethods` feature now requires Rust 1.62 + +
+Click to expand + +Due to limitations in the `inventory` crate which the `multiple-pymethods` feature depends on, this feature now requires Rust 1.62. +For more information see [dtolnay/inventory#32](https://github.com/dtolnay/inventory/issues/32). +
+ +### Added `impl IntoPy> for &str` + +
+Click to expand + +This may cause inference errors. + +Before: + +```rust,compile_fail +# use pyo3::prelude::*; +# +# fn main() { +Python::with_gil(|py| { + // Cannot infer either `Py` or `Py` + let _test = "test".into_py(py); +}); +# } +``` + +After, some type annotations may be necessary: + +```rust,ignore +# #![allow(deprecated)] +# use pyo3::prelude::*; +# +# fn main() { +Python::with_gil(|py| { + let _test: Py = "test".into_py(py); +}); +# } +``` + +
+ +### The `pyproto` feature is now disabled by default + +
+Click to expand + +In preparation for removing the deprecated `#[pyproto]` attribute macro in a future PyO3 version, it is now gated behind an opt-in feature flag. +This also gives a slight saving to compile times for code which does not use the deprecated macro. +
+ +### `PyTypeObject` trait has been deprecated + +
+Click to expand + +The `PyTypeObject` trait already was near-useless; almost all functionality was already on the `PyTypeInfo` trait, which `PyTypeObject` had a blanket implementation based upon. +In PyO3 0.17 the final method, `PyTypeObject::type_object` was moved to `PyTypeInfo::type_object`. + +To migrate, update trait bounds and imports from `PyTypeObject` to `PyTypeInfo`. + +Before: + +```rust,ignore +use pyo3::Python; +use pyo3::type_object::PyTypeObject; +use pyo3::types::PyType; + +fn get_type_object(py: Python<'_>) -> &PyType { + T::type_object(py) +} +``` + +After + +```rust,ignore +use pyo3::{Python, PyTypeInfo}; +use pyo3::types::PyType; + +fn get_type_object(py: Python<'_>) -> &PyType { + T::type_object(py) +} + +# Python::with_gil(|py| { get_type_object::(py); }); +``` + +
+ +### `impl IntoPy for [T; N]` now requires `T: IntoPy` rather than `T: ToPyObject` + +
+Click to expand + +If this leads to errors, simply implement `IntoPy`. +Because pyclasses already implement `IntoPy`, you probably don't need to worry about this. +
+ +### Each `#[pymodule]` can now only be initialized once per process + +
+Click to expand + +To make PyO3 modules sound in the presence of Python sub-interpreters, for now it has been necessary to explicitly disable the ability to initialize a `#[pymodule]` more than once in the same process. +Attempting to do this will now raise an `ImportError`. +
+ +## from 0.15.* to 0.16 + +### Drop support for older technologies + + + +
+Click to expand + +PyO3 0.16 has increased minimum Rust version to 1.48 and minimum Python version to 3.7. +This enables use of newer language features (enabling some of the other additions in 0.16) and simplifies maintenance of the project. +
+ +### `#[pyproto]` has been deprecated + +
+Click to expand + +In PyO3 0.15, the `#[pymethods]` attribute macro gained support for implementing "magic methods" such as `__str__` (aka "dunder" methods). +This implementation was not quite finalized at the time, with a few edge cases to be decided upon. +The existing `#[pyproto]` attribute macro was left untouched, because it covered these edge cases. + +In PyO3 0.16, the `#[pymethods]` implementation has been completed and is now the preferred way to implement magic methods. +To allow the PyO3 project to move forward, `#[pyproto]` has been deprecated (with expected removal in PyO3 0.18). + +Migration from `#[pyproto]` to `#[pymethods]` is straightforward; copying the existing methods directly from the `#[pyproto]` trait implementation is all that is needed in most cases. + +Before: + +```rust,compile_fail +use pyo3::prelude::*; +use pyo3::class::{PyObjectProtocol, PyIterProtocol}; +use pyo3::types::PyString; + +#[pyclass] +struct MyClass {} + +#[pyproto] +impl PyObjectProtocol for MyClass { + fn __str__(&self) -> &'static [u8] { + b"hello, world" + } +} + +#[pyproto] +impl PyIterProtocol for MyClass { + fn __iter__(slf: PyRef) -> PyResult<&PyAny> { + PyString::new(slf.py(), "hello, world").iter() + } +} +``` + +After + +```rust,compile_fail +use pyo3::prelude::*; +use pyo3::types::PyString; + +#[pyclass] +struct MyClass {} + +#[pymethods] +impl MyClass { + fn __str__(&self) -> &'static [u8] { + b"hello, world" + } + + fn __iter__(slf: PyRef) -> PyResult<&PyAny> { + PyString::new(slf.py(), "hello, world").iter() + } +} +``` + +
+ +### Removed `PartialEq` for object wrappers + +
+Click to expand + +The Python object wrappers `Py` and `PyAny` had implementations of `PartialEq` so that `object_a == object_b` would compare the Python objects for pointer equality, which corresponds to the `is` operator, not the `==` operator in Python. +This has been removed in favor of a new method: use `object_a.is(object_b)`. +This also has the advantage of not requiring the same wrapper type for `object_a` and `object_b`; you can now directly compare a `Py` with a `&PyAny` without having to convert. + +To check for Python object equality (the Python `==` operator), use the new method `eq()`. +
+ +### Container magic methods now match Python behavior + +
+Click to expand + +In PyO3 0.15, `__getitem__`, `__setitem__` and `__delitem__` in `#[pymethods]` would generate only the _mapping_ implementation for a `#[pyclass]`. +To match the Python behavior, these methods now generate both the _mapping_ **and** _sequence_ implementations. + +This means that classes implementing these `#[pymethods]` will now also be treated as sequences, same as a Python `class` would be. +Small differences in behavior may result: + +- PyO3 will allow instances of these classes to be cast to `PySequence` as well as `PyMapping`. +- Python will provide a default implementation of `__iter__` (if the class did not have one) which repeatedly calls `__getitem__` with integers (starting at 0) until an `IndexError` is raised. + +To explain this in detail, consider the following Python class: + +```python +class ExampleContainer: + + def __len__(self): + return 5 + + def __getitem__(self, idx: int) -> int: + if idx < 0 or idx > 5: + raise IndexError() + return idx +``` + +This class implements a Python [sequence](https://docs.python.org/3/glossary.html#term-sequence). + +The `__len__` and `__getitem__` methods are also used to implement a Python [mapping](https://docs.python.org/3/glossary.html#term-mapping). +In the Python C-API, these methods are not shared: the sequence `__len__` and `__getitem__` are defined by the `sq_length` and `sq_item` slots, and the mapping equivalents are `mp_length` and `mp_subscript`. +There are similar distinctions for `__setitem__` and `__delitem__`. + +Because there is no such distinction from Python, implementing these methods will fill the mapping and sequence slots simultaneously. +A Python class with `__len__` implemented, for example, will have both the `sq_length` and `mp_length` slots filled. + +The PyO3 behavior in 0.16 has been changed to be closer to this Python behavior by default. +
+ +### `wrap_pymodule!` and `wrap_pyfunction!` now respect privacy correctly + +
+Click to expand + +Prior to PyO3 0.16 the `wrap_pymodule!` and `wrap_pyfunction!` macros could use modules and functions whose defining `fn` was not reachable according Rust privacy rules. + +For example, the following code was legal before 0.16, but in 0.16 is rejected because the `wrap_pymodule!` macro cannot access the `private_submodule` function: + +```rust,compile_fail +mod foo { + use pyo3::prelude::*; + + #[pymodule] + fn private_submodule(_py: Python<'_>, m: &PyModule) -> PyResult<()> { + Ok(()) + } +} + +use pyo3::prelude::*; +use foo::*; + +#[pymodule] +fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { + m.add_wrapped(wrap_pymodule!(private_submodule))?; + Ok(()) +} +``` + +To fix it, make the private submodule visible, e.g. with `pub` or `pub(crate)`. + +```rust,ignore +mod foo { + use pyo3::prelude::*; + + #[pymodule] + pub(crate) fn private_submodule(_py: Python<'_>, m: &PyModule) -> PyResult<()> { + Ok(()) + } +} + +use pyo3::prelude::*; +use pyo3::wrap_pymodule; +use foo::*; + +#[pymodule] +fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { + m.add_wrapped(wrap_pymodule!(private_submodule))?; + Ok(()) +} +``` + +
+ +## from 0.14.* to 0.15 + +### Changes in sequence indexing + +
+Click to expand + +For all types that take sequence indices (`PyList`, `PyTuple` and `PySequence`), the API has been made consistent to only take `usize` indices, for consistency with Rust's indexing conventions. +Negative indices, which were only sporadically supported even in APIs that took `isize`, now aren't supported anywhere. + +Further, the `get_item` methods now always return a `PyResult` instead of panicking on invalid indices. +The `Index` trait has been implemented instead, and provides the same panic behavior as on Rust vectors. + +Note that _slice_ indices (accepted by `PySequence::get_slice` and other) still inherit the Python behavior of clamping the indices to the actual length, and not panicking/returning an error on out of range indices. + +An additional advantage of using Rust's indexing conventions for these types is that these types can now also support Rust's indexing operators as part of a consistent API: + +```rust,ignore +#![allow(deprecated)] +use pyo3::{Python, types::PyList}; + +Python::with_gil(|py| { + let list = PyList::new(py, &[1, 2, 3]); + assert_eq!(list[0..2].to_string(), "[1, 2]"); +}); +``` + +
+ +## from 0.13.* to 0.14 + +### `auto-initialize` feature is now opt-in + +
+Click to expand + +For projects embedding Python in Rust, PyO3 no longer automatically initializes a Python interpreter on the first call to `Python::with_gil` (or `Python::acquire_gil`) unless the [`auto-initialize` feature](features.md#auto-initialize) is enabled. +
+ +### New `multiple-pymethods` feature + +
+Click to expand + +`#[pymethods]` have been reworked with a simpler default implementation which removes the dependency on the `inventory` crate. +This reduces dependencies and compile times for the majority of users. + +The limitation of the new default implementation is that it cannot support multiple `#[pymethods]` blocks for the same `#[pyclass]`. +If you need this functionality, you must enable the `multiple-pymethods` feature which will switch `#[pymethods]` to the inventory-based implementation. +
+ +### Deprecated `#[pyproto]` methods + +
+Click to expand + +Some protocol (aka `__dunder__`) methods such as `__bytes__` and `__format__` have been possible to implement two ways in PyO3 for some time: via a `#[pyproto]` (e.g. `PyObjectProtocol` for the methods listed here), or by writing them directly in `#[pymethods]`. +This is only true for a handful of the `#[pyproto]` methods (for technical reasons to do with the way PyO3 currently interacts with the Python C-API). + +In the interest of having only one way to do things, the `#[pyproto]` forms of these methods have been deprecated. + +To migrate just move the affected methods from a `#[pyproto]` to a `#[pymethods]` block. + +Before: + +```rust,compile_fail +use pyo3::prelude::*; +use pyo3::class::basic::PyObjectProtocol; + +#[pyclass] +struct MyClass {} + +#[pyproto] +impl PyObjectProtocol for MyClass { + fn __bytes__(&self) -> &'static [u8] { + b"hello, world" + } +} +``` + +After: + +```rust,no_run +use pyo3::prelude::*; + +#[pyclass] +struct MyClass {} + +#[pymethods] +impl MyClass { + fn __bytes__(&self) -> &'static [u8] { + b"hello, world" + } +} +``` + +
+ +## from 0.12.* to 0.13 + +### Minimum Rust version increased to Rust 1.45 + +
+Click to expand + +PyO3 `0.13` makes use of new Rust language features stabilized between Rust 1.40 and Rust 1.45. +If you are using a Rust compiler older than Rust 1.45, you will need to update your toolchain to be able to continue using PyO3. +
+ +### Runtime changes to support the CPython limited API + +
+Click to expand + +In PyO3 `0.13` support was added for compiling against the CPython limited API. +This had a number of implications for _all_ PyO3 users, described here. + +The largest of these is that all types created from PyO3 are what CPython calls "heap" types. +The specific implications of this are: + +- If you wish to subclass one of these types _from Rust_ you must mark it `#[pyclass(subclass)]`, as you would if you wished to allow subclassing it from Python code. +- Type objects are now mutable - Python code can set attributes on them. +- `__module__` on types without `#[pyclass(module="mymodule")]` no longer returns `builtins`, it now raises `AttributeError`. +
+ +## from 0.11.* to 0.12 + +### `PyErr` has been reworked + +
+Click to expand + +In PyO3 `0.12` the `PyErr` type has been re-implemented to be significantly more compatible with the standard Rust error handling ecosystem. +Specifically `PyErr` now implements `Error + Send + Sync`, which are the standard traits used for error types. + +While this has necessitated the removal of a number of APIs, the resulting `PyErr` type should now be much more easier to work with. +The following sections list the changes in detail and how to migrate to the new APIs. +
+ +#### `PyErr::new` and `PyErr::from_type` now require `Send + Sync` for their argument + +
+Click to expand + +For most uses no change will be needed. +If you are trying to construct `PyErr` from a value that is not `Send + Sync`, you will need to first create the Python object and then use `PyErr::from_instance`. + +Similarly, any types which implemented `PyErrArguments` will now need to be `Send + Sync`. +
+ +#### `PyErr`'s contents are now private + +
+Click to expand + +It is no longer possible to access the fields `.ptype`, `.pvalue` and `.ptraceback` of a `PyErr`. +You should instead now use the new methods `PyErr::ptype`, `PyErr::pvalue` and `PyErr::ptraceback`. +
+ +#### `PyErrValue` and `PyErr::from_value` have been removed + +
+Click to expand + +As these were part the internals of `PyErr` which have been reworked, these APIs no longer exist. + +If you used this API, it is recommended to use `PyException::new_err` (see [the section on Exception types](#exception-types-have-been-reworked)). +
+ +#### `Into>` for `PyErr` has been removed + +
+Click to expand + +This implementation was redundant. +Just construct the `Result::Err` variant directly. + +Before: + +```rust,compile_fail +let result: PyResult<()> = PyErr::new::("error message").into(); +``` + +After (also using the new reworked exception types; see the following section): + +```rust,no_run +# use pyo3::{PyResult, exceptions::PyTypeError}; +let result: PyResult<()> = Err(PyTypeError::new_err("error message")); +``` + +
+ +### Exception types have been reworked + +
+Click to expand + +Previously exception types were zero-sized marker types purely used to construct `PyErr`. +In PyO3 0.12, these types have been replaced with full definitions and are usable in the same way as `PyAny`, `PyDict` etc. +This makes it possible to interact with Python exception objects. + +The new types also have names starting with the "Py" prefix. +For example, before: + +```rust,ignore +let err: PyErr = TypeError::py_err("error message"); +``` + +After: + +```rust,ignore +# use pyo3::{PyErr, PyResult, Python, type_object::PyTypeObject}; +# use pyo3::exceptions::{PyBaseException, PyTypeError}; +# Python::with_gil(|py| -> PyResult<()> { +let err: PyErr = PyTypeError::new_err("error message"); + +// Uses Display for PyErr, new for PyO3 0.12 +assert_eq!(err.to_string(), "TypeError: error message"); + +// Now possible to interact with exception instances, new for PyO3 0.12 +let instance: &PyBaseException = err.instance(py); +assert_eq!( + instance.getattr("__class__")?, + PyTypeError::type_object(py).as_ref() +); +# Ok(()) +# }).unwrap(); +``` + +
+ +### `FromPy` has been removed + +
+Click to expand + +To simplify the PyO3 conversion traits, the `FromPy` trait has been removed. +Previously there were two ways to define the to-Python conversion for a type: `FromPy for PyObject` and `IntoPy for T`. + +Now there is only one way to define the conversion, `IntoPy`, so downstream crates may need to adjust accordingly. + +Before: + +```rust,compile_fail +# use pyo3::prelude::*; +struct MyPyObjectWrapper(PyObject); + +impl FromPy for PyObject { + fn from_py(other: MyPyObjectWrapper, _py: Python<'_>) -> Self { + other.0 + } +} +``` + +After + +```rust,ignore +# use pyo3::prelude::*; +# #[allow(dead_code)] +struct MyPyObjectWrapper(PyObject); + +# #[allow(deprecated)] +impl IntoPy for MyPyObjectWrapper { + fn into_py(self, _py: Python<'_>) -> PyObject { + self.0 + } +} +``` + +Similarly, code which was using the `FromPy` trait can be trivially rewritten to use `IntoPy`. + +Before: + +```rust,compile_fail +# use pyo3::prelude::*; +# Python::with_gil(|py| { +let obj = PyObject::from_py(1.234, py); +# }) +``` + +After: + +```rust,ignore +# #![allow(deprecated)] +# use pyo3::prelude::*; +# Python::with_gil(|py| { +let obj: PyObject = 1.234.into_py(py); +# }) +``` + +
+ +### `PyObject` is now a type alias of `Py` + +
+Click to expand + +This should change very little from a usage perspective. +If you implemented traits for both `PyObject` and `Py`, you may find you can just remove the `PyObject` implementation. +
+ +### `AsPyRef` has been removed + +
+Click to expand + +As `PyObject` has been changed to be just a type alias, the only remaining implementor of `AsPyRef` was `Py`. +This removed the need for a trait, so the `AsPyRef::as_ref` method has been moved to `Py::as_ref`. + +This should require no code changes except removing `use pyo3::AsPyRef` for code which did not use `pyo3::prelude::*`. + +Before: + +```rust,ignore +use pyo3::{AsPyRef, Py, types::PyList}; +# pyo3::Python::with_gil(|py| { +let list_py: Py = PyList::empty(py).into(); +let list_ref: &PyList = list_py.as_ref(py); +# }) +``` + +After: + +```rust,ignore +use pyo3::{Py, types::PyList}; +# pyo3::Python::with_gil(|py| { +let list_py: Py = PyList::empty(py).into(); +let list_ref: &PyList = list_py.as_ref(py); +# }) +``` + +
+ +## from 0.10.* to 0.11 + +### Stable Rust + +
+Click to expand + +PyO3 now supports the stable Rust toolchain. +The minimum required version is 1.39.0. +
+ +### `#[pyclass]` structs must now be `Send` or `unsendable` + +
+Click to expand + +Because `#[pyclass]` structs can be sent between threads by the Python interpreter, they must implement `Send` or declared as `unsendable` (by `#[pyclass(unsendable)]`). +Note that `unsendable` is added in PyO3 `0.11.1` and `Send` is always required in PyO3 `0.11.0`. + +This may "break" some code which previously was accepted, even though it could be unsound. +There can be two fixes: + +1. If you think that your `#[pyclass]` actually must be `Send`able, then let's implement `Send`. + A common, safer way is using thread-safe types. + E.g., `Arc` instead of `Rc`, `Mutex` instead of `RefCell`, and `Box` instead of `Box`. + + Before: + + ```rust,compile_fail + use pyo3::prelude::*; + use std::rc::Rc; + use std::cell::RefCell; + + #[pyclass] + struct NotThreadSafe { + shared_bools: Rc>>, + closure: Box, + } + ``` + + After: + + ```rust,ignore + # #![allow(dead_code)] + use pyo3::prelude::*; + use std::sync::{Arc, Mutex}; + + #[pyclass] + struct ThreadSafe { + shared_bools: Arc>>, + closure: Box, + } + ``` + + In situations where you cannot change your `#[pyclass]` to automatically implement `Send` (e.g., when it contains a raw pointer), you can use `unsafe impl Send`. + In such cases, care should be taken to ensure the struct is actually thread safe. + See [the Rustonomicon](https://doc.rust-lang.org/nomicon/send-and-sync.html) for more. + +2. If you think that your `#[pyclass]` should not be accessed by another thread, you can use `unsendable` flag. + A class marked with `unsendable` panics when accessed by another thread, making it thread-safe to expose an unsendable object to the Python interpreter. + + Before: + + ```rust,compile_fail + use pyo3::prelude::*; + + #[pyclass] + struct Unsendable { + pointers: Vec<*mut std::ffi::c_char>, + } + ``` + + After: + + ```rust,no_run + # #![allow(dead_code)] + use pyo3::prelude::*; + + #[pyclass(unsendable)] + struct Unsendable { + pointers: Vec<*mut std::ffi::c_char>, + } + ``` + +
+ +### All `PyObject` and `Py` methods now take `Python` as an argument + +
+Click to expand + +Previously, a few methods such as `Object::get_refcnt` did not take `Python` as an argument (to ensure that the Python GIL was held by the current thread). +Technically, this was not sound. +To migrate, just pass a `py` argument to any calls to these methods. + +Before: + +```rust,compile_fail +# pyo3::Python::attach(|py| { +py.None().get_refcnt(); +# }) +``` + +After: + +```rust,ignore +# pyo3::Python::attach(|py| { +py.None().get_refcnt(py); +# }) +``` + +
+ +## from 0.9.* to 0.10 + +### `ObjectProtocol` is removed + +
+Click to expand + +All methods are moved to [`PyAny`]. +And since now all native types (e.g., `PyList`) implements `Deref`, all you need to do is remove `ObjectProtocol` from your code. +Or if you use `ObjectProtocol` by `use pyo3::prelude::*`, you have to do nothing. + +Before: + +```rust,compile_fail,ignore +use pyo3::ObjectProtocol; + +# pyo3::Python::with_gil(|py| { +let obj = py.eval("lambda: 'Hi :)'", None, None).unwrap(); +let hi: &pyo3::types::PyString = obj.call0().unwrap().downcast().unwrap(); +assert_eq!(hi.len().unwrap(), 5); +# }) +``` + +After: + +```rust,ignore +# pyo3::Python::with_gil(|py| { +let obj = py.eval("lambda: 'Hi :)'", None, None).unwrap(); +let hi: &pyo3::types::PyString = obj.call0().unwrap().downcast().unwrap(); +assert_eq!(hi.len().unwrap(), 5); +# }) +``` + +
+ +### No `#![feature(specialization)]` in user code + +
+Click to expand + +While PyO3 itself still requires specialization and nightly Rust, now you don't have to use `#![feature(specialization)]` in your crate. +
+ +## from 0.8.* to 0.9 + +### `#[new]` interface + +
+Click to expand + +[`PyRawObject`](https://docs.rs/pyo3/0.8.5/pyo3/type_object/struct.PyRawObject.html) is now removed and our syntax for constructors has changed. + +Before: + +```rust,compile_fail +#[pyclass] +struct MyClass {} + +#[pymethods] +impl MyClass { + #[new] + fn new(obj: &PyRawObject) { + obj.init(MyClass {}) + } +} +``` + +After: + +```rust,no_run +# use pyo3::prelude::*; +#[pyclass] +struct MyClass {} + +#[pymethods] +impl MyClass { + #[new] + fn new() -> Self { + MyClass {} + } +} +``` + +Basically you can return `Self` or `Result` directly. +For more, see [the constructor section](class.md#constructor) of this guide. +
+ +### PyCell + +
+Click to expand + +PyO3 0.9 introduces `PyCell`, which is a [`RefCell`]-like object wrapper for ensuring Rust's rules regarding aliasing of references are upheld. +For more detail, see the [Rust Book's section on Rust's rules of references](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#the-rules-of-references) + +For `#[pymethods]` or `#[pyfunction]`s, your existing code should continue to work without any change. +Python exceptions will automatically be raised when your functions are used in a way which breaks Rust's rules of references. + +Here is an example. + +```rust +# use pyo3::prelude::*; + +#[pyclass] +struct Names { + names: Vec, +} + +#[pymethods] +impl Names { + #[new] + fn new() -> Self { + Names { names: vec![] } + } + fn merge(&mut self, other: &mut Names) { + self.names.append(&mut other.names) + } +} +# Python::attach(|py| { +# let names = Py::new(py, Names::new()).unwrap(); +# pyo3::py_run!(py, names, r" +# try: +# names.merge(names) +# assert False, 'Unreachable' +# except RuntimeError as e: +# assert str(e) == 'Already borrowed' +# "); +# }) +``` + +`Names` has a `merge` method, which takes `&mut self` and another argument of type `&mut Self`. +Given this `#[pyclass]`, calling `names.merge(names)` in Python raises a [`PyBorrowMutError`] exception, since it requires two mutable borrows of `names`. + +However, for `#[pyproto]` and some functions, you need to manually fix the code. + +#### Object creation + +In 0.8 object creation was done with `PyRef::new` and `PyRefMut::new`. +In 0.9 these have both been removed. +To upgrade code, please use `PyCell::new` instead. +If you need [`PyRef`] or [`PyRefMut`], just call `.borrow()` or `.borrow_mut()` on the newly-created `PyCell`. + +Before: + +```rust,compile_fail +# use pyo3::prelude::*; +# #[pyclass] +# struct MyClass {} +# Python::with_gil(|py| { +let obj_ref = PyRef::new(py, MyClass {}).unwrap(); +# }) +``` + +After: + +```rust,ignore +# use pyo3::prelude::*; +# #[pyclass] +# struct MyClass {} +# Python::with_gil(|py| { +let obj = PyCell::new(py, MyClass {}).unwrap(); +let obj_ref = obj.borrow(); +# }) +``` + +#### Object extraction + +For `PyClass` types `T`, `&T` and `&mut T` no longer have [`FromPyObject`] implementations. +Instead you should extract `PyRef` or `PyRefMut`, respectively. +If `T` implements `Clone`, you can extract `T` itself. +In addition, you can also extract `&PyCell`, though you rarely need it. + +Before: + +```compile_fail +let obj: &PyAny = create_obj(); +let obj_ref: &MyClass = obj.extract().unwrap(); +let obj_ref_mut: &mut MyClass = obj.extract().unwrap(); +``` + +After: + +```rust,ignore +# use pyo3::prelude::*; +# use pyo3::types::IntoPyDict; +# #[pyclass] #[derive(Clone)] struct MyClass {} +# #[pymethods] impl MyClass { #[new]fn new() -> Self { MyClass {} }} +# Python::with_gil(|py| { +# let typeobj = py.get_type::(); +# let d = [("c", typeobj)].into_py_dict(py); +# let create_obj = || py.eval("c()", None, Some(d)).unwrap(); +let obj: &PyAny = create_obj(); +let obj_cell: &PyCell = obj.extract().unwrap(); +let obj_cloned: MyClass = obj.extract().unwrap(); // extracted by cloning the object +{ + let obj_ref: PyRef<'_, MyClass> = obj.extract().unwrap(); + // we need to drop obj_ref before we can extract a PyRefMut due to Rust's rules of references +} +let obj_ref_mut: PyRefMut<'_, MyClass> = obj.extract().unwrap(); +# }) +``` + +#### `#[pyproto]` + +Most of the arguments to methods in `#[pyproto]` impls require a [`FromPyObject`] implementation. +So if your protocol methods take `&T` or `&mut T` (where `T: PyClass`), please use [`PyRef`] or [`PyRefMut`] instead. + +Before: + +```rust,compile_fail +# use pyo3::prelude::*; +# use pyo3::class::PySequenceProtocol; +#[pyclass] +struct ByteSequence { + elements: Vec, +} +#[pyproto] +impl PySequenceProtocol for ByteSequence { + fn __concat__(&self, other: &Self) -> PyResult { + let mut elements = self.elements.clone(); + elements.extend_from_slice(&other.elements); + Ok(Self { elements }) + } +} +``` + +After: + +```rust,compile_fail +# use pyo3::prelude::*; +# use pyo3::class::PySequenceProtocol; +#[pyclass] +struct ByteSequence { + elements: Vec, +} +#[pyproto] +impl PySequenceProtocol for ByteSequence { + fn __concat__(&self, other: PyRef<'p, Self>) -> PyResult { + let mut elements = self.elements.clone(); + elements.extend_from_slice(&other.elements); + Ok(Self { elements }) + } +} +``` + +
+ + + +[`FromPyObject`]: {{#PYO3_DOCS_URL}}/pyo3/conversion/trait.FromPyObject.html +[`PyAny`]: {{#PYO3_DOCS_URL}}/pyo3/types/struct.PyAny.html +[`PyBorrowMutError`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyBorrowMutError.html +[`PyRef`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRef.html +[`PyRefMut`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRef.html + +[`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html diff --git a/vendor/pyo3/guide/src/module.md b/vendor/pyo3/guide/src/module.md new file mode 100644 index 0000000..eab280f --- /dev/null +++ b/vendor/pyo3/guide/src/module.md @@ -0,0 +1,176 @@ +# Python modules + +You can create a module using `#[pymodule]`: + +```rust,no_run +# mod declarative_module_basic_test { +use pyo3::prelude::*; + +#[pyfunction] +fn double(x: usize) -> usize { + x * 2 +} + +/// This module is implemented in Rust. +#[pymodule] +mod my_extension { + use pyo3::prelude::*; + + #[pymodule_export] + use super::double; // The double function is made available from Python, works also with classes + + #[pyfunction] // Inline definition of a pyfunction, also made available to Python + fn triple(x: usize) -> usize { + x * 3 + } +} +# } +``` + +The `#[pymodule]` procedural macro takes care of creating the initialization function of your module and exposing it to Python. + +The module's name defaults to the name of the Rust module. +You can override the module name by using `#[pyo3(name = "custom_name")]`: + +```rust,no_run +# mod declarative_module_custom_name_test { +use pyo3::prelude::*; + +#[pyfunction] +fn double(x: usize) -> usize { + x * 2 +} + +#[pymodule(name = "custom_name")] +mod my_extension { + #[pymodule_export] + use super::double; +} +# } +``` + +The name of the module must match the name of the `.so` or `.pyd` file. +Otherwise, you will get an import error in Python with the following message: `ImportError: dynamic module does not define module export function (PyInit_name_of_your_module)` + +To import the module, either: + +- copy the shared library as described in [Manual builds](building-and-distribution.md#manual-builds), or +- use a tool, e.g. `maturin develop` with [maturin](https://github.com/PyO3/maturin) or +`python setup.py develop` with [setuptools-rust](https://github.com/PyO3/setuptools-rust). + +## Documentation + +The [Rust doc comments](https://doc.rust-lang.org/stable/book/ch03-04-comments.html) of the Rust module will be applied automatically as the Python docstring of your module. + +For example, building off of the above code, this will print `This module is implemented in Rust.`: + +```python +import my_extension + +print(my_extension.__doc__) +``` + +## Python submodules + +You can create a module hierarchy within a single extension module by just `use`ing modules like functions or classes. +For example, you could define the modules `parent_module` and `parent_module.child_module`: + +```rust +use pyo3::prelude::*; + +#[pymodule] +mod parent_module { + #[pymodule_export] + use super::child_module; +} + +#[pymodule] +mod child_module { + #[pymodule_export] + use super::func; +} + +#[pyfunction] +fn func() -> String { + "func".to_string() +} +# +# fn main() { +# Python::attach(|py| { +# use pyo3::wrap_pymodule; +# use pyo3::types::IntoPyDict; +# let parent_module = wrap_pymodule!(parent_module)(py); +# let ctx = [("parent_module", parent_module)].into_py_dict(py).unwrap(); +# +# py.run(c"assert parent_module.child_module.func() == 'func'", None, Some(&ctx)).unwrap(); +# }) +# } +``` + +Note that this does not define a package, so this won’t allow Python code to directly import submodules by using `from parent_module import child_module`. +For more information, see [#759](https://github.com/PyO3/pyo3/issues/759) and [#1517](https://github.com/PyO3/pyo3/issues/1517#issuecomment-808664021). + +You can provide the `submodule` argument to `#[pymodule()]` for modules that are not top-level modules in order for them to properly generate the `#[pyclass]` `module` attribute automatically. + +## Inline declaration + +It is possible to declare functions, classes, sub-modules and constants inline in a module: + +For example: + +```rust,no_run +# mod declarative_module_test { +#[pyo3::pymodule] +mod my_extension { + use pyo3::prelude::*; + + #[pymodule_export] + const PI: f64 = std::f64::consts::PI; // Exports PI constant as part of the module + + #[pyfunction] // This will be part of the module + fn double(x: usize) -> usize { + x * 2 + } + + #[pyclass] // This will be part of the module + struct Unit; + + #[pymodule] + mod submodule { + // This is a submodule + use pyo3::prelude::*; + + #[pyclass] + struct Nested; + } +} +# } +``` + +In this case, `#[pymodule]` macro automatically sets the `module` attribute of the `#[pyclass]` macros declared inside of it with its name. +For nested modules, the name of the parent module is automatically added. +In the previous example, the `Nested` class will have for `module` `my_extension.submodule`. + +## Procedural initialization + +If the macros provided by PyO3 are not enough, it is possible to run code at the module initialization: + +```rust,no_run +# mod procedural_module_test { +#[pyo3::pymodule] +mod my_extension { + use pyo3::prelude::*; + + #[pyfunction] + fn double(x: usize) -> usize { + x * 2 + } + + #[pymodule_init] + fn init(m: &Bound<'_, PyModule>) -> PyResult<()> { + // Arbitrary code to run at the module initialization + m.add("double2", m.getattr("double")?) + } +} +# } +``` diff --git a/vendor/pyo3/guide/src/parallelism.md b/vendor/pyo3/guide/src/parallelism.md new file mode 100644 index 0000000..06746a9 --- /dev/null +++ b/vendor/pyo3/guide/src/parallelism.md @@ -0,0 +1,183 @@ +# Parallelism + +Historically, CPython was limited by the global interpreter lock (GIL), which only allowed a single thread to drive the Python interpreter at a time. +This made threading in Python a bad fit for [CPU-bound](https://en.wikipedia.org/wiki/CPU-bound) tasks and often forced developers to accept the overhead of multiprocessing. + +Rust is well-suited to multithreaded code, and libraries like [`rayon`] can help you leverage safe parallelism with minimal effort. +The [`Python::detach`] method can be used to allow the Python interpreter to do other work while the Rust work is ongoing. + +To enable full parallelism in your application, consider also using [free-threaded Python](./free-threading.md) which is supported since Python 3.14. + +## Parallelism under the Python GIL + +Let's take a look at our [word-count](https://github.com/PyO3/pyo3/blob/main/examples/word-count/src/lib.rs) example, where we have a `search` function that utilizes the [`rayon`] crate to count words in parallel. + +```rust,no_run +# #![allow(dead_code)] +use pyo3::prelude::*; + +// These traits let us use `par_lines` and `map`. +use rayon::str::ParallelString; +use rayon::iter::ParallelIterator; + +/// Count the occurrences of needle in line, case insensitive +fn count_line(line: &str, needle: &str) -> usize { + let mut total = 0; + for word in line.split(' ') { + if word == needle { + total += 1; + } + } + total +} + +#[pyfunction] +fn search(contents: &str, needle: &str) -> usize { + contents + .par_lines() + .map(|line| count_line(line, needle)) + .sum() +} +``` + +But let's assume you have a long running Rust function which you would like to execute several times in parallel. +For the sake of example let's take a sequential version of the word count: + +```rust,no_run +# #![allow(dead_code)] +# fn count_line(line: &str, needle: &str) -> usize { +# let mut total = 0; +# for word in line.split(' ') { +# if word == needle { +# total += 1; +# } +# } +# total +# } +# +fn search_sequential(contents: &str, needle: &str) -> usize { + contents.lines().map(|line| count_line(line, needle)).sum() +} +``` + +To enable parallel execution of this function, the [`Python::detach`] method can be used to temporarily release the GIL, thus allowing other Python threads to run. +We then have a function exposed to the Python runtime which calls `search_sequential` inside a closure passed to [`Python::detach`] to enable true parallelism: + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +# +# fn count_line(line: &str, needle: &str) -> usize { +# let mut total = 0; +# for word in line.split(' ') { +# if word == needle { +# total += 1; +# } +# } +# total +# } +# +# fn search_sequential(contents: &str, needle: &str) -> usize { +# contents.lines().map(|line| count_line(line, needle)).sum() +# } +#[pyfunction] +fn search_sequential_detached(py: Python<'_>, contents: &str, needle: &str) -> usize { + py.detach(|| search_sequential(contents, needle)) +} +``` + +Now Python threads can use more than one CPU core, resolving the limitation which usually makes multi-threading in Python only good for IO-bound tasks: + +```Python +from concurrent.futures import ThreadPoolExecutor +from word_count import search_sequential_detached + +executor = ThreadPoolExecutor(max_workers=2) + +future_1 = executor.submit( + word_count.search_sequential_detached, contents, needle +) +future_2 = executor.submit( + word_count.search_sequential_detached, contents, needle +) +result_1 = future_1.result() +result_2 = future_2.result() +``` + +## Benchmark + +Let's benchmark the `word-count` example to verify that we really did unlock parallelism with PyO3. + +We are using `pytest-benchmark` to benchmark four word count functions: + +1. Pure Python version +2. Rust parallel version +3. Rust sequential version +4. Rust sequential version executed twice with two Python threads + +The benchmark script can be found [in the PyO3 GitHub repository](https://github.com/PyO3/pyo3/blob/main/examples/word-count/tests/test_word_count.py), and we can run `nox` in the `word-count` folder to benchmark these functions. + +While the results of the benchmark of course depend on your machine, the relative results should be similar to this (mid 2020): + +```text +-------------------------------------------------------------------------------------------------- benchmark: 4 tests ------------------------------------------------------------------------------------------------- +Name (time in ms) Min Max Mean StdDev Median IQR Outliers OPS Rounds Iterations +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +test_word_count_rust_parallel 1.7315 (1.0) 4.6495 (1.0) 1.9972 (1.0) 0.4299 (1.0) 1.8142 (1.0) 0.2049 (1.0) 40;46 500.6943 (1.0) 375 1 +test_word_count_rust_sequential 7.3348 (4.24) 10.3556 (2.23) 8.0035 (4.01) 0.7785 (1.81) 7.5597 (4.17) 0.8641 (4.22) 26;5 124.9457 (0.25) 121 1 +test_word_count_rust_sequential_twice_with_threads 7.9839 (4.61) 10.3065 (2.22) 8.4511 (4.23) 0.4709 (1.10) 8.2457 (4.55) 0.3927 (1.92) 17;17 118.3274 (0.24) 114 1 +test_word_count_python_sequential 27.3985 (15.82) 45.4527 (9.78) 28.9604 (14.50) 4.1449 (9.64) 27.5781 (15.20) 0.4638 (2.26) 3;5 34.5299 (0.07) 35 1 +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +``` + +You can see that the Python threaded version is not much slower than the Rust sequential version, which means compared to an execution on a single CPU core the speed has doubled. + +## Sharing Python objects between Rust threads + +In the example above we made a Python interface to a low-level rust function, and then leveraged the python `threading` module to run the low-level function in parallel. +It is also possible to spawn threads in Rust that acquire the GIL and operate on Python objects. +However, care must be taken to avoid writing code that deadlocks with the GIL in these cases. + +- Note: This example is meant to illustrate how to drop and re-acquire the GIL + to avoid creating deadlocks. Unless the spawned threads subsequently + release the GIL or you are using the free-threaded build of CPython, you + will not see any speedups due to multi-threaded parallelism using `rayon` + to parallelize code that acquires and holds the GIL for the entire + execution of the spawned thread. + +In the example below, we share a `Vec` of User ID objects defined using the `pyclass` macro and spawn threads to process the collection of data into a `Vec` of booleans based on a predicate using a `rayon` parallel iterator: + +```rust,no_run +use pyo3::prelude::*; + +// These traits let us use int_par_iter and map +use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; + +#[pyclass] +struct UserID { + id: i64, +} + +let allowed_ids: Vec = Python::attach(|outer_py| { + let instances: Vec> = (0..10).map(|x| Py::new(outer_py, UserID { id: x }).unwrap()).collect(); + outer_py.detach(|| { + instances.par_iter().map(|instance| { + Python::attach(|inner_py| { + instance.borrow(inner_py).id > 5 + }) + }).collect() + }) +}); +assert!(allowed_ids.into_iter().filter(|b| *b).count() == 4); +``` + +It's important to note that there is an `outer_py` Python token as well as an `inner_py` token. +Sharing Python tokens between threads is not allowed and threads must individually attach to the interpreter to access data wrapped by a Python object. + +It's also important to see that this example uses [`Python::detach`] to wrap the code that spawns OS threads via `rayon`. +If this example didn't use `detach`, a `rayon` worker thread would block on acquiring the GIL while a thread that owns the GIL spins forever waiting for the result of the `rayon` thread. +Calling `detach` allows the GIL to be released in the thread collecting the results from the worker threads. +You should always call `detach` in situations that spawn worker threads, but especially so in cases where worker threads need to acquire the GIL, to prevent deadlocks. + +[`Python::detach`]: {{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#method.detach +[`rayon`]: https://github.com/rayon-rs/rayon diff --git a/vendor/pyo3/guide/src/performance.md b/vendor/pyo3/guide/src/performance.md new file mode 100644 index 0000000..8b5d91f --- /dev/null +++ b/vendor/pyo3/guide/src/performance.md @@ -0,0 +1,181 @@ +# Performance + +To achieve the best possible performance, it is useful to be aware of several tricks and sharp edges concerning PyO3's API. + +## `extract` versus `cast` + +Pythonic API implemented using PyO3 are often polymorphic, i.e. they will accept `&Bound<'_, PyAny>` and try to turn this into multiple more concrete types to which the requested operation is applied. +This often leads to chains of calls to `extract`, e.g. + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +# use pyo3::{exceptions::PyTypeError, types::PyList}; + +fn frobnicate_list<'py>(list: &Bound<'_, PyList>) -> PyResult> { + todo!() +} + +fn frobnicate_vec<'py>(vec: Vec>) -> PyResult> { + todo!() +} + +#[pyfunction] +fn frobnicate<'py>(value: &Bound<'py, PyAny>) -> PyResult> { + if let Ok(list) = value.extract::>() { + frobnicate_list(&list) + } else if let Ok(vec) = value.extract::>>() { + frobnicate_vec(vec) + } else { + Err(PyTypeError::new_err("Cannot frobnicate that type.")) + } +} +``` + +This suboptimal as the `FromPyObject` trait requires `extract` to have a `Result` return type. +For native types like `PyList`, it faster to use `cast` (which `extract` calls internally) when the error value is ignored. +This avoids the costly conversion of a `PyDowncastError` to a `PyErr` required to fulfil the `FromPyObject` contract, i.e. + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +# use pyo3::{exceptions::PyTypeError, types::PyList}; +# fn frobnicate_list<'py>(list: &Bound<'_, PyList>) -> PyResult> { todo!() } +# fn frobnicate_vec<'py>(vec: Vec>) -> PyResult> { todo!() } +# +#[pyfunction] +fn frobnicate<'py>(value: &Bound<'py, PyAny>) -> PyResult> { + // Use `cast` instead of `extract` as turning `PyDowncastError` into `PyErr` is quite costly. + if let Ok(list) = value.cast::() { + frobnicate_list(list) + } else if let Ok(vec) = value.extract::>>() { + frobnicate_vec(vec) + } else { + Err(PyTypeError::new_err("Cannot frobnicate that type.")) + } +} +``` + +## Access to Bound implies access to Python token + +Calling `Python::attach` is effectively a no-op when we're already attached to the interpreter, but checking that this is the case still has a cost. +If an existing Python token can not be accessed, for example when implementing a pre-existing trait, but a Python-bound reference is available, this cost can be avoided by exploiting that access to Python-bound reference gives zero-cost access to a Python token via `Bound::py`. + +For example, instead of writing + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +# use pyo3::types::PyList; + +struct Foo(Py); + +struct FooBound<'py>(Bound<'py, PyList>); + +impl PartialEq for FooBound<'_> { + fn eq(&self, other: &Foo) -> bool { + Python::attach(|py| { + let len = other.0.bind(py).len(); + self.0.len() == len + }) + } +} +``` + +use the more efficient + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +# use pyo3::types::PyList; +# struct Foo(Py); +# struct FooBound<'py>(Bound<'py, PyList>); +# +impl PartialEq for FooBound<'_> { + fn eq(&self, other: &Foo) -> bool { + // Access to `&Bound<'py, PyAny>` implies access to `Python<'py>`. + let py = self.0.py(); + let len = other.0.bind(py).len(); + self.0.len() == len + } +} +``` + +## Calling Python callables (`__call__`) + +CPython support multiple calling protocols: [`tp_call`] and [`vectorcall`]. +[`vectorcall`] is a more efficient protocol unlocking faster calls. +PyO3 will try to dispatch Python `call`s using the [`vectorcall`] calling convention to archive maximum performance if possible and falling back to [`tp_call`] otherwise. +This is implemented using the (internal) `PyCallArgs` trait. +It defines how Rust types can be used as Python `call` arguments. +This trait is currently implemented for + +- Rust tuples, where each member implements `IntoPyObject`, +- `Bound<'_, PyTuple>` +- `Py` + +Rust tuples may make use of [`vectorcall`] where as `Bound<'_, PyTuple>` and `Py` can only use [`tp_call`]. +For maximum performance prefer using Rust tuples as arguments. + +[`tp_call`]: https://docs.python.org/3/c-api/call.html#the-tp-call-protocol +[`vectorcall`]: https://docs.python.org/3/c-api/call.html#the-vectorcall-protocol + +## Detach from the interpreter for long-running Rust-only work + +When executing Rust code which does not need to interact with the Python interpreter, use [`Python::detach`] to allow the Python interpreter to proceed without waiting for the current thread. + +On the GIL-enabled build, this is crucial for best performance as only a single thread may ever be attached at a time. + +On the free-threaded build, this is still best practice as there are several "stop the world" events (such as garbage collection) where all threads attached to the Python interpreter are forced to wait. + +As a rule of thumb, attaching and detaching from the Python interpreter takes less than a millisecond, so any work which is expected to take multiple milliseconds can likely benefit from detaching from the interpreter. + +[`Python::detach`]: {{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#method.detach + +## Disable the global reference pool + +PyO3 uses global mutable state to keep track of deferred reference count updates implied by `impl Drop for Py` being called without being attached to the interpreter. +The necessary synchronization to obtain and apply these reference count updates when PyO3-based code next attaches to the interpreter is somewhat expensive and can become a significant part of the cost of crossing the Python-Rust boundary. + +This functionality can be avoided by setting the `pyo3_disable_reference_pool` conditional compilation flag. +This removes the global reference pool and the associated costs completely. +However, it does _not_ remove the `Drop` implementation for `Py` which is necessary to interoperate with existing Rust code written without PyO3-based code in mind. +To stay compatible with the wider Rust ecosystem in these cases, we keep the implementation but abort when `Drop` is called without being attached to the interpreter. +If `pyo3_leak_on_drop_without_reference_pool` is additionally enabled, objects dropped without being attached to Python will be leaked instead which is always sound but might have determinal effects like resource exhaustion in the long term. + +This limitation is important to keep in mind when this setting is used, especially when embedding Python code into a Rust application as it is quite easy to accidentally drop a `Py` (or types containing it like `PyErr`, `PyBackedStr` or `PyBackedBytes`) returned from `Python::attach` without making sure to re-attach beforehand. +For example, the following code + +```rust,ignore +# use pyo3::prelude::*; +# use pyo3::types::PyList; +let numbers: Py = Python::attach(|py| PyList::empty(py).unbind()); + +Python::attach(|py| { + numbers.bind(py).append(23).unwrap(); +}); + +Python::attach(|py| { + numbers.bind(py).append(42).unwrap(); +}); +``` + +will abort if the list not explicitly disposed via + +```rust +# use pyo3::prelude::*; +# use pyo3::types::PyList; +let numbers: Py = Python::attach(|py| PyList::empty(py).unbind()); + +Python::attach(|py| { + numbers.bind(py).append(23).unwrap(); +}); + +Python::attach(|py| { + numbers.bind(py).append(42).unwrap(); +}); + +Python::attach(move |py| { + drop(numbers); +}); +``` diff --git a/vendor/pyo3/guide/src/python-from-rust.md b/vendor/pyo3/guide/src/python-from-rust.md new file mode 100644 index 0000000..caa8a0d --- /dev/null +++ b/vendor/pyo3/guide/src/python-from-rust.md @@ -0,0 +1,63 @@ +# Calling Python in Rust code + +This chapter of the guide documents some ways to interact with Python code from Rust. + +Below is an introduction to the `'py` lifetime and some general remarks about how PyO3's API reasons about Python code. + +The subchapters also cover the following topics: + +- Python object types available in PyO3's API +- How to work with Python exceptions +- How to call Python functions +- How to execute existing Python code + +## The `'py` lifetime + +To safely interact with the Python interpreter a Rust thread must be [attached] to the Python interpreter. +PyO3 has a `Python<'py>` token that is used to prove that these conditions are met. +Its lifetime `'py` is a central part of PyO3's API. + +The `Python<'py>` token serves three purposes: + +- It provides global APIs for the Python interpreter, such as [`py.eval()`][eval] and [`py.import()`][import]. +- It can be passed to functions that require a proof of attachment, such as [`Py::clone_ref`][clone_ref]. +- Its lifetime `'py` is used to bind many of PyO3's types to the Python interpreter, such as [`Bound<'py, T>`][Bound]. + +PyO3's types that are bound to the `'py` lifetime, for example `Bound<'py, T>`, all contain a `Python<'py>` token. +This means they have full access to the Python interpreter and offer a complete API for interacting with Python objects. + +Consult [PyO3's API documentation][obtaining-py] to learn how to acquire one of these tokens. + +### The Global Interpreter Lock + +Prior to the introduction of free-threaded Python (first available in 3.13, fully supported in 3.14), the Python interpreter was made thread-safe by the global interpreter lock. +This ensured that only one Python thread can use the Python interpreter and its API at the same time. +Historically, Rust code was able to use the GIL as a synchronization guarantee, but the introduction of free-threaded Python removed this possibility. + +The [`pyo3::sync`] module offers synchronization tools which abstract over both Python builds. + +To enable any parallelism on the GIL-enabled build, and best throughput on the free-threaded build, non-Python operations (system calls and native Rust code) should consider detaching from the Python interpreter to allow other work to proceed. +See [the section on parallelism](parallelism.md) for how to do that using PyO3's API. + +## Python's memory model + +Python's memory model differs from Rust's memory model in two key ways: + +- There is no concept of ownership; all Python objects are shared and usually implemented via reference counting +- There is no concept of exclusive (`&mut`) references; any reference can mutate a Python object + +PyO3's API reflects this by providing smart pointer types, `Py`, `Bound<'py, T>`, and (the very rarely used) `Borrowed<'a, 'py, T>`. +These smart pointers all use Python reference counting. +See the [subchapter on types](./types.md) for more detail on these types. + +Because of the lack of exclusive `&mut` references, PyO3's APIs for Python objects, for example [`PyListMethods::append`], use shared references. +This is safe because Python objects have internal mechanisms to prevent data races (as of time of writing, the Python GIL). + +[attached]: https://docs.python.org/3.14/glossary.html#term-attached-thread-state +[obtaining-py]: {{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#obtaining-a-python-token +[`pyo3::sync`]: {{#PYO3_DOCS_URL}}/pyo3/sync/index.html +[eval]: {{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#method.eval +[import]: {{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#method.import +[clone_ref]: {{#PYO3_DOCS_URL}}/pyo3/prelude/struct.Py.html#method.clone_ref +[Bound]: {{#PYO3_DOCS_URL}}/pyo3/struct.Bound.html +[`PyListMethods::append`]: {{#PYO3_DOCS_URL}}/pyo3/types/trait.PyListMethods.html#tymethod.append diff --git a/vendor/pyo3/guide/src/python-from-rust/calling-existing-code.md b/vendor/pyo3/guide/src/python-from-rust/calling-existing-code.md new file mode 100644 index 0000000..48f54d0 --- /dev/null +++ b/vendor/pyo3/guide/src/python-from-rust/calling-existing-code.md @@ -0,0 +1,391 @@ +# Executing existing Python code + +If you already have some existing Python code that you need to execute from Rust, the following FAQs can help you select the right PyO3 functionality for your situation: + +## Want to access Python APIs? Then use `PyModule::import` + +[`PyModule::import`] can be used to get handle to a Python module from Rust. +You can use this to import and use any Python module available in your environment. + +```rust +use pyo3::prelude::*; + +fn main() -> PyResult<()> { + Python::attach(|py| { + let builtins = PyModule::import(py, "builtins")?; + let total: i32 = builtins + .getattr("sum")? + .call1((vec![1, 2, 3],))? + .extract()?; + assert_eq!(total, 6); + Ok(()) + }) +} +``` + +[`PyModule::import`]: {{#PYO3_DOCS_URL}}/pyo3/types/struct.PyModule.html#method.import + +## Want to run just an expression? Then use `eval` + +[`Python::eval`]({{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#method.eval) is a method to execute a [Python expression](https://docs.python.org/3/reference/expressions.html) and return the evaluated value as a `Bound<'py, PyAny>` object. + +```rust +use pyo3::prelude::*; + +# fn main() -> Result<(), ()> { +Python::attach(|py| { + let result = py + .eval(c"[i * 10 for i in range(5)]", None, None) + .map_err(|e| { + e.print_and_set_sys_last_vars(py); + })?; + let res: Vec = result.extract().unwrap(); + assert_eq!(res, vec![0, 10, 20, 30, 40]); + Ok(()) +}) +# } +``` + +## Want to run statements? Then use `run` + +[`Python::run`] is a method to execute one or more [Python statements](https://docs.python.org/3/reference/simple_stmts.html). +This method returns nothing (like any Python statement), but you can get access to manipulated objects via the `locals` dict. + +You can also use the [`py_run!`] macro, which is a shorthand for [`Python::run`]. +Since [`py_run!`] panics on exceptions, we recommend you use this macro only for quickly testing your Python extension modules. + +```rust +use pyo3::prelude::*; +use pyo3::py_run; + +# fn main() { +#[pyclass] +struct UserData { + id: u32, + name: String, +} + +#[pymethods] +impl UserData { + fn as_tuple(&self) -> (u32, String) { + (self.id, self.name.clone()) + } + + fn __repr__(&self) -> PyResult { + Ok(format!("User {}(id: {})", self.name, self.id)) + } +} + +Python::attach(|py| { + let userdata = UserData { + id: 34, + name: "Yu".to_string(), + }; + let userdata = Py::new(py, userdata).unwrap(); + let userdata_as_tuple = (34, "Yu"); + py_run!(py, userdata userdata_as_tuple, r#" +assert repr(userdata) == "User Yu(id: 34)" +assert userdata.as_tuple() == userdata_as_tuple + "#); +}) +# } +``` + +## You have a Python file or code snippet? Then use `PyModule::from_code` + +[`PyModule::from_code`]({{#PYO3_DOCS_URL}}/pyo3/types/struct.PyModule.html#method.from_code) can be used to generate a Python module which can then be used just as if it was imported with `PyModule::import`. + +**Warning**: This will compile and execute code. +**Never** pass untrusted code to this function! + +```rust +use pyo3::{prelude::*, types::IntoPyDict}; + +# fn main() -> PyResult<()> { +Python::attach(|py| { + let activators = PyModule::from_code( + py, + cr#" +def relu(x): + """see https://en.wikipedia.org/wiki/Rectifier_(neural_networks)""" + return max(0.0, x) + +def leaky_relu(x, slope=0.01): + return x if x >= 0 else x * slope + "#, + c"activators.py", + c"activators", + )?; + + let relu_result: f64 = activators.getattr("relu")?.call1((-1.0,))?.extract()?; + assert_eq!(relu_result, 0.0); + + let kwargs = [("slope", 0.2)].into_py_dict(py)?; + let lrelu_result: f64 = activators + .getattr("leaky_relu")? + .call((-1.0,), Some(&kwargs))? + .extract()?; + assert_eq!(lrelu_result, -0.2); +# Ok(()) +}) +# } +``` + +## Want to embed Python in Rust with additional modules? + +Python maintains the `sys.modules` dict as a cache of all imported modules. +An import in Python will first attempt to lookup the module from this dict, and if not present will use various strategies to attempt to locate and load the module. + +The [`append_to_inittab`]({{#PYO3_DOCS_URL}}/pyo3/macro.append_to_inittab.html) macro can be used to add additional `#[pymodule]` modules to an embedded Python interpreter. +The macro **must** be invoked _before_ initializing Python. + +As an example, the below adds the module `foo` to the embedded interpreter: + +```rust +use pyo3::prelude::*; + +#[pymodule] +mod foo { + use pyo3::prelude::*; + + #[pyfunction] + fn add_one(x: i64) -> i64 { + x + 1 + } +} + +# #[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))] +fn main() -> PyResult<()> { + pyo3::append_to_inittab!(foo); + Python::attach(|py| Python::run(py, c"import foo; foo.add_one(6)", None, None)) +} +# #[cfg(all(Py_LIMITED_API, Py_GIL_DISABLED))] +# fn main() -> () {} +``` + +If `append_to_inittab` cannot be used due to constraints in the program, an alternative is to create a module using [`PyModule::new`] and insert it manually into `sys.modules`: + +```rust +use pyo3::prelude::*; +use pyo3::types::PyDict; + +#[pyfunction] +pub fn add_one(x: i64) -> i64 { + x + 1 +} + +fn main() -> PyResult<()> { + Python::attach(|py| { + // Create new module + let foo_module = PyModule::new(py, "foo")?; + foo_module.add_function(wrap_pyfunction!(add_one, &foo_module)?)?; + + // Import and get sys.modules + let sys = PyModule::import(py, "sys")?; + let py_modules: Bound<'_, PyDict> = sys.getattr("modules")?.cast_into()?; + + // Insert foo into sys.modules + py_modules.set_item("foo", foo_module)?; + + // Now we can import + run our python code + Python::run(py, c"import foo; foo.add_one(6)", None, None) + }) +} +``` + +## Include multiple Python files + +You can include a file at compile time by using [`std::include_str`](https://doc.rust-lang.org/std/macro.include_str.html) macro. + +Or you can load a file at runtime by using [`std::fs::read_to_string`](https://doc.rust-lang.org/std/fs/fn.read_to_string.html) function. + +Many Python files can be included and loaded as modules. +If one file depends on another you must preserve correct order while declaring `PyModule`. + +Example directory structure: + +```text +. +├── Cargo.lock +├── Cargo.toml +├── python_app +│ ├── app.py +│ └── utils +│ └── foo.py +└── src + └── main.rs +``` + +`python_app/app.py`: + +```python +from utils.foo import bar + + +def run(): + return bar() +``` + +`python_app/utils/foo.py`: + +```python +def bar(): + return "baz" +``` + +The example below shows: + +- how to include content of `app.py` and `utils/foo.py` into your rust binary +- how to call function `run()` (declared in `app.py`) that needs function + imported from `utils/foo.py` + +`src/main.rs`: + +```rust,ignore +use pyo3::prelude::*; +use pyo3_ffi::c_str; + +fn main() -> PyResult<()> { + let py_foo = c_str!(include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/python_app/utils/foo.py" + ))); + let py_app = c_str!(include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/python_app/app.py"))); + let from_python = Python::attach(|py| -> PyResult> { + PyModule::from_code(py, py_foo, c"foo.py", c"utils.foo")?; + let app: Py = PyModule::from_code(py, py_app, c"app.py", c"")? + .getattr("run")? + .into(); + app.call0(py) + }); + + println!("py: {}", from_python?); + Ok(()) +} +``` + +The example below shows: + +- how to load content of `app.py` at runtime so that it sees its dependencies + automatically +- how to call function `run()` (declared in `app.py`) that needs function + imported from `utils/foo.py` + +It is recommended to use absolute paths because then your binary can be run from anywhere as long as your `app.py` is in the expected directory (in this example that directory is `/usr/share/python_app`). + +`src/main.rs`: + +```rust,no_run +use pyo3::prelude::*; +use pyo3::types::PyList; +use std::fs; +use std::path::Path; +use std::ffi::CString; + +fn main() -> PyResult<()> { + let path = Path::new("/usr/share/python_app"); + let py_app = CString::new(fs::read_to_string(path.join("app.py"))?)?; + let from_python = Python::attach(|py| -> PyResult> { + let syspath = py + .import("sys")? + .getattr("path")? + .cast_into::()?; + syspath.insert(0, path)?; + let app: Py = PyModule::from_code(py, py_app.as_c_str(), c"app.py", c"")? + .getattr("run")? + .into(); + app.call0(py) + }); + + println!("py: {}", from_python?); + Ok(()) +} +``` + +## Need to use a context manager from Rust? + +Use context managers by directly invoking `__enter__` and `__exit__`. + +```rust +use pyo3::prelude::*; + +fn main() { + Python::attach(|py| { + let custom_manager = PyModule::from_code( + py, + cr#" +class House(object): + def __init__(self, address): + self.address = address + def __enter__(self): + print(f"Welcome to {self.address}!") + def __exit__(self, type, value, traceback): + if type: + print(f"Sorry you had {type} trouble at {self.address}") + else: + print(f"Thank you for visiting {self.address}, come again soon!") + + "#, + c"house.py", + c"house", + ) + .unwrap(); + + let house_class = custom_manager.getattr("House").unwrap(); + let house = house_class.call1(("123 Main Street",)).unwrap(); + + house.call_method0("__enter__").unwrap(); + + let result = py.eval(c"undefined_variable + 1", None, None); + + // If the eval threw an exception we'll pass it through to the context manager. + // Otherwise, __exit__ is called with empty arguments (Python "None"). + match result { + Ok(_) => { + let none = py.None(); + house + .call_method1("__exit__", (&none, &none, &none)) + .unwrap(); + } + Err(e) => { + house + .call_method1( + "__exit__", + ( + e.get_type(py), + e.value(py), + e.traceback(py), + ), + ) + .unwrap(); + } + } + }) +} +``` + +## Handling system signals/interrupts (Ctrl-C) + +The best way to handle system signals when running Rust code is to periodically call `Python::check_signals` to handle any signals captured by Python's signal handler. +See also [the FAQ entry](../faq.md#ctrl-c-doesnt-do-anything-while-my-rust-code-is-executing). + +Alternatively, set Python's `signal` module to take the default action for a signal: + +```rust +use pyo3::prelude::*; + +# fn main() -> PyResult<()> { +Python::attach(|py| -> PyResult<()> { + let signal = py.import("signal")?; + // Set SIGINT to have the default action + signal + .getattr("signal")? + .call1((signal.getattr("SIGINT")?, signal.getattr("SIG_DFL")?))?; + Ok(()) +}) +# } +``` + +[`py_run!`]: {{#PYO3_DOCS_URL}}/pyo3/macro.py_run.html +[`Python::run`]: {{#PYO3_DOCS_URL}}/pyo3/marker/struct.Python.html#method.run +[`PyModule::new`]: {{#PYO3_DOCS_URL}}/pyo3/types/struct.PyModule.html#method.new diff --git a/vendor/pyo3/guide/src/python-from-rust/function-calls.md b/vendor/pyo3/guide/src/python-from-rust/function-calls.md new file mode 100644 index 0000000..6574b86 --- /dev/null +++ b/vendor/pyo3/guide/src/python-from-rust/function-calls.md @@ -0,0 +1,115 @@ +# Calling Python functions + +The `Bound<'py, T>` smart pointer (such as `Bound<'py, PyAny>`, `Bound<'py, PyList>`, or `Bound<'py, MyClass>`) can be used to call Python functions. + +PyO3 offers two APIs to make function calls: + +- [`call`]({{#PYO3_DOCS_URL}}/pyo3/types/trait.PyAnyMethods.html#tymethod.call) - call any callable Python object. +- [`call_method`]({{#PYO3_DOCS_URL}}/pyo3/types/trait.PyAnyMethods.html#tymethod.call_method) - call a method on the Python object. + +Both of these APIs take `args` and `kwargs` arguments (for positional and keyword arguments respectively). +There are variants for less complex calls: + +- [`call1`]({{#PYO3_DOCS_URL}}/pyo3/types/trait.PyAnyMethods.html#tymethod.call1) and [`call_method1`]({{#PYO3_DOCS_URL}}/pyo3/types/trait.PyAnyMethods.html#tymethod.call_method1) to call only with positional `args`. +- [`call0`]({{#PYO3_DOCS_URL}}/pyo3/types/trait.PyAnyMethods.html#tymethod.call0) and [`call_method0`]({{#PYO3_DOCS_URL}}/pyo3/types/trait.PyAnyMethods.html#tymethod.call_method0) to call with no arguments. + +For convenience the [`Py`](../types.md#pyt) smart pointer also exposes these same six API methods, but needs a `Python` token as an additional first argument to prove the thread is attached to the Python interpreter. + +The example below calls a Python function behind a `Py` reference: + +```rust +use pyo3::prelude::*; +use pyo3::types::PyTuple; + +fn main() -> PyResult<()> { + let arg1 = "arg1"; + let arg2 = "arg2"; + let arg3 = "arg3"; + + Python::attach(|py| { + let fun: Py = PyModule::from_code( + py, + c"def example(*args, **kwargs): + if args != (): + print('called with args', args) + if kwargs != {}: + print('called with kwargs', kwargs) + if args == () and kwargs == {}: + print('called with no arguments')", + c"example.py", + c"", + )? + .getattr("example")? + .into(); + + // call object without any arguments + fun.call0(py)?; + + // pass object with Rust tuple of positional arguments + let args = (arg1, arg2, arg3); + fun.call1(py, args)?; + + // call object with Python tuple of positional arguments + let args = PyTuple::new(py, &[arg1, arg2, arg3])?; + fun.call1(py, args)?; + Ok(()) + }) +} +``` + +## Creating keyword arguments + +For the `call` and `call_method` APIs, `kwargs` are `Option<&Bound<'py, PyDict>>`, so can either be `None` or `Some(&dict)`. +You can use the [`IntoPyDict`]({{#PYO3_DOCS_URL}}/pyo3/types/trait.IntoPyDict.html) trait to convert other dict-like containers, e.g. `HashMap` or `BTreeMap`, as well as tuples with up to 10 elements and `Vec`s where each element is a two-element tuple. +To pass keyword arguments of different types, construct a `PyDict` object. + +```rust +use pyo3::prelude::*; +use pyo3::types::{PyDict, IntoPyDict}; +use std::collections::HashMap; + +fn main() -> PyResult<()> { + let key1 = "key1"; + let val1 = 1; + let key2 = "key2"; + let val2 = 2; + + Python::attach(|py| { + let fun: Py = PyModule::from_code( + py, + c"def example(*args, **kwargs): + if args != (): + print('called with args', args) + if kwargs != {}: + print('called with kwargs', kwargs) + if args == () and kwargs == {}: + print('called with no arguments')", + c"example.py", + c"", + )? + .getattr("example")? + .into(); + + // call object with PyDict + let kwargs = [(key1, val1)].into_py_dict(py)?; + fun.call(py, (), Some(&kwargs))?; + + // pass arguments as Vec + let kwargs = vec![(key1, val1), (key2, val2)]; + fun.call(py, (), Some(&kwargs.into_py_dict(py)?))?; + + // pass arguments as HashMap + let mut kwargs = HashMap::<&str, i32>::new(); + kwargs.insert(key1, 1); + fun.call(py, (), Some(&kwargs.into_py_dict(py)?))?; + + // pass arguments of different types as PyDict + let kwargs = PyDict::new(py); + kwargs.set_item(key1, val1)?; + kwargs.set_item(key2, "string")?; + fun.call(py, (), Some(&kwargs))?; + + Ok(()) + }) +} +``` diff --git a/vendor/pyo3/guide/src/python-typing-hints.md b/vendor/pyo3/guide/src/python-typing-hints.md new file mode 100644 index 0000000..44c52de --- /dev/null +++ b/vendor/pyo3/guide/src/python-typing-hints.md @@ -0,0 +1,256 @@ +# Typing and IDE hints for your Python package + +PyO3 provides an easy to use interface to code native Python libraries in Rust. +The accompanying Maturin allows you to build and publish them as a package. +Yet, for a better user experience, Python libraries should provide typing hints and documentation for all public entities, so that IDEs can show them during development and type analyzing tools such as `mypy` can use them to properly verify the code. + +Currently the best solution for the problem is to manually maintain `*.pyi` files and ship them along with the package. + +PyO3 is working on automated their generation. +See the [type stub generation](type-stub.md) documentation for a description of the current state of automated generation. + +## Introduction to `pyi` files + +`pyi` files (an abbreviation for `Python Interface`) are called "stub files" in most of the documentation related to them. +A very good definition of what it is can be found in [old MyPy documentation](https://github.com/python/mypy/wiki/Creating-Stubs-For-Python-Modules): + +> A stubs file only contains a description of the public interface of the module without any implementations. + +There is also [extensive documentation on type stubs on the official Python typing documentation](https://typing.readthedocs.io/en/latest/source/stubs.html). + +Most Python developers probably already encountered them when trying to use their IDE's "Go to Definition" function on any builtin type. +For example, the definitions of a few standard exceptions look like this: + +```python +class BaseException(object): + args: Tuple[Any, ...] + __cause__: BaseException | None + __context__: BaseException | None + __suppress_context__: bool + __traceback__: TracebackType | None + def __init__(self, *args: object) -> None: ... + def __str__(self) -> str: ... + def __repr__(self) -> str: ... + def with_traceback(self: _TBE, tb: TracebackType | None) -> _TBE: ... + +class SystemExit(BaseException): + code: int + +class Exception(BaseException): ... + +class StopIteration(Exception): + value: Any +``` + +As we can see, those are not full definitions containing implementation, but just a description of the interface. +It is usually all that the user of the library needs. + +### What do the PEPs say? + +At the time of writing this documentation, the `pyi` files are referenced in four PEPs. + +[PEP8 - Style Guide for Python Code - #Function Annotations](https://www.python.org/dev/peps/pep-0008/#function-annotations) (last point) recommends all third party library creators to provide stub files as the source of knowledge about the package for type checker tools. + +> (...) it is expected that users of third party library packages may want to run type checkers over those packages. For this purpose [PEP 484](https://www.python.org/dev/peps/pep-0484) recommends the use of stub files: .pyi files that are read by the type checker in preference of the corresponding .py files. (...) + +[PEP484 - Type Hints - #Stub Files](https://www.python.org/dev/peps/pep-0484/#stub-files) defines stub files as follows. + +> Stub files are files containing type hints that are only for use by the type checker, not at runtime. + +It contains a specification for them (highly recommended reading, since it contains at least one thing that is not used in normal Python code) and also some general information about where to store the stub files. + +[PEP561 - Distributing and Packaging Type Information](https://www.python.org/dev/peps/pep-0561/) describes in detail how to build packages that will enable type checking. +In particular it contains information about how the stub files must be distributed in order for type checkers to use them. + +[PEP560 - Core support for typing module and generic types](https://www.python.org/dev/peps/pep-0560/) describes the details on how Python's type system internally supports generics, including both runtime behavior and integration with static type checkers. + +## How to do it? + +[PEP561](https://www.python.org/dev/peps/pep-0561/) recognizes three ways of distributing type information: + +- `inline` - the typing is placed directly in source (`py`) files; +- `separate package with stub files` - the typing is placed in `pyi` files distributed in their own, separate package; +- `in-package stub files` - the typing is placed in `pyi` files distributed in the same package as source files. + +The first way is tricky with PyO3 since we do not have `py` files. +When it has been investigated and necessary changes are implemented, this document will be updated. + +The second way is easy to do, and the whole work can be fully separated from the main library code. +The example repo for the package with stub files can be found in [PEP561 references section](https://www.python.org/dev/peps/pep-0561/#references): [Stub package repository](https://github.com/ethanhs/stub-package) + +The third way is described below. + +### Including `pyi` files in your PyO3/Maturin build package + +When source files are in the same package as stub files, they should be placed next to each other. +We need a way to do that with Maturin. +Also, in order to mark our package as typing-enabled we need to add an empty file named `py.typed` to the package. + +#### If you do not have other Python files + +If you do not need to add any other Python files apart from `pyi` to the package, Maturin provides a way to do most of the work for you. +As documented in the [Maturin Guide](https://github.com/PyO3/maturin/#mixed-rustpython-projects), the only thing you need to do is to create a stub file for your module named `.pyi` in your project root and Maturin will do the rest. + +```text +my-rust-project/ +├── Cargo.toml +├── my_project.pyi # <<< add type stubs for Rust functions in the my_project module here +├── pyproject.toml +└── src + └── lib.rs +``` + +For an example `pyi` file see the [`my_project.pyi` content](#my_projectpyi-content) section. + +#### If you need other Python files + +If you need to add other Python files apart from `pyi` to the package, you can do it also, but that requires some more work. +Maturin provides an easy way to add files to a package ([documentation](https://github.com/PyO3/maturin/blob/0dee40510083c03607834c821eea76964140a126/Readme.md#mixed-rustpython-projects)). +You just need to create a folder with the name of your module next to the `Cargo.toml` file (for customization see documentation linked above). + +The folder structure would be: + +```text +my-project +├── Cargo.toml +├── my_project +│ ├── __init__.py +│ ├── my_project.pyi +│ ├── other_python_file.py +│ └── py.typed +├── pyproject.toml +├── Readme.md +└── src + └── lib.rs +``` + +Let's go a little bit more into detail regarding the files inside the package folder. + +##### `__init__.py` content + +As we now specify our own package content, we have to provide the `__init__.py` file, so the folder is treated as a package and we can import things from it. +We can always use the same content that Maturin creates for us if we do not specify a Python source folder. +For PyO3 bindings it would be: + +```python +from .my_project import * +``` + +That way everything that is exposed by our extension module can be imported directly from the package. + +##### `py.typed` requirement + +As stated in [PEP561](https://www.python.org/dev/peps/pep-0561/): +> Package maintainers who wish to support type checking of their code MUST add a marker file named py.typed to their package supporting typing. This marker applies recursively: if a top-level package includes it, all its sub-packages MUST support type checking as well. + +If we do not include that file, some IDEs might still use our `pyi` files to show hints, but the type checkers might not. +MyPy will raise an error in this situation: + +```text +error: Skipping analyzing "my_project": found module but no type hints or library stubs +``` + +The file is just a marker file, so it should be empty. + +##### `my_project.pyi` content + +Our module stub file. +This document does not aim at describing how to write them, since you can find a lot of documentation on it, starting from the already quoted [PEP484](https://www.python.org/dev/peps/pep-0484/#stub-files). + +The example can look like this: + +```python +class Car: + """ + A class representing a car. + + :param body_type: the name of body type, e.g. hatchback, sedan + :param horsepower: power of the engine in horsepower + """ + def __init__(self, body_type: str, horsepower: int) -> None: ... + + @classmethod + def from_unique_name(cls, name: str) -> 'Car': + """ + Creates a Car based on unique name + + :param name: model name of a car to be created + :return: a Car instance with default data + """ + + def best_color(self) -> str: + """ + Gets the best color for the car. + + :return: the name of the color our great algorithm thinks is the best for this car + """ +``` + +### Supporting Generics + +Type annotations can also be made generic in Python. +They are useful for working with different types while maintaining type safety. +Usually, generic classes inherit from the `typing.Generic` metaclass. + + +Take for example the following `.pyi` file that specifies a `Car` that can accept multiple types of wheels: + +```python +from typing import Generic, TypeVar + +W = TypeVar('W') + +class Car(Generic[W]): + def __init__(self, wheels: list[W]) -> None: ... + + def get_wheels(self) -> list[W]: ... + + def change_wheel(self, wheel_number: int, wheel: W) -> None: ... +``` + +This way, the end-user can specify the type with variables such as `truck: Car[SteelWheel] = ...` and `f1_car: Car[AlloyWheel] = ...`. + +There is also a special syntax for specifying generic types in Python 3.12+: + +```python +class Car[W]: + def __init__(self, wheels: list[W]) -> None: ... + + def get_wheels(self) -> list[W]: ... +``` + +#### Runtime Behaviour + +Stub files (`pyi`) are only useful for static type checkers and ignored at runtime. +Therefore, PyO3 classes do not inherit from `typing.Generic` even if specified in the stub files. + +This can cause some runtime issues, as annotating a variable like `f1_car: Car[AlloyWheel] = ...` can make Python call magic methods that are not defined. + +To overcome this limitation, implementers can pass the `generic` parameter to `pyclass` in Rust: + +```rust ignore +#[pyclass(generic)] +``` + +#### Advanced Users + +`#[pyclass(generic)]` implements a very simple runtime behavior that accepts any generic argument. +Advanced users can opt to manually implement [`__class_getitem__`](https://docs.python.org/3/reference/datamodel.html#emulating-generic-types) for the generic class to have more control. + +```rust ignore +impl MyClass { + #[classmethod] + #[pyo3(signature = (key, /))] + pub fn __class_getitem__( + cls: &Bound<'_, PyType>, + key: &Bound<'_, PyAny>, + ) -> PyResult> { + /* implementation details */ + } +} +``` + +Note that [`pyo3::types::PyGenericAlias`][pygenericalias] can be helpful when implementing `__class_getitem__` as it can create [`types.GenericAlias`][genericalias] objects from Rust. + +[pygenericalias]: {{#PYO3_DOCS_URL}}/pyo3/types/struct.PyGenericAlias.html +[genericalias]: https://docs.python.org/3/library/types.html#types.GenericAlias diff --git a/vendor/pyo3/guide/src/rust-from-python.md b/vendor/pyo3/guide/src/rust-from-python.md new file mode 100644 index 0000000..3b525d3 --- /dev/null +++ b/vendor/pyo3/guide/src/rust-from-python.md @@ -0,0 +1,13 @@ +# Using Rust from Python + +This chapter of the guide is dedicated to explaining how to wrap Rust code into Python objects. + +PyO3 uses Rust's "procedural macros" to provide a powerful yet simple API to denote what Rust code should map into Python objects. + +PyO3 can create three types of Python objects: + +- Python modules, via the `#[pymodule]` macro +- Python functions, via the `#[pyfunction]` macro +- Python classes, via the `#[pyclass]` macro (plus `#[pymethods]` to define methods for those classes) + +The following subchapters go through each of these in turn. diff --git a/vendor/pyo3/guide/src/trait-bounds.md b/vendor/pyo3/guide/src/trait-bounds.md new file mode 100644 index 0000000..c11c2e9 --- /dev/null +++ b/vendor/pyo3/guide/src/trait-bounds.md @@ -0,0 +1,561 @@ +# Using in Python a Rust function with trait bounds + +PyO3 allows for easy conversion from Rust to Python for certain functions and classes (see the [conversion table](conversions/tables.md)). +However, it is not always straightforward to convert Rust code that requires a given trait implementation as an argument. + +This tutorial explains how to convert a Rust function that takes a trait as argument for use in Python with classes implementing the same methods as the trait. + +Why is this useful? + +## Pros + +- Make your Rust code available to Python users +- Code complex algorithms in Rust with the help of the borrow checker + +### Cons + +- Not as fast as native Rust (type conversion has to be performed and one part of the code runs in Python) +- You need to adapt your code to expose it + +## Example + +Let's work with the following basic example of an implementation of a optimization solver operating on a given model. + +Let's say we have a function `solve` that operates on a model and mutates its state. +The argument of the function can be any model that implements the `Model` trait : + +```rust,no_run +# #![allow(dead_code)] +pub trait Model { + fn set_variables(&mut self, inputs: &Vec); + fn compute(&mut self); + fn get_results(&self) -> Vec; +} + +pub fn solve(model: &mut T) { + println!("Magic solver that mutates the model into a resolved state"); +} +``` + +Let's assume we have the following constraints: + +- We cannot change that code as it runs on many Rust models. +- We also have many Python models that cannot be solved as this solver is not available in that language. + +Rewriting it in Python would be cumbersome and error-prone, as everything is already available in Rust. + +How could we expose this solver to Python thanks to PyO3 ? + +## Implementation of the trait bounds for the Python class + +If a Python class implements the same three methods as the `Model` trait, it seems logical it could be adapted to use the solver. +However, it is not possible to pass a `Py` to it as it does not implement the Rust trait (even if the Python model has the required methods). + +In order to implement the trait, we must write a wrapper around the calls in Rust to the Python model. +The method signatures must be the same as the trait, keeping in mind that the Rust trait cannot be changed for the purpose of making the code available in Python. + +The Python model we want to expose is the following one, which already contains all the required methods: + +```python +class Model: + def set_variables(self, inputs): + self.inputs = inputs + def compute(self): + self.results = [elt**2 - 3 for elt in self.inputs] + def get_results(self): + return self.results +``` + +The following wrapper will call the Python model from Rust, using a struct to hold the model as a `PyAny` object: + +```rust,no_run +# #![allow(dead_code)] +use pyo3::prelude::*; +use pyo3::types::PyList; + +# pub trait Model { +# fn set_variables(&mut self, inputs: &Vec); +# fn compute(&mut self); +# fn get_results(&self) -> Vec; +# } + +struct UserModel { + model: Py, +} + +impl Model for UserModel { + fn set_variables(&mut self, var: &Vec) { + println!("Rust calling Python to set the variables"); + Python::attach(|py| { + self.model + .bind(py) + .call_method("set_variables", (PyList::new(py, var).unwrap(),), None) + .unwrap(); + }) + } + + fn get_results(&self) -> Vec { + println!("Rust calling Python to get the results"); + Python::attach(|py| { + self.model + .bind(py) + .call_method("get_results", (), None) + .unwrap() + .extract() + .unwrap() + }) + } + + fn compute(&mut self) { + println!("Rust calling Python to perform the computation"); + Python::attach(|py| { + self.model + .bind(py) + .call_method("compute", (), None) + .unwrap(); + }) + } +} +``` + +Now that this bit is implemented, let's expose the model wrapper to Python. +Let's add the PyO3 annotations and add a constructor: + +```rust,no_run +# #![allow(dead_code)] +# fn main() {} +# pub trait Model { +# fn set_variables(&mut self, inputs: &Vec); +# fn compute(&mut self); +# fn get_results(&self) -> Vec; +# } +# use pyo3::prelude::*; + +#[pyclass] +struct UserModel { + model: Py, +} + +#[pymethods] +impl UserModel { + #[new] + pub fn new(model: Py) -> Self { + UserModel { model } + } +} + +#[pymodule] +mod trait_exposure { + #[pymodule_export] + use super::UserModel; +} +``` + +Now we add the PyO3 annotations to the trait implementation: + +```rust,ignore +#[pymethods] +impl Model for UserModel { + // the previous trait implementation +} +``` + +However, the previous code will not compile. +The compilation error is the following one: `error: #[pymethods] cannot be used on trait impl blocks` + +That's a bummer! +However, we can write a second wrapper around these functions to call them directly. +This wrapper will also perform the type conversions between Python and Rust. + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +# use pyo3::types::PyList; +# +# pub trait Model { +# fn set_variables(&mut self, inputs: &Vec); +# fn compute(&mut self); +# fn get_results(&self) -> Vec; +# } +# +# #[pyclass] +# struct UserModel { +# model: Py, +# } +# +# impl Model for UserModel { +# fn set_variables(&mut self, var: &Vec) { +# println!("Rust calling Python to set the variables"); +# Python::attach(|py| { +# self.model.bind(py) +# .call_method("set_variables", (PyList::new(py, var).unwrap(),), None) +# .unwrap(); +# }) +# } +# +# fn get_results(&self) -> Vec { +# println!("Rust calling Python to get the results"); +# Python::attach(|py| { +# self.model +# .bind(py) +# .call_method("get_results", (), None) +# .unwrap() +# .extract() +# .unwrap() +# }) +# } +# +# fn compute(&mut self) { +# println!("Rust calling Python to perform the computation"); +# Python::attach(|py| { +# self.model +# .bind(py) +# .call_method("compute", (), None) +# .unwrap(); +# }) +# +# } +# } + +#[pymethods] +impl UserModel { + pub fn set_variables(&mut self, var: Vec) { + println!("Set variables from Python calling Rust"); + Model::set_variables(self, &var) + } + + pub fn get_results(&mut self) -> Vec { + println!("Get results from Python calling Rust"); + Model::get_results(self) + } + + pub fn compute(&mut self) { + println!("Compute from Python calling Rust"); + Model::compute(self) + } +} +``` + +This wrapper handles the type conversion between the PyO3 requirements and the trait. +In order to meet PyO3 requirements, this wrapper must: + +- return an object of type `PyResult` +- use only values, not references in the method signatures + +Let's run the file python file: + +```python +class Model: + def set_variables(self, inputs): + self.inputs = inputs + def compute(self): + self.results = [elt**2 - 3 for elt in self.inputs] + def get_results(self): + return self.results + +if __name__=="__main__": + import trait_exposure + + myModel = Model() + my_rust_model = trait_exposure.UserModel(myModel) + my_rust_model.set_variables([2.0]) + print("Print value from Python: ", myModel.inputs) + my_rust_model.compute() + print("Print value from Python through Rust: ", my_rust_model.get_results()) + print("Print value directly from Python: ", myModel.get_results()) +``` + +This outputs: + +```block +Set variables from Python calling Rust +Set variables from Rust calling Python +Print value from Python: [2.0] +Compute from Python calling Rust +Compute from Rust calling Python +Get results from Python calling Rust +Get results from Rust calling Python +Print value from Python through Rust: [1.0] +Print value directly from Python: [1.0] +``` + +We have now successfully exposed a Rust model that implements the `Model` trait to Python! + +We will now expose the `solve` function, but before, let's talk about types errors. + +## Type errors in Python + +What happens if you have type errors when using Python and how can you improve the error messages? + +### Wrong types in Python function arguments + +Let's assume in the first case that you will use in your Python file `my_rust_model.set_variables(2.0)` instead of `my_rust_model.set_variables([2.0])`. + +The Rust signature expects a vector, which corresponds to a list in Python. +What happens if instead of a vector, we pass a single value ? + +At the execution of Python, we get : + +```block +File "main.py", line 15, in + my_rust_model.set_variables(2) +TypeError +``` + +It is a type error and Python points to it, so it's easy to identify and solve. + +### Wrong types in Python method signatures + +Let's assume now that the return type of one of the methods of our Model class is wrong, for example the `get_results` method that is expected to return a `Vec` in Rust, a list in Python. + +```python +class Model: + def set_variables(self, inputs): + self.inputs = inputs + def compute(self): + self.results = [elt**2 -3 for elt in self.inputs] + def get_results(self): + return self.results[0] + #return self.results <-- this is the expected output +``` + +This call results in the following panic: + +```block +pyo3_runtime.PanicException: called `Result::unwrap()` on an `Err` value: PyErr { type: Py(0x10dcf79f0, PhantomData) } +``` + +This error code is not helpful for a Python user that does not know anything about Rust, or someone that does not know PyO3 was used to interface the Rust code. + +However, as we are responsible for making the Rust code available to Python, we can do something about it. + +The issue is that we called `unwrap` anywhere we could, and therefore any panic from PyO3 will be directly forwarded to the end user. + +Let's modify the code performing the type conversion to give a helpful error message to the Python user: + +We used in our `get_results` method the following call that performs the type conversion: + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +# use pyo3::types::PyList; +# +# pub trait Model { +# fn set_variables(&mut self, inputs: &Vec); +# fn compute(&mut self); +# fn get_results(&self) -> Vec; +# } +# +# #[pyclass] +# struct UserModel { +# model: Py, +# } + +impl Model for UserModel { + fn get_results(&self) -> Vec { + println!("Rust calling Python to get the results"); + Python::attach(|py| { + self.model + .bind(py) + .call_method("get_results", (), None) + .unwrap() + .extract() + .unwrap() + }) + } +# fn set_variables(&mut self, var: &Vec) { +# println!("Rust calling Python to set the variables"); +# Python::attach(|py| { +# self.model.bind(py) +# .call_method("set_variables", (PyList::new(py, var).unwrap(),), None) +# .unwrap(); +# }) +# } +# +# fn compute(&mut self) { +# println!("Rust calling Python to perform the computation"); +# Python::attach(|py| { +# self.model +# .bind(py) +# .call_method("compute", (), None) +# .unwrap(); +# }) +# } +} +``` + +Let's break it down in order to perform better error handling: + +```rust,no_run +# #![allow(dead_code)] +# use pyo3::prelude::*; +# use pyo3::types::PyList; +# +# pub trait Model { +# fn set_variables(&mut self, inputs: &Vec); +# fn compute(&mut self); +# fn get_results(&self) -> Vec; +# } +# +# #[pyclass] +# struct UserModel { +# model: Py, +# } + +impl Model for UserModel { + fn get_results(&self) -> Vec { + println!("Get results from Rust calling Python"); + Python::attach(|py| { + let py_result: Bound<'_, PyAny> = self + .model + .bind(py) + .call_method("get_results", (), None) + .unwrap(); + + if py_result.get_type().name().unwrap() != "list" { + panic!( + "Expected a list for the get_results() method signature, got {}", + py_result.get_type().name().unwrap() + ); + } + py_result.extract() + }) + .unwrap() + } +# fn set_variables(&mut self, var: &Vec) { +# println!("Rust calling Python to set the variables"); +# Python::attach(|py| { +# let py_model = self.model.bind(py) +# .call_method("set_variables", (PyList::new(py, var).unwrap(),), None) +# .unwrap(); +# }) +# } +# +# fn compute(&mut self) { +# println!("Rust calling Python to perform the computation"); +# Python::attach(|py| { +# self.model +# .bind(py) +# .call_method("compute", (), None) +# .unwrap(); +# }) +# } +} +``` + +By doing so, you catch the result of the Python computation and check its type in order to be able to deliver a better error message before performing the unwrapping. + +Of course, it does not cover all the possible wrong outputs: the user could return a list of strings instead of a list of floats. +In this case, a runtime panic would still occur due to PyO3, but with an error message much more difficult to decipher for non-rust user. + +It is up to the developer exposing the rust code to decide how much effort to invest into Python type error handling and improved error messages. + +## The final code + +Now let's expose the `solve()` function to make it available from Python. + +It is not possible to directly expose the `solve` function to Python, as the type conversion cannot be performed. +It requires an object implementing the `Model` trait as input. + +However, the `UserModel` already implements this trait. +Because of this, we can write a function wrapper that takes the `UserModel`--which has already been exposed to Python--as an argument in order to call the core function `solve`. + +It is also required to make the struct public. + +```rust,no_run +# #![allow(dead_code)] +# fn main() {} +use pyo3::prelude::*; +use pyo3::types::PyList; + +pub trait Model { + fn set_variables(&mut self, var: &Vec); + fn get_results(&self) -> Vec; + fn compute(&mut self); +} + +pub fn solve(model: &mut T) { + println!("Magic solver that mutates the model into a resolved state"); +} + +#[pyfunction] +#[pyo3(name = "solve")] +pub fn solve_wrapper(model: &mut UserModel) { + solve(model); +} + +#[pyclass] +pub struct UserModel { + model: Py, +} + +#[pymethods] +impl UserModel { + #[new] + pub fn new(model: Py) -> Self { + UserModel { model } + } + + pub fn set_variables(&mut self, var: Vec) { + println!("Set variables from Python calling Rust"); + Model::set_variables(self, &var) + } + + pub fn get_results(&mut self) -> Vec { + println!("Get results from Python calling Rust"); + Model::get_results(self) + } + + pub fn compute(&mut self) { + Model::compute(self) + } +} + +#[pymodule] +mod trait_exposure { + #[pymodule_export] + use super::{UserModel, solve_wrapper}; +} + +impl Model for UserModel { + fn set_variables(&mut self, var: &Vec) { + println!("Rust calling Python to set the variables"); + Python::attach(|py| { + self.model + .bind(py) + .call_method("set_variables", (PyList::new(py, var).unwrap(),), None) + .unwrap(); + }) + } + + fn get_results(&self) -> Vec { + println!("Get results from Rust calling Python"); + Python::attach(|py| { + let py_result: Bound<'_, PyAny> = self + .model + .bind(py) + .call_method("get_results", (), None) + .unwrap(); + + if py_result.get_type().name().unwrap() != "list" { + panic!( + "Expected a list for the get_results() method signature, got {}", + py_result.get_type().name().unwrap() + ); + } + py_result.extract() + }) + .unwrap() + } + + fn compute(&mut self) { + println!("Rust calling Python to perform the computation"); + Python::attach(|py| { + self.model + .bind(py) + .call_method("compute", (), None) + .unwrap(); + }) + } +} +``` diff --git a/vendor/pyo3/guide/src/type-stub.md b/vendor/pyo3/guide/src/type-stub.md new file mode 100644 index 0000000..132dcf9 --- /dev/null +++ b/vendor/pyo3/guide/src/type-stub.md @@ -0,0 +1,89 @@ +# Type stub generation (`*.pyi` files) and introspection + +*This feature is still in active development.* +*See [the related issue](https://github.com/PyO3/pyo3/issues/5137).* + +*For documentation on type stubs and how to use them with stable PyO3, refer to [this page](python-typing-hints.md)* + +PyO3 has a work in progress support to generate [type stub files](https://typing.python.org/en/latest/spec/distributing.html#stub-files). + +It works using: + +1. PyO3 macros (`#[pyclass]`) that generate constant JSON strings that are then included in the built binaries by rustc if the `experimental-inspect` feature is enabled. +2. The `pyo3-introspection` crate that can parse the generated binaries, extract the JSON strings and build stub files from it. +3. Build tools like `maturin` exposing options in their CLI API to generate the stubs file. + +For example, the following Rust code + +```rust +#[pymodule] +pub mod example { + use pyo3::prelude::*; + + #[pymodule_export] + pub const CONSTANT: &str = "FOO"; + + #[pyclass(eq)] + #[derive(Eq)] + struct Class { + value: usize + } + + #[pymethods] + impl Class { + #[new] + fn new(value: usize) -> Self { + Self { value } + } + + #[getter] + fn value(&self) -> usize { + self.value + } + } + + #[pyfunction] + #[pyo3(signature = (arg: "list[int]") -> "list[int]")] + fn list_of_int_identity(arg: Bound<'_, PyAny>) -> Bound<'_, PyAny> { + arg + } +} +``` + +will generate the following stub file: + +```python +import typing + +CONSTANT: typing.Final = "FOO" + +class Class: + def __init__(self, value: int) -> None: ... + + @property + def value(self) -> int: ... + + def __eq__(self, value: object, /) -> bool: ... + def __ne__(self, value: object, /) -> bool: ... + +def list_of_int_identity(arg: "list[int]") -> "list[int]": ... +``` + +The only piece of new syntax is that the `#[pyo3(signature = ...)]` attribute can contain type annotations like `#[pyo3(signature = (arg: "list[int]") -> "list[int]")]` (note the `""` around type annotations). +This is useful when PyO3 is not able to derive proper type annotations by itself. + +To generate stubs file with `maturin` you can use `maturin generate-stubs --output stubs` that will build the project then generate the stubs in the `stubs` directory. +You can also directly integrate the stubs in the built wheels by doing `maturin build --generate-stubs` (works also with `maturin develop`). + +PyO3 also provides the smaller `pyo3-introspection` binary that allows to generate stubs from an existing built extension using something like `pyo3-introspection my_module_binary.so my_module_name output` to introspect the `my_module_binary.so` dynamic library for the `my_module_name` Python module and generate its stubs in the `output` directory. + +## Constraints and limitations + +- The `experimental-inspect` feature is required to generate the introspection fragments. +- Lots of features are not implemented yet. + See [the related issue](https://github.com/PyO3/pyo3/issues/5137) for a list of them. +- Introspection only works with Python modules declared with an inline Rust module. + Modules declared using a function are not supported. +- `FromPyObject::INPUT_TYPE` and `IntoPyObject::OUTPUT_TYPE` must be implemented for PyO3 to get the proper input/output type annotations to use. +- PyO3 is not able to introspect the content of `#[pymodule]` and `#[pymodule_init]` functions. + If they are present, the module is tagged as incomplete using a fake `def __getattr__(name: str) -> Incomplete: ...` function [following best practices](https://typing.python.org/en/latest/guides/writing_stubs.html#incomplete-stubs). diff --git a/vendor/pyo3/guide/src/types.md b/vendor/pyo3/guide/src/types.md new file mode 100644 index 0000000..8db0779 --- /dev/null +++ b/vendor/pyo3/guide/src/types.md @@ -0,0 +1,371 @@ +# Python object types + +PyO3 offers two main sets of types to interact with Python objects. +This section of the guide expands into detail about these types and how to choose which to use. + +The first set of types are the smart pointers which all Python objects are wrapped in. +These are `Py`, `Bound<'py, T>`, and `Borrowed<'a, 'py, T>`. +The [first section below](#pyo3s-smart-pointers) expands on each of these in detail and why there are three of them. + +The second set of types are types which fill in the generic parameter `T` of the smart pointers. +The most common is `PyAny`, which represents any Python object (similar to Python's `typing.Any`). +There are also concrete types for many Python built-in types, such as `PyList`, `PyDict`, and `PyTuple`. +User defined `#[pyclass]` types also fit this category. +The [second section below](#concrete-python-types) expands on how to use these types. + +## PyO3's smart pointers + +PyO3's API offers three generic [smart pointers](glossary.md#smart-pointer): `Py`, `Bound<'py, T>` and `Borrowed<'a, 'py, T>`. +For each of these the type parameter `T` will be filled by a [concrete Python type](#concrete-python-types). +For example, a Python list object can be represented by `Py`, `Bound<'py, PyList>`, and `Borrowed<'a, 'py, PyList>`. + +These smart pointers behave differently due to their lifetime parameters. `Py` has no lifetime parameters, `Bound<'py, T>` has [the `'py` lifetime](./python-from-rust.md#the-py-lifetime) as a parameter, and `Borrowed<'a, 'py, T>` has the `'py` lifetime plus an additional lifetime `'a` to denote the lifetime it is borrowing data for. (You can read more about these lifetimes in the subsections below). + +Python objects are reference counted, like [`std::sync::Arc`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html). +A major reason for these smart pointers is to bring Python's reference counting to a Rust API. + +The recommendation of when to use each of these smart pointers is as follows: + +- Use `Bound<'py, T>` for as much as possible, as it offers the most efficient and complete API. +- Use `Py` mostly just for storage inside Rust `struct`s which do not want to or can't add a lifetime parameter for `Bound<'py, T>`. +- `Borrowed<'a, 'py, T>` is almost never used. + It is occasionally present at the boundary between Rust and the Python interpreter, for example when borrowing data from Python tuples (which is safe because they are immutable). + +The sections below also explain these smart pointers in a little more detail. + +### `Py` + +[`Py`][Py] is the foundational smart pointer in PyO3's API. +The type parameter `T` denotes the type of the Python object. +Very frequently this is `PyAny`, meaning any Python object. + +Because `Py` is not bound to [the `'py` lifetime](./python-from-rust.md#the-py-lifetime), it is the type to use when storing a Python object inside a Rust `struct` or `enum` which do not want to have a lifetime parameter. +In particular, [`#[pyclass]`][pyclass] types are not permitted to have a lifetime, so `Py` is the correct type to store Python objects inside them. + +The lack of binding to the `'py` lifetime also carries drawbacks: + +- Almost all methods on `Py` require a `Python<'py>` token as the first argument +- Other functionality, such as [`Drop`][Drop], needs to check at runtime for attachment to the Python interpreter, at a small performance cost + +Because of the drawbacks `Bound<'py, T>` is preferred for many of PyO3's APIs. +In particular, `Bound<'py, T>` is better for function arguments. + +To convert a `Py` into a `Bound<'py, T>`, the `Py::bind` and `Py::into_bound` methods are available. `Bound<'py, T>` can be converted back into `Py` using [`Bound::unbind`]. + +### `Bound<'py, T>` + +[`Bound<'py, T>`][Bound] is the counterpart to `Py` which is also bound to the `'py` lifetime. +It can be thought of as equivalent to the Rust tuple `(Python<'py>, Py)`. + +By having the binding to the `'py` lifetime, `Bound<'py, T>` can offer the complete PyO3 API at maximum efficiency. +This means that `Bound<'py, T>` should usually be used whenever carrying this lifetime is acceptable, and `Py` otherwise. + +`Bound<'py, T>` engages in Python reference counting. +This means that `Bound<'py, T>` owns a Python object. +Rust code which just wants to borrow a Python object should use a shared reference `&Bound<'py, T>`. +Just like `std::sync::Arc`, using `.clone()` and `drop()` will cheaply increment and decrement the reference count of the object (just in this case, the reference counting is implemented by the Python interpreter itself). + +To give an example of how `Bound<'py, T>` is PyO3's primary API type, consider the following Python code: + +```python +def example(): + x = list() # create a Python list + x.append(1) # append the integer 1 to it + y = x # create a second reference to the list + del x # delete the original reference +``` + +Using PyO3's API, and in particular `Bound<'py, PyList>`, this code translates into the following Rust code: + +```rust +use pyo3::prelude::*; +use pyo3::types::PyList; + +fn example<'py>(py: Python<'py>) -> PyResult<()> { + let x: Bound<'py, PyList> = PyList::empty(py); + x.append(1)?; + let y: Bound<'py, PyList> = x.clone(); // y is a new reference to the same list + drop(x); // release the original reference x + Ok(()) +} +# Python::attach(example).unwrap(); +``` + +Or, without the type annotations: + +```rust +use pyo3::prelude::*; +use pyo3::types::PyList; + +fn example(py: Python<'_>) -> PyResult<()> { + let x = PyList::empty(py); + x.append(1)?; + let y = x.clone(); + drop(x); + Ok(()) +} +# Python::attach(example).unwrap(); +``` + +#### Function argument lifetimes + +Because the `'py` lifetime often appears in many function arguments as part of the `Bound<'py, T>` smart pointer, the Rust compiler will often require annotations of input and output lifetimes. +This occurs when the function output has at least one lifetime, and there is more than one lifetime present on the inputs. + +To demonstrate, consider this function which takes accepts Python objects and applies the [Python `+` operation][PyAnyMethods::add] to them: + +```rust,compile_fail +# use pyo3::prelude::*; +fn add(left: &'_ Bound<'_, PyAny>, right: &'_ Bound<'_, PyAny>) -> PyResult> { + left.add(right) +} +``` + +Because the Python `+` operation might raise an exception, this function returns `PyResult>`. +It doesn't need ownership of the inputs, so it takes `&Bound<'_, PyAny>` shared references. +To demonstrate the point, all lifetimes have used the wildcard `'_` to allow the Rust compiler to attempt to infer them. +Because there are four input lifetimes (two lifetimes of the shared references, and two `'py` lifetimes unnamed inside the `Bound<'_, PyAny>` pointers), the compiler cannot reason about which must be connected to the output. + +The correct way to solve this is to add the `'py` lifetime as a parameter for the function, and name all the `'py` lifetimes inside the `Bound<'py, PyAny>` smart pointers. +For the shared references, it's also fine to reduce `&'_` to just `&`. +The working end result is below: + +```rust +# use pyo3::prelude::*; +fn add<'py>( + left: &Bound<'py, PyAny>, + right: &Bound<'py, PyAny>, +) -> PyResult> { + left.add(right) +} +# Python::attach(|py| { +# let s = pyo3::types::PyString::new(py, "s"); +# assert!(add(&s, &s).unwrap().eq("ss").unwrap()); +# }) +``` + +If naming the `'py` lifetime adds unwanted complexity to the function signature, it is also acceptable to return `Py`, which has no lifetime. +The cost is instead paid by a slight increase in implementation complexity, as seen by the introduction of a call to [`Bound::unbind`]: + +```rust +# use pyo3::prelude::*; +fn add(left: &Bound<'_, PyAny>, right: &Bound<'_, PyAny>) -> PyResult> { + let output: Bound<'_, PyAny> = left.add(right)?; + Ok(output.unbind()) +} +# Python::attach(|py| { +# let s = pyo3::types::PyString::new(py, "s"); +# assert!(add(&s, &s).unwrap().bind(py).eq("ss").unwrap()); +# }) +``` + +### `Borrowed<'a, 'py, T>` + +[`Borrowed<'a, 'py, T>`][Borrowed] is an advanced type used just occasionally at the edge of interaction with the Python interpreter. +It can be thought of as analogous to the shared reference `&'a Bound<'py, T>`. +The difference is that `Borrowed<'a, 'py, T>` is just a smart pointer rather than a reference-to-a-smart-pointer, which is a helpful reduction in indirection in specific interactions with the Python interpreter. + +`Borrowed<'a, 'py, T>` dereferences to `Bound<'py, T>`, so all methods on `Bound<'py, T>` are available on `Borrowed<'a, 'py, T>`. + +An example where `Borrowed<'a, 'py, T>` is used is in [`PyTupleMethods::get_borrowed_item`]({{#PYO3_DOCS_URL}}/pyo3/types/trait.PyTupleMethods.html#tymethod.get_item): + +```rust +use pyo3::prelude::*; +use pyo3::types::PyTuple; + +# fn example<'py>(py: Python<'py>) -> PyResult<()> { +// Create a new tuple with the elements (0, 1, 2) +let t = PyTuple::new(py, [0, 1, 2])?; +for i in 0..=2 { + let entry: Borrowed<'_, 'py, PyAny> = t.get_borrowed_item(i)?; + // `PyAnyMethods::extract` is available on `Borrowed` + // via the dereference to `Bound` + let value: usize = entry.extract()?; + assert_eq!(i, value); +} +# Ok(()) +# } +# Python::attach(example).unwrap(); +``` + +### Casting between smart pointer types + +To convert between `Py` and `Bound<'py, T>` use the `bind()` / `into_bound()` methods. +Use the `as_unbound()` / `unbind()` methods to go back from `Bound<'py, T>` to `Py`. + +```rust,ignore +let obj: Py = ...; +let bound: &Bound<'py, PyAny> = obj.bind(py); +let bound: Bound<'py, PyAny> = obj.into_bound(py); + +let obj: &Py = bound.as_unbound(); +let obj: Py = bound.unbind(); +``` + +To convert between `Bound<'py, T>` and `Borrowed<'a, 'py, T>` use the `as_borrowed()` method. +`Borrowed<'a, 'py, T>` has a deref coercion to `Bound<'py, T>`. +Use the `to_owned()` method to increment the Python reference count and to create a new `Bound<'py, T>` from the `Borrowed<'a, 'py, T>`. + +```rust,ignore +let bound: Bound<'py, PyAny> = ...; +let borrowed: Borrowed<'_, 'py, PyAny> = bound.as_borrowed(); + +// deref coercion +let bound: &Bound<'py, PyAny> = &borrowed; + +// create a new Bound by increase the Python reference count +let bound: Bound<'py, PyAny> = borrowed.to_owned(); +``` + +To convert between `Py` and `Borrowed<'a, 'py, T>` use the `bind_borrowed()` method. +Use either `as_unbound()` or `.to_owned().unbind()` to go back to `Py` from `Borrowed<'a, 'py, T>`, via `Bound<'py, T>`. + +```rust,ignore +let obj: Py = ...; +let borrowed: Borrowed<'_, 'py, PyAny> = bound.as_borrowed(); + +// via deref coercion to Bound and then using Bound::as_unbound +let obj: &Py = borrowed.as_unbound(); + +// via a new Bound by increasing the Python reference count, and unbind it +let obj: Py = borrowed.to_owned().unbind(). +``` + +## Concrete Python types + +In all of `Py`, `Bound<'py, T>`, and `Borrowed<'a, 'py, T>`, the type parameter `T` denotes the type of the Python object referred to by the smart pointer. + +This parameter `T` can be filled by: + +- [`PyAny`][PyAny], which represents any Python object, +- Native Python types such as `PyList`, `PyTuple`, and `PyDict`, and +- [`#[pyclass]`][pyclass] types defined from Rust + +The following subsections covers some further detail about how to work with these types: + +- the APIs that are available for these concrete types, +- how to cast `Bound<'py, T>` to a specific concrete type, and +- how to get Rust data out of a `Bound<'py, T>`. + +### Using APIs for concrete Python types + +Each concrete Python type such as `PyAny`, `PyTuple` and `PyDict` exposes its API on the corresponding bound smart pointer `Bound<'py, PyAny>`, `Bound<'py, PyTuple>` and `Bound<'py, PyDict>`. + +Each type's API is exposed as a trait: [`PyAnyMethods`], [`PyTupleMethods`], [`PyDictMethods`], and so on for all concrete types. +Using traits rather than associated methods on the `Bound` smart pointer is done for a couple of reasons: + +- Clarity of documentation: each trait gets its own documentation page in the PyO3 API docs. + If all methods were on the `Bound` smart pointer directly, the vast majority of PyO3's API would be on a single, extremely long, documentation page. +- Consistency: downstream code implementing Rust APIs for existing Python types can also follow this pattern of using a trait. + Downstream code would not be allowed to add new associated methods directly on the `Bound` type. +- Future design: it is hoped that a future Rust with [arbitrary self types](https://github.com/rust-lang/rust/issues/44874) will remove the need for these traits in favour of placing the methods directly on `PyAny`, `PyTuple`, `PyDict`, and so on. + +These traits are all included in the `pyo3::prelude` module, so with the glob import `use pyo3::prelude::*` the full PyO3 API is made available to downstream code. + +The following function accesses the first item in the input Python list, using the `.get_item()` method from the `PyListMethods` trait: + +```rust +use pyo3::prelude::*; +use pyo3::types::PyList; + +fn get_first_item<'py>(list: &Bound<'py, PyList>) -> PyResult> { + list.get_item(0) +} +# Python::attach(|py| { +# let l = PyList::new(py, ["hello world"]).unwrap(); +# assert!(get_first_item(&l).unwrap().eq("hello world").unwrap()); +# }) +``` + +### Casting between Python object types + +To cast `Bound<'py, T>` smart pointers to some other type, use the [`.cast()`][Bound::cast] family of functions. +This converts `&Bound<'py, T>` to a different `&Bound<'py, U>`, without transferring ownership. +There is also [`.cast_into()`][Bound::cast_into] to convert `Bound<'py, T>` to `Bound<'py, U>` with transfer of ownership. +These methods are available for all types `T` which implement the [`PyTypeCheck`] trait. + +Casting to `Bound<'py, PyAny>` can be done with `.as_any()` or `.into_any()`. + +For example, the following snippet shows how to cast `Bound<'py, PyAny>` to `Bound<'py, PyTuple>`: + +```rust +# use pyo3::prelude::*; +# use pyo3::types::PyTuple; +# fn example<'py>(py: Python<'py>) -> PyResult<()> { +// create a new Python `tuple`, and use `.into_any()` to erase the type +let obj: Bound<'py, PyAny> = PyTuple::empty(py).into_any(); + +// use `.cast()` to cast to `PyTuple` without transferring ownership +let _: &Bound<'py, PyTuple> = obj.cast()?; + +// use `.cast_into()` to cast to `PyTuple` with transfer of ownership +let _: Bound<'py, PyTuple> = obj.cast_into()?; +# Ok(()) +# } +# Python::attach(example).unwrap() +``` + +Custom [`#[pyclass]`][pyclass] types implement [`PyTypeCheck`], so `.cast()` also works for these types. +The snippet below is the same as the snippet above casting instead to a custom type `MyClass`: + +```rust +use pyo3::prelude::*; + +#[pyclass] +struct MyClass {} + +# fn example<'py>(py: Python<'py>) -> PyResult<()> { +// create a new Python `tuple`, and use `.into_any()` to erase the type +let obj: Bound<'py, PyAny> = Bound::new(py, MyClass {})?.into_any(); + +// use `.cast()` to cast to `MyClass` without transferring ownership +let _: &Bound<'py, MyClass> = obj.cast()?; + +// use `.cast_into()` to cast to `MyClass` with transfer of ownership +let _: Bound<'py, MyClass> = obj.cast_into()?; +# Ok(()) +# } +# Python::attach(example).unwrap() +``` + +### Extracting Rust data from Python objects + +To extract Rust data from Python objects, use [`.extract()`][PyAnyMethods::extract] instead of `.cast()`. +This method is available for all types which implement the [`FromPyObject`] trait. + +For example, the following snippet extracts a Rust tuple of integers from a Python tuple: + +```rust +# use pyo3::prelude::*; +# use pyo3::types::PyTuple; +# fn example<'py>(py: Python<'py>) -> PyResult<()> { +// create a new Python `tuple`, and use `.into_any()` to erase the type +let obj: Bound<'py, PyAny> = PyTuple::new(py, [1, 2, 3])?.into_any(); + +// extracting the Python `tuple` to a rust `(i32, i32, i32)` tuple +let (x, y, z) = obj.extract::<(i32, i32, i32)>()?; +assert_eq!((x, y, z), (1, 2, 3)); +# Ok(()) +# } +# Python::attach(example).unwrap() +``` + +To avoid copying data, [`#[pyclass]`][pyclass] types can directly reference Rust data stored within the Python objects without needing to `.extract()`. +See the [corresponding documentation in the class section of the guide](./class.md#bound-and-interior-mutability) for more detail. + +[Bound]: {{#PYO3_DOCS_URL}}/pyo3/struct.Bound.html +[`Bound::unbind`]: {{#PYO3_DOCS_URL}}/pyo3/struct.Bound.html#method.unbind +[Py]: {{#PYO3_DOCS_URL}}/pyo3/struct.Py.html +[PyAnyMethods::add]: {{#PYO3_DOCS_URL}}/pyo3/types/trait.PyAnyMethods.html#tymethod.add +[PyAnyMethods::extract]: {{#PYO3_DOCS_URL}}/pyo3/types/trait.PyAnyMethods.html#tymethod.extract +[Bound::cast]: {{#PYO3_DOCS_URL}}/pyo3/struct.Bound.html#method.cast +[Bound::cast_into]: {{#PYO3_DOCS_URL}}/pyo3/struct.Bound.html#method.cast_into +[`PyTypeCheck`]: {{#PYO3_DOCS_URL}}/pyo3/type_object/trait.PyTypeCheck.html +[`PyAnyMethods`]: {{#PYO3_DOCS_URL}}/pyo3/types/trait.PyAnyMethods.html +[`PyDictMethods`]: {{#PYO3_DOCS_URL}}/pyo3/types/trait.PyDictMethods.html +[`PyTupleMethods`]: {{#PYO3_DOCS_URL}}/pyo3/types/trait.PyTupleMethods.html +[pyclass]: class.md +[Borrowed]: {{#PYO3_DOCS_URL}}/pyo3/struct.Borrowed.html +[Drop]: https://doc.rust-lang.org/std/ops/trait.Drop.html +[PyAny]: {{#PYO3_DOCS_URL}}/pyo3/types/struct.PyAny.html +[`FromPyObject`]: {{#PYO3_DOCS_URL}}/pyo3/conversion/trait.FromPyObject.html diff --git a/vendor/pyo3/guide/theme/tabs.css b/vendor/pyo3/guide/theme/tabs.css new file mode 100644 index 0000000..8712b85 --- /dev/null +++ b/vendor/pyo3/guide/theme/tabs.css @@ -0,0 +1,25 @@ +.mdbook-tabs { + display: flex; +} + +.mdbook-tab { + background-color: var(--table-alternate-bg); + padding: 0.5rem 1rem; + cursor: pointer; + border: none; + font-size: 1.6rem; + line-height: 1.45em; +} + +.mdbook-tab.active { + background-color: var(--table-header-bg); + font-weight: bold; +} + +.mdbook-tab-content { + padding: 1rem 0rem; +} + +.mdbook-tab-content table { + margin: unset; +} diff --git a/vendor/pyo3/guide/theme/tabs.js b/vendor/pyo3/guide/theme/tabs.js new file mode 100644 index 0000000..8ba5e87 --- /dev/null +++ b/vendor/pyo3/guide/theme/tabs.js @@ -0,0 +1,75 @@ +/** + * Change active tab of tabs. + * + * @param {Element} container + * @param {string} name + */ +const changeTab = (container, name) => { + for (const child of container.children) { + if (!(child instanceof HTMLElement)) { + continue; + } + + if (child.classList.contains('mdbook-tabs')) { + for (const tab of child.children) { + if (!(tab instanceof HTMLElement)) { + continue; + } + + if (tab.dataset.tabname === name) { + tab.classList.add('active'); + } else { + tab.classList.remove('active'); + } + } + } else if (child.classList.contains('mdbook-tab-content')) { + if (child.dataset.tabname === name) { + child.classList.remove('hidden'); + } else { + child.classList.add('hidden'); + } + } + } +}; + +document.addEventListener('DOMContentLoaded', () => { + const tabs = document.querySelectorAll('.mdbook-tab'); + for (const tab of tabs) { + tab.addEventListener('click', () => { + if (!(tab instanceof HTMLElement)) { + return; + } + + if (!tab.parentElement || !tab.parentElement.parentElement) { + return; + } + + const container = tab.parentElement.parentElement; + const name = tab.dataset.tabname; + const global = container.dataset.tabglobal; + + changeTab(container, name); + + if (global) { + localStorage.setItem(`mdbook-tabs-${global}`, name); + + const globalContainers = document.querySelectorAll( + `.mdbook-tabs-container[data-tabglobal="${global}"]` + ); + for (const globalContainer of globalContainers) { + changeTab(globalContainer, name); + } + } + }); + } + + const containers = document.querySelectorAll('.mdbook-tabs-container[data-tabglobal]'); + for (const container of containers) { + const global = container.dataset.tabglobal; + + const name = localStorage.getItem(`mdbook-tabs-${global}`); + if (name && document.querySelector(`.mdbook-tab[data-tabname=${name}]`)) { + changeTab(container, name); + } + } +}); diff --git a/vendor/pyo3/newsfragments/.gitignore b/vendor/pyo3/newsfragments/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/vendor/pyo3/pyo3-runtime/LICENSE-APACHE b/vendor/pyo3/pyo3-runtime/LICENSE-APACHE new file mode 100644 index 0000000..72207b8 --- /dev/null +++ b/vendor/pyo3/pyo3-runtime/LICENSE-APACHE @@ -0,0 +1,178 @@ +Copyright (c) 2017-present PyO3 Project and Contributors. https://github.com/PyO3 + + 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/pyo3/pyo3-runtime/LICENSE-MIT b/vendor/pyo3/pyo3-runtime/LICENSE-MIT new file mode 100644 index 0000000..cd0ad00 --- /dev/null +++ b/vendor/pyo3/pyo3-runtime/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2023-present PyO3 Project and Contributors. https://github.com/PyO3 + +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/pyo3/pyo3-runtime/README.md b/vendor/pyo3/pyo3-runtime/README.md new file mode 100644 index 0000000..6863c09 --- /dev/null +++ b/vendor/pyo3/pyo3-runtime/README.md @@ -0,0 +1 @@ +Coming soon! diff --git a/vendor/pyo3/pyo3-runtime/pyproject.toml b/vendor/pyo3/pyo3-runtime/pyproject.toml new file mode 100644 index 0000000..dd6d0d5 --- /dev/null +++ b/vendor/pyo3/pyo3-runtime/pyproject.toml @@ -0,0 +1,33 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "pyo3-runtime" +dynamic = ["version"] +description = '' +readme = "README.md" +requires-python = ">=3.8" +license = "MIT OR Apache-2.0" +keywords = [] +authors = [ + { name = "David Hewitt", email = "1939362+davidhewitt@users.noreply.github.com" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Programming Language :: Python", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] +dependencies = [] + +[project.urls] +Homepage = "https://github.com/PyO3/pyo3" + +[tool.hatch.version] +path = "src/pyo3_runtime/__init__.py" diff --git a/vendor/pyo3/pyo3-runtime/src/pyo3_runtime/__init__.py b/vendor/pyo3/pyo3-runtime/src/pyo3_runtime/__init__.py new file mode 100644 index 0000000..f102a9c --- /dev/null +++ b/vendor/pyo3/pyo3-runtime/src/pyo3_runtime/__init__.py @@ -0,0 +1 @@ +__version__ = "0.0.1" diff --git a/vendor/pyo3/pyo3-runtime/tests/__init__.py b/vendor/pyo3/pyo3-runtime/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/vendor/pyo3/src/buffer.rs b/vendor/pyo3/src/buffer.rs new file mode 100644 index 0000000..915375f --- /dev/null +++ b/vendor/pyo3/src/buffer.rs @@ -0,0 +1,1083 @@ +// TODO https://github.com/PyO3/pyo3/issues/5487 +#![allow(clippy::undocumented_unsafe_blocks)] +#![cfg(any(not(Py_LIMITED_API), Py_3_11))] +// Copyright (c) 2017 Daniel Grunwald +// +// 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. + +//! `PyBuffer` implementation +#[cfg(feature = "experimental-inspect")] +use crate::inspect::{type_hint_identifier, PyStaticExpr}; +use crate::{err, exceptions::PyBufferError, ffi, FromPyObject, PyAny, PyResult, Python}; +use crate::{Borrowed, Bound, PyErr}; +use core::ffi::{ + c_char, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint, c_ulong, c_ulonglong, + c_ushort, c_void, +}; +use core::marker::{PhantomData, PhantomPinned}; +use core::pin::Pin; +use core::ptr::NonNull; +use core::{cell, mem, ptr, slice}; +use core::{ffi::CStr, fmt::Debug}; + +/// A typed form of [`PyUntypedBuffer`]. +#[repr(transparent)] +pub struct PyBuffer(PyUntypedBuffer, PhantomData<[T]>); + +/// Allows access to the underlying buffer used by a python object such as `bytes`, `bytearray` or `array.array`. +#[repr(transparent)] +pub struct PyUntypedBuffer( + // It is common for exporters filling `Py_buffer` struct to make it self-referential, e.g. see + // implementation of + // [`PyBuffer_FillInfo`](https://github.com/python/cpython/blob/2fd43a1ffe4ff1f6c46f6045bc327d6085c40fbf/Objects/abstract.c#L798-L802). + // + // Therefore we use `Pin>` to document for ourselves that the memory address of the `Py_buffer` is expected to be stable + Pin>, +); + +/// Wrapper around `ffi::Py_buffer` to be `!Unpin`. +#[repr(transparent)] +struct RawBuffer(ffi::Py_buffer, PhantomPinned); + +// PyBuffer send & sync guarantees are upheld by Python. +unsafe impl Send for PyUntypedBuffer {} +unsafe impl Sync for PyUntypedBuffer {} + +impl Debug for PyBuffer { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + debug_buffer("PyBuffer", &self.0, f) + } +} + +impl Debug for PyUntypedBuffer { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + debug_buffer("PyUntypedBuffer", self, f) + } +} + +fn debug_buffer( + name: &str, + b: &PyUntypedBuffer, + f: &mut core::fmt::Formatter<'_>, +) -> core::fmt::Result { + let raw = b.raw(); + f.debug_struct(name) + .field("buf", &raw.buf) + .field("obj", &raw.obj) + .field("len", &raw.len) + .field("itemsize", &raw.itemsize) + .field("readonly", &raw.readonly) + .field("ndim", &raw.ndim) + .field("format", &b.format()) + .field("shape", &b.shape()) + .field("strides", &b.strides()) + .field("suboffsets", &b.suboffsets()) + .field("internal", &raw.internal) + .finish() +} + +/// Represents the type of a Python buffer element. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum ElementType { + /// A signed integer type. + SignedInteger { + /// The width of the signed integer in bytes. + bytes: usize, + }, + /// An unsigned integer type. + UnsignedInteger { + /// The width of the unsigned integer in bytes. + bytes: usize, + }, + /// A boolean type. + Bool, + /// A float type. + Float { + /// The width of the float in bytes. + bytes: usize, + }, + /// An unknown type. This may occur when parsing has failed. + Unknown, +} + +impl ElementType { + /// Determines the `ElementType` from a Python `struct` module format string. + /// + /// See for more information + /// about struct format strings. + pub fn from_format(format: &CStr) -> ElementType { + match format.to_bytes() { + [size] | [b'@', size] => native_element_type_from_type_char(*size), + [b'=' | b'<' | b'>' | b'!', size] => standard_element_type_from_type_char(*size), + _ => ElementType::Unknown, + } + } +} + +fn native_element_type_from_type_char(type_char: u8) -> ElementType { + use self::ElementType::*; + match type_char { + b'c' => UnsignedInteger { + bytes: mem::size_of::(), + }, + b'b' => SignedInteger { + bytes: mem::size_of::(), + }, + b'B' => UnsignedInteger { + bytes: mem::size_of::(), + }, + b'?' => Bool, + b'h' => SignedInteger { + bytes: mem::size_of::(), + }, + b'H' => UnsignedInteger { + bytes: mem::size_of::(), + }, + b'i' => SignedInteger { + bytes: mem::size_of::(), + }, + b'I' => UnsignedInteger { + bytes: mem::size_of::(), + }, + b'l' => SignedInteger { + bytes: mem::size_of::(), + }, + b'L' => UnsignedInteger { + bytes: mem::size_of::(), + }, + b'q' => SignedInteger { + bytes: mem::size_of::(), + }, + b'Q' => UnsignedInteger { + bytes: mem::size_of::(), + }, + b'n' => SignedInteger { + bytes: mem::size_of::(), + }, + b'N' => UnsignedInteger { + bytes: mem::size_of::(), + }, + b'e' => Float { bytes: 2 }, + b'f' => Float { bytes: 4 }, + b'd' => Float { bytes: 8 }, + _ => Unknown, + } +} + +fn standard_element_type_from_type_char(type_char: u8) -> ElementType { + use self::ElementType::*; + match type_char { + b'c' | b'B' => UnsignedInteger { bytes: 1 }, + b'b' => SignedInteger { bytes: 1 }, + b'?' => Bool, + b'h' => SignedInteger { bytes: 2 }, + b'H' => UnsignedInteger { bytes: 2 }, + b'i' | b'l' => SignedInteger { bytes: 4 }, + b'I' | b'L' => UnsignedInteger { bytes: 4 }, + b'q' => SignedInteger { bytes: 8 }, + b'Q' => UnsignedInteger { bytes: 8 }, + b'e' => Float { bytes: 2 }, + b'f' => Float { bytes: 4 }, + b'd' => Float { bytes: 8 }, + _ => Unknown, + } +} + +#[cfg(target_endian = "little")] +fn is_matching_endian(c: u8) -> bool { + c == b'@' || c == b'=' || c == b'>' +} + +#[cfg(target_endian = "big")] +fn is_matching_endian(c: u8) -> bool { + c == b'@' || c == b'=' || c == b'>' || c == b'!' +} + +/// Trait implemented for possible element types of `PyBuffer`. +/// +/// # Safety +/// +/// This trait must only be implemented for types which represent valid elements of Python buffers. +pub unsafe trait Element: Copy { + /// Gets whether the element specified in the format string is potentially compatible. + /// Alignment and size are checked separately from this function. + fn is_compatible_format(format: &CStr) -> bool; +} + +impl FromPyObject<'_, '_> for PyBuffer { + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = type_hint_identifier!("collections.abc", "Buffer"); + + fn extract(obj: Borrowed<'_, '_, PyAny>) -> Result, Self::Error> { + Self::get(&obj) + } +} + +impl PyBuffer { + /// Gets the underlying buffer from the specified python object. + pub fn get(obj: &Bound<'_, PyAny>) -> PyResult { + PyUntypedBuffer::get(obj)?.into_typed() + } + + /// Gets the buffer memory as a slice. + /// + /// This function succeeds if: + /// * the buffer format is compatible with `T` + /// * alignment and size of buffer elements is matching the expectations for type `T` + /// * the buffer is C-style contiguous + /// + /// The returned slice uses type `Cell` because it's theoretically possible for any call into the Python runtime + /// to modify the values in the slice. + pub fn as_slice<'a>(&'a self, _py: Python<'a>) -> Option<&'a [ReadOnlyCell]> { + if self.is_c_contiguous() { + unsafe { + Some(slice::from_raw_parts( + self.raw().buf.cast(), + self.item_count(), + )) + } + } else { + None + } + } + + /// Gets the buffer memory as a slice. + /// + /// This function succeeds if: + /// * the buffer is not read-only + /// * the buffer format is compatible with `T` + /// * alignment and size of buffer elements is matching the expectations for type `T` + /// * the buffer is C-style contiguous + /// + /// The returned slice uses type `Cell` because it's theoretically possible for any call into the Python runtime + /// to modify the values in the slice. + pub fn as_mut_slice<'a>(&'a self, _py: Python<'a>) -> Option<&'a [cell::Cell]> { + if !self.readonly() && self.is_c_contiguous() { + unsafe { + Some(slice::from_raw_parts( + self.raw().buf.cast(), + self.item_count(), + )) + } + } else { + None + } + } + + /// Gets the buffer memory as a slice. + /// + /// This function succeeds if: + /// * the buffer format is compatible with `T` + /// * alignment and size of buffer elements is matching the expectations for type `T` + /// * the buffer is Fortran-style contiguous + /// + /// The returned slice uses type `Cell` because it's theoretically possible for any call into the Python runtime + /// to modify the values in the slice. + pub fn as_fortran_slice<'a>(&'a self, _py: Python<'a>) -> Option<&'a [ReadOnlyCell]> { + if mem::size_of::() == self.item_size() && self.is_fortran_contiguous() { + unsafe { + Some(slice::from_raw_parts( + self.raw().buf.cast(), + self.item_count(), + )) + } + } else { + None + } + } + + /// Gets the buffer memory as a slice. + /// + /// This function succeeds if: + /// * the buffer is not read-only + /// * the buffer format is compatible with `T` + /// * alignment and size of buffer elements is matching the expectations for type `T` + /// * the buffer is Fortran-style contiguous + /// + /// The returned slice uses type `Cell` because it's theoretically possible for any call into the Python runtime + /// to modify the values in the slice. + pub fn as_fortran_mut_slice<'a>(&'a self, _py: Python<'a>) -> Option<&'a [cell::Cell]> { + if !self.readonly() && self.is_fortran_contiguous() { + unsafe { + Some(slice::from_raw_parts( + self.raw().buf.cast(), + self.item_count(), + )) + } + } else { + None + } + } + + /// Copies the buffer elements to the specified slice. + /// If the buffer is multi-dimensional, the elements are written in C-style order. + /// + /// * Fails if the slice does not have the correct length (`buf.item_count()`). + /// * Fails if the buffer format is not compatible with type `T`. + /// + /// To check whether the buffer format is compatible before calling this method, + /// you can use `::is_compatible_format(buf.format())`. + /// Alternatively, `match buffer::ElementType::from_format(buf.format())`. + pub fn copy_to_slice(&self, py: Python<'_>, target: &mut [T]) -> PyResult<()> { + self._copy_to_slice(py, target, b'C') + } + + /// Copies the buffer elements to the specified slice. + /// If the buffer is multi-dimensional, the elements are written in Fortran-style order. + /// + /// * Fails if the slice does not have the correct length (`buf.item_count()`). + /// * Fails if the buffer format is not compatible with type `T`. + /// + /// To check whether the buffer format is compatible before calling this method, + /// you can use `::is_compatible_format(buf.format())`. + /// Alternatively, `match buffer::ElementType::from_format(buf.format())`. + pub fn copy_to_fortran_slice(&self, py: Python<'_>, target: &mut [T]) -> PyResult<()> { + self._copy_to_slice(py, target, b'F') + } + + fn _copy_to_slice(&self, py: Python<'_>, target: &mut [T], fort: u8) -> PyResult<()> { + if mem::size_of_val(target) != self.len_bytes() { + return Err(PyBufferError::new_err(format!( + "slice to copy to (of length {}) does not match buffer length of {}", + target.len(), + self.item_count() + ))); + } + + err::error_on_minusone(py, unsafe { + ffi::PyBuffer_ToContiguous( + target.as_mut_ptr().cast(), + #[cfg(Py_3_11)] + self.raw(), + #[cfg(not(Py_3_11))] + ptr::from_ref(self.raw()).cast_mut(), + self.raw().len, + fort as core::ffi::c_char, + ) + }) + } + + /// Copies the buffer elements to a newly allocated vector. + /// If the buffer is multi-dimensional, the elements are written in C-style order. + /// + /// Fails if the buffer format is not compatible with type `T`. + pub fn to_vec(&self, py: Python<'_>) -> PyResult> { + self._to_vec(py, b'C') + } + + /// Copies the buffer elements to a newly allocated vector. + /// If the buffer is multi-dimensional, the elements are written in Fortran-style order. + /// + /// Fails if the buffer format is not compatible with type `T`. + pub fn to_fortran_vec(&self, py: Python<'_>) -> PyResult> { + self._to_vec(py, b'F') + } + + fn _to_vec(&self, py: Python<'_>, fort: u8) -> PyResult> { + let item_count = self.item_count(); + let mut vec: Vec = Vec::with_capacity(item_count); + + // Copy the buffer into the uninitialized space in the vector. + // Due to T:Copy, we don't need to be concerned with Drop impls. + err::error_on_minusone(py, unsafe { + ffi::PyBuffer_ToContiguous( + vec.as_mut_ptr().cast(), + #[cfg(Py_3_11)] + self.raw(), + #[cfg(not(Py_3_11))] + ptr::from_ref(self.raw()).cast_mut(), + self.raw().len, + fort as core::ffi::c_char, + ) + })?; + // set vector length to mark the now-initialized space as usable + unsafe { vec.set_len(item_count) }; + Ok(vec) + } + + /// Copies the specified slice into the buffer. + /// If the buffer is multi-dimensional, the elements in the slice are expected to be in C-style order. + /// + /// * Fails if the buffer is read-only. + /// * Fails if the slice does not have the correct length (`buf.item_count()`). + /// * Fails if the buffer format is not compatible with type `T`. + /// + /// To check whether the buffer format is compatible before calling this method, + /// use `::is_compatible_format(buf.format())`. + /// Alternatively, `match buffer::ElementType::from_format(buf.format())`. + pub fn copy_from_slice(&self, py: Python<'_>, source: &[T]) -> PyResult<()> { + self._copy_from_slice(py, source, b'C') + } + + /// Copies the specified slice into the buffer. + /// If the buffer is multi-dimensional, the elements in the slice are expected to be in Fortran-style order. + /// + /// * Fails if the buffer is read-only. + /// * Fails if the slice does not have the correct length (`buf.item_count()`). + /// * Fails if the buffer format is not compatible with type `T`. + /// + /// To check whether the buffer format is compatible before calling this method, + /// use `::is_compatible_format(buf.format())`. + /// Alternatively, `match buffer::ElementType::from_format(buf.format())`. + pub fn copy_from_fortran_slice(&self, py: Python<'_>, source: &[T]) -> PyResult<()> { + self._copy_from_slice(py, source, b'F') + } + + fn _copy_from_slice(&self, py: Python<'_>, source: &[T], fort: u8) -> PyResult<()> { + if self.readonly() { + return Err(PyBufferError::new_err("cannot write to read-only buffer")); + } else if mem::size_of_val(source) != self.len_bytes() { + return Err(PyBufferError::new_err(format!( + "slice to copy from (of length {}) does not match buffer length of {}", + source.len(), + self.item_count() + ))); + } + + err::error_on_minusone(py, unsafe { + ffi::PyBuffer_FromContiguous( + #[cfg(Py_3_11)] + self.raw(), + #[cfg(not(Py_3_11))] + ptr::from_ref(self.raw()).cast_mut(), + #[cfg(Py_3_11)] + { + source.as_ptr().cast() + }, + #[cfg(not(Py_3_11))] + { + source.as_ptr().cast::().cast_mut() + }, + self.raw().len, + fort as core::ffi::c_char, + ) + }) + } +} + +impl core::ops::Deref for PyBuffer { + type Target = PyUntypedBuffer; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl PyUntypedBuffer { + /// Gets the underlying buffer from the specified python object. + pub fn get(obj: &Bound<'_, PyAny>) -> PyResult { + let buf = { + let mut buf = Box::::new_uninit(); + // SAFETY: RawBuffer is `#[repr(transparent)]` around FFI struct + err::error_on_minusone(obj.py(), unsafe { + ffi::PyObject_GetBuffer( + obj.as_ptr(), + buf.as_mut_ptr().cast::(), + ffi::PyBUF_FULL_RO, + ) + })?; + // Safety: buf is initialized by PyObject_GetBuffer. + unsafe { buf.assume_init() } + }; + // Create PyBuffer immediately so that if validation checks fail, the PyBuffer::drop code + // will call PyBuffer_Release (thus avoiding any leaks). + let buf = Self(Pin::from(buf)); + let raw = buf.raw(); + + if raw.shape.is_null() { + Err(PyBufferError::new_err("shape is null")) + } else if raw.strides.is_null() { + Err(PyBufferError::new_err("strides is null")) + } else { + Ok(buf) + } + } + + /// Returns a `[PyBuffer]` instance if the buffer can be interpreted as containing elements of type `T`. + pub fn into_typed(self) -> PyResult> { + self.ensure_compatible_with::()?; + Ok(PyBuffer(self, PhantomData)) + } + + /// Non-owning equivalent of [`into_typed()`][Self::into_typed]. + pub fn as_typed(&self) -> PyResult<&PyBuffer> { + self.ensure_compatible_with::()?; + // SAFETY: PyBuffer is repr(transparent) around PyUntypedBuffer + Ok(unsafe { NonNull::from(self).cast::>().as_ref() }) + } + + fn ensure_compatible_with(&self) -> PyResult<()> { + if mem::size_of::() != self.item_size() || !T::is_compatible_format(self.format()) { + Err(PyBufferError::new_err(format!( + "buffer contents are not compatible with {}", + core::any::type_name::() + ))) + } else if self.raw().buf.align_offset(mem::align_of::()) != 0 { + Err(PyBufferError::new_err(format!( + "buffer contents are insufficiently aligned for {}", + core::any::type_name::() + ))) + } else { + Ok(()) + } + } + + /// Releases the buffer object, freeing the reference to the Python object + /// which owns the buffer. + /// + /// This will automatically be called on drop. + pub fn release(self, _py: Python<'_>) { + // First move self into a ManuallyDrop, so that PyBuffer::drop will + // never be called. (It would attach to the interpreter and call PyBuffer_Release + // again.) + let mut mdself = mem::ManuallyDrop::new(self); + unsafe { + // Next, make the actual PyBuffer_Release call. + // Fine to get a mutable reference to the inner ffi::Py_buffer here, as we're destroying it. + mdself.0.release(); + + // Finally, drop the contained Pin> in place, to free the + // Box memory. + ptr::drop_in_place::>>(&mut mdself.0); + } + } + + /// Gets the pointer to the start of the buffer memory. + /// + /// Warning: the buffer memory can be mutated by other code (including + /// other Python functions, if the GIL is released, or other extension + /// modules even if the GIL is held). You must either access memory + /// atomically, or ensure there are no data races yourself. See + /// [this blog post] for more details. + /// + /// [this blog post]: https://alexgaynor.net/2022/oct/23/buffers-on-the-edge/ + #[inline] + pub fn buf_ptr(&self) -> *mut c_void { + self.raw().buf + } + + /// Returns the Python object that owns the buffer data. + /// + /// This is the object that was passed to [`PyBuffer::get()`] + /// when the buffer was created. + /// Calling this before [`release()`][Self::release] and cloning the result + /// allows you to keep the object alive after the buffer is released. + #[inline] + pub fn obj<'py>(&self, py: Python<'py>) -> Option<&Bound<'py, PyAny>> { + unsafe { Bound::ref_from_ptr_or_opt(py, &self.raw().obj).as_ref() } + } + + /// Gets a pointer to the specified item. + /// + /// If `indices.len() < self.dimensions()`, returns the start address of the sub-array at the specified dimension. + pub fn get_ptr(&self, indices: &[usize]) -> *mut c_void { + let shape = &self.shape()[..indices.len()]; + for i in 0..indices.len() { + assert!(indices[i] < shape[i]); + } + unsafe { + ffi::PyBuffer_GetPointer( + #[cfg(Py_3_11)] + self.raw(), + #[cfg(not(Py_3_11))] + ptr::from_ref(self.raw()).cast_mut(), + #[cfg(Py_3_11)] + indices.as_ptr().cast(), + #[cfg(not(Py_3_11))] + indices.as_ptr().cast_mut().cast(), + ) + } + } + + /// Gets whether the underlying buffer is read-only. + #[inline] + pub fn readonly(&self) -> bool { + self.raw().readonly != 0 + } + + /// Gets the size of a single element, in bytes. + /// Important exception: when requesting an unformatted buffer, item_size still has the value + #[inline] + pub fn item_size(&self) -> usize { + self.raw().itemsize as usize + } + + /// Gets the total number of items. + #[inline] + pub fn item_count(&self) -> usize { + (self.raw().len as usize) / (self.raw().itemsize as usize) + } + + /// `item_size() * item_count()`. + /// For contiguous arrays, this is the length of the underlying memory block. + /// For non-contiguous arrays, it is the length that the logical structure would have if it were copied to a contiguous representation. + #[inline] + pub fn len_bytes(&self) -> usize { + self.raw().len as usize + } + + /// Gets the number of dimensions. + /// + /// May be 0 to indicate a single scalar value. + #[inline] + pub fn dimensions(&self) -> usize { + self.raw().ndim as usize + } + + /// Returns an array of length `dimensions`. `shape()[i]` is the length of the array in dimension number `i`. + /// + /// May return None for single-dimensional arrays or scalar values (`dimensions() <= 1`); + /// You can call `item_count()` to get the length of the single dimension. + /// + /// Despite Python using an array of signed integers, the values are guaranteed to be non-negative. + /// However, dimensions of length 0 are possible and might need special attention. + #[inline] + pub fn shape(&self) -> &[usize] { + unsafe { slice::from_raw_parts(self.raw().shape.cast(), self.raw().ndim as usize) } + } + + /// Returns an array that holds, for each dimension, the number of bytes to skip to get to the next element in the dimension. + /// + /// Stride values can be any integer. For regular arrays, strides are usually positive, + /// but a consumer MUST be able to handle the case `strides[n] <= 0`. + #[inline] + pub fn strides(&self) -> &[isize] { + unsafe { slice::from_raw_parts(self.raw().strides, self.raw().ndim as usize) } + } + + /// An array of length ndim. + /// If `suboffsets[n] >= 0`, the values stored along the nth dimension are pointers and the suboffset value dictates how many bytes to add to each pointer after de-referencing. + /// A suboffset value that is negative indicates that no de-referencing should occur (striding in a contiguous memory block). + /// + /// If all suboffsets are negative (i.e. no de-referencing is needed), then this field must be NULL (the default value). + #[inline] + pub fn suboffsets(&self) -> Option<&[isize]> { + unsafe { + if self.raw().suboffsets.is_null() { + None + } else { + Some(slice::from_raw_parts( + self.raw().suboffsets, + self.raw().ndim as usize, + )) + } + } + } + + /// A string in struct module style syntax describing the contents of a single item. + #[inline] + pub fn format(&self) -> &CStr { + if self.raw().format.is_null() { + ffi::c_str!("B") + } else { + unsafe { CStr::from_ptr(self.raw().format) } + } + } + + /// Gets whether the buffer is contiguous in C-style order (last index varies fastest when visiting items in order of memory address). + #[inline] + pub fn is_c_contiguous(&self) -> bool { + unsafe { ffi::PyBuffer_IsContiguous(self.raw(), b'C' as core::ffi::c_char) != 0 } + } + + /// Gets whether the buffer is contiguous in Fortran-style order (first index varies fastest when visiting items in order of memory address). + #[inline] + pub fn is_fortran_contiguous(&self) -> bool { + unsafe { ffi::PyBuffer_IsContiguous(self.raw(), b'F' as core::ffi::c_char) != 0 } + } + + fn raw(&self) -> &ffi::Py_buffer { + &self.0 .0 + } +} + +impl RawBuffer { + /// Release the contents of this pinned buffer. + /// + /// # Safety + /// + /// - The buffer must not be used after calling this function. + /// - This function can only be called once. + /// - Must be attached to the interpreter. + /// + unsafe fn release(self: &mut Pin>) { + unsafe { + ffi::PyBuffer_Release(&mut Pin::get_unchecked_mut(self.as_mut()).0); + } + } +} + +impl Drop for PyUntypedBuffer { + fn drop(&mut self) { + if Python::try_attach(|_| unsafe { self.0.release() }).is_none() + && crate::internal::state::is_in_gc_traversal() + { + eprintln!("Warning: PyBuffer dropped while in GC traversal, this is a bug and will leak memory."); + } + // If `try_attach` failed and `is_in_gc_traversal()` is false, then probably the interpreter has + // already finalized and we can just assume that the underlying memory has already been freed. + // + // So we don't handle that case here. + } +} + +/// Like [core::cell::Cell], but only provides read-only access to the data. +/// +/// `&ReadOnlyCell` is basically a safe version of `*const T`: +/// The data cannot be modified through the reference, but other references may +/// be modifying the data. +#[repr(transparent)] +pub struct ReadOnlyCell(cell::UnsafeCell); + +impl ReadOnlyCell { + /// Returns a copy of the current value. + #[inline] + pub fn get(&self) -> T { + unsafe { *self.0.get() } + } + + /// Returns a pointer to the current value. + #[inline] + pub fn as_ptr(&self) -> *const T { + self.0.get() + } +} + +macro_rules! impl_element( + ($t:ty, $f:ident) => { + unsafe impl Element for $t { + fn is_compatible_format(format: &CStr) -> bool { + let slice = format.to_bytes(); + if slice.len() > 1 && !is_matching_endian(slice[0]) { + return false; + } + ElementType::from_format(format) == ElementType::$f { bytes: mem::size_of::<$t>() } + } + } + } +); + +impl_element!(u8, UnsignedInteger); +impl_element!(u16, UnsignedInteger); +impl_element!(u32, UnsignedInteger); +impl_element!(u64, UnsignedInteger); +impl_element!(usize, UnsignedInteger); +impl_element!(i8, SignedInteger); +impl_element!(i16, SignedInteger); +impl_element!(i32, SignedInteger); +impl_element!(i64, SignedInteger); +impl_element!(isize, SignedInteger); +impl_element!(f32, Float); +impl_element!(f64, Float); + +#[cfg(test)] +mod tests { + use super::*; + + use crate::ffi; + use crate::types::any::PyAnyMethods; + use crate::types::PyBytes; + use crate::Python; + + #[test] + fn test_debug() { + Python::attach(|py| { + let bytes = PyBytes::new(py, b"abcde"); + let buffer: PyBuffer = PyBuffer::get(&bytes).unwrap(); + let expected = format!( + concat!( + "PyBuffer {{ buf: {:?}, obj: {:?}, ", + "len: 5, itemsize: 1, readonly: 1, ", + "ndim: 1, format: \"B\", shape: [5], ", + "strides: [1], suboffsets: None, internal: {:?} }}", + ), + buffer.raw().buf, + buffer.raw().obj, + buffer.raw().internal + ); + let debug_repr = format!("{:?}", buffer); + assert_eq!(debug_repr, expected); + }); + } + + #[test] + fn test_element_type_from_format() { + use super::ElementType::*; + use core::mem::size_of; + + for (cstr, expected) in [ + // @ prefix goes to native_element_type_from_type_char + ( + c"@b", + SignedInteger { + bytes: size_of::(), + }, + ), + ( + c"@c", + UnsignedInteger { + bytes: size_of::(), + }, + ), + ( + c"@b", + SignedInteger { + bytes: size_of::(), + }, + ), + ( + c"@B", + UnsignedInteger { + bytes: size_of::(), + }, + ), + (c"@?", Bool), + ( + c"@h", + SignedInteger { + bytes: size_of::(), + }, + ), + ( + c"@H", + UnsignedInteger { + bytes: size_of::(), + }, + ), + ( + c"@i", + SignedInteger { + bytes: size_of::(), + }, + ), + ( + c"@I", + UnsignedInteger { + bytes: size_of::(), + }, + ), + ( + c"@l", + SignedInteger { + bytes: size_of::(), + }, + ), + ( + c"@L", + UnsignedInteger { + bytes: size_of::(), + }, + ), + ( + c"@q", + SignedInteger { + bytes: size_of::(), + }, + ), + ( + c"@Q", + UnsignedInteger { + bytes: size_of::(), + }, + ), + ( + c"@n", + SignedInteger { + bytes: size_of::(), + }, + ), + ( + c"@N", + UnsignedInteger { + bytes: size_of::(), + }, + ), + (c"@e", Float { bytes: 2 }), + (c"@f", Float { bytes: 4 }), + (c"@d", Float { bytes: 8 }), + (c"@z", Unknown), + // = prefix goes to standard_element_type_from_type_char + (c"=b", SignedInteger { bytes: 1 }), + (c"=c", UnsignedInteger { bytes: 1 }), + (c"=B", UnsignedInteger { bytes: 1 }), + (c"=?", Bool), + (c"=h", SignedInteger { bytes: 2 }), + (c"=H", UnsignedInteger { bytes: 2 }), + (c"=l", SignedInteger { bytes: 4 }), + (c"=l", SignedInteger { bytes: 4 }), + (c"=I", UnsignedInteger { bytes: 4 }), + (c"=L", UnsignedInteger { bytes: 4 }), + (c"=q", SignedInteger { bytes: 8 }), + (c"=Q", UnsignedInteger { bytes: 8 }), + (c"=e", Float { bytes: 2 }), + (c"=f", Float { bytes: 4 }), + (c"=d", Float { bytes: 8 }), + (c"=z", Unknown), + (c"=0", Unknown), + // unknown prefix -> Unknown + (c":b", Unknown), + ] { + assert_eq!( + ElementType::from_format(cstr), + expected, + "element from format &Cstr: {cstr:?}", + ); + } + } + + #[test] + fn test_compatible_size() { + // for the cast in PyBuffer::shape() + assert_eq!( + core::mem::size_of::(), + core::mem::size_of::() + ); + } + + #[test] + fn test_bytes_buffer() { + Python::attach(|py| { + let bytes = PyBytes::new(py, b"abcde"); + let buffer = PyBuffer::get(&bytes).unwrap(); + assert_eq!(buffer.dimensions(), 1); + assert_eq!(buffer.item_count(), 5); + assert_eq!(buffer.format().to_str().unwrap(), "B"); + assert_eq!(buffer.shape(), [5]); + // single-dimensional buffer is always contiguous + assert!(buffer.is_c_contiguous()); + assert!(buffer.is_fortran_contiguous()); + + let slice = buffer.as_slice(py).unwrap(); + assert_eq!(slice.len(), 5); + assert_eq!(slice[0].get(), b'a'); + assert_eq!(slice[2].get(), b'c'); + + assert_eq!(unsafe { *(buffer.get_ptr(&[1]).cast::()) }, b'b'); + + assert!(buffer.as_mut_slice(py).is_none()); + + assert!(buffer.copy_to_slice(py, &mut [0u8]).is_err()); + let mut arr = [0; 5]; + buffer.copy_to_slice(py, &mut arr).unwrap(); + assert_eq!(arr, b"abcde" as &[u8]); + + assert!(buffer.copy_from_slice(py, &[0u8; 5]).is_err()); + assert_eq!(buffer.to_vec(py).unwrap(), b"abcde"); + }); + } + + #[test] + fn test_array_buffer() { + Python::attach(|py| { + let array = py + .import("array") + .unwrap() + .call_method("array", ("f", (1.0, 1.5, 2.0, 2.5)), None) + .unwrap(); + let buffer = PyBuffer::get(&array).unwrap(); + assert_eq!(buffer.dimensions(), 1); + assert_eq!(buffer.item_count(), 4); + assert_eq!(buffer.format().to_str().unwrap(), "f"); + assert_eq!(buffer.shape(), [4]); + + // array creates a 1D contiguous buffer, so it's both C and F contiguous. This would + // be more interesting if we can come up with a 2D buffer but I think it would need a + // third-party lib or a custom class. + + // C-contiguous fns + let slice = buffer.as_slice(py).unwrap(); + assert_eq!(slice.len(), 4); + assert_eq!(slice[0].get(), 1.0); + assert_eq!(slice[3].get(), 2.5); + + let mut_slice = buffer.as_mut_slice(py).unwrap(); + assert_eq!(mut_slice.len(), 4); + assert_eq!(mut_slice[0].get(), 1.0); + mut_slice[3].set(2.75); + assert_eq!(slice[3].get(), 2.75); + + buffer + .copy_from_slice(py, &[10.0f32, 11.0, 12.0, 13.0]) + .unwrap(); + assert_eq!(slice[2].get(), 12.0); + + assert_eq!(buffer.to_vec(py).unwrap(), [10.0, 11.0, 12.0, 13.0]); + + // F-contiguous fns + let buffer = PyBuffer::get(&array).unwrap(); + let slice = buffer.as_fortran_slice(py).unwrap(); + assert_eq!(slice.len(), 4); + assert_eq!(slice[1].get(), 11.0); + + let mut_slice = buffer.as_fortran_mut_slice(py).unwrap(); + assert_eq!(mut_slice.len(), 4); + assert_eq!(mut_slice[2].get(), 12.0); + mut_slice[3].set(2.75); + assert_eq!(slice[3].get(), 2.75); + + buffer + .copy_from_fortran_slice(py, &[10.0f32, 11.0, 12.0, 13.0]) + .unwrap(); + assert_eq!(slice[2].get(), 12.0); + + assert_eq!(buffer.to_fortran_vec(py).unwrap(), [10.0, 11.0, 12.0, 13.0]); + }); + } + + #[test] + fn test_untyped_buffer() { + Python::attach(|py| { + let bytes = PyBytes::new(py, b"abcde"); + let untyped = PyUntypedBuffer::get(&bytes).unwrap(); + assert_eq!(untyped.dimensions(), 1); + assert_eq!(untyped.item_count(), 5); + assert_eq!(untyped.format().to_str().unwrap(), "B"); + assert_eq!(untyped.shape(), [5]); + + let typed: &PyBuffer = untyped.as_typed().unwrap(); + assert_eq!(typed.dimensions(), 1); + assert_eq!(typed.item_count(), 5); + assert_eq!(typed.format().to_str().unwrap(), "B"); + assert_eq!(typed.shape(), [5]); + }); + } + + #[test] + fn test_obj_getter() { + Python::attach(|py| { + let bytes = PyBytes::new(py, b"hello"); + let buf = PyUntypedBuffer::get(bytes.as_any()).unwrap(); + + // obj() returns the same object that owns the buffer + let owner = buf.obj(py).unwrap(); + assert!(owner.is_instance_of::()); + assert!(owner.is(&bytes)); + + // can keep the owner alive after releasing the buffer + let owner_ref: crate::Py = owner.clone().unbind(); + buf.release(py); + drop(bytes); + // owner_ref still valid after buffer and original are dropped + Python::attach(|py| { + let rebound = owner_ref.bind(py); + assert!(rebound.is_instance_of::()); + }); + }); + } +} diff --git a/vendor/pyo3/src/byteswriter.rs b/vendor/pyo3/src/byteswriter.rs new file mode 100644 index 0000000..d65e600 --- /dev/null +++ b/vendor/pyo3/src/byteswriter.rs @@ -0,0 +1,281 @@ +// TODO https://github.com/PyO3/pyo3/issues/5487 +#![allow(clippy::undocumented_unsafe_blocks)] + +#[cfg(feature = "experimental-inspect")] +use crate::inspect::PyStaticExpr; +#[cfg(feature = "experimental-inspect")] +use crate::PyTypeInfo; +#[cfg(not(Py_LIMITED_API))] +use crate::{ + err::error_on_minusone, + ffi::{ + self, + compat::{ + PyBytesWriter_Create, PyBytesWriter_Discard, PyBytesWriter_Finish, + PyBytesWriter_GetData, PyBytesWriter_GetSize, PyBytesWriter_Resize, + }, + }, + ffi_ptr_ext::FfiPtrExt, + py_result_ext::PyResultExt, +}; +use crate::{types::PyBytes, Bound, IntoPyObject, PyErr, PyResult, Python}; +#[cfg(not(Py_LIMITED_API))] +use core::{ + mem::ManuallyDrop, + ptr::{self, NonNull}, +}; +use std::io::IoSlice; + +pub struct PyBytesWriter<'py> { + python: Python<'py>, + #[cfg(not(Py_LIMITED_API))] + writer: NonNull, + #[cfg(Py_LIMITED_API)] + buffer: Vec, +} + +impl<'py> PyBytesWriter<'py> { + /// Create a new `PyBytesWriter` with a default initial capacity. + #[inline] + pub fn new(py: Python<'py>) -> PyResult { + Self::with_capacity(py, 0) + } + + /// Create a new `PyBytesWriter` with the specified initial capacity. + #[inline] + #[cfg_attr(Py_LIMITED_API, allow(clippy::unnecessary_wraps))] + pub fn with_capacity(py: Python<'py>, capacity: usize) -> PyResult { + cfg_select! { + not(Py_LIMITED_API) => NonNull::new(unsafe { PyBytesWriter_Create(capacity as _) }).map_or_else( + || Err(PyErr::fetch(py)), + |writer| { + let mut writer = PyBytesWriter { python: py, writer }; + if capacity > 0 { + // SAFETY: By setting the length to 0, we ensure no bytes are considered uninitialized. + unsafe { writer.set_len(0)? }; + } + Ok(writer) + }, + ), + Py_LIMITED_API => Ok(PyBytesWriter { + python: py, + buffer: Vec::with_capacity(capacity), + }) + } + } + + /// Get the current length of the internal buffer. + #[inline] + pub fn len(&self) -> usize { + cfg_select! { + not(Py_LIMITED_API) => unsafe { + PyBytesWriter_GetSize(self.writer.as_ptr()) as _ + }, + Py_LIMITED_API => self.buffer.len() + } + } + + #[inline] + #[cfg(not(Py_LIMITED_API))] + fn as_mut_ptr(&mut self) -> *mut u8 { + unsafe { PyBytesWriter_GetData(self.writer.as_ptr()) as _ } + } + + /// Set the length of the internal buffer to `new_len`. The new bytes are uninitialized. + /// + /// # Safety + /// The caller must ensure the new bytes are initialized. This will also make all pointers + /// returned by `as_mut_ptr` invalid, so the caller must not hold any references to the buffer + /// across this call. + #[inline] + #[cfg(not(Py_LIMITED_API))] + unsafe fn set_len(&mut self, new_len: usize) -> PyResult<()> { + unsafe { + error_on_minusone( + self.python, + PyBytesWriter_Resize(self.writer.as_ptr(), new_len as _), + ) + } + } +} + +impl<'py> TryFrom> for Bound<'py, PyBytes> { + type Error = PyErr; + + #[inline] + fn try_from(value: PyBytesWriter<'py>) -> Result { + let py = value.python; + cfg_select! { + // SAFETY: + // - we no longer use `value` after this call + // - `PyBytesWriter_Finish` will return a new reference to a bytes object on success + not(Py_LIMITED_API) => unsafe { + PyBytesWriter_Finish(ManuallyDrop::new(value).writer.as_ptr()) + .assume_owned_or_err(py) + .cast_into_unchecked() + }, + Py_LIMITED_API => Ok(PyBytes::new(py, &value.buffer)) + } + } +} + +impl<'py> IntoPyObject<'py> for PyBytesWriter<'py> { + type Target = PyBytes; + type Output = Bound<'py, PyBytes>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = PyBytes::TYPE_HINT; + + #[inline] + fn into_pyobject(self, _py: Python<'py>) -> Result { + self.try_into() + } +} + +#[cfg(not(Py_LIMITED_API))] +impl<'py> Drop for PyBytesWriter<'py> { + #[inline] + fn drop(&mut self) { + unsafe { PyBytesWriter_Discard(self.writer.as_ptr()) } + } +} + +#[cfg(not(Py_LIMITED_API))] +impl std::io::Write for PyBytesWriter<'_> { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.write_all(buf)?; + Ok(buf.len()) + } + + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> std::io::Result { + let len = bufs.iter().map(|b| b.len()).sum(); + let pos = self.len(); + + // SAFETY: We write the new uninitialized bytes below. + unsafe { self.set_len(self.len() + len)? } + + // SAFETY: We ensured enough capacity above and the ptr will be valid because we will not be + // resizing the buffer until we have written all the data. + let mut ptr = unsafe { self.as_mut_ptr().add(pos) }; + + for buf in bufs { + // SAFETY: We have ensured enough capacity above. + unsafe { ptr::copy_nonoverlapping(buf.as_ptr(), ptr, buf.len()) }; + + // SAFETY: We just wrote buf.len() bytes + ptr = unsafe { ptr.add(buf.len()) }; + } + Ok(len) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } + + fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> { + let len = buf.len(); + let pos = self.len(); + + // SAFETY: We write the new uninitialized bytes below. + unsafe { self.set_len(pos + len)? } + + // SAFETY: We have ensured enough capacity above. + unsafe { ptr::copy_nonoverlapping(buf.as_ptr(), self.as_mut_ptr().add(pos), len) }; + + Ok(()) + } +} + +#[cfg(Py_LIMITED_API)] +impl std::io::Write for PyBytesWriter<'_> { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.buffer.write(buf) + } + + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> std::io::Result { + self.buffer.write_vectored(bufs) + } + + fn flush(&mut self) -> std::io::Result<()> { + self.buffer.flush() + } + + fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> { + self.buffer.write_all(buf) + } + + fn write_fmt(&mut self, args: core::fmt::Arguments<'_>) -> std::io::Result<()> { + self.buffer.write_fmt(args) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::types::PyBytesMethods; + use std::io::Write; + + #[test] + fn test_io_write() { + Python::attach(|py| { + let buf = b"hallo world"; + let mut writer = PyBytesWriter::new(py).unwrap(); + assert_eq!(writer.write(buf).unwrap(), 11); + let bytes: Bound<'_, PyBytes> = writer.try_into().unwrap(); + assert_eq!(bytes.as_bytes(), buf); + }) + } + + #[test] + fn test_pre_allocated() { + Python::attach(|py| { + let buf = b"hallo world"; + let mut writer = PyBytesWriter::with_capacity(py, buf.len()).unwrap(); + assert_eq!(writer.len(), 0, "Writer position should be zero"); + assert_eq!(writer.write(buf).unwrap(), 11); + let bytes: Bound<'_, PyBytes> = writer.try_into().unwrap(); + assert_eq!(bytes.as_bytes(), buf); + }) + } + + #[test] + fn test_io_write_vectored() { + Python::attach(|py| { + let bufs = [IoSlice::new(b"hallo "), IoSlice::new(b"world")]; + let mut writer = PyBytesWriter::new(py).unwrap(); + assert_eq!(writer.write_vectored(&bufs).unwrap(), 11); + let bytes: Bound<'_, PyBytes> = writer.try_into().unwrap(); + assert_eq!(bytes.as_bytes(), b"hallo world"); + }) + } + + #[test] + fn test_io_write_vectored_large() { + Python::attach(|py| { + let large_data = vec![b'\n'; 1024]; // 1 KB + let bufs = [ + IoSlice::new(b"hallo"), + IoSlice::new(&large_data), + IoSlice::new(b"world"), + ]; + let mut writer = PyBytesWriter::new(py).unwrap(); + assert_eq!(writer.write_vectored(&bufs).unwrap(), 1034); + let bytes: Bound<'_, PyBytes> = writer.try_into().unwrap(); + assert!(bytes.as_bytes().starts_with(b"hallo\n")); + assert!(bytes.as_bytes().ends_with(b"world")); + assert_eq!(bytes.as_bytes().len(), 1034); + }) + } + + #[test] + fn test_large_data() { + Python::attach(|py| { + let mut writer = PyBytesWriter::new(py).unwrap(); + let large_data = vec![0; 1024]; // 1 KB + writer.write_all(&large_data).unwrap(); + let bytes: Bound<'_, PyBytes> = writer.try_into().unwrap(); + assert_eq!(bytes.as_bytes(), large_data.as_slice()); + }) + } +} diff --git a/vendor/pyo3/src/call.rs b/vendor/pyo3/src/call.rs new file mode 100644 index 0000000..09dd625 --- /dev/null +++ b/vendor/pyo3/src/call.rs @@ -0,0 +1,315 @@ +// TODO https://github.com/PyO3/pyo3/issues/5487 +#![allow(clippy::undocumented_unsafe_blocks)] + +//! Defines how Python calls are dispatched, see [`PyCallArgs`].for more information. + +use crate::ffi_ptr_ext::FfiPtrExt as _; +use crate::types::{PyAnyMethods as _, PyDict, PyString, PyTuple}; +use crate::{ffi, Borrowed, Bound, IntoPyObjectExt as _, Py, PyAny, PyResult}; + +pub(crate) mod private { + use super::*; + + pub trait Sealed {} + + impl Sealed for () {} + impl Sealed for Bound<'_, PyTuple> {} + impl Sealed for &'_ Bound<'_, PyTuple> {} + impl Sealed for Py {} + impl Sealed for &'_ Py {} + impl Sealed for Borrowed<'_, '_, PyTuple> {} + pub struct Token; +} + +/// This trait marks types that can be used as arguments to Python function +/// calls. +/// +/// This trait is currently implemented for Rust tuple (up to a size of 12), +/// [`Bound<'py, PyTuple>`] and [`Py`]. Custom types that are +/// convertible to `PyTuple` via `IntoPyObject` need to do so before passing it +/// to `call`. +/// +/// This trait is not intended to used by downstream crates directly. As such it +/// has no publicly available methods and cannot be implemented outside of +/// `pyo3`. The corresponding public API is available through [`call`] +/// ([`call0`], [`call1`] and friends) on [`PyAnyMethods`]. +/// +/// # What is `PyCallArgs` used for? +/// `PyCallArgs` is used internally in `pyo3` to dispatch the Python calls in +/// the most optimal way for the current build configuration. Certain types, +/// such as Rust tuples, do allow the usage of a faster calling convention of +/// the Python interpreter (if available). More types that may take advantage +/// from this may be added in the future. +/// +/// [`call0`]: crate::types::PyAnyMethods::call0 +/// [`call1`]: crate::types::PyAnyMethods::call1 +/// [`call`]: crate::types::PyAnyMethods::call +/// [`PyAnyMethods`]: crate::types::PyAnyMethods +#[diagnostic::on_unimplemented( + message = "`{Self}` cannot used as a Python `call` argument", + note = "`PyCallArgs` is implemented for Rust tuples, `Bound<'py, PyTuple>` and `Py`", + note = "if your type is convertible to `PyTuple` via `IntoPyObject`, call `.into_pyobject(py)` manually", + note = "if you meant to pass the type as a single argument, wrap it in a 1-tuple, `(,)`" +)] +pub trait PyCallArgs<'py>: Sized + private::Sealed { + #[doc(hidden)] + fn call( + self, + function: Borrowed<'_, 'py, PyAny>, + kwargs: Borrowed<'_, 'py, PyDict>, + token: private::Token, + ) -> PyResult>; + + #[doc(hidden)] + fn call_positional( + self, + function: Borrowed<'_, 'py, PyAny>, + token: private::Token, + ) -> PyResult>; + + #[doc(hidden)] + fn call_method_positional( + self, + object: Borrowed<'_, 'py, PyAny>, + method_name: Borrowed<'_, 'py, PyString>, + _: private::Token, + ) -> PyResult> { + object + .getattr(method_name) + .and_then(|method| method.call1(self)) + } +} + +impl<'py> PyCallArgs<'py> for () { + fn call( + self, + function: Borrowed<'_, 'py, PyAny>, + kwargs: Borrowed<'_, 'py, PyDict>, + token: private::Token, + ) -> PyResult> { + let args = self.into_pyobject_or_pyerr(function.py())?; + args.call(function, kwargs, token) + } + + fn call_positional( + self, + function: Borrowed<'_, 'py, PyAny>, + token: private::Token, + ) -> PyResult> { + let args = self.into_pyobject_or_pyerr(function.py())?; + args.call_positional(function, token) + } +} + +impl<'py> PyCallArgs<'py> for Bound<'py, PyTuple> { + #[inline] + fn call( + self, + function: Borrowed<'_, 'py, PyAny>, + kwargs: Borrowed<'_, 'py, PyDict>, + token: private::Token, + ) -> PyResult> { + self.as_borrowed().call(function, kwargs, token) + } + + #[inline] + fn call_positional( + self, + function: Borrowed<'_, 'py, PyAny>, + token: private::Token, + ) -> PyResult> { + self.as_borrowed().call_positional(function, token) + } +} + +impl<'py> PyCallArgs<'py> for &'_ Bound<'py, PyTuple> { + #[inline] + fn call( + self, + function: Borrowed<'_, 'py, PyAny>, + kwargs: Borrowed<'_, 'py, PyDict>, + token: private::Token, + ) -> PyResult> { + self.as_borrowed().call(function, kwargs, token) + } + + #[inline] + fn call_positional( + self, + function: Borrowed<'_, 'py, PyAny>, + token: private::Token, + ) -> PyResult> { + self.as_borrowed().call_positional(function, token) + } +} + +impl<'py> PyCallArgs<'py> for Py { + #[inline] + fn call( + self, + function: Borrowed<'_, 'py, PyAny>, + kwargs: Borrowed<'_, 'py, PyDict>, + token: private::Token, + ) -> PyResult> { + self.bind_borrowed(function.py()) + .call(function, kwargs, token) + } + + #[inline] + fn call_positional( + self, + function: Borrowed<'_, 'py, PyAny>, + token: private::Token, + ) -> PyResult> { + self.bind_borrowed(function.py()) + .call_positional(function, token) + } +} + +impl<'py> PyCallArgs<'py> for &'_ Py { + #[inline] + fn call( + self, + function: Borrowed<'_, 'py, PyAny>, + kwargs: Borrowed<'_, 'py, PyDict>, + token: private::Token, + ) -> PyResult> { + self.bind_borrowed(function.py()) + .call(function, kwargs, token) + } + + #[inline] + fn call_positional( + self, + function: Borrowed<'_, 'py, PyAny>, + token: private::Token, + ) -> PyResult> { + self.bind_borrowed(function.py()) + .call_positional(function, token) + } +} + +impl<'py> PyCallArgs<'py> for Borrowed<'_, 'py, PyTuple> { + #[inline] + fn call( + self, + function: Borrowed<'_, 'py, PyAny>, + kwargs: Borrowed<'_, 'py, PyDict>, + _: private::Token, + ) -> PyResult> { + unsafe { + ffi::PyObject_Call(function.as_ptr(), self.as_ptr(), kwargs.as_ptr()) + .assume_owned_or_err(function.py()) + } + } + + #[inline] + fn call_positional( + self, + function: Borrowed<'_, 'py, PyAny>, + _: private::Token, + ) -> PyResult> { + unsafe { + ffi::PyObject_Call(function.as_ptr(), self.as_ptr(), core::ptr::null_mut()) + .assume_owned_or_err(function.py()) + } + } +} + +#[cfg(test)] +#[cfg(feature = "macros")] +mod tests { + use crate::{ + pyfunction, + types::{PyDict, PyTuple}, + Py, + }; + + #[pyfunction(signature = (*args, **kwargs), crate = "crate")] + fn args_kwargs( + args: Py, + kwargs: Option>, + ) -> (Py, Option>) { + (args, kwargs) + } + + #[test] + fn test_call() { + use crate::{ + types::{IntoPyDict, PyAnyMethods, PyDict, PyTuple}, + wrap_pyfunction, Py, Python, + }; + + Python::attach(|py| { + let f = wrap_pyfunction!(args_kwargs, py).unwrap(); + + let args = PyTuple::new(py, [1, 2, 3]).unwrap(); + let kwargs = &[("foo", 1), ("bar", 2)].into_py_dict(py).unwrap(); + + macro_rules! check_call { + ($args:expr, $kwargs:expr) => { + let (a, k): (Py, Py) = f + .call(args.clone(), Some(kwargs)) + .unwrap() + .extract() + .unwrap(); + assert!(a.is(&args)); + assert!(k.is(kwargs)); + }; + } + + // Bound<'py, PyTuple> + check_call!(args.clone(), kwargs); + + // &Bound<'py, PyTuple> + check_call!(&args, kwargs); + + // Py + check_call!(args.clone().unbind(), kwargs); + + // &Py + check_call!(&args.as_unbound(), kwargs); + + // Borrowed<'_, '_, PyTuple> + check_call!(args.as_borrowed(), kwargs); + }) + } + + #[test] + fn test_call_positional() { + use crate::{ + types::{PyAnyMethods, PyNone, PyTuple}, + wrap_pyfunction, Py, Python, + }; + + Python::attach(|py| { + let f = wrap_pyfunction!(args_kwargs, py).unwrap(); + + let args = PyTuple::new(py, [1, 2, 3]).unwrap(); + + macro_rules! check_call { + ($args:expr, $kwargs:expr) => { + let (a, k): (Py, Py) = + f.call1(args.clone()).unwrap().extract().unwrap(); + assert!(a.is(&args)); + assert!(k.is_none(py)); + }; + } + + // Bound<'py, PyTuple> + check_call!(args.clone(), kwargs); + + // &Bound<'py, PyTuple> + check_call!(&args, kwargs); + + // Py + check_call!(args.clone().unbind(), kwargs); + + // &Py + check_call!(args.as_unbound(), kwargs); + + // Borrowed<'_, '_, PyTuple> + check_call!(args.as_borrowed(), kwargs); + }) + } +} diff --git a/vendor/pyo3/src/conversion.rs b/vendor/pyo3/src/conversion.rs new file mode 100644 index 0000000..200793a --- /dev/null +++ b/vendor/pyo3/src/conversion.rs @@ -0,0 +1,646 @@ +//! Defines conversions between Rust and Python types. +use crate::err::PyResult; +use crate::impl_::pyclass::ExtractPyClassWithClone; +#[cfg(feature = "experimental-inspect")] +use crate::inspect::{type_hint_identifier, type_hint_subscript, PyStaticExpr}; +use crate::pyclass::boolean_struct::False; +use crate::pyclass::{PyClassGuardError, PyClassGuardMutError}; +use crate::types::PyList; +use crate::types::PyTuple; +use crate::{ + Borrowed, Bound, BoundObject, Py, PyAny, PyClass, PyClassGuard, PyErr, PyRef, PyRefMut, + PyTypeCheck, Python, +}; +use core::convert::Infallible; +use core::marker::PhantomData; + +/// Defines a conversion from a Rust type to a Python object, which may fail. +/// +/// This trait has `#[derive(IntoPyObject)]` to automatically implement it for simple types and +/// `#[derive(IntoPyObjectRef)]` to implement the same for references. +/// +/// It functions similarly to std's [`TryInto`] trait, but requires a [`Python<'py>`] token +/// as an argument. +/// +/// The [`into_pyobject`][IntoPyObject::into_pyobject] method is designed for maximum flexibility and efficiency; it +/// - allows for a concrete Python type to be returned (the [`Target`][IntoPyObject::Target] associated type) +/// - allows for the smart pointer containing the Python object to be either `Bound<'py, Self::Target>` or `Borrowed<'a, 'py, Self::Target>` +/// to avoid unnecessary reference counting overhead +/// - allows for a custom error type to be returned in the event of a conversion error to avoid +/// unnecessarily creating a Python exception +/// +/// # See also +/// +/// - The [`IntoPyObjectExt`] trait, which provides convenience methods for common usages of +/// `IntoPyObject` which erase type information and convert errors to `PyErr`. +#[diagnostic::on_unimplemented( + message = "`{Self}` cannot be converted to a Python object", + note = "`IntoPyObject` is automatically implemented by the `#[pyclass]` macro", + note = "if you do not wish to have a corresponding Python type, implement it manually", + note = "if you do not own `{Self}` you can perform a manual conversion to one of the types in `pyo3::types::*`" +)] +pub trait IntoPyObject<'py>: Sized { + /// The Python output type + type Target; + /// The smart pointer type to use. + /// + /// This will usually be [`Bound<'py, Target>`], but in special cases [`Borrowed<'a, 'py, Target>`] can be + /// used to minimize reference counting overhead. + type Output: BoundObject<'py, Self::Target>; + /// The type returned in the event of a conversion error. + type Error: Into; + + /// Extracts the type hint information for this type when it appears as a return value. + /// + /// For example, `Vec` would return `List[int]`. + /// The default implementation returns `Any`, which is correct for any type. + /// + /// For most types, the return value for this method will be identical to that of [`FromPyObject::INPUT_TYPE`]. + /// It may be different for some types, such as `Dict`, to allow duck-typing: functions return `Dict` but take `Mapping` as argument. + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = type_hint_identifier!("_typeshed", "Incomplete"); + + /// Performs the conversion. + fn into_pyobject(self, py: Python<'py>) -> Result; + + /// Converts sequence of Self into a Python object. Used to specialize `Vec`, `[u8; N]` + /// and `SmallVec<[u8; N]>` as a sequence of bytes into a `bytes` object. + #[doc(hidden)] + fn owned_sequence_into_pyobject( + iter: I, + py: Python<'py>, + _: private::Token, + ) -> Result, PyErr> + where + I: IntoIterator + AsRef<[Self]>, + I::IntoIter: ExactSizeIterator, + { + Ok(PyList::new(py, iter)?.into_any()) + } + + /// Converts sequence of Self into a Python object. Used to specialize `&[u8]` and `Cow<[u8]>` + /// as a sequence of bytes into a `bytes` object. + #[doc(hidden)] + fn borrowed_sequence_into_pyobject( + iter: I, + py: Python<'py>, + _: private::Token, + ) -> Result, PyErr> + where + Self: private::Reference, + I: IntoIterator + AsRef<[::BaseType]>, + I::IntoIter: ExactSizeIterator, + { + Ok(PyList::new(py, iter)?.into_any()) + } + + /// The output type of [`IntoPyObject::owned_sequence_into_pyobject`] and [`IntoPyObject::borrowed_sequence_into_pyobject`] + #[cfg(feature = "experimental-inspect")] + #[doc(hidden)] + const SEQUENCE_OUTPUT_TYPE: PyStaticExpr = + type_hint_subscript!(PyList::TYPE_HINT, Self::OUTPUT_TYPE); +} + +pub(crate) mod private { + pub struct Token; + + pub trait Reference { + type BaseType; + } + + impl Reference for &'_ T { + type BaseType = T; + } +} + +impl<'py, T: PyTypeCheck> IntoPyObject<'py> for Bound<'py, T> { + type Target = T; + type Output = Bound<'py, Self::Target>; + type Error = Infallible; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = T::TYPE_HINT; + + fn into_pyobject(self, _py: Python<'py>) -> Result { + Ok(self) + } +} + +impl<'a, 'py, T: PyTypeCheck> IntoPyObject<'py> for &'a Bound<'py, T> { + type Target = T; + type Output = Borrowed<'a, 'py, Self::Target>; + type Error = Infallible; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = T::TYPE_HINT; + + fn into_pyobject(self, _py: Python<'py>) -> Result { + Ok(self.as_borrowed()) + } +} + +impl<'a, 'py, T: PyTypeCheck> IntoPyObject<'py> for Borrowed<'a, 'py, T> { + type Target = T; + type Output = Borrowed<'a, 'py, Self::Target>; + type Error = Infallible; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = T::TYPE_HINT; + + fn into_pyobject(self, _py: Python<'py>) -> Result { + Ok(self) + } +} + +impl<'a, 'py, T: PyTypeCheck> IntoPyObject<'py> for &Borrowed<'a, 'py, T> { + type Target = T; + type Output = Borrowed<'a, 'py, Self::Target>; + type Error = Infallible; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = T::TYPE_HINT; + + fn into_pyobject(self, _py: Python<'py>) -> Result { + Ok(*self) + } +} + +impl<'py, T: PyTypeCheck> IntoPyObject<'py> for Py { + type Target = T; + type Output = Bound<'py, Self::Target>; + type Error = Infallible; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = T::TYPE_HINT; + + fn into_pyobject(self, py: Python<'py>) -> Result { + Ok(self.into_bound(py)) + } +} + +impl<'a, 'py, T: PyTypeCheck> IntoPyObject<'py> for &'a Py { + type Target = T; + type Output = Borrowed<'a, 'py, Self::Target>; + type Error = Infallible; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = T::TYPE_HINT; + + fn into_pyobject(self, py: Python<'py>) -> Result { + Ok(self.bind_borrowed(py)) + } +} + +impl<'a, 'py, T> IntoPyObject<'py> for &&'a T +where + &'a T: IntoPyObject<'py>, +{ + type Target = <&'a T as IntoPyObject<'py>>::Target; + type Output = <&'a T as IntoPyObject<'py>>::Output; + type Error = <&'a T as IntoPyObject<'py>>::Error; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = <&'a T as IntoPyObject<'py>>::OUTPUT_TYPE; + + #[inline] + fn into_pyobject(self, py: Python<'py>) -> Result { + (*self).into_pyobject(py) + } +} + +mod into_pyobject_ext { + pub trait Sealed {} + impl<'py, T> Sealed for T where T: super::IntoPyObject<'py> {} +} + +/// Convenience methods for common usages of [`IntoPyObject`]. Every type that implements +/// [`IntoPyObject`] also implements this trait. +/// +/// These methods: +/// - Drop type information from the output, returning a `PyAny` object. +/// - Always convert the `Error` type to `PyErr`, which may incur a performance penalty but it +/// more convenient in contexts where the `?` operator would produce a `PyErr` anyway. +pub trait IntoPyObjectExt<'py>: IntoPyObject<'py> + into_pyobject_ext::Sealed { + /// Converts `self` into an owned Python object, dropping type information. + #[inline] + fn into_bound_py_any(self, py: Python<'py>) -> PyResult> { + match self.into_pyobject(py) { + Ok(obj) => Ok(obj.into_any().into_bound()), + Err(err) => Err(err.into()), + } + } + + /// Converts `self` into an owned Python object, dropping type information and unbinding it + /// from the `'py` lifetime. + #[inline] + fn into_py_any(self, py: Python<'py>) -> PyResult> { + match self.into_pyobject(py) { + Ok(obj) => Ok(obj.into_any().unbind()), + Err(err) => Err(err.into()), + } + } + + /// Converts `self` into a Python object. + /// + /// This is equivalent to calling [`into_pyobject`][IntoPyObject::into_pyobject] followed + /// with `.map_err(Into::into)` to convert the error type to [`PyErr`]. This is helpful + /// for generic code which wants to make use of the `?` operator. + #[inline] + fn into_pyobject_or_pyerr(self, py: Python<'py>) -> PyResult { + match self.into_pyobject(py) { + Ok(obj) => Ok(obj), + Err(err) => Err(err.into()), + } + } +} + +impl<'py, T> IntoPyObjectExt<'py> for T where T: IntoPyObject<'py> {} + +/// Extract a type from a Python object. +/// +/// +/// Normal usage is through the `extract` methods on [`Bound`], [`Borrowed`] and [`Py`], which +/// forward to this trait. +/// +/// # Examples +/// +/// ```rust +/// use pyo3::prelude::*; +/// use pyo3::types::PyString; +/// +/// # fn main() -> PyResult<()> { +/// Python::attach(|py| { +/// // Calling `.extract()` on a `Bound` smart pointer +/// let obj: Bound<'_, PyString> = PyString::new(py, "blah"); +/// let s: String = obj.extract()?; +/// # assert_eq!(s, "blah"); +/// +/// // Calling `.extract(py)` on a `Py` smart pointer +/// let obj: Py = obj.unbind(); +/// let s: String = obj.extract(py)?; +/// # assert_eq!(s, "blah"); +/// # Ok(()) +/// }) +/// # } +/// ``` +/// +/// Note: Depending on the Python version and implementation, some [`FromPyObject`] implementations +/// may produce a result that borrows into the Python type. This is described by the input lifetime +/// `'a` of `obj`. +/// +/// Types that must not borrow from the input can use [`FromPyObjectOwned`] as a restriction. This +/// is most often the case for collection types. See its documentation for more details. +/// +/// # How to implement [`FromPyObject`]? +/// ## `#[derive(FromPyObject)]` +/// The simplest way to implement [`FromPyObject`] for a custom type is to make use of our derive +/// macro. +/// ```rust,no_run +/// # #![allow(dead_code)] +/// use pyo3::prelude::*; +/// +/// #[derive(FromPyObject)] +/// struct MyObject { +/// msg: String, +/// list: Vec +/// } +/// # fn main() {} +/// ``` +/// By default this will try to extract each field from the Python object by attribute access, but +/// this can be customized. For more information about the derive macro, its configuration as well +/// as its working principle for other types, take a look at the [guide]. +/// +/// In case the derive macro is not sufficient or can not be used for some other reason, +/// [`FromPyObject`] can be implemented manually. In the following types without lifetime parameters +/// are handled first, because they are a little bit simpler. Types with lifetime parameters are +/// explained below. +/// +/// ## Manual implementation for types without lifetime +/// Types that do not contain lifetime parameters are unable to borrow from the Python object, so +/// the lifetimes of [`FromPyObject`] can be elided: +/// ```rust,no_run +/// # #![allow(dead_code)] +/// use pyo3::prelude::*; +/// +/// struct MyObject { +/// msg: String, +/// list: Vec +/// } +/// +/// impl FromPyObject<'_, '_> for MyObject { +/// type Error = PyErr; +/// +/// fn extract(obj: Borrowed<'_, '_, PyAny>) -> Result { +/// Ok(MyObject { +/// msg: obj.getattr("msg")?.extract()?, +/// list: obj.getattr("list")?.extract()?, +/// }) +/// } +/// } +/// +/// # fn main() {} +/// ``` +/// This is basically what the derive macro above expands to. +/// +/// ## Manual implementation for types with lifetime parameters +/// For types that contain lifetimes, these lifetimes need to be bound to the corresponding +/// [`FromPyObject`] lifetime. This is roughly how the extraction of a typed [`Bound`] is +/// implemented within PyO3. +/// +/// ```rust,no_run +/// # #![allow(dead_code)] +/// use pyo3::prelude::*; +/// use pyo3::types::PyString; +/// +/// struct MyObject<'py>(Bound<'py, PyString>); +/// +/// impl<'py> FromPyObject<'_, 'py> for MyObject<'py> { +/// type Error = PyErr; +/// +/// fn extract(obj: Borrowed<'_, 'py, PyAny>) -> Result { +/// Ok(MyObject(obj.cast()?.to_owned())) +/// } +/// } +/// +/// # fn main() {} +/// ``` +/// +/// # Details +/// [`Cow<'a, str>`] is an example of an output type that may or may not borrow from the input +/// lifetime `'a`. Which variant will be produced depends on the runtime type of the Python object. +/// For a Python byte string, the existing string data can be borrowed for `'a` into a +/// [`Cow::Borrowed`]. For a Python Unicode string, the data may have to be reencoded to UTF-8, and +/// copied into a [`Cow::Owned`]. It does _not_ depend on the Python lifetime `'py`. +/// +/// The output type may also depend on the Python lifetime `'py`. This allows the output type to +/// keep interacting with the Python interpreter. See also [`Bound<'py, T>`]. +/// +/// [`Cow<'a, str>`]: alloc::borrow::Cow +/// [`Cow::Borrowed`]: alloc::borrow::Cow::Borrowed +/// [`Cow::Owned`]: alloc::borrow::Cow::Owned +/// [guide]: https://pyo3.rs/latest/conversions/traits.html#deriving-frompyobject +pub trait FromPyObject<'a, 'py>: Sized { + /// The type returned in the event of a conversion error. + /// + /// For most use cases defaulting to [PyErr] here is perfectly acceptable. Using a custom error + /// type can be used to avoid having to create a Python exception object in the case where that + /// exception never reaches Python. This may lead to slightly better performance under certain + /// conditions. + /// + /// # Note + /// Unfortunately `Try` and thus `?` is based on [`From`], not [`Into`], so implementations may + /// need to use `.map_err(Into::into)` sometimes to convert a generic `Error` into a [`PyErr`]. + type Error: Into; + + /// Provides the type hint information for this type when it appears as an argument. + /// + /// For example, `Vec` would be `collections.abc.Sequence[int]`. + /// The default value is `typing.Any`, which is correct for any type. + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = type_hint_identifier!("_typeshed", "Incomplete"); + + /// Extracts `Self` from the bound smart pointer `obj`. + /// + /// Users are advised against calling this method directly: instead, use this via + /// [`Bound<'_, PyAny>::extract`](crate::types::any::PyAnyMethods::extract) or [`Py::extract`]. + fn extract(obj: Borrowed<'a, 'py, PyAny>) -> Result; + + /// Specialization hook for extracting sequences for types like `Vec` and `[u8; N]`, + /// where the bytes can be directly copied from some python objects without going through + /// iteration. + #[doc(hidden)] + #[inline(always)] + fn sequence_extractor( + _obj: Borrowed<'_, 'py, PyAny>, + _: private::Token, + ) -> Option> { + struct NeverASequence(PhantomData); + + impl FromPyObjectSequence for NeverASequence { + type Target = T; + + fn to_vec(&self) -> Vec { + unreachable!() + } + + fn to_array(&self) -> PyResult<[Self::Target; N]> { + unreachable!() + } + } + + Option::>::None + } + + /// Helper used to make a specialized path in extracting `DateTime` where `Tz` is + /// `chrono::Local`, which will accept "naive" datetime objects as being in the local timezone. + #[cfg(feature = "chrono-local")] + #[inline] + fn as_local_tz(_: private::Token) -> Option { + None + } +} + +mod from_py_object_sequence { + use crate::PyResult; + + /// Private trait for implementing specialized sequence extraction for `Vec` and `[u8; N]` + #[doc(hidden)] + pub trait FromPyObjectSequence { + type Target; + + fn to_vec(&self) -> Vec; + + fn to_array(&self) -> PyResult<[Self::Target; N]>; + } +} + +// Only reachable / implementable inside PyO3 itself. +pub(crate) use from_py_object_sequence::FromPyObjectSequence; + +/// A data structure that can be extracted without borrowing any data from the input. +/// +/// This is primarily useful for trait bounds. For example a [`FromPyObject`] implementation of a +/// wrapper type may be able to borrow data from the input, but a [`FromPyObject`] implementation of +/// a collection type may only extract owned data. +/// +/// For example [`PyList`] will not hand out references tied to its own lifetime, but "owned" +/// references independent of it. (Similar to [`Vec>`] where you clone the [`Arc`] out). +/// This makes it impossible to collect borrowed types in a collection, since they would not borrow +/// from the original [`PyList`], but the much shorter lived element reference. See the example +/// below. +/// +/// ```,no_run +/// # use pyo3::prelude::*; +/// # #[allow(dead_code)] +/// pub struct MyWrapper(T); +/// +/// impl<'a, 'py, T> FromPyObject<'a, 'py> for MyWrapper +/// where +/// T: FromPyObject<'a, 'py> +/// { +/// type Error = T::Error; +/// +/// fn extract(obj: Borrowed<'a, 'py, PyAny>) -> Result { +/// obj.extract().map(MyWrapper) +/// } +/// } +/// +/// # #[allow(dead_code)] +/// pub struct MyVec(Vec); +/// +/// impl<'py, T> FromPyObject<'_, 'py> for MyVec +/// where +/// T: FromPyObjectOwned<'py> // 👈 can only extract owned values, because each `item` below +/// // is a temporary short lived owned reference +/// { +/// type Error = PyErr; +/// +/// fn extract(obj: Borrowed<'_, 'py, PyAny>) -> Result { +/// let mut v = MyVec(Vec::new()); +/// for item in obj.try_iter()? { +/// v.0.push(item?.extract::().map_err(Into::into)?); +/// } +/// Ok(v) +/// } +/// } +/// ``` +/// +/// [`PyList`]: crate::types::PyList +/// [`Arc`]: alloc::sync::Arc +pub trait FromPyObjectOwned<'py>: for<'a> FromPyObject<'a, 'py> {} +impl<'py, T> FromPyObjectOwned<'py> for T where T: for<'a> FromPyObject<'a, 'py> {} + +impl<'a, 'py, T> FromPyObject<'a, 'py> for T +where + T: PyClass + Clone + ExtractPyClassWithClone, +{ + type Error = PyClassGuardError<'a, 'py>; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = ::TYPE_HINT; + + fn extract(obj: Borrowed<'a, 'py, PyAny>) -> Result { + Ok(obj.extract::>()?.clone()) + } +} + +impl<'a, 'py, T> FromPyObject<'a, 'py> for PyRef<'py, T> +where + T: PyClass, +{ + type Error = PyClassGuardError<'a, 'py>; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = ::TYPE_HINT; + + fn extract(obj: Borrowed<'a, 'py, PyAny>) -> Result { + obj.cast::() + .map_err(|e| PyClassGuardError(Some(e)))? + .try_borrow() + .map_err(|_| PyClassGuardError(None)) + } +} + +impl<'a, 'py, T> FromPyObject<'a, 'py> for PyRefMut<'py, T> +where + T: PyClass, +{ + type Error = PyClassGuardMutError<'a, 'py>; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = ::TYPE_HINT; + + fn extract(obj: Borrowed<'a, 'py, PyAny>) -> Result { + obj.cast::() + .map_err(|e| PyClassGuardMutError(Some(e)))? + .try_borrow_mut() + .map_err(|_| PyClassGuardMutError(None)) + } +} + +impl<'py> IntoPyObject<'py> for () { + type Target = PyTuple; + type Output = Bound<'py, Self::Target>; + type Error = Infallible; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = + type_hint_subscript!(PyTuple::TYPE_HINT, PyStaticExpr::Tuple { elts: &[] }); + + fn into_pyobject(self, py: Python<'py>) -> Result { + Ok(PyTuple::empty(py)) + } +} + +/// ```rust,compile_fail +/// use pyo3::prelude::*; +/// +/// #[pyclass] +/// struct TestClass { +/// num: u32, +/// } +/// +/// let t = TestClass { num: 10 }; +/// +/// Python::attach(|py| { +/// let pyvalue = Py::new(py, t).unwrap().to_object(py); +/// let t: TestClass = pyvalue.extract(py).unwrap(); +/// }) +/// ``` +mod test_no_clone {} + +#[cfg(test)] +mod tests { + #[test] + #[cfg(feature = "macros")] + fn test_pyclass_skip_from_py_object() { + use crate::{types::PyAnyMethods, FromPyObject, IntoPyObject, PyErr, Python}; + + #[crate::pyclass(crate = "crate", skip_from_py_object)] + #[derive(Clone)] + struct Foo(i32); + + impl<'py> FromPyObject<'_, 'py> for Foo { + type Error = PyErr; + + fn extract(obj: crate::Borrowed<'_, 'py, crate::PyAny>) -> Result { + if let Ok(obj) = obj.cast::() { + Ok(obj.borrow().clone()) + } else { + obj.extract::().map(Self) + } + } + } + Python::attach(|py| { + let foo1 = 42i32.into_pyobject(py)?; + assert_eq!(foo1.extract::()?.0, 42); + + let foo2 = Foo(0).into_pyobject(py)?; + assert_eq!(foo2.extract::()?.0, 0); + + Ok::<_, PyErr>(()) + }) + .unwrap(); + } + + #[test] + #[cfg(feature = "macros")] + fn test_pyclass_from_py_object() { + use crate::{types::PyAnyMethods, IntoPyObject, PyErr, Python}; + + #[crate::pyclass(crate = "crate", from_py_object)] + #[derive(Clone)] + struct Foo(i32); + + Python::attach(|py| { + let foo1 = 42i32.into_pyobject(py)?; + assert!(foo1.extract::().is_err()); + + let foo2 = Foo(0).into_pyobject(py)?; + assert_eq!(foo2.extract::()?.0, 0); + + Ok::<_, PyErr>(()) + }) + .unwrap(); + } +} diff --git a/vendor/pyo3/src/conversions/anyhow.rs b/vendor/pyo3/src/conversions/anyhow.rs new file mode 100644 index 0000000..2ff9595 --- /dev/null +++ b/vendor/pyo3/src/conversions/anyhow.rs @@ -0,0 +1,190 @@ +#![cfg(feature = "anyhow")] + +//! A conversion from [anyhow]’s [`Error`][anyhow-error] type to [`PyErr`]. +//! +//! Use of an error handling library like [anyhow] is common in application code and when you just +//! want error handling to be easy. If you are writing a library or you need more control over your +//! errors you might want to design your own error type instead. +//! +//! When the inner error is a [`PyErr`] without source, it will be extracted out. +//! Otherwise a Python [`RuntimeError`] will be created. +//! You might find that you need to map the error from your Rust code into another Python exception. +//! See [`PyErr::new`] for more information about that. +//! +//! For information about error handling in general, see the [Error handling] chapter of the Rust +//! book. +//! +//! # Setup +//! +//! To use this feature, add this to your **`Cargo.toml`**: +//! +//! ```toml +//! [dependencies] +//! ## change * to the version you want to use, ideally the latest. +//! anyhow = "*" +#![doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"), "\", features = [\"anyhow\"] }")] +//! ``` +//! +//! Note that you must use compatible versions of anyhow and PyO3. +//! The required anyhow version may vary based on the version of PyO3. +//! +//! # Example: Propagating a `PyErr` into [`anyhow::Error`] +//! +//! ```rust +//! use pyo3::prelude::*; +//! use std::path::PathBuf; +//! +//! // A wrapper around a Rust function. +//! // The pyfunction macro performs the conversion to a PyErr +//! #[pyfunction] +//! fn py_open(filename: PathBuf) -> anyhow::Result> { +//! let data = std::fs::read(filename)?; +//! Ok(data) +//! } +//! +//! fn main() { +//! let error = Python::attach(|py| -> PyResult> { +//! let fun = wrap_pyfunction!(py_open, py)?; +//! let text = fun.call1(("foo.txt",))?.extract::>()?; +//! Ok(text) +//! }).unwrap_err(); +//! +//! println!("{}", error); +//! } +//! ``` +//! +//! # Example: Using `anyhow` in general +//! +//! Note that you don't need this feature to convert a [`PyErr`] into an [`anyhow::Error`], because +//! it can already convert anything that implements [`Error`](core::error::Error): +//! +//! ```rust +//! use pyo3::prelude::*; +//! use pyo3::types::PyBytes; +//! +//! // An example function that must handle multiple error types. +//! // +//! // To do this you usually need to design your own error type or use +//! // `Box`. `anyhow` is a convenient alternative for this. +//! pub fn decompress(bytes: &[u8]) -> anyhow::Result { +//! // An arbitrary example of a Python api you +//! // could call inside an application... +//! // This might return a `PyErr`. +//! let res = Python::attach(|py| { +//! let zlib = PyModule::import(py, "zlib")?; +//! let decompress = zlib.getattr("decompress")?; +//! let bytes = PyBytes::new(py, bytes); +//! let value = decompress.call1((bytes,))?; +//! value.extract::>() +//! })?; +//! +//! // This might be a `FromUtf8Error`. +//! let text = String::from_utf8(res)?; +//! +//! Ok(text) +//! } +//! +//! fn main() -> anyhow::Result<()> { +//! let bytes: &[u8] = b"x\x9c\x8b\xcc/U(\xce\xc8/\xcdIQ((\xcaOJL\xca\xa9T\ +//! (-NU(\xc9HU\xc8\xc9LJ\xcbI,IUH.\x02\x91\x99y\xc5%\ +//! \xa9\x89)z\x00\xf2\x15\x12\xfe"; +//! let text = decompress(bytes)?; +//! +//! println!("The text is \"{}\"", text); +//! # assert_eq!(text, "You should probably use the libflate crate instead."); +//! Ok(()) +//! } +//! ``` +//! +//! [anyhow]: https://docs.rs/anyhow/ "A trait object based error system for easy idiomatic error handling in Rust applications." +//! [anyhow-error]: https://docs.rs/anyhow/latest/anyhow/struct.Error.html "Anyhows `Error` type, a wrapper around a dynamic error type" +//! [`RuntimeError`]: https://docs.python.org/3/library/exceptions.html#RuntimeError "Built-in Exceptions — Python documentation" +//! [Error handling]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html "Recoverable Errors with Result - The Rust Programming Language" + +use crate::exceptions::PyRuntimeError; +use crate::PyErr; + +impl From for PyErr { + fn from(mut error: anyhow::Error) -> Self { + // Errors containing a PyErr without chain or context are returned as the underlying error + if error.source().is_none() { + error = match error.downcast::() { + Ok(py_err) => return py_err, + Err(error) => error, + }; + } + PyRuntimeError::new_err(format!("{error:?}")) + } +} + +#[cfg(test)] +mod test_anyhow { + use crate::exceptions::{PyRuntimeError, PyValueError}; + use crate::prelude::*; + use crate::types::IntoPyDict; + + use anyhow::{anyhow, bail, Context, Result}; + + fn f() -> Result<()> { + use std::io; + bail!(io::Error::new(io::ErrorKind::PermissionDenied, "oh no!")); + } + + fn g() -> Result<()> { + f().context("f failed") + } + + fn h() -> Result<()> { + g().context("g failed") + } + + #[test] + fn test_pyo3_exception_contents() { + let err = h().unwrap_err(); + let expected_contents = format!("{err:?}"); + let pyerr = PyErr::from(err); + + Python::attach(|py| { + let locals = [("err", pyerr)].into_py_dict(py).unwrap(); + let pyerr = py.run(c"raise err", None, Some(&locals)).unwrap_err(); + assert_eq!(pyerr.value(py).to_string(), expected_contents); + }) + } + + fn k() -> Result<()> { + Err(anyhow!("Some sort of error")) + } + + #[test] + fn test_pyo3_exception_contents2() { + let err = k().unwrap_err(); + let expected_contents = format!("{err:?}"); + let pyerr = PyErr::from(err); + + Python::attach(|py| { + let locals = [("err", pyerr)].into_py_dict(py).unwrap(); + let pyerr = py.run(c"raise err", None, Some(&locals)).unwrap_err(); + assert_eq!(pyerr.value(py).to_string(), expected_contents); + }) + } + + #[test] + fn test_pyo3_unwrap_simple_err() { + let origin_exc = PyValueError::new_err("Value Error"); + let err: anyhow::Error = origin_exc.into(); + let converted: PyErr = err.into(); + assert!(Python::attach( + |py| converted.is_instance_of::(py) + )) + } + #[test] + fn test_pyo3_unwrap_complex_err() { + let origin_exc = PyValueError::new_err("Value Error"); + let mut err: anyhow::Error = origin_exc.into(); + err = err.context("Context"); + let converted: PyErr = err.into(); + assert!(Python::attach( + |py| converted.is_instance_of::(py) + )) + } +} diff --git a/vendor/pyo3/src/conversions/bigdecimal.rs b/vendor/pyo3/src/conversions/bigdecimal.rs new file mode 100644 index 0000000..c25d3d0 --- /dev/null +++ b/vendor/pyo3/src/conversions/bigdecimal.rs @@ -0,0 +1,264 @@ +#![cfg(feature = "bigdecimal")] +//! Conversions to and from [bigdecimal](https://docs.rs/bigdecimal)'s [`BigDecimal`] type. +//! +//! This is useful for converting Python's decimal.Decimal into and from a native Rust type. +//! +//! # Setup +//! +//! To use this feature, add to your **`Cargo.toml`**: +//! +//! ```toml +//! [dependencies] +#![doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"), "\", features = [\"bigdecimal\"] }")] +//! bigdecimal = "0.4" +//! ``` +//! +//! Note that you must use a compatible version of bigdecimal and PyO3. +//! The required bigdecimal version may vary based on the version of PyO3. +//! +//! # Example +//! +//! Rust code to create a function that adds one to a BigDecimal +//! +//! ```rust +//! use bigdecimal::BigDecimal; +//! use pyo3::prelude::*; +//! +//! #[pyfunction] +//! fn add_one(d: BigDecimal) -> BigDecimal { +//! d + 1 +//! } +//! +//! #[pymodule] +//! fn my_module(m: &Bound<'_, PyModule>) -> PyResult<()> { +//! m.add_function(wrap_pyfunction!(add_one, m)?)?; +//! Ok(()) +//! } +//! ``` +//! +//! Python code that validates the functionality +//! +//! +//! ```python +//! from my_module import add_one +//! from decimal import Decimal +//! +//! d = Decimal("2") +//! value = add_one(d) +//! +//! assert d + 1 == value +//! ``` + +use core::str::FromStr; + +#[cfg(feature = "experimental-inspect")] +use crate::inspect::PyStaticExpr; +#[cfg(feature = "experimental-inspect")] +use crate::type_hint_identifier; +use crate::types::PyTuple; +use crate::{ + exceptions::PyValueError, + sync::PyOnceLock, + types::{PyAnyMethods, PyStringMethods, PyType}, + Borrowed, Bound, FromPyObject, IntoPyObject, Py, PyAny, PyErr, PyResult, Python, +}; +use bigdecimal::BigDecimal; +use num_bigint::Sign; + +fn get_decimal_cls(py: Python<'_>) -> PyResult<&Bound<'_, PyType>> { + static DECIMAL_CLS: PyOnceLock> = PyOnceLock::new(); + DECIMAL_CLS.import(py, "decimal", "Decimal") +} + +fn get_invalid_operation_error_cls(py: Python<'_>) -> PyResult<&Bound<'_, PyType>> { + static INVALID_OPERATION_CLS: PyOnceLock> = PyOnceLock::new(); + INVALID_OPERATION_CLS.import(py, "decimal", "InvalidOperation") +} + +impl FromPyObject<'_, '_> for BigDecimal { + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = type_hint_identifier!("decimal", "Decimal"); + + fn extract(obj: Borrowed<'_, '_, PyAny>) -> PyResult { + let py_str = &obj.str()?; + let rs_str = &py_str.to_cow()?; + BigDecimal::from_str(rs_str).map_err(|e| PyValueError::new_err(e.to_string())) + } +} + +impl<'py> IntoPyObject<'py> for BigDecimal { + type Target = PyAny; + + type Output = Bound<'py, Self::Target>; + + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = type_hint_identifier!("decimal", "Decimal"); + + fn into_pyobject(self, py: Python<'py>) -> Result { + let cls = get_decimal_cls(py)?; + let (bigint, scale) = self.into_bigint_and_scale(); + if scale == 0 { + return cls.call1((bigint,)); + } + let exponent = scale.checked_neg().ok_or_else(|| { + get_invalid_operation_error_cls(py) + .map_or_else(|err| err, |cls| PyErr::from_type(cls.clone(), ())) + })?; + let (sign, digits) = bigint.to_radix_be(10); + let signed = matches!(sign, Sign::Minus).into_pyobject(py)?; + let digits = PyTuple::new(py, digits)?; + + cls.call1(((signed, digits, exponent),)) + } +} + +#[cfg(test)] +mod test_bigdecimal { + use super::*; + use crate::types::dict::PyDictMethods; + use crate::types::PyDict; + use alloc::ffi::CString; + + use bigdecimal::{One, Zero}; + #[cfg(not(target_arch = "wasm32"))] + use proptest::prelude::*; + + macro_rules! convert_constants { + ($name:ident, $rs:expr, $py:literal) => { + #[test] + fn $name() { + Python::attach(|py| { + let rs_orig = $rs; + let rs_dec = rs_orig.clone().into_pyobject(py).unwrap(); + let locals = PyDict::new(py); + locals.set_item("rs_dec", &rs_dec).unwrap(); + // Checks if BigDecimal -> Python Decimal conversion is correct + py.run( + &CString::new(format!( + "import decimal\npy_dec = decimal.Decimal(\"{}\")\nassert py_dec == rs_dec", + $py + )) + .unwrap(), + None, + Some(&locals), + ) + .unwrap(); + // Checks if Python Decimal -> BigDecimal conversion is correct + let py_dec = locals.get_item("py_dec").unwrap().unwrap(); + let py_result: BigDecimal = py_dec.extract().unwrap(); + assert_eq!(rs_orig, py_result); + }) + } + }; + } + + convert_constants!(convert_zero, BigDecimal::zero(), "0"); + convert_constants!(convert_one, BigDecimal::one(), "1"); + convert_constants!(convert_neg_one, -BigDecimal::one(), "-1"); + convert_constants!(convert_two, BigDecimal::from(2), "2"); + convert_constants!(convert_ten, BigDecimal::from_str("10").unwrap(), "10"); + convert_constants!( + convert_one_hundred_point_one, + BigDecimal::from_str("100.1").unwrap(), + "100.1" + ); + convert_constants!( + convert_one_thousand, + BigDecimal::from_str("1000").unwrap(), + "1000" + ); + convert_constants!( + convert_scientific, + BigDecimal::from_str("1e10").unwrap(), + "1e10" + ); + + #[cfg(not(target_arch = "wasm32"))] + proptest! { + #[test] + fn test_roundtrip( + number in 0..28u32 + ) { + let num = BigDecimal::from(number); + Python::attach(|py| { + let rs_dec = num.clone().into_pyobject(py).unwrap(); + let locals = PyDict::new(py); + locals.set_item("rs_dec", &rs_dec).unwrap(); + py.run( + &CString::new(format!( + "import decimal\npy_dec = decimal.Decimal(\"{num}\")\nassert py_dec == rs_dec")).unwrap(), + None, Some(&locals)).unwrap(); + let roundtripped: BigDecimal = rs_dec.extract().unwrap(); + assert_eq!(num, roundtripped); + }) + } + + #[test] + fn test_integers(num in any::()) { + Python::attach(|py| { + let py_num = num.into_pyobject(py).unwrap(); + let roundtripped: BigDecimal = py_num.extract().unwrap(); + let rs_dec = BigDecimal::from(num); + assert_eq!(rs_dec, roundtripped); + }) + } + } + + #[test] + fn test_nan() { + Python::attach(|py| { + let locals = PyDict::new(py); + py.run( + c"import decimal\npy_dec = decimal.Decimal(\"NaN\")", + None, + Some(&locals), + ) + .unwrap(); + let py_dec = locals.get_item("py_dec").unwrap().unwrap(); + let roundtripped: Result = py_dec.extract(); + assert!(roundtripped.is_err()); + }) + } + + #[test] + fn test_infinity() { + Python::attach(|py| { + let locals = PyDict::new(py); + py.run( + c"import decimal\npy_dec = decimal.Decimal(\"Infinity\")", + None, + Some(&locals), + ) + .unwrap(); + let py_dec = locals.get_item("py_dec").unwrap().unwrap(); + let roundtripped: Result = py_dec.extract(); + assert!(roundtripped.is_err()); + }) + } + + #[test] + fn test_no_precision_loss() { + Python::attach(|py| { + let src = "1e4"; + let expected = get_decimal_cls(py) + .unwrap() + .call1((src,)) + .unwrap() + .call_method0("as_tuple") + .unwrap(); + let actual = src + .parse::() + .unwrap() + .into_pyobject(py) + .unwrap() + .call_method0("as_tuple") + .unwrap(); + + assert!(actual.eq(expected).unwrap()); + }); + } +} diff --git a/vendor/pyo3/src/conversions/bytes.rs b/vendor/pyo3/src/conversions/bytes.rs new file mode 100644 index 0000000..20f4d1c --- /dev/null +++ b/vendor/pyo3/src/conversions/bytes.rs @@ -0,0 +1,147 @@ +// TODO https://github.com/PyO3/pyo3/issues/5487 +#![allow(clippy::undocumented_unsafe_blocks)] +#![cfg(feature = "bytes")] + +//! Conversions to and from [bytes](https://docs.rs/bytes/latest/bytes/)'s [`Bytes`]. +//! +//! This is useful for efficiently converting Python's `bytes` types efficiently. +//! While `bytes` will be directly borrowed, converting from `bytearray` will result in a copy. +//! +//! When converting `Bytes` back into Python, this will do a copy, just like `&[u8]` and `Vec`. +//! +//! # When to use `Bytes` +//! +//! Unless you specifically need [`Bytes`] for ref-counted ownership and sharing, +//! you may find that using `&[u8]`, `Vec`, [`Bound`], or [`PyBackedBytes`] +//! is simpler for most use cases. +//! +//! # Setup +//! +//! To use this feature, add in your **`Cargo.toml`**: +//! +//! ```toml +//! [dependencies] +//! bytes = "1.10" +#![doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"), "\", features = [\"bytes\"] }")] +//! ``` +//! +//! Note that you must use compatible versions of bytes and PyO3. +//! +//! # Example +//! +//! Rust code to create functions which return `Bytes` or take `Bytes` as arguments: +//! +//! ```rust,no_run +//! use pyo3::prelude::*; +//! use bytes::Bytes; +//! +//! #[pyfunction] +//! fn get_message_bytes() -> Bytes { +//! Bytes::from_static(b"Hello Python!") +//! } +//! +//! #[pyfunction] +//! fn num_bytes(bytes: Bytes) -> usize { +//! bytes.len() +//! } +//! +//! #[pymodule] +//! fn my_module(m: &Bound<'_, PyModule>) -> PyResult<()> { +//! m.add_function(wrap_pyfunction!(get_message_bytes, m)?)?; +//! m.add_function(wrap_pyfunction!(num_bytes, m)?)?; +//! Ok(()) +//! } +//! ``` +//! +//! Python code that calls these functions: +//! +//! ```python +//! from my_module import get_message_bytes, num_bytes +//! +//! message = get_message_bytes() +//! assert message == b"Hello Python!" +//! +//! size = num_bytes(message) +//! assert size == 13 +//! ``` +use bytes::Bytes; + +use crate::conversion::IntoPyObject; +#[cfg(feature = "experimental-inspect")] +use crate::inspect::PyStaticExpr; +use crate::instance::Bound; +use crate::pybacked::PyBackedBytes; +use crate::types::PyBytes; +#[cfg(feature = "experimental-inspect")] +use crate::PyTypeInfo; +use crate::{Borrowed, CastError, FromPyObject, PyAny, PyErr, Python}; + +impl<'a, 'py> FromPyObject<'a, 'py> for Bytes { + type Error = CastError<'a, 'py>; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = PyBackedBytes::INPUT_TYPE; + + fn extract(obj: Borrowed<'a, 'py, PyAny>) -> Result { + Ok(Bytes::from_owner(obj.extract::()?)) + } +} + +impl<'py> IntoPyObject<'py> for Bytes { + type Target = PyBytes; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = PyBytes::TYPE_HINT; + + fn into_pyobject(self, py: Python<'py>) -> Result { + Ok(PyBytes::new(py, &self)) + } +} + +impl<'py> IntoPyObject<'py> for &Bytes { + type Target = PyBytes; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = PyBytes::TYPE_HINT; + + fn into_pyobject(self, py: Python<'py>) -> Result { + Ok(PyBytes::new(py, self)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::types::{PyAnyMethods, PyByteArray, PyByteArrayMethods, PyBytes}; + use crate::Python; + + #[test] + fn test_bytes() { + Python::attach(|py| { + let py_bytes = PyBytes::new(py, b"foobar"); + let bytes: Bytes = py_bytes.extract().unwrap(); + assert_eq!(&*bytes, b"foobar"); + + let bytes = Bytes::from_static(b"foobar").into_pyobject(py).unwrap(); + assert!(bytes.is_instance_of::()); + }); + } + + #[test] + fn test_bytearray() { + Python::attach(|py| { + let py_bytearray = PyByteArray::new(py, b"foobar"); + let bytes: Bytes = py_bytearray.extract().unwrap(); + assert_eq!(&*bytes, b"foobar"); + + // Editing the bytearray should not change extracted Bytes + unsafe { py_bytearray.as_bytes_mut()[0] = b'x' }; + assert_eq!(&bytes, "foobar"); + assert_eq!(&py_bytearray.extract::>().unwrap(), b"xoobar"); + }); + } +} diff --git a/vendor/pyo3/src/conversions/chrono.rs b/vendor/pyo3/src/conversions/chrono.rs new file mode 100644 index 0000000..6b38453 --- /dev/null +++ b/vendor/pyo3/src/conversions/chrono.rs @@ -0,0 +1,1525 @@ +#![cfg(feature = "chrono")] + +//! Conversions to and from [chrono](https://docs.rs/chrono/)’s `Duration`, +//! `NaiveDate`, `NaiveTime`, `DateTime`, `FixedOffset`, and `Utc`. +//! +//! # Setup +//! +//! To use this feature, add this to your **`Cargo.toml`**: +//! +//! ```toml +//! [dependencies] +//! chrono = "0.4" +#![doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"), "\", features = [\"chrono\"] }")] +//! ``` +//! +//! Note that you must use compatible versions of chrono and PyO3. +//! The required chrono version may vary based on the version of PyO3. +//! +//! # Example: Convert a `datetime.datetime` to chrono's `DateTime` +//! +//! ```rust +//! use chrono::{DateTime, Duration, TimeZone, Utc}; +//! use pyo3::{Python, PyResult, IntoPyObject, types::PyAnyMethods}; +//! +//! fn main() -> PyResult<()> { +//! Python::initialize(); +//! Python::attach(|py| { +//! // Build some chrono values +//! let chrono_datetime = Utc.with_ymd_and_hms(2022, 1, 1, 12, 0, 0).unwrap(); +//! let chrono_duration = Duration::seconds(1); +//! // Convert them to Python +//! let py_datetime = chrono_datetime.into_pyobject(py)?; +//! let py_timedelta = chrono_duration.into_pyobject(py)?; +//! // Do an operation in Python +//! let py_sum = py_datetime.call_method1("__add__", (py_timedelta,))?; +//! // Convert back to Rust +//! let chrono_sum: DateTime = py_sum.extract()?; +//! println!("DateTime: {}", chrono_datetime); +//! Ok(()) +//! }) +//! } +//! ``` + +use crate::conversion::{FromPyObjectOwned, IntoPyObject}; +use crate::exceptions::{PyTypeError, PyUserWarning, PyValueError}; +#[cfg(feature = "experimental-inspect")] +use crate::inspect::PyStaticExpr; +use crate::intern; +use crate::types::any::PyAnyMethods; +use crate::types::PyNone; +use crate::types::{PyDate, PyDateTime, PyDelta, PyTime, PyTzInfo, PyTzInfoAccess}; +#[cfg(not(Py_LIMITED_API))] +use crate::types::{PyDateAccess, PyDeltaAccess, PyTimeAccess}; +#[cfg(feature = "chrono-local")] +use crate::{ + exceptions::PyRuntimeError, + sync::PyOnceLock, + types::{PyString, PyStringMethods}, + Py, +}; +#[cfg(feature = "experimental-inspect")] +use crate::{type_hint_identifier, PyTypeInfo}; +use crate::{Borrowed, Bound, FromPyObject, IntoPyObjectExt, PyAny, PyErr, PyResult, Python}; +use chrono::offset::{FixedOffset, Utc}; +#[cfg(feature = "chrono-local")] +use chrono::Local; +use chrono::{ + DateTime, Datelike, Duration, LocalResult, NaiveDate, NaiveDateTime, NaiveTime, Offset, + TimeZone, Timelike, +}; + +impl<'py> IntoPyObject<'py> for Duration { + type Target = PyDelta; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = PyDelta::TYPE_HINT; + + fn into_pyobject(self, py: Python<'py>) -> Result { + // Total number of days + let days = self.num_days(); + // Remainder of seconds + let secs_dur = self - Duration::days(days); + let secs = secs_dur.num_seconds(); + // Fractional part of the microseconds + let micros = (secs_dur - Duration::seconds(secs_dur.num_seconds())) + .num_microseconds() + // This should never panic since we are just getting the fractional + // part of the total microseconds, which should never overflow. + .unwrap(); + // We do not need to check the days i64 to i32 cast from rust because + // python will panic with OverflowError. + // We pass true as the `normalize` parameter since we'd need to do several checks here to + // avoid that, and it shouldn't have a big performance impact. + // The seconds and microseconds cast should never overflow since it's at most the number of seconds per day + PyDelta::new( + py, + days.try_into().unwrap_or(i32::MAX), + secs.try_into()?, + micros.try_into()?, + true, + ) + } +} + +impl<'py> IntoPyObject<'py> for &Duration { + type Target = PyDelta; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = Duration::OUTPUT_TYPE; + + #[inline] + fn into_pyobject(self, py: Python<'py>) -> Result { + (*self).into_pyobject(py) + } +} + +impl FromPyObject<'_, '_> for Duration { + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = PyDelta::TYPE_HINT; + + fn extract(ob: Borrowed<'_, '_, PyAny>) -> Result { + let delta = ob.cast::()?; + // Python size are much lower than rust size so we do not need bound checks. + // 0 <= microseconds < 1000000 + // 0 <= seconds < 3600*24 + // -999999999 <= days <= 999999999 + #[cfg(not(Py_LIMITED_API))] + let (days, seconds, microseconds) = { + ( + delta.get_days().into(), + delta.get_seconds().into(), + delta.get_microseconds().into(), + ) + }; + #[cfg(Py_LIMITED_API)] + let (days, seconds, microseconds) = { + let py = delta.py(); + ( + delta.getattr(intern!(py, "days"))?.extract()?, + delta.getattr(intern!(py, "seconds"))?.extract()?, + delta.getattr(intern!(py, "microseconds"))?.extract()?, + ) + }; + Ok( + Duration::days(days) + + Duration::seconds(seconds) + + Duration::microseconds(microseconds), + ) + } +} + +impl<'py> IntoPyObject<'py> for NaiveDate { + type Target = PyDate; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = PyDate::TYPE_HINT; + + fn into_pyobject(self, py: Python<'py>) -> Result { + let DateArgs { year, month, day } = (&self).into(); + PyDate::new(py, year, month, day) + } +} + +impl<'py> IntoPyObject<'py> for &NaiveDate { + type Target = PyDate; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = NaiveDate::OUTPUT_TYPE; + + #[inline] + fn into_pyobject(self, py: Python<'py>) -> Result { + (*self).into_pyobject(py) + } +} + +impl FromPyObject<'_, '_> for NaiveDate { + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = PyDate::TYPE_HINT; + + fn extract(ob: Borrowed<'_, '_, PyAny>) -> Result { + let date = &*ob.cast::()?; + py_date_to_naive_date(date) + } +} + +impl<'py> IntoPyObject<'py> for NaiveTime { + type Target = PyTime; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = PyTime::TYPE_HINT; + + fn into_pyobject(self, py: Python<'py>) -> Result { + let TimeArgs { + hour, + min, + sec, + micro, + truncated_leap_second, + } = (&self).into(); + + let time = PyTime::new(py, hour, min, sec, micro, None)?; + + if truncated_leap_second { + warn_truncated_leap_second(&time); + } + + Ok(time) + } +} + +impl<'py> IntoPyObject<'py> for &NaiveTime { + type Target = PyTime; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = NaiveTime::OUTPUT_TYPE; + + #[inline] + fn into_pyobject(self, py: Python<'py>) -> Result { + (*self).into_pyobject(py) + } +} + +impl FromPyObject<'_, '_> for NaiveTime { + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = PyTime::TYPE_HINT; + + fn extract(ob: Borrowed<'_, '_, PyAny>) -> Result { + let time = &*ob.cast::()?; + py_time_to_naive_time(time) + } +} + +impl<'py> IntoPyObject<'py> for NaiveDateTime { + type Target = PyDateTime; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = PyDateTime::TYPE_HINT; + + fn into_pyobject(self, py: Python<'py>) -> Result { + let DateArgs { year, month, day } = (&self.date()).into(); + let TimeArgs { + hour, + min, + sec, + micro, + truncated_leap_second, + } = (&self.time()).into(); + + let datetime = PyDateTime::new(py, year, month, day, hour, min, sec, micro, None)?; + + if truncated_leap_second { + warn_truncated_leap_second(&datetime); + } + + Ok(datetime) + } +} + +impl<'py> IntoPyObject<'py> for &NaiveDateTime { + type Target = PyDateTime; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = NaiveDateTime::OUTPUT_TYPE; + + #[inline] + fn into_pyobject(self, py: Python<'py>) -> Result { + (*self).into_pyobject(py) + } +} + +impl FromPyObject<'_, '_> for NaiveDateTime { + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = PyDateTime::TYPE_HINT; + + fn extract(dt: Borrowed<'_, '_, PyAny>) -> Result { + let dt = &*dt.cast::()?; + + // If the user tries to convert a timezone aware datetime into a naive one, + // we return a hard error. We could silently remove tzinfo, or assume local timezone + // and do a conversion, but better leave this decision to the user of the library. + let has_tzinfo = dt.get_tzinfo().is_some(); + if has_tzinfo { + return Err(PyTypeError::new_err("expected a datetime without tzinfo")); + } + + let dt = NaiveDateTime::new(py_date_to_naive_date(dt)?, py_time_to_naive_time(dt)?); + Ok(dt) + } +} + +impl<'py, Tz: TimeZone> IntoPyObject<'py> for DateTime +where + Tz: IntoPyObject<'py>, +{ + type Target = PyDateTime; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = <&DateTime>::OUTPUT_TYPE; + + #[inline] + fn into_pyobject(self, py: Python<'py>) -> Result { + (&self).into_pyobject(py) + } +} + +impl<'py, Tz: TimeZone> IntoPyObject<'py> for &DateTime +where + Tz: IntoPyObject<'py>, +{ + type Target = PyDateTime; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = PyDateTime::TYPE_HINT; + + fn into_pyobject(self, py: Python<'py>) -> Result { + let tz = self.timezone().into_bound_py_any(py)?.cast_into()?; + + let DateArgs { year, month, day } = (&self.naive_local().date()).into(); + let TimeArgs { + hour, + min, + sec, + micro, + truncated_leap_second, + } = (&self.naive_local().time()).into(); + + let fold = matches!( + self.timezone().offset_from_local_datetime(&self.naive_local()), + LocalResult::Ambiguous(_, latest) if self.offset().fix() == latest.fix() + ); + + let datetime = PyDateTime::new_with_fold( + py, + year, + month, + day, + hour, + min, + sec, + micro, + Some(&tz), + fold, + )?; + + if truncated_leap_second { + warn_truncated_leap_second(&datetime); + } + + Ok(datetime) + } +} + +impl<'py, Tz> FromPyObject<'_, 'py> for DateTime +where + Tz: TimeZone + FromPyObjectOwned<'py>, +{ + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = PyDateTime::TYPE_HINT; + + fn extract(dt: Borrowed<'_, 'py, PyAny>) -> Result { + let dt = &*dt.cast::()?; + let tzinfo = dt.get_tzinfo(); + + let tz = if let Some(tzinfo) = tzinfo { + tzinfo.extract().map_err(Into::into)? + } else { + // Special case: allow naive `datetime` objects for `DateTime`, interpreting them as local time. + #[cfg(feature = "chrono-local")] + if let Some(tz) = Tz::as_local_tz(crate::conversion::private::Token) { + return py_datetime_to_datetime_with_timezone(dt, tz); + } + + return Err(PyTypeError::new_err( + "expected a datetime with non-None tzinfo", + )); + }; + + py_datetime_to_datetime_with_timezone(dt, tz) + } +} + +impl<'py> IntoPyObject<'py> for FixedOffset { + type Target = PyTzInfo; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = type_hint_identifier!("datetime", "timezone"); + + fn into_pyobject(self, py: Python<'py>) -> Result { + let seconds_offset = self.local_minus_utc(); + let td = PyDelta::new(py, 0, seconds_offset, 0, true)?; + PyTzInfo::fixed_offset(py, td) + } +} + +impl<'py> IntoPyObject<'py> for &FixedOffset { + type Target = PyTzInfo; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = FixedOffset::OUTPUT_TYPE; + + #[inline] + fn into_pyobject(self, py: Python<'py>) -> Result { + (*self).into_pyobject(py) + } +} + +impl FromPyObject<'_, '_> for FixedOffset { + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = PyTzInfo::TYPE_HINT; + + /// Convert python tzinfo to rust [`FixedOffset`]. + /// + /// Note that the conversion will result in precision lost in microseconds as chrono offset + /// does not supports microseconds. + fn extract(ob: Borrowed<'_, '_, PyAny>) -> Result { + let ob = ob.cast::()?; + + // Passing Python's None to the `utcoffset` function will only + // work for timezones defined as fixed offsets in Python. + // Any other timezone would require a datetime as the parameter, and return + // None if the datetime is not provided. + // Trying to convert None to a PyDelta in the next line will then fail. + let py_timedelta = + ob.call_method1(intern!(ob.py(), "utcoffset"), (PyNone::get(ob.py()),))?; + if py_timedelta.is_none() { + return Err(PyTypeError::new_err(format!( + "{ob:?} is not a fixed offset timezone" + ))); + } + let total_seconds: Duration = py_timedelta.extract()?; + // This cast is safe since the timedelta is limited to -24 hours and 24 hours. + let total_seconds = total_seconds.num_seconds() as i32; + FixedOffset::east_opt(total_seconds) + .ok_or_else(|| PyValueError::new_err("fixed offset out of bounds")) + } +} + +impl<'py> IntoPyObject<'py> for Utc { + type Target = PyTzInfo; + type Output = Borrowed<'static, 'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = type_hint_identifier!("datetime", "timezone"); + + fn into_pyobject(self, py: Python<'py>) -> Result { + PyTzInfo::utc(py) + } +} + +impl<'py> IntoPyObject<'py> for &Utc { + type Target = PyTzInfo; + type Output = Borrowed<'static, 'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = Utc::OUTPUT_TYPE; + + #[inline] + fn into_pyobject(self, py: Python<'py>) -> Result { + (*self).into_pyobject(py) + } +} + +impl FromPyObject<'_, '_> for Utc { + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = Utc::OUTPUT_TYPE; + + fn extract(ob: Borrowed<'_, '_, PyAny>) -> Result { + let py_utc = Utc.into_pyobject(ob.py())?; + if ob.eq(py_utc)? { + Ok(Utc) + } else { + Err(PyValueError::new_err("expected datetime.timezone.utc")) + } + } +} + +#[cfg(feature = "chrono-local")] +impl<'py> IntoPyObject<'py> for Local { + type Target = PyTzInfo; + type Output = Borrowed<'static, 'py, Self::Target>; + type Error = PyErr; + + #[cfg(all(feature = "experimental-inspect", Py_3_9))] + const OUTPUT_TYPE: PyStaticExpr = type_hint_identifier!("zoneinfo", "ZoneInfo"); + + #[cfg(all(feature = "experimental-inspect", not(Py_3_9)))] + const OUTPUT_TYPE: PyStaticExpr = PyTzInfo::TYPE_HINT; + + fn into_pyobject(self, py: Python<'py>) -> Result { + static LOCAL_TZ: PyOnceLock> = PyOnceLock::new(); + let tz = LOCAL_TZ + .get_or_try_init(py, || { + let iana_name = iana_time_zone::get_timezone().map_err(|e| { + PyRuntimeError::new_err(format!("Could not get local timezone: {e}")) + })?; + PyTzInfo::timezone(py, iana_name).map(Bound::unbind) + })? + .bind_borrowed(py); + Ok(tz) + } +} + +#[cfg(feature = "chrono-local")] +impl<'py> IntoPyObject<'py> for &Local { + type Target = PyTzInfo; + type Output = Borrowed<'static, 'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = Local::OUTPUT_TYPE; + + #[inline] + fn into_pyobject(self, py: Python<'py>) -> Result { + (*self).into_pyobject(py) + } +} + +#[cfg(feature = "chrono-local")] +impl FromPyObject<'_, '_> for Local { + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = Local::OUTPUT_TYPE; + + fn extract(ob: Borrowed<'_, '_, PyAny>) -> PyResult { + let local_tz = Local.into_pyobject(ob.py())?; + if ob.eq(local_tz)? { + Ok(Local) + } else { + let name = local_tz.getattr("key")?.cast_into::()?; + Err(PyValueError::new_err(format!( + "expected local timezone {}", + name.to_cow()? + ))) + } + } + + #[inline] + fn as_local_tz(_: crate::conversion::private::Token) -> Option { + Some(Local) + } +} + +struct DateArgs { + year: i32, + month: u8, + day: u8, +} + +impl From<&NaiveDate> for DateArgs { + fn from(value: &NaiveDate) -> Self { + Self { + year: value.year(), + month: value.month() as u8, + day: value.day() as u8, + } + } +} + +struct TimeArgs { + hour: u8, + min: u8, + sec: u8, + micro: u32, + truncated_leap_second: bool, +} + +impl From<&NaiveTime> for TimeArgs { + fn from(value: &NaiveTime) -> Self { + let ns = value.nanosecond(); + let checked_sub = ns.checked_sub(1_000_000_000); + let truncated_leap_second = checked_sub.is_some(); + let micro = checked_sub.unwrap_or(ns) / 1000; + Self { + hour: value.hour() as u8, + min: value.minute() as u8, + sec: value.second() as u8, + micro, + truncated_leap_second, + } + } +} + +fn warn_truncated_leap_second(obj: &Bound<'_, PyAny>) { + let py = obj.py(); + if let Err(e) = PyErr::warn( + py, + &py.get_type::(), + c"ignored leap-second, `datetime` does not support leap-seconds", + 0, + ) { + e.write_unraisable(py, Some(obj)) + }; +} + +#[cfg(not(Py_LIMITED_API))] +fn py_date_to_naive_date( + py_date: impl core::ops::Deref, +) -> PyResult { + NaiveDate::from_ymd_opt( + py_date.get_year(), + py_date.get_month().into(), + py_date.get_day().into(), + ) + .ok_or_else(|| PyValueError::new_err("invalid or out-of-range date")) +} + +#[cfg(Py_LIMITED_API)] +fn py_date_to_naive_date(py_date: &Bound<'_, PyAny>) -> PyResult { + NaiveDate::from_ymd_opt( + py_date.getattr(intern!(py_date.py(), "year"))?.extract()?, + py_date.getattr(intern!(py_date.py(), "month"))?.extract()?, + py_date.getattr(intern!(py_date.py(), "day"))?.extract()?, + ) + .ok_or_else(|| PyValueError::new_err("invalid or out-of-range date")) +} + +#[cfg(not(Py_LIMITED_API))] +fn py_time_to_naive_time( + py_time: impl core::ops::Deref, +) -> PyResult { + NaiveTime::from_hms_micro_opt( + py_time.get_hour().into(), + py_time.get_minute().into(), + py_time.get_second().into(), + py_time.get_microsecond(), + ) + .ok_or_else(|| PyValueError::new_err("invalid or out-of-range time")) +} + +#[cfg(Py_LIMITED_API)] +fn py_time_to_naive_time(py_time: &Bound<'_, PyAny>) -> PyResult { + NaiveTime::from_hms_micro_opt( + py_time.getattr(intern!(py_time.py(), "hour"))?.extract()?, + py_time + .getattr(intern!(py_time.py(), "minute"))? + .extract()?, + py_time + .getattr(intern!(py_time.py(), "second"))? + .extract()?, + py_time + .getattr(intern!(py_time.py(), "microsecond"))? + .extract()?, + ) + .ok_or_else(|| PyValueError::new_err("invalid or out-of-range time")) +} + +fn py_datetime_to_datetime_with_timezone( + dt: &Bound<'_, PyDateTime>, + tz: Tz, +) -> PyResult> { + let naive_dt = NaiveDateTime::new(py_date_to_naive_date(dt)?, py_time_to_naive_time(dt)?); + match naive_dt.and_local_timezone(tz) { + LocalResult::Single(value) => Ok(value), + LocalResult::Ambiguous(earliest, latest) => { + #[cfg(not(Py_LIMITED_API))] + let fold = dt.get_fold(); + + #[cfg(Py_LIMITED_API)] + let fold = dt.getattr(intern!(dt.py(), "fold"))?.extract::()? > 0; + + if fold { + Ok(latest) + } else { + Ok(earliest) + } + } + LocalResult::None => Err(PyValueError::new_err(format!( + "The datetime {dt:?} contains an incompatible timezone" + ))), + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{test_utils::assert_warnings, types::PyTuple, BoundObject}; + use core::cmp::Ordering; + use std::panic; + + #[test] + // Only Python>=3.9 has the zoneinfo package + // We skip the test on windows too since we'd need to install + // tzdata there to make this work. + #[cfg(all(Py_3_9, not(target_os = "windows")))] + fn test_zoneinfo_is_not_fixed_offset() { + use crate::types::any::PyAnyMethods; + use crate::types::dict::PyDictMethods; + + Python::attach(|py| { + let locals = crate::types::PyDict::new(py); + py.run( + c"import zoneinfo; zi = zoneinfo.ZoneInfo('Europe/London')", + None, + Some(&locals), + ) + .unwrap(); + let result: PyResult = locals.get_item("zi").unwrap().unwrap().extract(); + assert!(result.is_err()); + let res = result.err().unwrap(); + // Also check the error message is what we expect + let msg = res.value(py).repr().unwrap().to_string(); + assert_eq!(msg, "TypeError(\"zoneinfo.ZoneInfo(key='Europe/London') is not a fixed offset timezone\")"); + }); + } + + #[test] + fn test_timezone_aware_to_naive_fails() { + // Test that if a user tries to convert a python's timezone aware datetime into a naive + // one, the conversion fails. + Python::attach(|py| { + let py_datetime = + new_py_datetime_ob(py, "datetime", (2022, 1, 1, 1, 0, 0, 0, python_utc(py))); + // Now test that converting a PyDateTime with tzinfo to a NaiveDateTime fails + let res: PyResult = py_datetime.extract(); + assert_eq!( + res.unwrap_err().value(py).repr().unwrap().to_string(), + "TypeError('expected a datetime without tzinfo')" + ); + }); + } + + #[test] + fn test_naive_to_timezone_aware_fails() { + // Test that if a user tries to convert a python's timezone aware datetime into a naive + // one, the conversion fails. + Python::attach(|py| { + let py_datetime = new_py_datetime_ob(py, "datetime", (2022, 1, 1, 1, 0, 0, 0)); + // Now test that converting a PyDateTime with tzinfo to a NaiveDateTime fails + let res: PyResult> = py_datetime.extract(); + assert_eq!( + res.unwrap_err().value(py).repr().unwrap().to_string(), + "TypeError('expected a datetime with non-None tzinfo')" + ); + + // Now test that converting a PyDateTime with tzinfo to a NaiveDateTime fails + let res: PyResult> = py_datetime.extract(); + assert_eq!( + res.unwrap_err().value(py).repr().unwrap().to_string(), + "TypeError('expected a datetime with non-None tzinfo')" + ); + }); + } + + #[test] + fn test_invalid_types_fail() { + // Test that if a user tries to convert a python's timezone aware datetime into a naive + // one, the conversion fails. + Python::attach(|py| { + let none = py.None().into_bound(py); + assert_eq!( + none.extract::().unwrap_err().to_string(), + "TypeError: 'None' is not an instance of 'timedelta'" + ); + assert_eq!( + none.extract::().unwrap_err().to_string(), + "TypeError: 'None' is not an instance of 'tzinfo'" + ); + assert_eq!( + none.extract::().unwrap_err().to_string(), + "ValueError: expected datetime.timezone.utc" + ); + assert_eq!( + none.extract::().unwrap_err().to_string(), + "TypeError: 'None' is not an instance of 'time'" + ); + assert_eq!( + none.extract::().unwrap_err().to_string(), + "TypeError: 'None' is not an instance of 'date'" + ); + assert_eq!( + none.extract::().unwrap_err().to_string(), + "TypeError: 'None' is not an instance of 'datetime'" + ); + assert_eq!( + none.extract::>().unwrap_err().to_string(), + "TypeError: 'None' is not an instance of 'datetime'" + ); + assert_eq!( + none.extract::>() + .unwrap_err() + .to_string(), + "TypeError: 'None' is not an instance of 'datetime'" + ); + }); + } + + #[test] + fn test_pyo3_timedelta_into_pyobject() { + // Utility function used to check different durations. + // The `name` parameter is used to identify the check in case of a failure. + let check = |name: &'static str, delta: Duration, py_days, py_seconds, py_ms| { + Python::attach(|py| { + let delta = delta.into_pyobject(py).unwrap(); + let py_delta = new_py_datetime_ob(py, "timedelta", (py_days, py_seconds, py_ms)); + assert!( + delta.eq(&py_delta).unwrap(), + "{name}: {delta} != {py_delta}" + ); + }); + }; + + let delta = Duration::days(-1) + Duration::seconds(1) + Duration::microseconds(-10); + check("delta normalization", delta, -1, 1, -10); + + // Check the minimum value allowed by PyDelta, which is different + // from the minimum value allowed in Duration. This should pass. + let delta = Duration::seconds(-86399999913600); // min + check("delta min value", delta, -999999999, 0, 0); + + // Same, for max value + let delta = Duration::seconds(86399999999999) + Duration::nanoseconds(999999000); // max + check("delta max value", delta, 999999999, 86399, 999999); + + // Also check that trying to convert an out of bound value errors. + Python::attach(|py| { + // min_value and max_value were deprecated in chrono 0.4.39 + #[allow(deprecated)] + { + assert!(Duration::min_value().into_pyobject(py).is_err()); + assert!(Duration::max_value().into_pyobject(py).is_err()); + } + }); + } + + #[test] + fn test_pyo3_timedelta_frompyobject() { + // Utility function used to check different durations. + // The `name` parameter is used to identify the check in case of a failure. + let check = |name: &'static str, delta: Duration, py_days, py_seconds, py_ms| { + Python::attach(|py| { + let py_delta = new_py_datetime_ob(py, "timedelta", (py_days, py_seconds, py_ms)); + let py_delta: Duration = py_delta.extract().unwrap(); + assert_eq!(py_delta, delta, "{name}: {py_delta} != {delta}"); + }) + }; + + // Check the minimum value allowed by PyDelta, which is different + // from the minimum value allowed in Duration. This should pass. + check( + "min py_delta value", + Duration::seconds(-86399999913600), + -999999999, + 0, + 0, + ); + // Same, for max value + check( + "max py_delta value", + Duration::seconds(86399999999999) + Duration::microseconds(999999), + 999999999, + 86399, + 999999, + ); + + // This check is to assert that we can't construct every possible Duration from a PyDelta + // since they have different bounds. + Python::attach(|py| { + let low_days: i32 = -1000000000; + // This is possible + assert!(panic::catch_unwind(|| Duration::days(low_days as i64)).is_ok()); + // This panics on PyDelta::new + assert!(panic::catch_unwind(|| { + let py_delta = new_py_datetime_ob(py, "timedelta", (low_days, 0, 0)); + if let Ok(_duration) = py_delta.extract::() { + // So we should never get here + } + }) + .is_err()); + + let high_days: i32 = 1000000000; + // This is possible + assert!(panic::catch_unwind(|| Duration::days(high_days as i64)).is_ok()); + // This panics on PyDelta::new + assert!(panic::catch_unwind(|| { + let py_delta = new_py_datetime_ob(py, "timedelta", (high_days, 0, 0)); + if let Ok(_duration) = py_delta.extract::() { + // So we should never get here + } + }) + .is_err()); + }); + } + + #[test] + fn test_pyo3_date_into_pyobject() { + let eq_ymd = |name: &'static str, year, month, day| { + Python::attach(|py| { + let date = NaiveDate::from_ymd_opt(year, month, day) + .unwrap() + .into_pyobject(py) + .unwrap(); + let py_date = new_py_datetime_ob(py, "date", (year, month, day)); + assert_eq!( + date.compare(&py_date).unwrap(), + Ordering::Equal, + "{name}: {date} != {py_date}" + ); + }) + }; + + eq_ymd("past date", 2012, 2, 29); + eq_ymd("min date", 1, 1, 1); + eq_ymd("future date", 3000, 6, 5); + eq_ymd("max date", 9999, 12, 31); + } + + #[test] + fn test_pyo3_date_frompyobject() { + let eq_ymd = |name: &'static str, year, month, day| { + Python::attach(|py| { + let py_date = new_py_datetime_ob(py, "date", (year, month, day)); + let py_date: NaiveDate = py_date.extract().unwrap(); + let date = NaiveDate::from_ymd_opt(year, month, day).unwrap(); + assert_eq!(py_date, date, "{name}: {date} != {py_date}"); + }) + }; + + eq_ymd("past date", 2012, 2, 29); + eq_ymd("min date", 1, 1, 1); + eq_ymd("future date", 3000, 6, 5); + eq_ymd("max date", 9999, 12, 31); + } + + #[test] + fn test_pyo3_datetime_into_pyobject_utc() { + Python::attach(|py| { + let check_utc = + |name: &'static str, year, month, day, hour, minute, second, ms, py_ms| { + let datetime = NaiveDate::from_ymd_opt(year, month, day) + .unwrap() + .and_hms_micro_opt(hour, minute, second, ms) + .unwrap() + .and_utc(); + let datetime = datetime.into_pyobject(py).unwrap(); + let py_datetime = new_py_datetime_ob( + py, + "datetime", + ( + year, + month, + day, + hour, + minute, + second, + py_ms, + python_utc(py), + ), + ); + assert_eq!( + datetime.compare(&py_datetime).unwrap(), + Ordering::Equal, + "{name}: {datetime} != {py_datetime}" + ); + }; + + check_utc("regular", 2014, 5, 6, 7, 8, 9, 999_999, 999_999); + + assert_warnings!( + py, + check_utc("leap second", 2014, 5, 6, 7, 8, 59, 1_999_999, 999_999), + [( + PyUserWarning, + "ignored leap-second, `datetime` does not support leap-seconds" + )] + ); + }) + } + + #[test] + fn test_pyo3_datetime_into_pyobject_fixed_offset() { + Python::attach(|py| { + let check_fixed_offset = + |name: &'static str, year, month, day, hour, minute, second, ms, py_ms| { + let offset = FixedOffset::east_opt(3600).unwrap(); + let datetime = NaiveDate::from_ymd_opt(year, month, day) + .unwrap() + .and_hms_micro_opt(hour, minute, second, ms) + .unwrap() + .and_local_timezone(offset) + .unwrap(); + let datetime = datetime.into_pyobject(py).unwrap(); + let py_tz = offset.into_pyobject(py).unwrap(); + let py_datetime = new_py_datetime_ob( + py, + "datetime", + (year, month, day, hour, minute, second, py_ms, py_tz), + ); + assert_eq!( + datetime.compare(&py_datetime).unwrap(), + Ordering::Equal, + "{name}: {datetime} != {py_datetime}" + ); + }; + + check_fixed_offset("regular", 2014, 5, 6, 7, 8, 9, 999_999, 999_999); + + assert_warnings!( + py, + check_fixed_offset("leap second", 2014, 5, 6, 7, 8, 59, 1_999_999, 999_999), + [( + PyUserWarning, + "ignored leap-second, `datetime` does not support leap-seconds" + )] + ); + }) + } + + #[test] + #[cfg(all(Py_3_9, feature = "chrono-tz", not(windows)))] + fn test_pyo3_datetime_into_pyobject_tz() { + Python::attach(|py| { + let datetime = NaiveDate::from_ymd_opt(2024, 12, 11) + .unwrap() + .and_hms_opt(23, 3, 13) + .unwrap() + .and_local_timezone(chrono_tz::Tz::Europe__London) + .unwrap(); + let datetime = datetime.into_pyobject(py).unwrap(); + let py_datetime = new_py_datetime_ob( + py, + "datetime", + ( + 2024, + 12, + 11, + 23, + 3, + 13, + 0, + python_zoneinfo(py, "Europe/London"), + ), + ); + assert_eq!(datetime.compare(&py_datetime).unwrap(), Ordering::Equal); + }) + } + + #[test] + fn test_pyo3_datetime_frompyobject_utc() { + Python::attach(|py| { + let year = 2014; + let month = 5; + let day = 6; + let hour = 7; + let minute = 8; + let second = 9; + let micro = 999_999; + let tz_utc = PyTzInfo::utc(py).unwrap(); + let py_datetime = new_py_datetime_ob( + py, + "datetime", + (year, month, day, hour, minute, second, micro, tz_utc), + ); + let py_datetime: DateTime = py_datetime.extract().unwrap(); + let datetime = NaiveDate::from_ymd_opt(year, month, day) + .unwrap() + .and_hms_micro_opt(hour, minute, second, micro) + .unwrap() + .and_utc(); + assert_eq!(py_datetime, datetime,); + }) + } + + #[test] + #[cfg(feature = "chrono-local")] + fn test_pyo3_naive_datetime_frompyobject_local() { + Python::attach(|py| { + let year = 2014; + let month = 5; + let day = 6; + let hour = 7; + let minute = 8; + let second = 9; + let micro = 999_999; + let py_datetime = new_py_datetime_ob( + py, + "datetime", + (year, month, day, hour, minute, second, micro), + ); + let py_datetime: DateTime = py_datetime.extract().unwrap(); + let expected_datetime = NaiveDate::from_ymd_opt(year, month, day) + .unwrap() + .and_hms_micro_opt(hour, minute, second, micro) + .unwrap() + .and_local_timezone(Local) + .unwrap(); + assert_eq!(py_datetime, expected_datetime); + }) + } + + #[test] + fn test_pyo3_datetime_frompyobject_fixed_offset() { + Python::attach(|py| { + let year = 2014; + let month = 5; + let day = 6; + let hour = 7; + let minute = 8; + let second = 9; + let micro = 999_999; + let offset = FixedOffset::east_opt(3600).unwrap(); + let py_tz = offset.into_pyobject(py).unwrap(); + let py_datetime = new_py_datetime_ob( + py, + "datetime", + (year, month, day, hour, minute, second, micro, py_tz), + ); + let datetime_from_py: DateTime = py_datetime.extract().unwrap(); + let datetime = NaiveDate::from_ymd_opt(year, month, day) + .unwrap() + .and_hms_micro_opt(hour, minute, second, micro) + .unwrap(); + let datetime = datetime.and_local_timezone(offset).unwrap(); + + assert_eq!(datetime_from_py, datetime); + assert!( + py_datetime.extract::>().is_err(), + "Extracting Utc from nonzero FixedOffset timezone will fail" + ); + + let utc = python_utc(py); + let py_datetime_utc = new_py_datetime_ob( + py, + "datetime", + (year, month, day, hour, minute, second, micro, utc), + ); + assert!( + py_datetime_utc.extract::>().is_ok(), + "Extracting FixedOffset from Utc timezone will succeed" + ); + }) + } + + #[test] + fn test_pyo3_offset_fixed_into_pyobject() { + Python::attach(|py| { + // Chrono offset + let offset = FixedOffset::east_opt(3600) + .unwrap() + .into_pyobject(py) + .unwrap(); + // Python timezone from timedelta + let td = new_py_datetime_ob(py, "timedelta", (0, 3600, 0)); + let py_timedelta = new_py_datetime_ob(py, "timezone", (td,)); + // Should be equal + assert!(offset.eq(py_timedelta).unwrap()); + + // Same but with negative values + let offset = FixedOffset::east_opt(-3600) + .unwrap() + .into_pyobject(py) + .unwrap(); + let td = new_py_datetime_ob(py, "timedelta", (0, -3600, 0)); + let py_timedelta = new_py_datetime_ob(py, "timezone", (td,)); + assert!(offset.eq(py_timedelta).unwrap()); + }) + } + + #[test] + fn test_pyo3_offset_fixed_frompyobject() { + Python::attach(|py| { + let py_timedelta = new_py_datetime_ob(py, "timedelta", (0, 3600, 0)); + let py_tzinfo = new_py_datetime_ob(py, "timezone", (py_timedelta,)); + let offset: FixedOffset = py_tzinfo.extract().unwrap(); + assert_eq!(FixedOffset::east_opt(3600).unwrap(), offset); + }) + } + + #[test] + fn test_pyo3_offset_utc_into_pyobject() { + Python::attach(|py| { + let utc = Utc.into_pyobject(py).unwrap(); + let py_utc = python_utc(py); + assert!(utc.is(&py_utc)); + }) + } + + #[test] + fn test_pyo3_offset_utc_frompyobject() { + Python::attach(|py| { + let py_utc = python_utc(py); + let py_utc: Utc = py_utc.extract().unwrap(); + assert_eq!(Utc, py_utc); + + let py_timedelta = new_py_datetime_ob(py, "timedelta", (0, 0, 0)); + let py_timezone_utc = new_py_datetime_ob(py, "timezone", (py_timedelta,)); + let py_timezone_utc: Utc = py_timezone_utc.extract().unwrap(); + assert_eq!(Utc, py_timezone_utc); + + let py_timedelta = new_py_datetime_ob(py, "timedelta", (0, 3600, 0)); + let py_timezone = new_py_datetime_ob(py, "timezone", (py_timedelta,)); + assert!(py_timezone.extract::().is_err()); + }) + } + + #[test] + fn test_pyo3_time_into_pyobject() { + Python::attach(|py| { + let check_time = |name: &'static str, hour, minute, second, ms, py_ms| { + let time = NaiveTime::from_hms_micro_opt(hour, minute, second, ms) + .unwrap() + .into_pyobject(py) + .unwrap(); + let py_time = new_py_datetime_ob(py, "time", (hour, minute, second, py_ms)); + assert!(time.eq(&py_time).unwrap(), "{name}: {time} != {py_time}"); + }; + + check_time("regular", 3, 5, 7, 999_999, 999_999); + + assert_warnings!( + py, + check_time("leap second", 3, 5, 59, 1_999_999, 999_999), + [( + PyUserWarning, + "ignored leap-second, `datetime` does not support leap-seconds" + )] + ); + }) + } + + #[test] + fn test_pyo3_time_frompyobject() { + let hour = 3; + let minute = 5; + let second = 7; + let micro = 999_999; + Python::attach(|py| { + let py_time = new_py_datetime_ob(py, "time", (hour, minute, second, micro)); + let py_time: NaiveTime = py_time.extract().unwrap(); + let time = NaiveTime::from_hms_micro_opt(hour, minute, second, micro).unwrap(); + assert_eq!(py_time, time); + }) + } + + fn new_py_datetime_ob<'py, A>(py: Python<'py>, name: &str, args: A) -> Bound<'py, PyAny> + where + A: IntoPyObject<'py, Target = PyTuple>, + { + py.import("datetime") + .unwrap() + .getattr(name) + .unwrap() + .call1( + args.into_pyobject(py) + .map_err(Into::into) + .unwrap() + .into_bound(), + ) + .unwrap() + } + + fn python_utc(py: Python<'_>) -> Bound<'_, PyAny> { + py.import("datetime") + .unwrap() + .getattr("timezone") + .unwrap() + .getattr("utc") + .unwrap() + } + + #[cfg(all(Py_3_9, feature = "chrono-tz", not(windows)))] + fn python_zoneinfo<'py>(py: Python<'py>, timezone: &str) -> Bound<'py, PyAny> { + py.import("zoneinfo") + .unwrap() + .getattr("ZoneInfo") + .unwrap() + .call1((timezone,)) + .unwrap() + } + + #[cfg(not(any(target_arch = "wasm32")))] + mod proptests { + use super::*; + use crate::test_utils::CatchWarnings; + use crate::types::IntoPyDict; + use alloc::ffi::CString; + use proptest::prelude::*; + + proptest! { + + // Range is limited to 1970 to 2038 due to windows limitations + #[test] + fn test_pyo3_offset_fixed_frompyobject_created_in_python(timestamp in 0..(i32::MAX as i64), timedelta in -86399i32..=86399i32) { + Python::attach(|py| { + + let globals = [("datetime", py.import("datetime").unwrap())].into_py_dict(py).unwrap(); + let code = format!("datetime.datetime.fromtimestamp({timestamp}).replace(tzinfo=datetime.timezone(datetime.timedelta(seconds={timedelta})))"); + let t = py.eval(&CString::new(code).unwrap(), Some(&globals), None).unwrap(); + + // Get ISO 8601 string from python + let py_iso_str = t.call_method0("isoformat").unwrap(); + + // Get ISO 8601 string from rust + let t = t.extract::>().unwrap(); + // Python doesn't print the seconds of the offset if they are 0 + let rust_iso_str = if timedelta % 60 == 0 { + t.format("%Y-%m-%dT%H:%M:%S%:z").to_string() + } else { + t.format("%Y-%m-%dT%H:%M:%S%::z").to_string() + }; + + // They should be equal + assert_eq!(py_iso_str.to_string(), rust_iso_str); + }) + } + + #[test] + fn test_duration_roundtrip(days in -999999999i64..=999999999i64) { + // Test roundtrip conversion rust->python->rust for all allowed + // python values of durations (from -999999999 to 999999999 days), + Python::attach(|py| { + let dur = Duration::days(days); + let py_delta = dur.into_pyobject(py).unwrap(); + let roundtripped: Duration = py_delta.extract().expect("Round trip"); + assert_eq!(dur, roundtripped); + }) + } + + #[test] + fn test_fixed_offset_roundtrip(secs in -86399i32..=86399i32) { + Python::attach(|py| { + let offset = FixedOffset::east_opt(secs).unwrap(); + let py_offset = offset.into_pyobject(py).unwrap(); + let roundtripped: FixedOffset = py_offset.extract().expect("Round trip"); + assert_eq!(offset, roundtripped); + }) + } + + #[test] + fn test_naive_date_roundtrip( + year in 1i32..=9999i32, + month in 1u32..=12u32, + day in 1u32..=31u32 + ) { + // Test roundtrip conversion rust->python->rust for all allowed + // python dates (from year 1 to year 9999) + Python::attach(|py| { + // We use to `from_ymd_opt` constructor so that we only test valid `NaiveDate`s. + // This is to skip the test if we are creating an invalid date, like February 31. + if let Some(date) = NaiveDate::from_ymd_opt(year, month, day) { + let py_date = date.into_pyobject(py).unwrap(); + let roundtripped: NaiveDate = py_date.extract().expect("Round trip"); + assert_eq!(date, roundtripped); + } + }) + } + + #[test] + fn test_naive_time_roundtrip( + hour in 0u32..=23u32, + min in 0u32..=59u32, + sec in 0u32..=59u32, + micro in 0u32..=1_999_999u32 + ) { + // Test roundtrip conversion rust->python->rust for naive times. + // Python time has a resolution of microseconds, so we only test + // NaiveTimes with microseconds resolution, even if NaiveTime has nanosecond + // resolution. + Python::attach(|py| { + if let Some(time) = NaiveTime::from_hms_micro_opt(hour, min, sec, micro) { + // Wrap in CatchWarnings to avoid to_object firing warning for truncated leap second + let py_time = CatchWarnings::enter(py, |_| time.into_pyobject(py)).unwrap(); + let roundtripped: NaiveTime = py_time.extract().expect("Round trip"); + // Leap seconds are not roundtripped + let expected_roundtrip_time = micro.checked_sub(1_000_000).map(|micro| NaiveTime::from_hms_micro_opt(hour, min, sec, micro).unwrap()).unwrap_or(time); + assert_eq!(expected_roundtrip_time, roundtripped); + } + }) + } + + #[test] + fn test_naive_datetime_roundtrip( + year in 1i32..=9999i32, + month in 1u32..=12u32, + day in 1u32..=31u32, + hour in 0u32..=24u32, + min in 0u32..=60u32, + sec in 0u32..=60u32, + micro in 0u32..=999_999u32 + ) { + Python::attach(|py| { + let date_opt = NaiveDate::from_ymd_opt(year, month, day); + let time_opt = NaiveTime::from_hms_micro_opt(hour, min, sec, micro); + if let (Some(date), Some(time)) = (date_opt, time_opt) { + let dt = NaiveDateTime::new(date, time); + let pydt = dt.into_pyobject(py).unwrap(); + let roundtripped: NaiveDateTime = pydt.extract().expect("Round trip"); + assert_eq!(dt, roundtripped); + } + }) + } + + #[test] + fn test_utc_datetime_roundtrip( + year in 1i32..=9999i32, + month in 1u32..=12u32, + day in 1u32..=31u32, + hour in 0u32..=23u32, + min in 0u32..=59u32, + sec in 0u32..=59u32, + micro in 0u32..=1_999_999u32 + ) { + Python::attach(|py| { + let date_opt = NaiveDate::from_ymd_opt(year, month, day); + let time_opt = NaiveTime::from_hms_micro_opt(hour, min, sec, micro); + if let (Some(date), Some(time)) = (date_opt, time_opt) { + let dt: DateTime = NaiveDateTime::new(date, time).and_utc(); + // Wrap in CatchWarnings to avoid into_py firing warning for truncated leap second + let py_dt = CatchWarnings::enter(py, |_| dt.into_pyobject(py)).unwrap(); + let roundtripped: DateTime = py_dt.extract().expect("Round trip"); + // Leap seconds are not roundtripped + let expected_roundtrip_time = micro.checked_sub(1_000_000).map(|micro| NaiveTime::from_hms_micro_opt(hour, min, sec, micro).unwrap()).unwrap_or(time); + let expected_roundtrip_dt: DateTime = NaiveDateTime::new(date, expected_roundtrip_time).and_utc(); + assert_eq!(expected_roundtrip_dt, roundtripped); + } + }) + } + + #[test] + fn test_fixed_offset_datetime_roundtrip( + year in 1i32..=9999i32, + month in 1u32..=12u32, + day in 1u32..=31u32, + hour in 0u32..=23u32, + min in 0u32..=59u32, + sec in 0u32..=59u32, + micro in 0u32..=1_999_999u32, + offset_secs in -86399i32..=86399i32 + ) { + Python::attach(|py| { + let date_opt = NaiveDate::from_ymd_opt(year, month, day); + let time_opt = NaiveTime::from_hms_micro_opt(hour, min, sec, micro); + let offset = FixedOffset::east_opt(offset_secs).unwrap(); + if let (Some(date), Some(time)) = (date_opt, time_opt) { + let dt: DateTime = NaiveDateTime::new(date, time).and_local_timezone(offset).unwrap(); + // Wrap in CatchWarnings to avoid into_py firing warning for truncated leap second + let py_dt = CatchWarnings::enter(py, |_| dt.into_pyobject(py)).unwrap(); + let roundtripped: DateTime = py_dt.extract().expect("Round trip"); + // Leap seconds are not roundtripped + let expected_roundtrip_time = micro.checked_sub(1_000_000).map(|micro| NaiveTime::from_hms_micro_opt(hour, min, sec, micro).unwrap()).unwrap_or(time); + let expected_roundtrip_dt: DateTime = NaiveDateTime::new(date, expected_roundtrip_time).and_local_timezone(offset).unwrap(); + assert_eq!(expected_roundtrip_dt, roundtripped); + } + }) + } + + #[test] + #[cfg(all(feature = "chrono-local", not(target_os = "windows")))] + fn test_local_datetime_roundtrip( + year in 1i32..=9999i32, + month in 1u32..=12u32, + day in 1u32..=31u32, + hour in 0u32..=23u32, + min in 0u32..=59u32, + sec in 0u32..=59u32, + micro in 0u32..=1_999_999u32, + ) { + Python::attach(|py| { + let date_opt = NaiveDate::from_ymd_opt(year, month, day); + let time_opt = NaiveTime::from_hms_micro_opt(hour, min, sec, micro); + if let (Some(date), Some(time)) = (date_opt, time_opt) { + let dts = match NaiveDateTime::new(date, time).and_local_timezone(Local) { + LocalResult::None => return, + LocalResult::Single(dt) => [Some((dt, false)), None], + LocalResult::Ambiguous(dt1, dt2) => [Some((dt1, false)), Some((dt2, true))], + }; + for (dt, fold) in dts.iter().filter_map(|input| *input) { + // Wrap in CatchWarnings to avoid into_py firing warning for truncated leap second + let py_dt = CatchWarnings::enter(py, |_| dt.into_pyobject(py)).unwrap(); + let roundtripped: DateTime = py_dt.extract().expect("Round trip"); + // Leap seconds are not roundtripped + let expected_roundtrip_time = micro.checked_sub(1_000_000).map(|micro| NaiveTime::from_hms_micro_opt(hour, min, sec, micro).unwrap()).unwrap_or(time); + let expected_roundtrip_dt: DateTime = if fold { + NaiveDateTime::new(date, expected_roundtrip_time).and_local_timezone(Local).latest() + } else { + NaiveDateTime::new(date, expected_roundtrip_time).and_local_timezone(Local).earliest() + }.unwrap(); + assert_eq!(expected_roundtrip_dt, roundtripped); + } + } + }) + } + } + } +} diff --git a/vendor/pyo3/src/conversions/chrono_tz.rs b/vendor/pyo3/src/conversions/chrono_tz.rs new file mode 100644 index 0000000..153e488 --- /dev/null +++ b/vendor/pyo3/src/conversions/chrono_tz.rs @@ -0,0 +1,229 @@ +#![cfg(all(Py_3_9, feature = "chrono-tz"))] + +//! Conversions to and from [chrono-tz](https://docs.rs/chrono-tz/)’s `Tz`. +//! +//! This feature requires at least Python 3.9. +//! +//! # Setup +//! +//! To use this feature, add this to your **`Cargo.toml`**: +//! +//! ```toml +//! [dependencies] +//! chrono-tz = "0.8" +#![doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"), "\", features = [\"chrono-tz\"] }")] +//! ``` +//! +//! Note that you must use compatible versions of chrono, chrono-tz and PyO3. +//! The required chrono version may vary based on the version of PyO3. +//! +//! # Example: Convert a `zoneinfo.ZoneInfo` to chrono-tz's `Tz` +//! +//! ```rust,no_run +//! use chrono_tz::Tz; +//! use pyo3::{Python, PyResult, IntoPyObject, types::PyAnyMethods}; +//! +//! fn main() -> PyResult<()> { +//! Python::initialize(); +//! Python::attach(|py| { +//! // Convert to Python +//! let py_tzinfo = Tz::Europe__Paris.into_pyobject(py)?; +//! // Convert back to Rust +//! assert_eq!(py_tzinfo.extract::()?, Tz::Europe__Paris); +//! Ok(()) +//! }) +//! } +//! ``` +use crate::conversion::IntoPyObject; +use crate::exceptions::PyValueError; +#[cfg(feature = "experimental-inspect")] +use crate::inspect::PyStaticExpr; +#[cfg(feature = "experimental-inspect")] +use crate::type_hint_identifier; +use crate::types::{any::PyAnyMethods, PyTzInfo}; +#[cfg(all(feature = "experimental-inspect", not(Py_3_9)))] +use crate::PyTypeInfo; +use crate::{intern, Borrowed, Bound, FromPyObject, PyAny, PyErr, Python}; +use alloc::borrow::Cow; +use chrono_tz::Tz; +use core::str::FromStr; + +impl<'py> IntoPyObject<'py> for Tz { + type Target = PyTzInfo; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(all(feature = "experimental-inspect", Py_3_9))] + const OUTPUT_TYPE: PyStaticExpr = type_hint_identifier!("zoneinfo", "ZoneInfo"); + + #[cfg(all(feature = "experimental-inspect", not(Py_3_9)))] + const OUTPUT_TYPE: PyStaticExpr = PyTzInfo::TYPE_HINT; + + fn into_pyobject(self, py: Python<'py>) -> Result { + PyTzInfo::timezone(py, self.name()) + } +} + +impl<'py> IntoPyObject<'py> for &Tz { + type Target = PyTzInfo; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = Tz::OUTPUT_TYPE; + + #[inline] + fn into_pyobject(self, py: Python<'py>) -> Result { + (*self).into_pyobject(py) + } +} + +impl FromPyObject<'_, '_> for Tz { + type Error = PyErr; + + #[cfg(all(feature = "experimental-inspect", Py_3_9))] + const INPUT_TYPE: PyStaticExpr = type_hint_identifier!("zoneinfo", "ZoneInfo"); + + #[cfg(all(feature = "experimental-inspect", not(Py_3_9)))] + const INPUT_TYPE: PyStaticExpr = PyTzInfo::TYPE_HINT; + + fn extract(ob: Borrowed<'_, '_, PyAny>) -> Result { + Tz::from_str( + &ob.getattr(intern!(ob.py(), "key"))? + .extract::>()?, + ) + .map_err(|e| PyValueError::new_err(e.to_string())) + } +} + +#[cfg(all(test, not(windows)))] // Troubles loading timezones on Windows +mod tests { + use super::*; + use crate::prelude::PyAnyMethods; + use crate::types::IntoPyDict; + use crate::types::PyTzInfo; + use crate::Bound; + use crate::Python; + use chrono::offset::LocalResult; + use chrono::NaiveDate; + use chrono::{DateTime, Utc}; + use chrono_tz::Tz; + + #[test] + fn test_frompyobject() { + Python::attach(|py| { + assert_eq!( + new_zoneinfo(py, "Europe/Paris").extract::().unwrap(), + Tz::Europe__Paris + ); + assert_eq!(new_zoneinfo(py, "UTC").extract::().unwrap(), Tz::UTC); + assert_eq!( + new_zoneinfo(py, "Etc/GMT-5").extract::().unwrap(), + Tz::Etc__GMTMinus5 + ); + }); + } + + #[test] + fn test_ambiguous_datetime_to_pyobject() { + let dates = [ + DateTime::::from_str("2020-10-24 23:00:00 UTC").unwrap(), + DateTime::::from_str("2020-10-25 00:00:00 UTC").unwrap(), + DateTime::::from_str("2020-10-25 01:00:00 UTC").unwrap(), + ]; + + let dates = dates.map(|dt| dt.with_timezone(&Tz::Europe__London)); + + assert_eq!( + dates.map(|dt| dt.to_string()), + [ + "2020-10-25 00:00:00 BST", + "2020-10-25 01:00:00 BST", + "2020-10-25 01:00:00 GMT" + ] + ); + + let dates = Python::attach(|py| { + let pydates = dates.map(|dt| dt.into_pyobject(py).unwrap()); + assert_eq!( + pydates + .clone() + .map(|dt| dt.getattr("hour").unwrap().extract::().unwrap()), + [0, 1, 1] + ); + + assert_eq!( + pydates + .clone() + .map(|dt| dt.getattr("fold").unwrap().extract::().unwrap() > 0), + [false, false, true] + ); + + pydates.map(|dt| dt.extract::>().unwrap()) + }); + + assert_eq!( + dates.map(|dt| dt.to_string()), + [ + "2020-10-25 00:00:00 BST", + "2020-10-25 01:00:00 BST", + "2020-10-25 01:00:00 GMT" + ] + ); + } + + #[test] + fn test_nonexistent_datetime_from_pyobject() { + // Pacific_Apia skipped the 30th of December 2011 entirely + + let naive_dt = NaiveDate::from_ymd_opt(2011, 12, 30) + .unwrap() + .and_hms_opt(2, 0, 0) + .unwrap(); + let tz = Tz::Pacific__Apia; + + // sanity check + assert_eq!(naive_dt.and_local_timezone(tz), LocalResult::None); + + Python::attach(|py| { + // create as a Python object manually + let py_tz = tz.into_pyobject(py).unwrap(); + let py_dt_naive = naive_dt.into_pyobject(py).unwrap(); + let py_dt = py_dt_naive + .call_method( + "replace", + (), + Some(&[("tzinfo", py_tz)].into_py_dict(py).unwrap()), + ) + .unwrap(); + + // now try to extract + let err = py_dt.extract::>().unwrap_err(); + assert_eq!(err.to_string(), "ValueError: The datetime datetime.datetime(2011, 12, 30, 2, 0, tzinfo=zoneinfo.ZoneInfo(key='Pacific/Apia')) contains an incompatible timezone"); + }); + } + + #[test] + #[cfg(not(Py_GIL_DISABLED))] // https://github.com/python/cpython/issues/116738#issuecomment-2404360445 + fn test_into_pyobject() { + Python::attach(|py| { + let assert_eq = |l: Bound<'_, PyTzInfo>, r: Bound<'_, PyTzInfo>| { + assert!(l.eq(&r).unwrap(), "{l:?} != {r:?}"); + }; + + assert_eq( + Tz::Europe__Paris.into_pyobject(py).unwrap(), + new_zoneinfo(py, "Europe/Paris"), + ); + assert_eq(Tz::UTC.into_pyobject(py).unwrap(), new_zoneinfo(py, "UTC")); + assert_eq( + Tz::Etc__GMTMinus5.into_pyobject(py).unwrap(), + new_zoneinfo(py, "Etc/GMT-5"), + ); + }); + } + + fn new_zoneinfo<'py>(py: Python<'py>, name: &str) -> Bound<'py, PyTzInfo> { + PyTzInfo::timezone(py, name).unwrap() + } +} diff --git a/vendor/pyo3/src/conversions/either.rs b/vendor/pyo3/src/conversions/either.rs new file mode 100644 index 0000000..5c40511 --- /dev/null +++ b/vendor/pyo3/src/conversions/either.rs @@ -0,0 +1,173 @@ +#![cfg(feature = "either")] + +//! Conversion to/from +//! [either](https://docs.rs/either/ "A library for easy idiomatic error handling and reporting in Rust applications")’s +//! [`Either`] type to a union of two Python types. +//! +//! Use of a generic sum type like [either] is common when you want to either accept one of two possible +//! types as an argument or return one of two possible types from a function, without having to define +//! a helper type manually yourself. +//! +//! # Setup +//! +//! To use this feature, add this to your **`Cargo.toml`**: +//! +//! ```toml +//! [dependencies] +//! ## change * to the version you want to use, ideally the latest. +//! either = "*" +#![doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"), "\", features = [\"either\"] }")] +//! ``` +//! +//! Note that you must use compatible versions of either and PyO3. +//! The required either version may vary based on the version of PyO3. +//! +//! # Example: Convert a `int | str` to `Either`. +//! +//! ```rust +//! use either::Either; +//! use pyo3::{Python, PyResult, IntoPyObject, types::PyAnyMethods}; +//! +//! fn main() -> PyResult<()> { +//! Python::initialize(); +//! Python::attach(|py| { +//! // Create a string and an int in Python. +//! let py_str = "crab".into_pyobject(py)?; +//! let py_int = 42i32.into_pyobject(py)?; +//! // Now convert it to an Either. +//! let either_str: Either = py_str.extract()?; +//! let either_int: Either = py_int.extract()?; +//! Ok(()) +//! }) +//! } +//! ``` +//! +//! [either](https://docs.rs/either/ "A library for easy idiomatic error handling and reporting in Rust applications")’s + +#[cfg(feature = "experimental-inspect")] +use crate::inspect::PyStaticExpr; +#[cfg(feature = "experimental-inspect")] +use crate::type_hint_union; +use crate::{ + exceptions::PyTypeError, Borrowed, Bound, FromPyObject, IntoPyObject, IntoPyObjectExt, PyAny, + PyErr, Python, +}; +use either::Either; + +#[cfg_attr(docsrs, doc(cfg(feature = "either")))] +impl<'py, L, R> IntoPyObject<'py> for Either +where + L: IntoPyObject<'py>, + R: IntoPyObject<'py>, +{ + type Target = PyAny; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = type_hint_union!(L::OUTPUT_TYPE, R::OUTPUT_TYPE); + + fn into_pyobject(self, py: Python<'py>) -> Result { + match self { + Either::Left(l) => l.into_bound_py_any(py), + Either::Right(r) => r.into_bound_py_any(py), + } + } +} + +#[cfg_attr(docsrs, doc(cfg(feature = "either")))] +impl<'a, 'py, L, R> IntoPyObject<'py> for &'a Either +where + &'a L: IntoPyObject<'py>, + &'a R: IntoPyObject<'py>, +{ + type Target = PyAny; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = type_hint_union!(<&L>::OUTPUT_TYPE, <&R>::OUTPUT_TYPE); + + fn into_pyobject(self, py: Python<'py>) -> Result { + match self { + Either::Left(l) => l.into_bound_py_any(py), + Either::Right(r) => r.into_bound_py_any(py), + } + } +} + +#[cfg_attr(docsrs, doc(cfg(feature = "either")))] +impl<'a, 'py, L, R> FromPyObject<'a, 'py> for Either +where + L: FromPyObject<'a, 'py>, + R: FromPyObject<'a, 'py>, +{ + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = type_hint_union!(L::INPUT_TYPE, R::INPUT_TYPE); + + #[inline] + fn extract(obj: Borrowed<'a, 'py, PyAny>) -> Result { + if let Ok(l) = obj.extract::() { + Ok(Either::Left(l)) + } else if let Ok(r) = obj.extract::() { + Ok(Either::Right(r)) + } else { + // TODO: it might be nice to use the `type_input()` name here once `type_input` + // is not experimental, rather than the Rust type names. + let err_msg = format!( + "failed to convert the value to 'Union[{}, {}]'", + core::any::type_name::(), + core::any::type_name::() + ); + Err(PyTypeError::new_err(err_msg)) + } + } +} + +#[cfg(test)] +mod tests { + use alloc::borrow::Cow; + + use crate::exceptions::PyTypeError; + use crate::{IntoPyObject, Python}; + + use crate::types::PyAnyMethods; + use either::Either; + + #[test] + fn test_either_conversion() { + type E = Either; + type E1 = Either; + type E2 = Either; + + Python::attach(|py| { + let l = E::Left(42); + let obj_l = (&l).into_pyobject(py).unwrap(); + assert_eq!(obj_l.extract::().unwrap(), 42); + assert_eq!(obj_l.extract::().unwrap(), l); + + let r = E::Right("foo".to_owned()); + let obj_r = (&r).into_pyobject(py).unwrap(); + assert_eq!(obj_r.extract::>().unwrap(), "foo"); + assert_eq!(obj_r.extract::().unwrap(), r); + + let obj_s = "foo".into_pyobject(py).unwrap(); + let err = obj_s.extract::().unwrap_err(); + assert!(err.is_instance_of::(py)); + assert_eq!( + err.to_string(), + "TypeError: failed to convert the value to 'Union[i32, f32]'" + ); + + let obj_i = 42i32.into_pyobject(py).unwrap(); + assert_eq!(obj_i.extract::().unwrap(), E1::Left(42)); + assert_eq!(obj_i.extract::().unwrap(), E2::Left(42.0)); + + let obj_f = 42.0f64.into_pyobject(py).unwrap(); + assert_eq!(obj_f.extract::().unwrap(), E1::Right(42.0)); + assert_eq!(obj_f.extract::().unwrap(), E2::Left(42.0)); + }); + } +} diff --git a/vendor/pyo3/src/conversions/eyre.rs b/vendor/pyo3/src/conversions/eyre.rs new file mode 100644 index 0000000..1aaaaf0 --- /dev/null +++ b/vendor/pyo3/src/conversions/eyre.rs @@ -0,0 +1,196 @@ +#![cfg(feature = "eyre")] + +//! A conversion from +//! [eyre](https://docs.rs/eyre/ "A library for easy idiomatic error handling and reporting in Rust applications.")’s +//! [`Report`] type to [`PyErr`]. +//! +//! Use of an error handling library like [eyre] is common in application code and when you just +//! want error handling to be easy. If you are writing a library or you need more control over your +//! errors you might want to design your own error type instead. +//! +//! When the inner error is a [`PyErr`] without source, it will be extracted out. +//! Otherwise a Python [`RuntimeError`] will be created. +//! You might find that you need to map the error from your Rust code into another Python exception. +//! See [`PyErr::new`] for more information about that. +//! +//! For information about error handling in general, see the [Error handling] chapter of the Rust +//! book. +//! +//! # Setup +//! +//! To use this feature, add this to your **`Cargo.toml`**: +//! +//! ```toml +//! [dependencies] +//! ## change * to the version you want to use, ideally the latest. +//! eyre = "*" +#![doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"), "\", features = [\"eyre\"] }")] +//! ``` +//! +//! Note that you must use compatible versions of eyre and PyO3. +//! The required eyre version may vary based on the version of PyO3. +//! +//! # Example: Propagating a `PyErr` into [`eyre::Report`] +//! +//! ```rust +//! use pyo3::prelude::*; +//! use std::path::PathBuf; +//! +//! // A wrapper around a Rust function. +//! // The pyfunction macro performs the conversion to a PyErr +//! #[pyfunction] +//! fn py_open(filename: PathBuf) -> eyre::Result> { +//! let data = std::fs::read(filename)?; +//! Ok(data) +//! } +//! +//! fn main() { +//! let error = Python::attach(|py| -> PyResult> { +//! let fun = wrap_pyfunction!(py_open, py)?; +//! let text = fun.call1(("foo.txt",))?.extract::>()?; +//! Ok(text) +//! }).unwrap_err(); +//! +//! println!("{}", error); +//! } +//! ``` +//! +//! # Example: Using `eyre` in general +//! +//! Note that you don't need this feature to convert a [`PyErr`] into an [`eyre::Report`], because +//! it can already convert anything that implements [`Error`](core::error::Error): +//! +//! ```rust +//! use pyo3::prelude::*; +//! use pyo3::types::PyBytes; +//! +//! // An example function that must handle multiple error types. +//! // +//! // To do this you usually need to design your own error type or use +//! // `Box`. `eyre` is a convenient alternative for this. +//! pub fn decompress(bytes: &[u8]) -> eyre::Result { +//! // An arbitrary example of a Python api you +//! // could call inside an application... +//! // This might return a `PyErr`. +//! let res = Python::attach(|py| { +//! let zlib = PyModule::import(py, "zlib")?; +//! let decompress = zlib.getattr("decompress")?; +//! let bytes = PyBytes::new(py, bytes); +//! let value = decompress.call1((bytes,))?; +//! value.extract::>() +//! })?; +//! +//! // This might be a `FromUtf8Error`. +//! let text = String::from_utf8(res)?; +//! +//! Ok(text) +//! } +//! +//! fn main() -> eyre::Result<()> { +//! let bytes: &[u8] = b"x\x9c\x8b\xcc/U(\xce\xc8/\xcdIQ((\xcaOJL\xca\xa9T\ +//! (-NU(\xc9HU\xc8\xc9LJ\xcbI,IUH.\x02\x91\x99y\xc5%\ +//! \xa9\x89)z\x00\xf2\x15\x12\xfe"; +//! let text = decompress(bytes)?; +//! +//! println!("The text is \"{}\"", text); +//! # assert_eq!(text, "You should probably use the libflate crate instead."); +//! Ok(()) +//! } +//! ``` +//! +//! [eyre]: https://docs.rs/eyre/ "A library for easy idiomatic error handling and reporting in Rust applications." +//! [`RuntimeError`]: https://docs.python.org/3/library/exceptions.html#RuntimeError "Built-in Exceptions — Python documentation" +//! [Error handling]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html "Recoverable Errors with Result - The Rust Programming Language" + +use crate::exceptions::PyRuntimeError; +use crate::PyErr; +use eyre::Report; + +/// Converts [`eyre::Report`] to a [`PyErr`] containing a [`PyRuntimeError`]. +/// +/// If you want to raise a different Python exception you will have to do so manually. See +/// [`PyErr::new`] for more information about that. +impl From for PyErr { + fn from(mut error: Report) -> Self { + // Errors containing a PyErr without chain or context are returned as the underlying error + if error.source().is_none() { + error = match error.downcast::() { + Ok(py_err) => return py_err, + Err(error) => error, + }; + } + PyRuntimeError::new_err(format!("{error:?}")) + } +} + +#[cfg(test)] +mod tests { + use crate::exceptions::{PyRuntimeError, PyValueError}; + use crate::prelude::*; + use crate::types::IntoPyDict; + + use eyre::{bail, eyre, Report, Result, WrapErr}; + + fn f() -> Result<()> { + use std::io; + bail!(io::Error::new(io::ErrorKind::PermissionDenied, "oh no!")); + } + + fn g() -> Result<()> { + f().wrap_err("f failed") + } + + fn h() -> Result<()> { + g().wrap_err("g failed") + } + + #[test] + fn test_pyo3_exception_contents() { + let err = h().unwrap_err(); + let expected_contents = format!("{err:?}"); + let pyerr = PyErr::from(err); + + Python::attach(|py| { + let locals = [("err", pyerr)].into_py_dict(py).unwrap(); + let pyerr = py.run(c"raise err", None, Some(&locals)).unwrap_err(); + assert_eq!(pyerr.value(py).to_string(), expected_contents); + }) + } + + fn k() -> Result<()> { + Err(eyre!("Some sort of error")) + } + + #[test] + fn test_pyo3_exception_contents2() { + let err = k().unwrap_err(); + let expected_contents = format!("{err:?}"); + let pyerr = PyErr::from(err); + + Python::attach(|py| { + let locals = [("err", pyerr)].into_py_dict(py).unwrap(); + let pyerr = py.run(c"raise err", None, Some(&locals)).unwrap_err(); + assert_eq!(pyerr.value(py).to_string(), expected_contents); + }) + } + + #[test] + fn test_pyo3_unwrap_simple_err() { + let origin_exc = PyValueError::new_err("Value Error"); + let report: Report = origin_exc.into(); + let converted: PyErr = report.into(); + assert!(Python::attach( + |py| converted.is_instance_of::(py) + )) + } + #[test] + fn test_pyo3_unwrap_complex_err() { + let origin_exc = PyValueError::new_err("Value Error"); + let mut report: Report = origin_exc.into(); + report = report.wrap_err("Wrapped"); + let converted: PyErr = report.into(); + assert!(Python::attach( + |py| converted.is_instance_of::(py) + )) + } +} diff --git a/vendor/pyo3/src/conversions/hashbrown.rs b/vendor/pyo3/src/conversions/hashbrown.rs new file mode 100644 index 0000000..c841523 --- /dev/null +++ b/vendor/pyo3/src/conversions/hashbrown.rs @@ -0,0 +1,246 @@ +#![cfg(feature = "hashbrown")] + +//! Conversions to and from [hashbrown](https://docs.rs/hashbrown/)’s +//! `HashMap` and `HashSet`. +//! +//! # Setup +//! +//! To use this feature, add this to your **`Cargo.toml`**: +//! +//! ```toml +//! [dependencies] +//! # change * to the latest versions +//! hashbrown = "*" +#![doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"), "\", features = [\"hashbrown\"] }")] +//! ``` +//! +//! Note that you must use compatible versions of hashbrown and PyO3. +//! The required hashbrown version may vary based on the version of PyO3. +#[cfg(feature = "experimental-inspect")] +use crate::inspect::PyStaticExpr; +use crate::{ + conversion::{FromPyObjectOwned, IntoPyObject}, + types::{ + any::PyAnyMethods, dict::PyDictMethods, frozenset::PyFrozenSetMethods, set::PySetMethods, + PyDict, PyFrozenSet, PySet, + }, + Borrowed, Bound, FromPyObject, PyAny, PyErr, PyResult, Python, +}; +#[cfg(feature = "experimental-inspect")] +use crate::{type_hint_subscript, type_hint_union, PyTypeInfo}; +use core::hash; + +impl<'py, K, V, H> IntoPyObject<'py> for hashbrown::HashMap +where + K: IntoPyObject<'py> + Eq + hash::Hash, + V: IntoPyObject<'py>, + H: hash::BuildHasher, +{ + type Target = PyDict; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = + type_hint_subscript!(PyDict::TYPE_HINT, K::OUTPUT_TYPE, V::OUTPUT_TYPE); + + fn into_pyobject(self, py: Python<'py>) -> Result { + let dict = PyDict::new(py); + for (k, v) in self { + dict.set_item(k, v)?; + } + Ok(dict) + } +} + +impl<'a, 'py, K, V, H> IntoPyObject<'py> for &'a hashbrown::HashMap +where + &'a K: IntoPyObject<'py> + Eq + hash::Hash, + &'a V: IntoPyObject<'py>, + H: hash::BuildHasher, +{ + type Target = PyDict; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = + type_hint_subscript!(PyDict::TYPE_HINT, <&K>::OUTPUT_TYPE, <&V>::OUTPUT_TYPE); + + fn into_pyobject(self, py: Python<'py>) -> Result { + let dict = PyDict::new(py); + for (k, v) in self { + dict.set_item(k, v)?; + } + Ok(dict) + } +} + +impl<'py, K, V, S> FromPyObject<'_, 'py> for hashbrown::HashMap +where + K: FromPyObjectOwned<'py> + Eq + hash::Hash, + V: FromPyObjectOwned<'py>, + S: hash::BuildHasher + Default, +{ + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = + type_hint_subscript!(PyDict::TYPE_HINT, K::INPUT_TYPE, V::INPUT_TYPE); + + fn extract(ob: Borrowed<'_, 'py, PyAny>) -> Result { + let dict = ob.cast::()?; + let mut ret = hashbrown::HashMap::with_capacity_and_hasher(dict.len(), S::default()); + for (k, v) in dict.iter() { + ret.insert( + k.extract().map_err(Into::into)?, + v.extract().map_err(Into::into)?, + ); + } + Ok(ret) + } +} + +impl<'py, K, H> IntoPyObject<'py> for hashbrown::HashSet +where + K: IntoPyObject<'py> + Eq + hash::Hash, + H: hash::BuildHasher, +{ + type Target = PySet; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = type_hint_subscript!(PySet::TYPE_HINT, K::OUTPUT_TYPE); + + fn into_pyobject(self, py: Python<'py>) -> Result { + PySet::new(py, self) + } +} + +impl<'a, 'py, K, H> IntoPyObject<'py> for &'a hashbrown::HashSet +where + &'a K: IntoPyObject<'py> + Eq + hash::Hash, + H: hash::BuildHasher, +{ + type Target = PySet; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = type_hint_subscript!(PySet::TYPE_HINT, <&K>::OUTPUT_TYPE); + + fn into_pyobject(self, py: Python<'py>) -> Result { + PySet::new(py, self) + } +} + +impl<'py, K, S> FromPyObject<'_, 'py> for hashbrown::HashSet +where + K: FromPyObjectOwned<'py> + Eq + hash::Hash, + S: hash::BuildHasher + Default, +{ + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = type_hint_union!( + type_hint_subscript!(PySet::TYPE_HINT, K::INPUT_TYPE), + type_hint_subscript!(PyFrozenSet::TYPE_HINT, K::INPUT_TYPE) + ); + + fn extract(ob: Borrowed<'_, 'py, PyAny>) -> PyResult { + match ob.cast::() { + Ok(set) => set + .iter() + .map(|any| any.extract().map_err(Into::into)) + .collect(), + Err(err) => { + if let Ok(frozen_set) = ob.cast::() { + frozen_set + .iter() + .map(|any| any.extract().map_err(Into::into)) + .collect() + } else { + Err(PyErr::from(err)) + } + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::types::IntoPyDict; + use std::collections::hash_map::RandomState; + + #[test] + fn test_hashbrown_hashmap_into_pyobject() { + Python::attach(|py| { + let mut map = + hashbrown::HashMap::::with_hasher(RandomState::new()); + map.insert(1, 1); + + let py_map = (&map).into_pyobject(py).unwrap(); + + assert_eq!(py_map.len(), 1); + assert!( + py_map + .get_item(1) + .unwrap() + .unwrap() + .extract::() + .unwrap() + == 1 + ); + assert_eq!(map, py_map.extract().unwrap()); + }); + } + + #[test] + fn test_hashbrown_hashmap_into_dict() { + Python::attach(|py| { + let mut map = + hashbrown::HashMap::::with_hasher(RandomState::new()); + map.insert(1, 1); + + let py_map = map.into_py_dict(py).unwrap(); + + assert_eq!(py_map.len(), 1); + assert_eq!( + py_map + .get_item(1) + .unwrap() + .unwrap() + .extract::() + .unwrap(), + 1 + ); + }); + } + + #[test] + fn test_extract_hashbrown_hashset() { + Python::attach(|py| { + let set = PySet::new(py, [1, 2, 3, 4, 5]).unwrap(); + let hash_set: hashbrown::HashSet = set.extract().unwrap(); + assert_eq!(hash_set, [1, 2, 3, 4, 5].iter().copied().collect()); + + let set = PyFrozenSet::new(py, [1, 2, 3, 4, 5]).unwrap(); + let hash_set: hashbrown::HashSet = set.extract().unwrap(); + assert_eq!(hash_set, [1, 2, 3, 4, 5].iter().copied().collect()); + }); + } + + #[test] + fn test_hashbrown_hashset_into_pyobject() { + Python::attach(|py| { + let hs: hashbrown::HashSet = + [1, 2, 3, 4, 5].iter().cloned().collect(); + + let hso = hs.clone().into_pyobject(py).unwrap(); + + assert_eq!(hs, hso.extract().unwrap()); + }); + } +} diff --git a/vendor/pyo3/src/conversions/indexmap.rs b/vendor/pyo3/src/conversions/indexmap.rs new file mode 100644 index 0000000..8088749 --- /dev/null +++ b/vendor/pyo3/src/conversions/indexmap.rs @@ -0,0 +1,251 @@ +#![cfg(feature = "indexmap")] + +//! Conversions to and from [indexmap](https://docs.rs/indexmap/)’s +//! `IndexMap`. +//! +//! [`indexmap::IndexMap`] is a hash table that is closely compatible with the standard [`std::collections::HashMap`], +//! with the difference that it preserves the insertion order when iterating over keys. It was inspired +//! by Python's 3.6+ dict implementation. +//! +//! Dictionary order is guaranteed to be insertion order in Python, hence IndexMap is a good candidate +//! for maintaining an equivalent behaviour in Rust. +//! +//! # Setup +//! +//! To use this feature, add this to your **`Cargo.toml`**: +//! +//! ```toml +//! [dependencies] +//! # change * to the latest versions +//! indexmap = "*" +#![doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"), "\", features = [\"indexmap\"] }")] +//! ``` +//! +//! Note that you must use compatible versions of indexmap and PyO3. +//! The required indexmap version may vary based on the version of PyO3. +//! +//! # Examples +//! +//! Using [indexmap](https://docs.rs/indexmap) to return a dictionary with some statistics +//! about a list of numbers. Because of the insertion order guarantees, the Python code will +//! always print the same result, matching users' expectations about Python's dict. +//! ```rust +//! use indexmap::{indexmap, IndexMap}; +//! use pyo3::prelude::*; +//! +//! fn median(data: &Vec) -> f32 { +//! let sorted_data = data.clone().sort(); +//! let mid = data.len() / 2; +//! if data.len() % 2 == 0 { +//! data[mid] as f32 +//! } +//! else { +//! (data[mid] + data[mid - 1]) as f32 / 2.0 +//! } +//! } +//! +//! fn mean(data: &Vec) -> f32 { +//! data.iter().sum::() as f32 / data.len() as f32 +//! } +//! fn mode(data: &Vec) -> f32 { +//! let mut frequency = IndexMap::new(); // we can use IndexMap as any hash table +//! +//! for &element in data { +//! *frequency.entry(element).or_insert(0) += 1; +//! } +//! +//! frequency +//! .iter() +//! .max_by(|a, b| a.1.cmp(&b.1)) +//! .map(|(k, _v)| *k) +//! .unwrap() as f32 +//! } +//! +//! #[pyfunction] +//! fn calculate_statistics(data: Vec) -> IndexMap<&'static str, f32> { +//! indexmap! { +//! "median" => median(&data), +//! "mean" => mean(&data), +//! "mode" => mode(&data), +//! } +//! } +//! +//! #[pymodule] +//! fn my_module(m: &Bound<'_, PyModule>) -> PyResult<()> { +//! m.add_function(wrap_pyfunction!(calculate_statistics, m)?)?; +//! Ok(()) +//! } +//! ``` +//! +//! Python code: +//! ```python +//! from my_module import calculate_statistics +//! +//! data = [1, 1, 1, 3, 4, 5] +//! print(calculate_statistics(data)) +//! # always prints {"median": 2.0, "mean": 2.5, "mode": 1.0} in the same order +//! # if another hash table was used, the order could be random +//! ``` + +use crate::conversion::{FromPyObjectOwned, IntoPyObject}; +#[cfg(feature = "experimental-inspect")] +use crate::inspect::PyStaticExpr; +use crate::types::*; +#[cfg(feature = "experimental-inspect")] +use crate::{type_hint_subscript, PyTypeInfo}; +use crate::{Borrowed, Bound, FromPyObject, PyErr, Python}; +use core::hash; + +impl<'py, K, V, H> IntoPyObject<'py> for indexmap::IndexMap +where + K: IntoPyObject<'py> + Eq + hash::Hash, + V: IntoPyObject<'py>, + H: hash::BuildHasher, +{ + type Target = PyDict; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = + type_hint_subscript!(PyDict::TYPE_HINT, K::OUTPUT_TYPE, V::OUTPUT_TYPE); + + fn into_pyobject(self, py: Python<'py>) -> Result { + let dict = PyDict::new(py); + for (k, v) in self { + dict.set_item(k, v)?; + } + Ok(dict) + } +} + +impl<'a, 'py, K, V, H> IntoPyObject<'py> for &'a indexmap::IndexMap +where + &'a K: IntoPyObject<'py> + Eq + hash::Hash, + &'a V: IntoPyObject<'py>, + H: hash::BuildHasher, +{ + type Target = PyDict; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const OUTPUT_TYPE: PyStaticExpr = + type_hint_subscript!(PyDict::TYPE_HINT, <&K>::OUTPUT_TYPE, <&V>::OUTPUT_TYPE); + + fn into_pyobject(self, py: Python<'py>) -> Result { + let dict = PyDict::new(py); + for (k, v) in self { + dict.set_item(k, v)?; + } + Ok(dict) + } +} + +impl<'py, K, V, S> FromPyObject<'_, 'py> for indexmap::IndexMap +where + K: FromPyObjectOwned<'py> + Eq + hash::Hash, + V: FromPyObjectOwned<'py>, + S: hash::BuildHasher + Default, +{ + type Error = PyErr; + + #[cfg(feature = "experimental-inspect")] + const INPUT_TYPE: PyStaticExpr = + type_hint_subscript!(PyDict::TYPE_HINT, K::INPUT_TYPE, V::INPUT_TYPE); + + fn extract(ob: Borrowed<'_, 'py, PyAny>) -> Result { + let dict = ob.cast::()?; + let mut ret = indexmap::IndexMap::with_capacity_and_hasher(dict.len(), S::default()); + for (k, v) in dict.iter() { + ret.insert( + k.extract().map_err(Into::into)?, + v.extract().map_err(Into::into)?, + ); + } + Ok(ret) + } +} + +#[cfg(test)] +mod test_indexmap { + + use crate::types::*; + use crate::{IntoPyObject, Python}; + + #[test] + fn test_indexmap_indexmap_into_pyobject() { + Python::attach(|py| { + let mut map = indexmap::IndexMap::::new(); + map.insert(1, 1); + + let py_map = (&map).into_pyobject(py).unwrap(); + + assert_eq!(py_map.len(), 1); + assert!( + py_map + .get_item(1) + .unwrap() + .unwrap() + .extract::() + .unwrap() + == 1 + ); + assert_eq!( + map, + py_map.extract::>().unwrap() + ); + }); + } + + #[test] + fn test_indexmap_indexmap_into_dict() { + Python::attach(|py| { + let mut map = indexmap::IndexMap::::new(); + map.insert(1, 1); + + let py_map = map.into_py_dict(py).unwrap(); + + assert_eq!(py_map.len(), 1); + assert_eq!( + py_map + .get_item(1) + .unwrap() + .unwrap() + .extract::() + .unwrap(), + 1 + ); + }); + } + + #[test] + fn test_indexmap_indexmap_insertion_order_round_trip() { + Python::attach(|py| { + let n = 20; + let mut map = indexmap::IndexMap::::new(); + + for i in 1..=n { + if i % 2 == 1 { + map.insert(i, i); + } else { + map.insert(n - i, i); + } + } + + let py_map = (&map).into_py_dict(py).unwrap(); + + let trip_map = py_map.extract::>().unwrap(); + + for (((k1, v1), (k2, v2)), (k3, v3)) in + map.iter().zip(py_map.iter()).zip(trip_map.iter()) + { + let k2 = k2.extract::().unwrap(); + let v2 = v2.extract::().unwrap(); + assert_eq!((k1, v1), (&k2, &v2)); + assert_eq!((k1, v1), (k3, v3)); + assert_eq!((&k2, &v2), (k3, v3)); + } + }); + } +} diff --git a/vendor/pyo3/src/conversions/jiff.rs b/vendor/pyo3/src/conversions/jiff.rs new file mode 100644 index 0000000..593811f --- /dev/null +++ b/vendor/pyo3/src/conversions/jiff.rs @@ -0,0 +1,1318 @@ +#![cfg(feature = "jiff-02")] + +//! Conversions to and from [jiff](https://docs.rs/jiff/)’s `Span`, `SignedDuration`, `TimeZone`, +//! `Offset`, `Date`, `Time`, `DateTime`, `Zoned`, and `Timestamp`. +//! +//! # Setup +//! +//! To use this feature, add this to your **`Cargo.toml`**: +//! +//! ```toml +//! [dependencies] +//! jiff = "0.2" +#![doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"), "\", features = [\"jiff-02\"] }")] +//! ``` +//! +//! Note that you must use compatible versions of jiff and PyO3. +//! The required jiff version may vary based on the version of PyO3. +//! +//! # Example: Convert a `datetime.datetime` to jiff `Zoned` +//! +//! ```rust +//! # #![cfg_attr(windows, allow(unused_imports))] +//! # use jiff_02 as jiff; +//! use jiff::{Zoned, SignedDuration, ToSpan}; +//! use pyo3::{Python, PyResult, IntoPyObject, types::PyAnyMethods}; +//! +//! # #[cfg(windows)] +//! # fn main() -> () {} +//! # #[cfg(not(windows))] +//! fn main() -> PyResult<()> { +//! Python::initialize(); +//! Python::attach(|py| { +//! // Build some jiff values +//! let jiff_zoned = Zoned::now(); +//! let jiff_span = 1.second(); +//! // Convert them to Python +//! let py_datetime = jiff_zoned.into_pyobject(py)?; +//! let py_timedelta = SignedDuration::try_from(jiff_span)?.into_pyobject(py)?; +//! // Do an operation in Python +//! let py_sum = py_datetime.call_method1("__add__", (py_timedelta,))?; +//! // Convert back to Rust +//! let jiff_sum: Zoned = py_sum.extract()?; +//! println!("Zoned: {}", jiff_sum); +//! Ok(()) +//! }) +//! } +//! ``` +use crate::exceptions::{PyTypeError, PyValueError}; +#[cfg(feature = "experimental-inspect")] +use crate::inspect::PyStaticExpr; +use crate::types::{PyAnyMethods, PyNone}; +use crate::types::{PyDate, PyDateTime, PyDelta, PyTime, PyTzInfo, PyTzInfoAccess}; +#[cfg(not(Py_LIMITED_API))] +use crate::types::{PyDateAccess, PyDeltaAccess, PyTimeAccess}; +use crate::{intern, Borrowed, Bound, FromPyObject, IntoPyObject, PyAny, PyErr, PyResult, Python}; +#[cfg(feature = "experimental-inspect")] +use crate::{type_hint_identifier, PyTypeInfo}; +use alloc::borrow::Cow; +use jiff::civil::{Date, DateTime, ISOWeekDate, Time}; +use jiff::tz::{Offset, TimeZone}; +use jiff::{SignedDuration, Span, Timestamp, Zoned}; +#[cfg(feature = "jiff-02")] +use jiff_02 as jiff; + +fn datetime_to_pydatetime<'py>( + py: Python<'py>, + datetime: DateTime, + fold: bool, + timezone: Option<&TimeZone>, +) -> PyResult> { + PyDateTime::new_with_fold( + py, + datetime.year().into(), + datetime.month().try_into()?, + datetime.day().try_into()?, + datetime.hour().try_into()?, + datetime.minute().try_into()?, + datetime.second().try_into()?, + (datetime.subsec_nanosecond() / 1000).try_into()?, + timezone + .map(|tz| tz.into_pyobject(py)) + .transpose()? + .as_ref(), + fold, + ) +} + +#[cfg(not(Py_LIMITED_API))] +fn pytime_to_time(time: &impl PyTimeAccess) -> PyResult