This commit is contained in:
Nienna 2026-09-02 21:48:27 +08:00
commit 1e75612e82
1203 changed files with 496046 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

269
Cargo.lock generated Normal file
View file

@ -0,0 +1,269 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "cc"
version = "1.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96"
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 = "datastream-client"
version = "0.0.0"
[[package]]
name = "datastream-server"
version = "0.0.0"
dependencies = [
"dns",
"http",
"postgresql-client",
"rustls",
"rustls-pki-types",
"uri",
"webpki-roots",
]
[[package]]
name = "dns"
version = "0.0.0"
dependencies = [
"uri",
]
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "getrandom"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "html"
version = "0.0.0"
[[package]]
name = "http"
version = "0.0.0"
dependencies = [
"rustls",
"rustls-pki-types",
"time",
"uri",
"webpki-roots",
]
[[package]]
name = "libc"
version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "once_cell"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "postgresql-client"
version = "0.0.0"
[[package]]
name = "ring"
version = "0.17.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
dependencies = [
"cc",
"cfg-if",
"getrandom",
"libc",
"untrusted",
"windows-sys",
]
[[package]]
name = "rustls"
version = "0.23.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f"
dependencies = [
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-pki-types"
version = "1.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9"
dependencies = [
"zeroize",
]
[[package]]
name = "rustls-webpki"
version = "0.103.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
name = "shlex"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "time"
version = "0.0.0"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "uri"
version = "0.0.0"
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "web-server"
version = "0.0.0"
dependencies = [
"rustls",
"rustls-pki-types",
"uri",
"webpki-roots",
]
[[package]]
name = "webpki-roots"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[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"
[[package]]
name = "zeroize"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"

13
Cargo.toml Normal file
View file

@ -0,0 +1,13 @@
[workspace]
resolver = "3"
members = [
"datastream-server",
"datastream-client",
"postgresql-client",
"html",
"http",
"uri",
"dns",
"time",
"web-server",
]

View file

@ -0,0 +1,6 @@
[package]
name = "datastream-client"
version = "0.0.0"
edition = "2024"
[dependencies]

View file

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

View file

@ -0,0 +1,13 @@
[package]
name = "datastream-server"
version = "0.0.0"
edition = "2024"
[dependencies]
postgresql-client = {path = "../postgresql-client"}
uri = { path = "../uri" }
http = { path = "../http" }
dns = { path = "../dns" }
rustls = { version = "0.23.41", default-features = false, features = ["std", "tls12", "ring"] }
rustls-pki-types = "1.14.1"
webpki-roots = "1.0.8"

View file

@ -0,0 +1,75 @@
#![warn(clippy::todo, clippy::unimplemented)]
use std::{io::{Read, Result as IoResult, Write}, net::{IpAddr, TcpStream}, sync::Arc};
use postgresql_client::{PsqlSession, Location};
use uri::Host;
use http::{Response, parse::parse_response, Header, Request, RequestTarget};
fn main() {
println!("Hello, world!");
let psql_session = PsqlSession::connect(None).unwrap();
}
fn todostuff() {
todo!()
}
//WIP: Tear apart and reconfigure structure.
fn fetch_resource_http(host: Host, path: String) -> Result<Response, String> {
let request = Request {
method: http::Method::Get,
version: http::HttpVersion::Http11,
target: RequestTarget::Origin(path),
headers: vec![Header::Host(host.clone())],
body: vec![],
};
//Connect to a host.
let mut connection = TcpStream::connect((match host {
Host::Ip(ip_addr) => ip_addr,
Host::Name(domain) => dns::lookup_via_system(domain).unwrap()[0],
}, 443)).unwrap();
// Negotiate a TLS connection.
let root_store = rustls::RootCertStore::from_iter(
webpki_roots::TLS_SERVER_ROOTS
.iter()
.cloned(),
);
let config = rustls::ClientConfig::builder()
.with_root_certificates(root_store)
.with_no_client_auth();
let rc_config = Arc::new(config);
let example_com = "example.com".try_into().unwrap();
let mut client = rustls::ClientConnection::new(rc_config, example_com).unwrap();
//Get the writer
let mut writer = client.writer();
// Start sending data
request.write_to(&mut writer).unwrap();
loop {
let mut buf = vec!();
if client.wants_read() && connection.peek(&mut buf).is_ok() {
client.read_tls(&mut connection).unwrap();
client.process_new_packets().unwrap();
let mut plaintext = vec!();
client.reader().read_to_end(&mut plaintext).unwrap();
match parse_response(&plaintext) {
Ok(Some(r)) => return Ok(r), //We have a complete response.
Ok(None) => continue, // We need more bytes, keep reading.
Err(e) => panic!(), // Some error, return.
};
}
}
}

7
dns/Cargo.toml Normal file
View file

@ -0,0 +1,7 @@
[package]
name = "dns"
version = "0.0.0"
edition = "2024"
[dependencies]
uri = {path = "../uri"}

2
dns/README.md Normal file
View file

@ -0,0 +1,2 @@
A basic dns lookup library.
Trying to be just a bit more complicated that using the system lookup, with options for custom dns server lookup

208
dns/src/lib.rs Normal file
View file

@ -0,0 +1,208 @@
mod parse;
mod message;
use message::{Header};
use uri::HostName;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
#[derive(Debug,Copy,Clone)]
pub enum Error {
ServerNotFound,
RecordNotFound,
ConnectionTerminated,
}
pub type Result<T> = std::result::Result<T, Error>;
#[repr(u16)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RecordType {
Reserved = 0,
A = 1,
NS = 2,
MD = 3,
MF = 4,
CNAME = 5,
SOA = 6,
MB = 7,
MG = 8,
MR = 9,
NULL = 10,
WKS = 11,
PTR = 12,
HINFO = 13,
MINFO = 14,
MX = 15,
TXT = 16,
RP = 17,
AFSDB = 18,
X25 = 19,
ISDN = 20,
RT = 21,
NSAP = 22,
NSAP_PTR = 23,
SIG = 24,
KEY = 25,
PX = 26,
GPOS = 27,
AAAA = 28,
LOC = 29,
NXT = 30,
EID = 31,
NIMLOC = 32,
SRV = 33,
ATMA = 34,
NAPTR = 35,
KX = 36,
CERT = 37,
A6 = 38,
DNAME = 39,
SINK = 40,
OPT = 41,
APL = 42,
DS = 43,
SSHFP = 44,
IPSECKEY = 45,
RRSIG = 46,
NSEC = 47,
DNSKEY = 48,
DHCID = 49,
NSEC3 = 50,
NSEC3PARAM = 51,
TLSA = 52,
SMIMEA = 53,
HIP = 55,
NINFO = 56,
RKEY = 57,
TALINK = 58,
CDS = 59,
CDNSKEY = 60,
OPENPGPKEY = 61,
CSYNC = 62,
ZONEMD = 63,
SVCB = 64,
HTTPS = 65,
DSYNC = 66,
HHIT = 67,
BRID = 68,
SPF = 99,
UINFO = 100,
UID = 101,
GID = 102,
UNSPEC = 103,
NID = 104,
L32 = 105,
L64 = 106,
LP = 107,
EUI48 = 108,
EUI64 = 109,
NXNAME = 128,
TKEY = 249,
TSIG = 250,
IXFR = 251,
AXFR = 252,
MAILB = 253,
MAILA = 254,
ANY = 255,
URI = 256,
CAA = 257,
AVC = 258,
DOA = 259,
AMTRELAY = 260,
RESINFO = 261,
WALLET = 262,
CLA = 263,
IPN = 264,
TA = 32768,
DLV = 32769,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Record {
A {
addr: Ipv4Addr,
},
AAAA {
addr: Ipv6Addr,
},
NS {
host: String,
},
CNAME {
host: String,
},
SOA {
mname: String,
rname: String,
serial: u32,
refresh: u32,
retry: u32,
expire: u32,
minimum: u32,
},
MX {
preference: u16,
exchange: String,
},
TXT {
text: Vec<String>,
},
SRV {
priority: u16,
weight: u16,
port: u16,
target: String,
},
PTR {
host: String,
},
CAA {
flags: u8,
tag: String,
value: Vec<u8>,
},
DS {
key_tag: u16,
algorithm: u8,
digest_type: u8,
digest: Vec<u8>,
},
DNSKEY {
flags: u16,
protocol: u8,
algorithm: u8,
public_key: Vec<u8>,
},
RRSIG {
type_covered: u16,
algorithm: u8,
labels: u8,
original_ttl: u32,
signature_expiration: u32,
signature_inception: u32,
key_tag: u16,
signer_name: String,
signature: Vec<u8>,
},
Unknown {
typ: u16,
data: Vec<u8>,
},
}
pub fn lookup_via_system(name: HostName) -> Result<Vec<IpAddr>> {
todo!()
}
pub fn lookup_via_server(server: IpAddr) -> Result<Record> {
todo!()
}
#[cfg(test)]
mod tests {
use super::*;
}

48
dns/src/message.rs Normal file
View file

@ -0,0 +1,48 @@
pub struct Header {
id: u16,
message_type: MessageType,
query_type: QueryType,
is_authority: bool,
is_truncated: bool,
recursion_desired: bool,
recursion_available: bool,
response_code: ResponseCode,
num_question_entries: u16,
num_answer_entries: u16,
num_nameserver_records: u16,
num_additonal_records: u16,
}
pub struct Question {
}
pub struct Resource {
}
#[repr(u8)]
pub enum MessageType {
Query = 0,
Response = 1,
}
#[repr(u8)]
pub enum QueryType {
Query = 0,
InverseQuery = 1,
Status = 2,
Other = 15,
}
#[repr(u8)]
pub enum ResponseCode {
Ok = 0,
FormatError = 1,
ServerFailure = 2,
NameError = 3,
NotImplemented = 4,
Refused = 5,
Other = 15,
}

24
dns/src/parse.rs Normal file
View file

@ -0,0 +1,24 @@
use crate::message::Header;
enum ParseError {
}
type Result<T> = std::result::Result<T,ParseError>;
fn parse_header(input: &[u8]) -> Result<Option<Header>> {
todo!()
}
fn parse_question_section(input: &[u8]) -> Result<Option<Header>> {
todo!()
}
fn parse_record_section(input: &[u8]) -> Result<Option<Header>> {
todo!()
}
fn parse_message(input: &[u8]) -> Result<Option<Header>> {
todo!()
}

6
html/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "html"
version = "0.0.0"
edition = "2024"
[dependencies]

14
html/src/lib.rs Normal file
View file

@ -0,0 +1,14 @@
pub fn add(left: u64, right: u64) -> u64 {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}

6
http/.cargo/config.toml Normal file
View file

@ -0,0 +1,6 @@
[source.crates-io]
replace-with = "vendored-sources"
[source.vendored-sources]
directory = "vendor"

11
http/Cargo.toml Normal file
View file

@ -0,0 +1,11 @@
[package]
name = "http"
version = "0.0.0"
edition = "2024"
[dependencies]
rustls = { version = "0.23.41", default-features = false, features = ["std", "tls12", "ring"] }
rustls-pki-types = "1.14.1"
webpki-roots = "1.0.8"
uri = { path = "../uri" }
time = { path = "../time" }

36
http/src/header.rs Normal file
View file

@ -0,0 +1,36 @@
use time::GregorianDateTime;
use crate::Host;
//WIP: Research and write more variants
pub enum Header {
Host(Host),
UserAgent(String),
Accept(Vec<(ContentType, Option<f32>)>),
ContentType(ContentType),
AcceptLanguage(Vec<(String, Option<f32>)>),
AcceptEncoding(Vec<(Encoding, Option<f32>)>),
ContentEncoding(Vec<Encoding>),
Cookie(Vec<u8>),
Priority(bool),
IfModifiedSince(GregorianDateTime),
Other(String,String),
}
//WIP: More Variants
pub enum Encoding {
Gzip,
Compress,
Deflate,
Br,
Zstd,
Dcb,
Dcz,
Identity,
Wildcard,
}
//TODO: Research variants and actually write
pub enum ContentType {
}

75
http/src/lib.rs Normal file
View file

@ -0,0 +1,75 @@
#![warn(clippy::todo, clippy::unimplemented)]
mod statuscode;
pub mod parse;
mod request;
mod response;
mod header;
pub use {request::{Request, RequestTarget},
response::{Response}, statuscode::{StatusCode, StatusClass}, header::Header};
use std::fmt::Display;
use parse::ParseError;
pub use uri::Host;
#[derive(Debug, PartialEq)]
pub enum HttpError {
Parse(ParseError),
}
#[derive(Debug, PartialEq)]
pub enum HttpVersion {
Http10,
Http11,
Http20,
Http30,
}
impl Display for HttpVersion {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
HttpVersion::Http10 => "HTTP/1.0",
HttpVersion::Http11 => "HTTP/1.1",
HttpVersion::Http20 => "HTTP/2",
HttpVersion::Http30 => "HTTP/3",
})
}
}
#[derive(Debug, PartialEq)]
pub enum Method {
Get,
Head,
Post,
Put,
Delete,
Connect,
Options,
Trace,
Patch,
}
impl Method {
pub fn from_bytes(bytes: &[u8]) -> Result<Method, ParseError> {
todo!()
}
}
impl Display for Method {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
Method::Get => "GET",
Method::Head => "HEAD",
Method::Post => "POST",
Method::Put => "PUT",
Method::Delete => "DELETE",
Method::Connect => "CONNECT",
Method::Options => "OPTIONS",
Method::Trace => "TRACE",
Method::Patch => "PATCH",
})
}
}

377
http/src/parse.rs Normal file
View file

@ -0,0 +1,377 @@
use crate::{HttpVersion, Method, request::{Request, RequestTarget}, response::Response, statuscode::{StatusClass, StatusCode}};
#[derive(Debug, PartialEq)]
pub enum ParseError {
TooLong,
Malformed,
BadStatusCode,
BadVersion,
InvalidEncoding,
MissingChunkSize,
}
#[derive(Debug, PartialEq)]
pub struct StatusLine {
version: HttpVersion,
status: Status,
reason: Vec<u8>,
}
pub struct RequestLine {
pub method: Method,
pub target: RequestTarget,
pub version: HttpVersion,
}
#[derive(Debug, PartialEq)]
pub struct Status {
pub code: u16,
}
impl Status {
pub fn known(self) -> Option<StatusCode> {
StatusCode::from_u16(self.code)
}
pub fn class(self) -> Option<StatusClass> {
match self.code / 100 {
1 => Some(StatusClass::Informational),
2 => Some(StatusClass::Success),
3 => Some(StatusClass::Redirection),
4 => Some(StatusClass::ClientError),
5 => Some(StatusClass::ServerError),
_ => None,
}
}
}
const MAX_STATUS_LINE_LEN: usize = 8192;
//TODO: Further testing + fuzzing + general onceover
pub fn parse_status_line(input: &[u8], request_type: Method) -> Result<Option<(StatusLine, usize)>, ParseError> {
let search_end = input.len().min(MAX_STATUS_LINE_LEN);
let line_end = match find_crlf(&input[..search_end]) {
Some(pos) => pos,
None => {
if input.len() >= MAX_STATUS_LINE_LEN {
return Err(ParseError::TooLong);
}
return Ok(None);
}
};
let line = &input[..line_end];
let first_space = line.iter().position(|&b| b.is_ascii_whitespace())
.ok_or(ParseError::Malformed)?;
let version_bytes = &line[..first_space];
let after_version = line[first_space + 1..].trim_ascii_start();
let (status_bytes, reason_bytes) = match after_version.iter().position(|&b| b.is_ascii_whitespace()) {
Some(p) => (after_version[..p].trim_ascii_end(), after_version[p + 1..].trim_ascii()),
None => (after_version.trim_ascii_end(), &[][..]),
};
let version = match version_bytes {
b"HTTP/1.1" => HttpVersion::Http11,
b"HTTP/1.0" => HttpVersion::Http10,
_ => return Err(ParseError::BadVersion),
};
if status_bytes.len() != 3 {
return Err(ParseError::BadStatusCode);
}
let mut status: u16 = 0;
for &b in status_bytes {
if !b.is_ascii_digit() {
return Err(ParseError::BadStatusCode);
}
status = status * 10 + (b - b'0') as u16;
}
Ok(Some((
StatusLine {
version,
status: Status { code: status },
reason: reason_bytes.to_vec(),
}, line_end + 2,
)))
}
const MAX_REQUEST_LINE_LEN: usize = 8192;
//TODO: Further testing + fuzzing + general onceover
pub fn parse_request_line(input: &[u8]) -> Result<Option<(RequestLine, usize)>, ParseError> {
let search_end = input.len().min(MAX_REQUEST_LINE_LEN);
let line_end = match find_crlf(&input[..search_end]) {
Some(pos) => pos,
None => {
if input.len() >= MAX_REQUEST_LINE_LEN {
return Err(ParseError::TooLong);
}
return Ok(None);
}
};
let line = &input[..line_end];
let first_space = line.iter().position(|&b| b.is_ascii_whitespace())
.ok_or(ParseError::Malformed)?;
let method_bytes = &line[..first_space];
let after_method = line[first_space + 1..].trim_ascii_start();
let (target_bytes, version_bytes) = match after_method.iter().position(|&b| b.is_ascii_whitespace()) {
Some(p) => (after_method[..p].trim_ascii_end(), after_method[p + 1..].trim_ascii()),
None => (after_method.trim_ascii_end(), &[][..]),
};
let method = Method::from_bytes(method_bytes)?;
let target = RequestTarget::from_bytes(target_bytes)?;
let version = match version_bytes {
b"HTTP/1.1" => HttpVersion::Http11,
b"HTTP/1.0" => HttpVersion::Http10,
_ => return Err(ParseError::BadVersion),
};
Ok(Some((
RequestLine {
method,
target,
version,
}, line_end + 2,
)))
}
const MAX_HEADERS_SECTION_LEN: usize = 8192; //8KiB
//TODO: Further testing + fuzzing + general onceover
fn parse_headers(input: &[u8]) -> Result<Option<(Vec<(String,String)>,usize)>, ParseError> {
//Frame the header section.
//let headers_end = match input.windows(4).position(|w| w == b"\r\n\r\n") {
// Some(pos) => pos,
// None => {
// if input.len() >= MAX_HEADERS_SECTION_LEN {
// return Err(ParseError::TooLong);
// }
// return Ok(None);
// }
//};
let mut headers = &input[..];
let mut fields = vec!();
let mut consumed = 0;
loop {
//if headers.is_empty() { break };
let line_end = match find_crlf(headers) {
Some(e) => e,
None => return Ok(None),
};
let line = &headers[..line_end];
consumed += line_end + 2;
if consumed > MAX_HEADERS_SECTION_LEN { return Err(ParseError::TooLong)}
if line.is_empty() { break };
let colon = line.iter().position(|&b| b == b':').ok_or(ParseError::Malformed)?; //Fails if no colon on line.
let field_name = str::from_utf8(&line[..colon]).map_err(|_| ParseError::InvalidEncoding)?.to_owned();
if field_name.trim_ascii_end().len() != field_name.len() { return Err(ParseError::Malformed) }
let field_value = str::from_utf8(&line[colon+1..]).map_err(|_| ParseError::InvalidEncoding)?.trim_ascii().to_owned();
fields.push((field_name,field_value));
headers = &headers[line_end+2..];
}
Ok(Some((fields,consumed)))
}
//TODO: Further testing + fuzzing + general onceover
fn parse_body(input: &[u8], encoding: Encoding) -> Result<Option<(Vec<u8>, usize)>, ParseError> {
match encoding {
Encoding::Length(l) => Ok(Some((input[..l].to_owned(), l))),
Encoding::Chunked => { parse_chunked_body(input) }
}
}
//TODO: Further testing + fuzzing + general onceover
fn parse_chunked_body(input: &[u8]) -> Result<Option<(Vec<u8>, usize)>, ParseError> {
let mut chunks = vec!();
let mut consumed = 0usize;
let mut remaining = &input[..];
loop {
//Chunk size + extensions (ignored) line.
let line_end = match find_crlf(remaining) {
Some(pos) => pos,
None => return Ok(None),
};
if line_end == 0 { return Err(ParseError::MissingChunkSize)};
let chunk_meta = &remaining[..line_end];
let semicolon = chunk_meta.iter().position(|&p| p == b';').unwrap_or(chunk_meta.len());
let chunk_size = usize::from_str_radix(str::from_utf8((&chunk_meta[..semicolon]).trim_ascii()).unwrap(), 16).unwrap();
if chunk_size == 0 { break }
//Chunk body.
remaining = &remaining[line_end+2..]; consumed += line_end+2;
chunks.push(&remaining[..chunk_size]);
if remaining[chunk_size..chunk_size+2] != [b'\r',b'\n'] { return Err(ParseError::Malformed) }
remaining = &remaining[chunk_size+2..]; consumed += chunk_size+2;
}
Ok(Some((chunks.into_iter().flatten().copied().collect(), consumed)))
}
//TODO: Write
pub fn parse_request(input: &[u8]) -> Result<Option<Request>, ParseError> {
todo!()
}
//TODO: Write
pub fn parse_response(input: &[u8]) -> Result<Option<Response>, ParseError> {
todo!()
}
enum Encoding {
Length(usize),
Chunked,
}
fn find_crlf(input: &[u8]) -> Option<usize> {
input.windows(2).position(|w| w == b"\r\n")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_find_crlf() {
assert_eq!(find_crlf(b"\r\n"), Some(0));
assert_eq!(find_crlf(b"\0\r\n"), Some(1));
assert_eq!(find_crlf(b"not here"), None);
assert_eq!(find_crlf(b"\n"), None);
assert_eq!(find_crlf(b"\r"), None);
assert_eq!(find_crlf(b"\n\r"), None);
}
#[test]
fn test_parse_status_line() {
assert_eq!(parse_status_line(b"HTTP/1.1 100 reason\r\nSOMEOTHERSHIT", Method::Get),
Ok(Some(( StatusLine { version: HttpVersion::Http11, status: Status { code: 100 }, reason: b"reason".as_slice().to_owned() },
21,
))));
assert_eq!(parse_status_line(b"HTTP/1.1 300 reason \r\nSOMEOTHERSHIT", Method::Get),
Ok(Some(( StatusLine { version: HttpVersion::Http11, status: Status { code: 300 }, reason: b"reason".as_slice().to_owned() },
35,
))));
assert_eq!(parse_status_line(b"HTTP/1.0 400 Some other reason\r\nSOMEOTHERSHIT", Method::Get),
Ok(Some(( StatusLine { version:HttpVersion::Http10, status: Status { code: 400 }, reason: b"Some other reason".as_slice().to_owned() },
32,
))));
}
#[test]
fn test_parse_status_line_invalid_version() {
assert_eq!(parse_status_line(b"HP/1.0 400 Some other reason\r\nSOMEOTHERSHIT", Method::Get),
Err(ParseError::BadVersion)
);
assert_eq!(parse_status_line(b"HTTP/1.2 400 Some other reason\r\nSOMEOTHERSHIT", Method::Get),
Err(ParseError::BadVersion)
);
assert_eq!(parse_status_line(b"HTTP/2.1 400 Some other reason\r\nSOMEOTHERSHIT", Method::Get),
Err(ParseError::BadVersion)
);
assert_eq!(parse_status_line(b"HTTP/1 400 Some other reason\r\nSOMEOTHERSHIT", Method::Get),
Err(ParseError::BadVersion)
);
assert_eq!(parse_status_line(b"HTTP/3 400 Some other reason\r\nSOMEOTHERSHIT", Method::Get),
Err(ParseError::BadVersion)
);
}
#[test]
fn test_parse_status_line_invalid_code() {
assert_eq!(parse_status_line(b"HTTP/1.1 0400 Some other reason\r\nSOMEOTHERSHIT", Method::Get),
Err(ParseError::BadStatusCode)
);
assert_eq!(parse_status_line(b"HTTP/1.1 4000 Some other reason\r\nSOMEOTHERSHIT", Method::Get),
Err(ParseError::BadStatusCode)
);
assert_eq!(parse_status_line(b"HTTP/1.1 040.0 Some other reason\r\nSOMEOTHERSHIT", Method::Get),
Err(ParseError::BadStatusCode)
);
assert_eq!(parse_status_line(b"HTTP/1.1 04 Some other reason\r\nSOMEOTHERSHIT", Method::Get),
Err(ParseError::BadStatusCode)
);
assert_eq!(parse_status_line(b"HTTP/1.1 0x64 Some other reason\r\nSOMEOTHERSHIT", Method::Get),
Err(ParseError::BadStatusCode)
);
}
#[test]
fn test_parse_status_line_no_reason() {
assert_eq!(parse_status_line(b"HTTP/1.1 100\r\nSOMEOTHERSHIT", Method::Get),
Ok(Some(( StatusLine { version: HttpVersion::Http11, status: Status { code: 100 }, reason: b"".as_slice().to_owned() },
14,
))));
assert_eq!(parse_status_line(b"HTTP/1.1 100 \t \r\nSOMEOTHERSHIT", Method::Get),
Ok(Some(( StatusLine { version: HttpVersion::Http11, status: Status { code: 100 }, reason: b"".as_slice().to_owned() },
17,
))));
}
#[test]
fn test_parse_status_line_empty() {
assert_eq!(parse_status_line(b"\r\n", Method::Get), Err(ParseError::Malformed));
assert_eq!(parse_status_line(b"", Method::Get), Ok(None));
}
#[test]
fn test_parse_status_line_oversize() {
let bytes = [b'1';65521];
assert_eq!(parse_status_line(&bytes, Method::Get), Err(ParseError::TooLong));
}
#[test]
fn test_parse_status_line_incomplete() {
assert_eq!(parse_status_line(b"", Method::Get), Ok(None));
}
#[test]
fn test_parse_headers() {
assert_eq!(parse_headers(b"Field1: Field value is this mate\r\n\r\n"), Ok(Some((vec![("Field1".to_owned(),"Field value is this mate".to_owned())], 36))));
}
#[test]
fn test_parse_headers_whitespace_in_name() {
assert_eq!(parse_headers(b"Field1 : Field value is this mate\r\n\r\n"), Err(ParseError::Malformed));
}
#[test]
fn test_parse_headers_incomplete() {
assert_eq!(parse_headers(b"Field1: field value is this mate \r\n"), Ok(None));
}
#[test]
fn test_parse_headers_too_long() {
let mut bytes = [b'\0';8196];
for i in 0..2049 {
bytes[i*4] = b'f';
bytes[i*4+1] = b':';
bytes[i*4+2] = b'\r';
bytes[i*4+3] = b'\n';
}
assert_eq!(parse_headers(&bytes), Err(ParseError::TooLong));
let mut bytes = [b'\0';8192];
for i in 0..2048 {
bytes[i*4] = b'f';
bytes[i*4+1] = b':';
bytes[i*4+2] = b'\r';
bytes[i*4+3] = b'\n';
}
assert_ne!(parse_headers(&bytes), Err(ParseError::TooLong));
}
}

0
http/src/parse2.rs Normal file
View file

129
http/src/request.rs Normal file
View file

@ -0,0 +1,129 @@
use std::io::{Write, Result as IoResult};
use uri::{Host, Uri};
use time::{Utc};
use crate::{HttpVersion, Method, parse::ParseError, header::Header};
///For Serialization. Does no extra processing of the contents otherwise.
/// Pre-fill with things like required headers, etc.
pub struct Request {
pub method: Method,
pub version: HttpVersion,
pub target: RequestTarget,
pub headers: Vec<Header>,
pub body: Vec<u8>,
}
pub enum RequestTarget {
Origin(String),
Absolute(Uri),
Authority(Host,u16),
Asterisk,
}
impl RequestTarget {
//TODO: Write
pub fn from_bytes(bytes: &[u8]) -> Result<RequestTarget, ParseError> {
todo!()
}
/// Write to a Writer. Outputs in the format expected by HTTP 1.1 for the request target in the request line.
fn write_to<W: Write>(&self, w: &mut W) -> IoResult<()> {
match self {
RequestTarget::Origin(o) => w.write_all(b"/").and(w.write_all(o.as_bytes())),
RequestTarget::Absolute(uri) => uri.write_to(w),
RequestTarget::Authority(host,port) => host.write_to(w).and(w.write_all(b":")).and(w.write_all(port.to_string().as_bytes())),
RequestTarget::Asterisk => w.write_all(b"*"),
}.and(w.write_all(b"/"))
}
}
impl Request {
fn write_request_line<W: Write>(&self, w: &mut W) -> IoResult<()> {
w.write_all(self.method.to_string().as_bytes())?;
w.write_all(b" ")?;
self.target.write_to(w);
w.write_all(b" ")?;
w.write_all(self.version.to_string().as_bytes())?;
w.write_all(b"\r\n")
}
pub fn write_to<W: Write>(&self, w: &mut W) -> IoResult<()> {
self.write_request_line(w)?;
for header in &self.headers {
header.write_to(w)?;
w.write_all(b"\r\n")?;
}
w.write_all(b"\r\n")?;
w.write_all(self.body.as_slice())
}
}
impl Header {
//WIP: More variants
/// Returns true if the header is permitted to be sent in a request.
fn is_request_header(&self) -> bool {
use Header::*;
match self {
Host(_) | UserAgent(_) | Accept(_) => true,
_ => false,
}
}
//WIP: More variants
/// Returns true if the header is permitted to be sent in a response.
fn is_response_header(&self) -> bool {
use Header::*;
match self {
ContentEncoding(_) | ContentType(_) => true,
_ => false,
}
}
fn name_as_bytes(&self) -> &[u8] {
match self {
Header::Host(_) => b"Host",
Header::UserAgent(_) => b"User-Agent",
Header::Accept(_) => b"Accept",
Header::ContentType(_) => b"Content-Type",
Header::AcceptLanguage(_) => b"Accept-Language",
Header::AcceptEncoding(_) => b"Accept-Encoding",
Header::ContentEncoding(_) => b"Content-Encoding",
Header::Cookie(_) => b"Cookie",
Header::Priority(_) => b"Priority",
Header::IfModifiedSince(_) => b"If-Modified-Since",
Header::Other(name, _) => name.as_str().as_bytes(),
}
}
fn value_as_bytes(&self) -> &[u8] {
match self {
Header::Host(host) => todo!(),
Header::UserAgent(agent) => todo!(),
Header::Accept(items) => todo!(),
Header::ContentType(content_type) => todo!(),
Header::AcceptLanguage(items) => todo!(),
Header::AcceptEncoding(items) => todo!(),
Header::ContentEncoding(encodings) => todo!(),
Header::Cookie(items) => todo!(),
Header::Priority(priority) => todo!(),
Header::IfModifiedSince(utc) => todo!(),
Header::Other(_, value) => value.as_str().as_bytes(),
}
}
//TODO: Write
fn write_value_to<W: Write>(&self, w: &mut W) -> IoResult<()> {
todo!();
}
fn write_to<W: Write>(&self, w: &mut W) -> IoResult<()> {
w.write_all(self.name_as_bytes())?;
w.write_all(b": ")?;
w.write_all(self.value_as_bytes())?;
Ok(())
}
}

15
http/src/response.rs Normal file
View file

@ -0,0 +1,15 @@
use std::io::{Write, Result as IoResult};
use uri::{Host, Uri};
use time::{Utc};
use crate::{HttpVersion, Method, header::Header, statuscode::StatusCode};
pub struct Response {
pub status_code: StatusCode,
pub reason: String,
pub version: HttpVersion,
pub headers: Vec<Header>,
pub body: Vec<u8>,
}

316
http/src/statuscode.rs Normal file
View file

@ -0,0 +1,316 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u16)]
pub enum StatusCode {
// 1xx Informational
Continue = 100,
SwitchingProtocols = 101,
Processing = 102,
EarlyHints = 103,
// 2xx Success
Ok = 200,
Created = 201,
Accepted = 202,
NonAuthoritativeInformation = 203,
NoContent = 204,
ResetContent = 205,
PartialContent = 206,
MultiStatus = 207,
AlreadyReported = 208,
ImUsed = 226,
// 3xx Redirection
MultipleChoices = 300,
MovedPermanently = 301,
Found = 302,
SeeOther = 303,
NotModified = 304,
UseProxy = 305,
// 306 is reserved and unused
TemporaryRedirect = 307,
PermanentRedirect = 308,
// 4xx Client Error
BadRequest = 400,
Unauthorized = 401,
PaymentRequired = 402,
Forbidden = 403,
NotFound = 404,
MethodNotAllowed = 405,
NotAcceptable = 406,
ProxyAuthenticationRequired = 407,
RequestTimeout = 408,
Conflict = 409,
Gone = 410,
LengthRequired = 411,
PreconditionFailed = 412,
ContentTooLarge = 413,
UriTooLong = 414,
UnsupportedMediaType = 415,
RangeNotSatisfiable = 416,
ExpectationFailed = 417,
ImATeapot = 418,
MisdirectedRequest = 421,
UnprocessableContent = 422,
Locked = 423,
FailedDependency = 424,
TooEarly = 425,
UpgradeRequired = 426,
PreconditionRequired = 428,
TooManyRequests = 429,
RequestHeaderFieldsTooLarge = 431,
UnavailableForLegalReasons = 451,
// 5xx Server Error
InternalServerError = 500,
NotImplemented = 501,
BadGateway = 502,
ServiceUnavailable = 503,
GatewayTimeout = 504,
HttpVersionNotSupported = 505,
VariantAlsoNegotiates = 506,
InsufficientStorage = 507,
LoopDetected = 508,
NotExtended = 510,
NetworkAuthenticationRequired = 511,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StatusClass {
Informational, // 1xx
Success, // 2xx
Redirection, // 3xx
ClientError, // 4xx
ServerError, // 5xx
}
impl StatusCode {
/// Convert a raw u16 into a StatusCode. Returns None for unrecognized codes.
pub fn from_u16(code: u16) -> Option<Self> {
Some(match code {
100 => Self::Continue,
101 => Self::SwitchingProtocols,
102 => Self::Processing,
103 => Self::EarlyHints,
200 => Self::Ok,
201 => Self::Created,
202 => Self::Accepted,
203 => Self::NonAuthoritativeInformation,
204 => Self::NoContent,
205 => Self::ResetContent,
206 => Self::PartialContent,
207 => Self::MultiStatus,
208 => Self::AlreadyReported,
226 => Self::ImUsed,
300 => Self::MultipleChoices,
301 => Self::MovedPermanently,
302 => Self::Found,
303 => Self::SeeOther,
304 => Self::NotModified,
305 => Self::UseProxy,
307 => Self::TemporaryRedirect,
308 => Self::PermanentRedirect,
400 => Self::BadRequest,
401 => Self::Unauthorized,
402 => Self::PaymentRequired,
403 => Self::Forbidden,
404 => Self::NotFound,
405 => Self::MethodNotAllowed,
406 => Self::NotAcceptable,
407 => Self::ProxyAuthenticationRequired,
408 => Self::RequestTimeout,
409 => Self::Conflict,
410 => Self::Gone,
411 => Self::LengthRequired,
412 => Self::PreconditionFailed,
413 => Self::ContentTooLarge,
414 => Self::UriTooLong,
415 => Self::UnsupportedMediaType,
416 => Self::RangeNotSatisfiable,
417 => Self::ExpectationFailed,
418 => Self::ImATeapot,
421 => Self::MisdirectedRequest,
422 => Self::UnprocessableContent,
423 => Self::Locked,
424 => Self::FailedDependency,
425 => Self::TooEarly,
426 => Self::UpgradeRequired,
428 => Self::PreconditionRequired,
429 => Self::TooManyRequests,
431 => Self::RequestHeaderFieldsTooLarge,
451 => Self::UnavailableForLegalReasons,
500 => Self::InternalServerError,
501 => Self::NotImplemented,
502 => Self::BadGateway,
503 => Self::ServiceUnavailable,
504 => Self::GatewayTimeout,
505 => Self::HttpVersionNotSupported,
506 => Self::VariantAlsoNegotiates,
507 => Self::InsufficientStorage,
508 => Self::LoopDetected,
510 => Self::NotExtended,
511 => Self::NetworkAuthenticationRequired,
_ => return None,
})
}
/// Get the numeric value. Since the enum is #[repr(u16)], this is a no-op cast.
pub fn as_u16(self) -> u16 {
self as u16
}
/// Classify by the hundreds digit.
pub fn class(self) -> StatusClass {
match self.as_u16() / 100 {
1 => StatusClass::Informational,
2 => StatusClass::Success,
3 => StatusClass::Redirection,
4 => StatusClass::ClientError,
5 => StatusClass::ServerError,
_ => unreachable!("all StatusCode variants are 1xx-5xx"),
}
}
pub fn is_informational(self) -> bool { matches!(self.class(), StatusClass::Informational) }
pub fn is_success(self) -> bool { matches!(self.class(), StatusClass::Success) }
pub fn is_redirection(self) -> bool { matches!(self.class(), StatusClass::Redirection) }
pub fn is_client_error(self) -> bool { matches!(self.class(), StatusClass::ClientError) }
pub fn is_server_error(self) -> bool { matches!(self.class(), StatusClass::ServerError) }
/// The default reason phrase. Servers can send anything they like;
/// this is what the registry recommends.
pub fn canonical_reason(self) -> &'static str {
match self {
Self::Continue => "Continue",
Self::SwitchingProtocols => "Switching Protocols",
Self::Processing => "Processing",
Self::EarlyHints => "Early Hints",
Self::Ok => "OK",
Self::Created => "Created",
Self::Accepted => "Accepted",
Self::NonAuthoritativeInformation => "Non-Authoritative Information",
Self::NoContent => "No Content",
Self::ResetContent => "Reset Content",
Self::PartialContent => "Partial Content",
Self::MultiStatus => "Multi-Status",
Self::AlreadyReported => "Already Reported",
Self::ImUsed => "IM Used",
Self::MultipleChoices => "Multiple Choices",
Self::MovedPermanently => "Moved Permanently",
Self::Found => "Found",
Self::SeeOther => "See Other",
Self::NotModified => "Not Modified",
Self::UseProxy => "Use Proxy",
Self::TemporaryRedirect => "Temporary Redirect",
Self::PermanentRedirect => "Permanent Redirect",
Self::BadRequest => "Bad Request",
Self::Unauthorized => "Unauthorized",
Self::PaymentRequired => "Payment Required",
Self::Forbidden => "Forbidden",
Self::NotFound => "Not Found",
Self::MethodNotAllowed => "Method Not Allowed",
Self::NotAcceptable => "Not Acceptable",
Self::ProxyAuthenticationRequired => "Proxy Authentication Required",
Self::RequestTimeout => "Request Timeout",
Self::Conflict => "Conflict",
Self::Gone => "Gone",
Self::LengthRequired => "Length Required",
Self::PreconditionFailed => "Precondition Failed",
Self::ContentTooLarge => "Content Too Large",
Self::UriTooLong => "URI Too Long",
Self::UnsupportedMediaType => "Unsupported Media Type",
Self::RangeNotSatisfiable => "Range Not Satisfiable",
Self::ExpectationFailed => "Expectation Failed",
Self::ImATeapot => "I'm a teapot",
Self::MisdirectedRequest => "Misdirected Request",
Self::UnprocessableContent => "Unprocessable Content",
Self::Locked => "Locked",
Self::FailedDependency => "Failed Dependency",
Self::TooEarly => "Too Early",
Self::UpgradeRequired => "Upgrade Required",
Self::PreconditionRequired => "Precondition Required",
Self::TooManyRequests => "Too Many Requests",
Self::RequestHeaderFieldsTooLarge => "Request Header Fields Too Large",
Self::UnavailableForLegalReasons => "Unavailable For Legal Reasons",
Self::InternalServerError => "Internal Server Error",
Self::NotImplemented => "Not Implemented",
Self::BadGateway => "Bad Gateway",
Self::ServiceUnavailable => "Service Unavailable",
Self::GatewayTimeout => "Gateway Timeout",
Self::HttpVersionNotSupported => "HTTP Version Not Supported",
Self::VariantAlsoNegotiates => "Variant Also Negotiates",
Self::InsufficientStorage => "Insufficient Storage",
Self::LoopDetected => "Loop Detected",
Self::NotExtended => "Not Extended",
Self::NetworkAuthenticationRequired => "Network Authentication Required",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn test_enum() {
}
#[test]
fn test_class() {
}
#[test]
fn is_informational() {
}
#[test]
fn is_success() {
}
#[test]
fn is_redirection() {
}
#[test]
fn is_client_error() {
}
#[test]
fn is_server_error() {
}
#[test]
fn test_canonical_reason() {
assert_eq!(StatusCode::Continue.canonical_reason(), "Continue");
assert_ne!(StatusCode::Continue.canonical_reason(), "Ok");
}
#[test]
fn test_as_u16() {
assert_eq!(StatusCode::Continue.as_u16(), 100);
}
#[test]
fn test_from_u16() {
assert_eq!(StatusCode::from_u16(100), Some(StatusCode::Continue));
assert_eq!(StatusCode::from_u16(600), None);
assert_eq!(StatusCode::from_u16(1000), None);
assert_eq!(StatusCode::from_u16(0100), Some(StatusCode::Continue));
assert_eq!(StatusCode::from_u16(001), None);
}
}

1
http/vendor/cc/.cargo-checksum.json vendored Normal file
View file

@ -0,0 +1 @@
{"files":{".cargo_vcs_info.json":"cf5afb0cbc1d9c66b3a9f8bc0c7d07834c0e41ab52fe7b6e1cdf6e96a197b1be","CHANGELOG.md":"9eb80365dff5691558d4e261eb82ef768e733ff3d5b5403e3cdd18d68dd33370","Cargo.lock":"5a0c090548b2ea7602c3a4e8ca7f8d1f4538dc875dd28d7aa22b7e9a376556f7","Cargo.toml":"7b6349fd108dec1ed9a187322dea88fa2e8cce55dbceab956451412e6530fdaf","Cargo.toml.orig":"2f3281a08d13b585f7808e0775a17e9cd32d7b8be41cfe95d9c1a1c5a970450c","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"cc952a506dc726eed3e128d47d62defbac4470bbb0e465f6a043ae8bf0c96d19","clippy.toml":"cf46251b0953d1a3c7a4f8f8941a08d8a416d5fc348dfe3f3c520eb93fcc18ea","src/command_helpers.rs":"650c9682edc3d7732249e327c1026c7cc733f3702f4867b9580223e97522d3c6","src/detect_compiler_family.c":"97ca4b021495611e828becea6187add37414186a16dfedd26c2947cbce6e8b2f","src/flags.rs":"11f22aa9741b0d445b19ab29ea1076cc32a4143316a74855b6bd682004217543","src/lib.rs":"81899387bcfec723c52e40f50a8af9fef00fb9fd75e0392c5f2658b72e084b4c","src/parallel/async_executor.rs":"4ce24435fff6b6555b43fee042c16bd65d4150d0346567f246b9190d85b45983","src/parallel/command_runner.rs":"1d17d9a037de93b31cc7ee6a914a1e1f6c1ac156cf8619f0014dcbaca6a0b215","src/parallel/job_token.rs":"858b684423bce773d04a042f3f9bafbd21deda21bbb1efefb078a20ef5d8a134","src/parallel/mod.rs":"bf156170790d40a76015a8c78cc2a391cbe1b60bb96c1fac1d047d26e342386a","src/parallel/stderr.rs":"840fe8d0ba613c98fa92cbebc374a028a3212ba7dcea58285483223a31acc7eb","src/target.rs":"a9d2d347a3a08015531f00b32bc8a7478f5636822cc8e0237ea9efa3f07d4cd4","src/target/apple.rs":"da9411b2c4db419e0fa39f765ee53b8665b3837fb39827679a53238734a4a1c1","src/target/generated.rs":"c53159c0903d759741ef901e84ce9f7ff31e800921aeb903769b4d80c9097968","src/target/llvm.rs":"190fe8d2b204cd4a6e68f2a1aada17ecd6390799564ed25792fcc08ab34710ba","src/target/parser.rs":"e2a5246a8fe46d39616410685cf7418f6b86344c5309bf09817978b182b3b38c","src/tempfile.rs":"3d9a4bd894862a345aa230a61ec266f0c68f4ef9713d1d9c727482e61f1ea7c3","src/tool.rs":"1d279a6f0738f9164ca794c85bd55951aa95e2adc788e75a6bb8133393d6cce8","src/utilities.rs":"ebb59ac01fb9588bcea0d0ee786e5d5a5696b4284a1245657625db03e830b72e"},"package":"e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96"}

6
http/vendor/cc/.cargo_vcs_info.json vendored Normal file
View file

@ -0,0 +1,6 @@
{
"git": {
"sha1": "640c66a8b8a225146a16068bad637d5e3417ffbf"
},
"path_in_vcs": ""
}

817
http/vendor/cc/CHANGELOG.md vendored Normal file
View file

@ -0,0 +1,817 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.2.65](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.64...cc-v1.2.65) - 2026-06-19
### Other
- Regenerate target info ([#1763](https://github.com/rust-lang/cc-rs/pull/1763))
## [1.2.64](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.63...cc-v1.2.64) - 2026-06-12
### Other
- Add more bare-metal 32-bit Arm support ([#1753](https://github.com/rust-lang/cc-rs/pull/1753))
- Remove unnecessary clone ([#1748](https://github.com/rust-lang/cc-rs/pull/1748))
- Add default compiler prefixes for thumbv7a/thumbv7r/thumbv8r bare-metal targets ([#1742](https://github.com/rust-lang/cc-rs/pull/1742))
## [1.2.63](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.62...cc-v1.2.63) - 2026-05-29
### Other
- Update shlex requirement from 1.3.0 to 2.0.1 ([#1736](https://github.com/rust-lang/cc-rs/pull/1736))
## [1.2.62](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.61...cc-v1.2.62) - 2026-05-08
### Other
- Regenerate target info ([#1721](https://github.com/rust-lang/cc-rs/pull/1721))
- Allow exceptions on wasm platforms ([#1714](https://github.com/rust-lang/cc-rs/pull/1714))
- Add relibc env ([#1710](https://github.com/rust-lang/cc-rs/pull/1710))
- recognize sh4 architecture in parse_arch() ([#1712](https://github.com/rust-lang/cc-rs/pull/1712))
## [1.2.61](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.60...cc-v1.2.61) - 2026-04-24
### Other
- fix `OutputKind::Capture` documentation ([#1705](https://github.com/rust-lang/cc-rs/pull/1705))
## [1.2.60](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.59...cc-v1.2.60) - 2026-04-10
### Fixed
- *(ar)* suppress warnings from `D` modifier probe ([#1700](https://github.com/rust-lang/cc-rs/pull/1700))
## [1.2.59](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.58...cc-v1.2.59) - 2026-04-03
### Fixed
- *(ar)* deterministic archives with `D` modifier ([#1697](https://github.com/rust-lang/cc-rs/pull/1697))
### Other
- Regenerate target info ([#1698](https://github.com/rust-lang/cc-rs/pull/1698))
- Fix target abi parsing for sanitiser targets ([#1695](https://github.com/rust-lang/cc-rs/pull/1695))
## [1.2.58](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.57...cc-v1.2.58) - 2026-03-27
### Other
- Update Compile-time Requirements to add info about clang-cl.exe ([#1693](https://github.com/rust-lang/cc-rs/pull/1693))
## [1.2.57](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.56...cc-v1.2.57) - 2026-03-13
### Other
- Size archiver batches according to argument length not argument count ([#1689](https://github.com/rust-lang/cc-rs/pull/1689))
- Added `Build::env` for setting environment variables of compiler invocations and other child processes ([#1656](https://github.com/rust-lang/cc-rs/pull/1656) [#1682](https://github.com/rust-lang/cc-rs/pull/1682))
## [1.2.56](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.55...cc-v1.2.56) - 2026-02-13
### Other
- Regenerate target info ([#1676](https://github.com/rust-lang/cc-rs/pull/1676))
- Fix `clang-cl` target when cross-compiling ([#1670](https://github.com/rust-lang/cc-rs/pull/1670))
## [1.2.55](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.54...cc-v1.2.55) - 2026-01-30
### Other
- Regenerate target info ([#1667](https://github.com/rust-lang/cc-rs/pull/1667))
- Fix RUSTFLAGS typo in test-linker-plugin-lto ([#1665](https://github.com/rust-lang/cc-rs/pull/1665))
- Disable PIC for armv7-sony-vita-newlibeabihf ([#1664](https://github.com/rust-lang/cc-rs/pull/1664))
## [1.2.54](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.53...cc-v1.2.54) - 2026-01-23
### Other
- Fix x86_64-unknown-linux-gnuasan parsing ([#1661](https://github.com/rust-lang/cc-rs/pull/1661))
- Regenerate target info ([#1660](https://github.com/rust-lang/cc-rs/pull/1660))
## [1.2.53](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.52...cc-v1.2.53) - 2026-01-16
### Other
- Add missing RISC-V targets ([#1657](https://github.com/rust-lang/cc-rs/pull/1657))
## [1.2.52](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.51...cc-v1.2.52) - 2026-01-09
### Other
- Fix contradictory doc for CC compiler in crate doc ([#1650](https://github.com/rust-lang/cc-rs/pull/1650))
- Have CUDA compilaion check for sbsa-linux when targeting aarch64. ([#1647](https://github.com/rust-lang/cc-rs/pull/1647))
- Update link for -Cdwarf-version; Remove -Z (stabilized in 1.88) ([#1648](https://github.com/rust-lang/cc-rs/pull/1648))
- Fix Build::env_tool to check for .exe on windows ([#1646](https://github.com/rust-lang/cc-rs/pull/1646))
## [1.2.51](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.50...cc-v1.2.51) - 2025-12-26
### Other
- Regenerate target info ([#1642](https://github.com/rust-lang/cc-rs/pull/1642))
- Update Readmes ([#1641](https://github.com/rust-lang/cc-rs/pull/1641))
## [1.2.50](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.49...cc-v1.2.50) - 2025-12-19
### Other
- Add tests for `OUT_DIR` escape for '..' file paths (#1631)
- Fix #283: Make warnings(false) actually suppress compiler warnings ([#1633](https://github.com/rust-lang/cc-rs/pull/1633))
## [1.2.49](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.48...cc-v1.2.49) - 2025-12-06
### Other
- Fix run_output to prevent infinite blocking ([#1627](https://github.com/rust-lang/cc-rs/pull/1627))
- Fix detect_family deadlock ([#1626](https://github.com/rust-lang/cc-rs/pull/1626))
- Fix link in new debug_str doc comment ([#1625](https://github.com/rust-lang/cc-rs/pull/1625))
- Support more of Cargo's debug levels with Build::debug_str ([#1624](https://github.com/rust-lang/cc-rs/pull/1624))
## [1.2.48](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.47...cc-v1.2.48) - 2025-11-28
### Other
- Regenerate target info ([#1620](https://github.com/rust-lang/cc-rs/pull/1620))
## [1.2.47](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.46...cc-v1.2.47) - 2025-11-21
### Other
- add helenos linker identifications ([#1615](https://github.com/rust-lang/cc-rs/pull/1615))
## [1.2.46](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.45...cc-v1.2.46) - 2025-11-14
### Other
- Add Visual Studio 2026 support ([#1609](https://github.com/rust-lang/cc-rs/pull/1609))
## [1.2.45](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.44...cc-v1.2.45) - 2025-11-07
### Other
- Regenerate target info ([#1606](https://github.com/rust-lang/cc-rs/pull/1606))
- Use a default check for the "env" variable in apple_sdk_name ([#1605](https://github.com/rust-lang/cc-rs/pull/1605))
## [1.2.44](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.43...cc-v1.2.44) - 2025-10-31
### Other
- Fix debug assertion for env/abi mismatch ([#1604](https://github.com/rust-lang/cc-rs/pull/1604))
- Update CHANGELOG for version 1.2.43 ([#1602](https://github.com/rust-lang/cc-rs/pull/1602))
- Stop passing an invalid target to `llvm-mingw`'s cross-compilation wrappers ([#1495](https://github.com/rust-lang/cc-rs/pull/1495))
## [1.2.43](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.42...cc-v1.2.43) - 2025-10-24
### Other
- Mark `static_flag` and `shared_flag` as deprecated ([#1582](https://github.com/rust-lang/cc-rs/pull/1582))
## [1.2.42](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.41...cc-v1.2.42) - 2025-10-24
### Other
- Fix check-semver-checks ([#1600](https://github.com/rust-lang/cc-rs/pull/1600))
- minor improvement for docs ([#1598](https://github.com/rust-lang/cc-rs/pull/1598))
- Fix linker-plugin-lto: use `-flto=thin` ([#1594](https://github.com/rust-lang/cc-rs/pull/1594))
- Disable check-buildstd for armv7k-apple-watchos ([#1599](https://github.com/rust-lang/cc-rs/pull/1599))
- Add elf abi to ppc64 targets ([#1596](https://github.com/rust-lang/cc-rs/pull/1596))
## [1.2.41](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.40...cc-v1.2.41) - 2025-10-10
### Other
- Allow using VCToolsVersion to request a specific msvc version ([#1589](https://github.com/rust-lang/cc-rs/pull/1589))
- Regenerate target info ([#1592](https://github.com/rust-lang/cc-rs/pull/1592))
- Regenerate windows sys bindings ([#1591](https://github.com/rust-lang/cc-rs/pull/1591))
- Update windows-bindgen requirement from 0.64 to 0.65 ([#1590](https://github.com/rust-lang/cc-rs/pull/1590))
- Fix `get_base_archiver_variant` for clang-cl: use `--print-search-dirs` ([#1587](https://github.com/rust-lang/cc-rs/pull/1587))
## [1.2.40](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.39...cc-v1.2.40) - 2025-10-03
### Other
- Reorder changelog and remove duplicate Unreleased section ([#1579](https://github.com/rust-lang/cc-rs/pull/1579))
- Prefer clang if linker-plugin-lto specified ([#1573](https://github.com/rust-lang/cc-rs/pull/1573))
- Fix building for Mac Catalyst ([#1577](https://github.com/rust-lang/cc-rs/pull/1577))
- Improve ESP microcontroller targets ([#1574](https://github.com/rust-lang/cc-rs/pull/1574))
## [1.2.39](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.38...cc-v1.2.39) - 2025-09-26
### Other
- Fix cross compilation to xtensa-esp32s3-espidf ([#1569](https://github.com/rust-lang/cc-rs/pull/1569))
- Fix autodetect_wasi_compiler: support non utf-8 path ([#1568](https://github.com/rust-lang/cc-rs/pull/1568))
- Regenerate target info ([#1567](https://github.com/rust-lang/cc-rs/pull/1567))
- Fix rustcflags mapping: require -Clinker-plugin-lto for -flto ([#1564](https://github.com/rust-lang/cc-rs/pull/1564))
- Use `$WASI_SDK_PATH` on WASI targets by default ([#1562](https://github.com/rust-lang/cc-rs/pull/1562))
- Fix atomicity violations in concurrent cache operations ([#1559](https://github.com/rust-lang/cc-rs/pull/1559))
## [1.2.38](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.37...cc-v1.2.38) - 2025-09-19
### Other
- updated the following local packages: find-msvc-tools
## [1.2.37](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.36...cc-v1.2.37) - 2025-09-12
### Other
- Fix errmsg in RustcCodegenFlags::set_rustc_flag ([#1551](https://github.com/rust-lang/cc-rs/pull/1551))
- propagate stack protector to Linux C compilers ([#1550](https://github.com/rust-lang/cc-rs/pull/1550))
- Extract new fn `run_commands_in_parallel` ([#1549](https://github.com/rust-lang/cc-rs/pull/1549))
## [1.2.36](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.35...cc-v1.2.36) - 2025-09-05
### Other
- Regenerate windows sys bindings ([#1548](https://github.com/rust-lang/cc-rs/pull/1548))
- Update windows-bindgen requirement from 0.62 to 0.63 ([#1547](https://github.com/rust-lang/cc-rs/pull/1547))
- Add fn get_ucrt_dir for find-msvc-tools ([#1546](https://github.com/rust-lang/cc-rs/pull/1546))
- Regenerate target info ([#1544](https://github.com/rust-lang/cc-rs/pull/1544))
- fix publish.yml ([#1543](https://github.com/rust-lang/cc-rs/pull/1543))
- Replace periods with underscores as well when parsing env variables ([#1541](https://github.com/rust-lang/cc-rs/pull/1541))
## [1.2.35](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.34...cc-v1.2.35) - 2025-09-01
### Fixed
- fix building for aarch64-apple-visionos-sim on nightly ([#1534](https://github.com/rust-lang/cc-rs/pull/1534))
- fix tests apple_sdkroot_wrong ([#1530](https://github.com/rust-lang/cc-rs/pull/1530))
### Other
- Regenerate target info ([#1536](https://github.com/rust-lang/cc-rs/pull/1536))
- Optimize Tool::to_command ([#1535](https://github.com/rust-lang/cc-rs/pull/1535))
- Extract find-msvc-tools ([#1531](https://github.com/rust-lang/cc-rs/pull/1531))
- Add prefer_clang_cl_over_msvc ([#1516](https://github.com/rust-lang/cc-rs/pull/1516))
## [1.2.34](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.33...cc-v1.2.34) - 2025-08-22
### Fixed
- add `-mcpu=mvp` and `-mmutable-globals` for `wasm32v1-none` ([#1524](https://github.com/rust-lang/cc-rs/pull/1524))
### Other
- Optimize parse_version in find_tools.rs ([#1527](https://github.com/rust-lang/cc-rs/pull/1527))
- Fallback to manually searching for tool dir ([#1526](https://github.com/rust-lang/cc-rs/pull/1526))
## [1.2.33](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.32...cc-v1.2.33) - 2025-08-15
### Other
- Regenerate target info ([#1521](https://github.com/rust-lang/cc-rs/pull/1521))
- [win][arm64ec] Add testing for Arm64EC Windows ([#1512](https://github.com/rust-lang/cc-rs/pull/1512))
- Fix parsing of nigthly targets ([#1517](https://github.com/rust-lang/cc-rs/pull/1517))
- [win][arm64ec] Fix finding assembler and setting is_arm for Arm64EC ([#1511](https://github.com/rust-lang/cc-rs/pull/1511))
## [1.2.32](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.31...cc-v1.2.32) - 2025-08-08
### Fixed
- fix new clippy lint introduced in rust 1.89.0 ([#1509](https://github.com/rust-lang/cc-rs/pull/1509))
### Other
- clarify cargo default if no rerun emitted ([#1508](https://github.com/rust-lang/cc-rs/pull/1508))
- extract compile_objects_sequential ([#1507](https://github.com/rust-lang/cc-rs/pull/1507))
- Windows `find_tools`: add support for finding Clang ([#1506](https://github.com/rust-lang/cc-rs/pull/1506))
- Add m68k-unknown-linux-gnu cross-compile target ([#1505](https://github.com/rust-lang/cc-rs/pull/1505))
## [1.2.31](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.30...cc-v1.2.31) - 2025-08-01
### Other
- Add doc for using sccache/ccache etc ([#1502](https://github.com/rust-lang/cc-rs/pull/1502))
- ability to statically link against C++ stdlib ([#1497](https://github.com/rust-lang/cc-rs/pull/1497))
- Add instructions on using sccache ([#1503](https://github.com/rust-lang/cc-rs/pull/1503))
- Add support for recognizing some architectures supported by GCC, but not LLVM. ([#1500](https://github.com/rust-lang/cc-rs/pull/1500))
## [1.2.30](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.29...cc-v1.2.30) - 2025-07-18
### Other
- define _REENTRANT by default ([#1496](https://github.com/rust-lang/cc-rs/pull/1496))
## [1.2.29](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.28...cc-v1.2.29) - 2025-07-05
### Other
- Fix target parsing for powerpc ([#1490](https://github.com/rust-lang/cc-rs/pull/1490))
## [1.2.28](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.27...cc-v1.2.28) - 2025-07-04
### Other
- Recognize `mlibc` environment ([#1488](https://github.com/rust-lang/cc-rs/pull/1488))
- Fix clippy warnings about not using variables in `format!` strings ([#1489](https://github.com/rust-lang/cc-rs/pull/1489))
## [1.2.27](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.26...cc-v1.2.27) - 2025-06-13
### Other
- Regenerate windows sys bindings ([#1485](https://github.com/rust-lang/cc-rs/pull/1485))
- Update windows-bindgen requirement from 0.61 to 0.62 ([#1484](https://github.com/rust-lang/cc-rs/pull/1484))
- Regenerate target info ([#1483](https://github.com/rust-lang/cc-rs/pull/1483))
## [1.2.26](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.25...cc-v1.2.26) - 2025-06-06
### Other
- Also set `SDKROOT` when building apple platforms ([#1475](https://github.com/rust-lang/cc-rs/pull/1475))
- use windows 2022 in CI ([#1479](https://github.com/rust-lang/cc-rs/pull/1479))
- Detect -Wslash-u-filename warning on clang-cl ([#1477](https://github.com/rust-lang/cc-rs/pull/1477))
## [1.2.25](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.24...cc-v1.2.25) - 2025-05-30
### Other
- make `powerp64` use `powerpc64-linux-gnu` prefix ([#1474](https://github.com/rust-lang/cc-rs/pull/1474))
## [1.2.24](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.23...cc-v1.2.24) - 2025-05-23
### Other
- Regenerate windows sys bindings ([#1471](https://github.com/rust-lang/cc-rs/pull/1471))
## [1.2.23](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.22...cc-v1.2.23) - 2025-05-16
### Other
- support "vxworks" and "nto" OSes on `get_base_archiver_variant` ([#1456](https://github.com/rust-lang/cc-rs/pull/1456))
## [1.2.22](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.21...cc-v1.2.22) - 2025-05-09
### Other
- Add `flags` method to `cc::Build` for adding multiple flags ([#1466](https://github.com/rust-lang/cc-rs/pull/1466))
## [1.2.21](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.20...cc-v1.2.21) - 2025-05-02
### Other
- Fix wasm32-unknown-unknown by passing -c ([#1424](https://github.com/rust-lang/cc-rs/pull/1424))
## [1.2.20](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.19...cc-v1.2.20) - 2025-04-25
### Other
- Regenerate target info ([#1461](https://github.com/rust-lang/cc-rs/pull/1461))
- Fix parser.rs on latest rustc nightly ([#1459](https://github.com/rust-lang/cc-rs/pull/1459))
## [1.2.19](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.18...cc-v1.2.19) - 2025-04-11
### Other
- Fix musl compilation: Add musl as a prefix fallback ([#1455](https://github.com/rust-lang/cc-rs/pull/1455))
## [1.2.18](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.17...cc-v1.2.18) - 2025-04-04
### Other
- Regenerate target info ([#1450](https://github.com/rust-lang/cc-rs/pull/1450))
- Use `std::thread::available_parallelism` for determining the default number of jobs ([#1447](https://github.com/rust-lang/cc-rs/pull/1447))
- Fix mips64-openwrt-linux-musl parsing ([#1449](https://github.com/rust-lang/cc-rs/pull/1449))
- Use compiler prefix `x86_64-linux-musl` ([#1443](https://github.com/rust-lang/cc-rs/pull/1443))
## [1.2.17](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.16...cc-v1.2.17) - 2025-03-21
### Other
- Regenerate target info ([#1439](https://github.com/rust-lang/cc-rs/pull/1439))
- Regenerate windows sys bindings ([#1437](https://github.com/rust-lang/cc-rs/pull/1437))
- Fix wasm32-wali-linux-musl target parsing ([#1434](https://github.com/rust-lang/cc-rs/pull/1434))
- Parse `rustc` target names ([#1413](https://github.com/rust-lang/cc-rs/pull/1413))
- Regenerate target info ([#1429](https://github.com/rust-lang/cc-rs/pull/1429))
- Added base support for `wasm32-wali-linux-musl` target ([#1373](https://github.com/rust-lang/cc-rs/pull/1373))
## [1.2.16](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.15...cc-v1.2.16) - 2025-02-28
### Fixed
- force windows compiler to run in `out_dir` to prevent artifacts in cwd (#1415)
### Other
- use `/arch:SSE2` for `x86` target arch (#1425)
- Regenerate windows-sys binding ([#1422](https://github.com/rust-lang/cc-rs/pull/1422))
- Regenerate target info ([#1418](https://github.com/rust-lang/cc-rs/pull/1418))
- Add LIB var when compiling flag_check (#1417)
- Change flag ordering ([#1403](https://github.com/rust-lang/cc-rs/pull/1403))
- Fix archiver detection for musl cross compilation ([#1404](https://github.com/rust-lang/cc-rs/pull/1404))
## [1.2.15](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.14...cc-v1.2.15) - 2025-02-21
### Other
- Regenerate target info ([#1406](https://github.com/rust-lang/cc-rs/pull/1406))
- Always read from all `CFLAGS`-style flags ([#1401](https://github.com/rust-lang/cc-rs/pull/1401))
- Simplify the error output on failed `Command` invocation ([#1397](https://github.com/rust-lang/cc-rs/pull/1397))
## [1.2.14](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.13...cc-v1.2.14) - 2025-02-14
### Other
- Regenerate target info ([#1398](https://github.com/rust-lang/cc-rs/pull/1398))
- Add support for setting `-gdwarf-{version}` based on RUSTFLAGS ([#1395](https://github.com/rust-lang/cc-rs/pull/1395))
- Add support for alternative network stack io-sock on QNX 7.1 aarch64 and x86_64 ([#1312](https://github.com/rust-lang/cc-rs/pull/1312))
## [1.2.13](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.12...cc-v1.2.13) - 2025-02-08
### Other
- Fix cross-compiling for Apple platforms ([#1389](https://github.com/rust-lang/cc-rs/pull/1389))
## [1.2.12](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.11...cc-v1.2.12) - 2025-02-04
### Other
- Split impl Build ([#1382](https://github.com/rust-lang/cc-rs/pull/1382))
- Don't specify both `-target` and `-mtargetos=` on Apple targets ([#1384](https://github.com/rust-lang/cc-rs/pull/1384))
## [1.2.11](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.10...cc-v1.2.11) - 2025-01-31
### Other
- Fix more flag inheritance ([#1380](https://github.com/rust-lang/cc-rs/pull/1380))
- Include wrapper args. in `stdout` family heuristics to restore classifying `clang --driver-mode=cl` as `Msvc { clang_cl: true }` ([#1378](https://github.com/rust-lang/cc-rs/pull/1378))
- Constrain `-Clto` and `-Cembed-bitcode` flag inheritance to be `clang`-only ([#1379](https://github.com/rust-lang/cc-rs/pull/1379))
- Pass deployment target with `-m*-version-min=` ([#1339](https://github.com/rust-lang/cc-rs/pull/1339))
- Regenerate target info ([#1376](https://github.com/rust-lang/cc-rs/pull/1376))
## [1.2.10](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.9...cc-v1.2.10) - 2025-01-17
### Other
- Fix CC_FORCE_DISABLE=0 evaluating to true ([#1371](https://github.com/rust-lang/cc-rs/pull/1371))
- Regenerate target info ([#1369](https://github.com/rust-lang/cc-rs/pull/1369))
- Make hidden lifetimes explicit. ([#1366](https://github.com/rust-lang/cc-rs/pull/1366))
## [1.2.9](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.8...cc-v1.2.9) - 2025-01-12
### Other
- Don't pass inherited PGO flags to GNU compilers (#1363)
- Adjusted zig cc judgment and avoided zigbuild errors([#1360](https://github.com/rust-lang/cc-rs/pull/1360)) ([#1361](https://github.com/rust-lang/cc-rs/pull/1361))
- Fix compilation on macOS using clang and fix compilation using zig-cc ([#1364](https://github.com/rust-lang/cc-rs/pull/1364))
## [1.2.8](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.7...cc-v1.2.8) - 2025-01-11
### Other
- Add `is_like_clang_cl()` getter (#1357)
- Fix clippy error in lib.rs ([#1356](https://github.com/rust-lang/cc-rs/pull/1356))
- Regenerate target info ([#1352](https://github.com/rust-lang/cc-rs/pull/1352))
- Fix compiler family detection issue with clang-cl on macOS ([#1328](https://github.com/rust-lang/cc-rs/pull/1328))
- Update `windows-bindgen` dependency ([#1347](https://github.com/rust-lang/cc-rs/pull/1347))
- Fix clippy warnings ([#1346](https://github.com/rust-lang/cc-rs/pull/1346))
## [1.2.7](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.6...cc-v1.2.7) - 2025-01-03
### Other
- Regenerate target info ([#1342](https://github.com/rust-lang/cc-rs/pull/1342))
- Document new supported architecture names in windows::find
- Make is_flag_supported_inner take an &Tool ([#1337](https://github.com/rust-lang/cc-rs/pull/1337))
- Fix is_flag_supported on msvc ([#1336](https://github.com/rust-lang/cc-rs/pull/1336))
- Allow using Visual Studio target names in `find_tool` ([#1335](https://github.com/rust-lang/cc-rs/pull/1335))
## [1.2.6](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.5...cc-v1.2.6) - 2024-12-27
### Other
- Don't inherit the `/Oy` flag for 64-bit targets ([#1330](https://github.com/rust-lang/cc-rs/pull/1330))
## [1.2.5](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.4...cc-v1.2.5) - 2024-12-19
### Other
- Check linking when testing if compiler flags are supported ([#1322](https://github.com/rust-lang/cc-rs/pull/1322))
## [1.2.4](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.3...cc-v1.2.4) - 2024-12-13
### Other
- Add support for C/C++ compiler for Neutrino QNX: `qcc` ([#1319](https://github.com/rust-lang/cc-rs/pull/1319))
- use -maix64 instead of -m64 ([#1307](https://github.com/rust-lang/cc-rs/pull/1307))
## [1.2.3](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.2...cc-v1.2.3) - 2024-12-06
### Other
- Improve detection of environment when compiling from msbuild or msvc ([#1310](https://github.com/rust-lang/cc-rs/pull/1310))
- Better error message when failing on unknown targets ([#1313](https://github.com/rust-lang/cc-rs/pull/1313))
- Optimize RustcCodegenFlags ([#1305](https://github.com/rust-lang/cc-rs/pull/1305))
## [1.2.2](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.1...cc-v1.2.2) - 2024-11-29
### Other
- Inherit flags from rustc ([#1279](https://github.com/rust-lang/cc-rs/pull/1279))
- Add support for using sccache wrapper with cuda/nvcc ([#1304](https://github.com/rust-lang/cc-rs/pull/1304))
- Fix msvc stdout not shown on error ([#1303](https://github.com/rust-lang/cc-rs/pull/1303))
- Regenerate target info ([#1301](https://github.com/rust-lang/cc-rs/pull/1301))
- Fix compilation of C++ code for armv7-unknown-linux-gnueabihf ([#1298](https://github.com/rust-lang/cc-rs/pull/1298))
- Fetch target info from Cargo even if `Build::target` is manually set ([#1299](https://github.com/rust-lang/cc-rs/pull/1299))
- Fix two files with different extensions having the same object name ([#1295](https://github.com/rust-lang/cc-rs/pull/1295))
- Allow disabling cc's ability to compile via env var CC_FORCE_DISABLE ([#1292](https://github.com/rust-lang/cc-rs/pull/1292))
- Regenerate target info ([#1293](https://github.com/rust-lang/cc-rs/pull/1293))
## [1.2.1](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.0...cc-v1.2.1) - 2024-11-14
### Other
- When invoking `cl -?`, set stdin to null ([#1288](https://github.com/rust-lang/cc-rs/pull/1288))
## [1.2.0](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.37...cc-v1.2.0) - 2024-11-11
### Added
- add i686-pc-windows-gnullvm prefix detection ([#1283](https://github.com/rust-lang/cc-rs/pull/1283))
### Other
- Allow only specifying the architecture ([#1285](https://github.com/rust-lang/cc-rs/pull/1285))
- Fix WASM vs. WASI options ([#1284](https://github.com/rust-lang/cc-rs/pull/1284))
## [1.1.37](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.36...cc-v1.1.37) - 2024-11-08
### Other
- Use relative directory for obj files hash ([#1270](https://github.com/rust-lang/cc-rs/pull/1270))
- Regenerate target info ([#1280](https://github.com/rust-lang/cc-rs/pull/1280))
## [1.1.36](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.35...cc-v1.1.36) - 2024-11-05
### Other
- Fix CUDA build with clang++. ([#1273](https://github.com/rust-lang/cc-rs/pull/1273))
## [1.1.35](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.34...cc-v1.1.35) - 2024-11-04
### Other
- Remove support for FRC ([#1268](https://github.com/rust-lang/cc-rs/pull/1268))
- Do not add -fPIC by default on UEFI targets ([#1263](https://github.com/rust-lang/cc-rs/pull/1263))
- Use -windows-gnu for all UEFI targets ([#1264](https://github.com/rust-lang/cc-rs/pull/1264))
## [1.1.34](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.33...cc-v1.1.34) - 2024-11-02
### Other
- Remove redundant flags ([#1256](https://github.com/rust-lang/cc-rs/pull/1256))
## [1.1.33](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.32...cc-v1.1.33) - 2024-11-02
### Other
- Reduce size of `cc::Build` and size of generated targets ([#1257](https://github.com/rust-lang/cc-rs/pull/1257))
## [1.1.32](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.31...cc-v1.1.32) - 2024-11-02
### Other
- Use `rustc`'s knowledge of LLVM/Clang target triples ([#1252](https://github.com/rust-lang/cc-rs/pull/1252))
- Use Cargo's target information when possible ([#1225](https://github.com/rust-lang/cc-rs/pull/1225))
## [1.1.31](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.30...cc-v1.1.31) - 2024-10-19
### Other
- Add comment explaining why cc does not rebuild on env PATH change ([#1247](https://github.com/rust-lang/cc-rs/pull/1247))
## [1.1.30](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.29...cc-v1.1.30) - 2024-10-11
### Other
- Don't pass -fPIC by default on wasm ([#1245](https://github.com/rust-lang/cc-rs/pull/1245))
## [1.1.29](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.28...cc-v1.1.29) - 2024-10-11
### Other
- Regenerate target info ([#1243](https://github.com/rust-lang/cc-rs/pull/1243))
## [1.1.28](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.27...cc-v1.1.28) - 2024-10-06
### Other
- Environment variables: For one accepting boolean, treat "0", "false" and empty env as false ([#1238](https://github.com/rust-lang/cc-rs/pull/1238))
## [1.1.27](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.26...cc-v1.1.27) - 2024-10-06
### Other
- Revert "Use debug version of MSVC runtime library on debug ([#1231](https://github.com/rust-lang/cc-rs/pull/1231))" ([#1237](https://github.com/rust-lang/cc-rs/pull/1237))
- Disable `CC_ENABLE_DEBUG_OUTPUT` if it is set to "0" ([#1234](https://github.com/rust-lang/cc-rs/pull/1234))
## [1.1.26](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.25...cc-v1.1.26) - 2024-10-06
### Other
- Use debug version of MSVC runtime library on debug ([#1231](https://github.com/rust-lang/cc-rs/pull/1231))
## [1.1.25](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.24...cc-v1.1.25) - 2024-10-05
### Other
- Remove incorrect "lib" prefixes in CXXSTDLIB doc comments ([#1228](https://github.com/rust-lang/cc-rs/pull/1228))
## [1.1.24](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.23...cc-v1.1.24) - 2024-10-01
### Other
- Fix wasm32-wasip1-threads: shared-memory disallowed due to not compiled with 'atomics' or 'bulk-memory' features ([#1221](https://github.com/rust-lang/cc-rs/pull/1221))
- Reduce the need for the host target triple ([#1224](https://github.com/rust-lang/cc-rs/pull/1224))
- Add auto cancellation for CI jobs ([#1222](https://github.com/rust-lang/cc-rs/pull/1222))
## [1.1.23](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.22...cc-v1.1.23) - 2024-09-30
### Other
- Update doc for detecting changes/upgrades of compilers ([#1218](https://github.com/rust-lang/cc-rs/pull/1218))
## [1.1.22](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.21...cc-v1.1.22) - 2024-09-27
### Other
- Don't rerun if PATH changes ([#1215](https://github.com/rust-lang/cc-rs/pull/1215))
## [1.1.21](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.20...cc-v1.1.21) - 2024-09-18
### Other
- disable pic for targets that end in `-none` ([#1212](https://github.com/rust-lang/cc-rs/pull/1212))
## [1.1.20](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.19...cc-v1.1.20) - 2024-09-17
### Other
- Add buildcache as known Rust and C/C++ compiler wrapper ([#1209](https://github.com/rust-lang/cc-rs/pull/1209))
## [1.1.19](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.18...cc-v1.1.19) - 2024-09-15
### Other
- Add support arm64e-apple-darwin ([#1207](https://github.com/rust-lang/cc-rs/pull/1207))
## [1.1.18](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.17...cc-v1.1.18) - 2024-09-07
### Other
- Fixed unsoundness in `StderrForwarder::forward_available` ([#1203](https://github.com/rust-lang/cc-rs/pull/1203))
## [1.1.17](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.16...cc-v1.1.17) - 2024-09-06
### Fixed
- fix finding toolchains when invoked by msbuild ([#1201](https://github.com/rust-lang/cc-rs/pull/1201))
## [1.1.16](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.15...cc-v1.1.16) - 2024-09-04
### Other
- Treat VxWorks wr-cc as a Gnu compiler ([#1198](https://github.com/rust-lang/cc-rs/pull/1198))
## [1.1.15](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.14...cc-v1.1.15) - 2024-08-26
### Other
- Add -mfloat-abi=hard as a default argument when using any arm/thumb-none-eabihf target ([#1194](https://github.com/rust-lang/cc-rs/pull/1194))
## [1.1.14](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.13...cc-v1.1.14) - 2024-08-23
### Other
- allow finding tools from path if VisualStudioDir is set
## [1.1.13](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.12...cc-v1.1.13) - 2024-08-16
### Other
- Fix detect family: should detect emscripten as clang, closes [#1185](https://github.com/rust-lang/cc-rs/pull/1185) ([#1186](https://github.com/rust-lang/cc-rs/pull/1186))
## [1.1.12](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.11...cc-v1.1.12) - 2024-08-15
### Other
- improve docs ([#1183](https://github.com/rust-lang/cc-rs/pull/1183))
## [1.1.11](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.10...cc-v1.1.11) - 2024-08-14
### Other
- Add support for parsing shell encoded `*FLAGS` ([#1181](https://github.com/rust-lang/cc-rs/pull/1181))
- Replace vector of tuples with BTreeMap which already is sorted and free of duplicates ([#1177](https://github.com/rust-lang/cc-rs/pull/1177))
## [1.1.10](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.9...cc-v1.1.10) - 2024-08-11
### Other
- Remap Windows targets triples to their LLVM counterparts ([#1176](https://github.com/rust-lang/cc-rs/pull/1176))
## [1.1.9](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.8...cc-v1.1.9) - 2024-08-11
### Other
- Add custom CC wrapper to the wrapper whitelist ([#1175](https://github.com/rust-lang/cc-rs/pull/1175))
## [1.1.8](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.7...cc-v1.1.8) - 2024-08-06
### Other
- Fix broken link in docs.rs ([#1173](https://github.com/rust-lang/cc-rs/pull/1173))
## [1.1.7](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.6...cc-v1.1.7) - 2024-07-29
### Other
- add `.objects` ([#1166](https://github.com/rust-lang/cc-rs/pull/1166))
## [1.1.6](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.5...cc-v1.1.6) - 2024-07-19
### Other
- Clippy fixes ([#1163](https://github.com/rust-lang/cc-rs/pull/1163))
## [1.1.5](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.4...cc-v1.1.5) - 2024-07-15
### Other
- Fix cyclic compilation: Use vendored once_cell ([#1154](https://github.com/rust-lang/cc-rs/pull/1154))
## [1.1.4](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.3...cc-v1.1.4) - 2024-07-14
### Other
- Support compiling on wasm targets (Supersede [#1068](https://github.com/rust-lang/cc-rs/pull/1068)) ([#1160](https://github.com/rust-lang/cc-rs/pull/1160))
## [1.1.3](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.2...cc-v1.1.3) - 2024-07-14
### Other
- Reduce msrv to 1.63 ([#1158](https://github.com/rust-lang/cc-rs/pull/1158))
- Revert "Use raw-dylib for windows-sys ([#1137](https://github.com/rust-lang/cc-rs/pull/1137))" ([#1157](https://github.com/rust-lang/cc-rs/pull/1157))
- Fix typos ([#1152](https://github.com/rust-lang/cc-rs/pull/1152))
- Fix `doc_lazy_continuation` lints ([#1153](https://github.com/rust-lang/cc-rs/pull/1153))
## [1.1.2](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.1...cc-v1.1.2) - 2024-07-12
### Other
- Add empty `jobserver` feature. ([#1150](https://github.com/rust-lang/cc-rs/pull/1150))
## [1.1.1](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.0...cc-v1.1.1) - 2024-07-12
### Other
- Fix is_flag_supported not respecting emit_rerun_if_env_changed ([#1147](https://github.com/rust-lang/cc-rs/pull/1147)) ([#1148](https://github.com/rust-lang/cc-rs/pull/1148))
## [1.1.0](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.106...cc-v1.1.0) - 2024-07-08
### Added
- add cargo_output to eliminate last vestiges of stdout pollution ([#1141](https://github.com/rust-lang/cc-rs/pull/1141))
## [1.0.106](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.105...cc-v1.0.106) - 2024-07-08
### Other
- Drop support for Visual Studio 12 (2013) ([#1046](https://github.com/rust-lang/cc-rs/pull/1046))
- Use raw-dylib for windows-sys ([#1137](https://github.com/rust-lang/cc-rs/pull/1137))
- Bump msrv to 1.67 ([#1143](https://github.com/rust-lang/cc-rs/pull/1143))
- Bump msrv to 1.65 ([#1140](https://github.com/rust-lang/cc-rs/pull/1140))
- Fix clippy warnings ([#1138](https://github.com/rust-lang/cc-rs/pull/1138))
## [1.0.105](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.104...cc-v1.0.105) - 2024-07-07
### Other
- Regenerate windows sys bindings ([#1132](https://github.com/rust-lang/cc-rs/pull/1132))
- Fix generate-windows-sys-bindings ([#1133](https://github.com/rust-lang/cc-rs/pull/1133))
- Fix gen-windows-sys-binding ([#1130](https://github.com/rust-lang/cc-rs/pull/1130))
- Fix gen-windows-sys-binding ([#1127](https://github.com/rust-lang/cc-rs/pull/1127))
- Update windows-bindgen requirement from 0.57 to 0.58 ([#1123](https://github.com/rust-lang/cc-rs/pull/1123))
## [1.0.104](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.103...cc-v1.0.104) - 2024-07-01
### Other
- Fixed link break about compile-time-requirements ([#1118](https://github.com/rust-lang/cc-rs/pull/1118))
## [1.0.103](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.102...cc-v1.0.103) - 2024-06-30
### Other
- Fix compilation for wasm: env WASI_SYSROOT should be optional ([#1114](https://github.com/rust-lang/cc-rs/pull/1114))
## [1.0.102](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.101...cc-v1.0.102) - 2024-06-29
### Other
- Fix invalid wasi targets compatibility ([#1105](https://github.com/rust-lang/cc-rs/pull/1105))
- Speedup regenerate-target-info and regenerate-windows-sys ([#1110](https://github.com/rust-lang/cc-rs/pull/1110))
## [1.0.101](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.100...cc-v1.0.101) - 2024-06-25
### Other
- Use `Build::getenv` instead of `env::var*` in anywhere that makes sense ([#1103](https://github.com/rust-lang/cc-rs/pull/1103))
## [1.0.100](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.99...cc-v1.0.100) - 2024-06-23
### Other
- Update publish.yml to use release-plz ([#1101](https://github.com/rust-lang/cc-rs/pull/1101))
- Accept `OsStr` instead of `str` for flags ([#1100](https://github.com/rust-lang/cc-rs/pull/1100))
- Use `dep:` syntax to avoid implicit features. ([#1099](https://github.com/rust-lang/cc-rs/pull/1099))
- Minor clippy fixes. ([#1098](https://github.com/rust-lang/cc-rs/pull/1098))
- Fix WASI compilation for C++ ([#1083](https://github.com/rust-lang/cc-rs/pull/1083))
- Regenerate windows sys bindings ([#1096](https://github.com/rust-lang/cc-rs/pull/1096))
- Rename regenerate-windows-sys to regenerate-windows-sys.yml ([#1095](https://github.com/rust-lang/cc-rs/pull/1095))
- Create regenerate-windows-sys.yml ([#1094](https://github.com/rust-lang/cc-rs/pull/1094))
- Update windows-bindgen requirement from 0.56 to 0.57 ([#1091](https://github.com/rust-lang/cc-rs/pull/1091))
- Eagerly close tempfile to fix [#1082](https://github.com/rust-lang/cc-rs/pull/1082) ([#1087](https://github.com/rust-lang/cc-rs/pull/1087))
- Output msvc.exe in the output directory ([#1090](https://github.com/rust-lang/cc-rs/pull/1090))
- Fix clippy warnings on Windows ([#1088](https://github.com/rust-lang/cc-rs/pull/1088))
- Don't try to free DLL on drop ([#1089](https://github.com/rust-lang/cc-rs/pull/1089))
- Fix panic safety issue in StderrForwarder ([#1079](https://github.com/rust-lang/cc-rs/pull/1079))

173
http/vendor/cc/Cargo.lock generated vendored Normal file
View file

@ -0,0 +1,173 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bitflags"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
[[package]]
name = "cc"
version = "1.2.65"
dependencies = [
"find-msvc-tools",
"jobserver",
"libc",
"shlex",
"tempfile",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[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 = "fastrand"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[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 = "jobserver"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
dependencies = [
"getrandom 0.3.4",
"libc",
]
[[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 = "once_cell"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[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 = "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 = "shlex"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
[[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 = "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 = "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 = "wit-bindgen"
version = "0.57.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"

79
http/vendor/cc/Cargo.toml vendored Normal file
View file

@ -0,0 +1,79 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
rust-version = "1.63"
name = "cc"
version = "1.2.65"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
build = false
exclude = [
"/.github",
"tests",
"src/bin",
]
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = """
A build-time dependency for Cargo build scripts to assist in invoking the native
C compiler to compile native C code into a static archive to be linked into Rust
code.
"""
homepage = "https://github.com/rust-lang/cc-rs"
documentation = "https://docs.rs/cc"
readme = "README.md"
keywords = ["build-dependencies"]
categories = ["development-tools::build-utils"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/cc-rs"
[features]
jobserver = []
parallel = [
"dep:libc",
"dep:jobserver",
]
[lib]
name = "cc"
path = "src/lib.rs"
[dependencies.find-msvc-tools]
version = "0.1.9"
[dependencies.jobserver]
version = "0.1.30"
optional = true
default-features = false
[dependencies.shlex]
version = "2.0.1"
[dev-dependencies.tempfile]
version = "3"
[target."cfg(unix)".dependencies.libc]
version = "0.2.62"
optional = true
default-features = false
[lints.rust.unexpected_cfgs]
level = "allow"
priority = 0
check-cfg = ["cfg(disable_clang_cl_tests)"]
[profile.release]
opt-level = 3
lto = true

59
http/vendor/cc/Cargo.toml.orig vendored Normal file
View file

@ -0,0 +1,59 @@
[package]
name = "cc"
version = "1.2.65"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/cc-rs"
homepage = "https://github.com/rust-lang/cc-rs"
documentation = "https://docs.rs/cc"
description = """
A build-time dependency for Cargo build scripts to assist in invoking the native
C compiler to compile native C code into a static archive to be linked into Rust
code.
"""
keywords = ["build-dependencies"]
readme = "README.md"
categories = ["development-tools::build-utils"]
# The binary target is only used by tests.
exclude = ["/.github", "tests", "src/bin"]
edition = "2018"
rust-version = "1.63"
[dependencies]
jobserver = { version = "0.1.30", default-features = false, optional = true }
shlex = "2.0.1"
find-msvc-tools = { version = "0.1.9", path = "find-msvc-tools" }
[target.'cfg(unix)'.dependencies]
# Don't turn on the feature "std" for this, see https://github.com/rust-lang/cargo/issues/4866
# which is still an issue with `resolver = "1"`.
libc = { version = "0.2.62", default-features = false, optional = true }
[features]
parallel = ["dep:libc", "dep:jobserver"]
# This is a placeholder feature for people who incorrectly used `cc` with `features = ["jobserver"]`
# so that they aren't broken. This has never enabled `parallel`, so we won't do that.
jobserver = []
[dev-dependencies]
tempfile = "3"
[workspace]
members = [
"find-msvc-tools",
"dev-tools/cc-test",
"dev-tools/gen-target-info",
"dev-tools/gen-windows-sys-binding",
"dev-tools/wasi-test",
]
[patch.crates-io]
cc = { path = "." }
[lints.rust]
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(disable_clang_cl_tests)'] }
[profile.release]
opt-level = 3 # Or "s" or "z" for different optimization goals
lto = true

201
http/vendor/cc/LICENSE-APACHE vendored Normal file
View file

@ -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.

25
http/vendor/cc/LICENSE-MIT vendored Normal file
View file

@ -0,0 +1,25 @@
Copyright (c) 2014 Alex Crichton
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

29
http/vendor/cc/README.md vendored Normal file
View file

@ -0,0 +1,29 @@
# cc-rs
A library for
[Cargo build scripts](https://doc.rust-lang.org/cargo/reference/build-scripts.html)
to compile a set of C/C++/assembly/CUDA files into a static archive for Cargo to
link into the crate being built. This crate does not compile code itself; it
calls out to the default compiler for the platform. This crate will
automatically detect situations such as cross compilation and various
environment variables and will build code appropriately.
Refer to the [documentation](https://docs.rs/cc) for detailed usage
instructions.
## License
This project is licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
https://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
https://opensource.org/license/mit)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in cc-rs by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.

7
http/vendor/cc/clippy.toml vendored Normal file
View file

@ -0,0 +1,7 @@
disallowed-methods = [
{ path = "std::env::var_os", reason = "Please use Build::getenv" },
{ path = "std::env::var", reason = "Please use Build::getenv" },
{ path = "std::env::set_var", reason = "use `GlobalEnv::lock().set`" },
{ path = "std::env::remove_var", reason = "use `GlobalEnv::lock().remove`" },
]
doc-valid-idents = ["AppleClang", "OpenBSD", ".."]

482
http/vendor/cc/src/command_helpers.rs vendored Normal file
View file

@ -0,0 +1,482 @@
//! Miscellaneous helpers for running commands
use std::{
borrow::Cow,
collections::hash_map,
ffi::OsString,
fmt::Display,
fs,
hash::Hasher,
io::{self, Read, Write},
path::Path,
process::{Child, ChildStderr, Command, Output, Stdio},
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
};
use crate::{utilities::cargo_env_var_os, Error, ErrorKind, Object};
#[derive(Clone, Debug)]
pub(crate) struct CargoOutput {
pub(crate) metadata: bool,
pub(crate) warnings: bool,
pub(crate) debug: bool,
pub(crate) output: OutputKind,
checked_dbg_var: Arc<AtomicBool>,
}
/// Different strategies for handling compiler output (to stdout)
#[derive(Clone, Debug)]
pub(crate) enum OutputKind {
/// Forward the output to this process' stdout ([`Stdio::inherit()`])
Forward,
/// Discard the output ([`Stdio::null()`])
Discard,
/// Capture the result ([`Stdio::piped()`])
Capture,
}
impl CargoOutput {
pub(crate) fn new() -> Self {
#[allow(clippy::disallowed_methods)]
Self {
metadata: true,
warnings: true,
output: OutputKind::Forward,
debug: match std::env::var_os("CC_ENABLE_DEBUG_OUTPUT") {
Some(v) => v != "0" && v != "false" && !v.is_empty(),
None => false,
},
checked_dbg_var: Arc::new(AtomicBool::new(false)),
}
}
pub(crate) fn print_metadata(&self, s: &dyn Display) {
if self.metadata {
println!("{s}");
}
}
pub(crate) fn print_warning(&self, arg: &dyn Display) {
if self.warnings {
println!("cargo:warning={arg}");
}
}
pub(crate) fn print_debug(&self, arg: &dyn Display) {
if self.metadata
&& self
.checked_dbg_var
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
.is_ok()
{
println!("cargo:rerun-if-env-changed=CC_ENABLE_DEBUG_OUTPUT");
}
if self.debug {
println!("{arg}");
}
}
fn stdio_for_warnings(&self) -> Stdio {
if self.warnings {
Stdio::piped()
} else {
Stdio::null()
}
}
fn stdio_for_output(&self) -> Stdio {
match self.output {
OutputKind::Capture => Stdio::piped(),
OutputKind::Forward => Stdio::inherit(),
OutputKind::Discard => Stdio::null(),
}
}
}
pub(crate) struct StderrForwarder {
inner: Option<(ChildStderr, Vec<u8>)>,
#[cfg(feature = "parallel")]
is_non_blocking: bool,
#[cfg(feature = "parallel")]
bytes_available_failed: bool,
/// number of bytes buffered in inner
bytes_buffered: usize,
}
const MIN_BUFFER_CAPACITY: usize = 100;
impl StderrForwarder {
pub(crate) fn new(child: &mut Child) -> Self {
Self {
inner: child
.stderr
.take()
.map(|stderr| (stderr, Vec::with_capacity(MIN_BUFFER_CAPACITY))),
bytes_buffered: 0,
#[cfg(feature = "parallel")]
is_non_blocking: false,
#[cfg(feature = "parallel")]
bytes_available_failed: false,
}
}
pub(crate) fn forward_available(&mut self) -> bool {
if let Some((stderr, buffer)) = self.inner.as_mut() {
loop {
// For non-blocking we check to see if there is data available, so we should try to
// read at least that much. For blocking, always read at least the minimum amount.
#[cfg(not(feature = "parallel"))]
let to_reserve = MIN_BUFFER_CAPACITY;
#[cfg(feature = "parallel")]
let to_reserve = if self.is_non_blocking && !self.bytes_available_failed {
match crate::parallel::stderr::bytes_available(stderr) {
#[cfg(windows)]
Ok(0) => break false,
#[cfg(unix)]
Ok(0) => {
// On Unix, depending on the implementation, we may sometimes get 0 in a
// loop (either there is data available or the pipe is broken), so
// continue with the non-blocking read anyway.
MIN_BUFFER_CAPACITY
}
#[cfg(windows)]
Err(_) => {
// On Windows, if we get an error then the pipe is broken, so flush
// the buffer and bail.
if !buffer.is_empty() {
write_warning(&buffer[..]);
}
self.inner = None;
break true;
}
#[cfg(unix)]
Err(_) => {
// On Unix, depending on the implementation, we may get spurious
// errors so make a note not to use bytes_available again and try
// the non-blocking read anyway.
self.bytes_available_failed = true;
MIN_BUFFER_CAPACITY
}
#[cfg(target_family = "wasm")]
Err(_) => panic!("bytes_available should always succeed on wasm"),
Ok(bytes_available) => MIN_BUFFER_CAPACITY.max(bytes_available),
}
} else {
MIN_BUFFER_CAPACITY
};
if self.bytes_buffered + to_reserve > buffer.len() {
buffer.resize(self.bytes_buffered + to_reserve, 0);
}
match stderr.read(&mut buffer[self.bytes_buffered..]) {
Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => {
// No data currently, yield back.
break false;
}
Err(err) if err.kind() == std::io::ErrorKind::Interrupted => {
// Interrupted, try again.
continue;
}
Ok(bytes_read) if bytes_read != 0 => {
self.bytes_buffered += bytes_read;
let mut consumed = 0;
for line in buffer[..self.bytes_buffered].split_inclusive(|&b| b == b'\n') {
// Only forward complete lines, leave the rest in the buffer.
if let Some((b'\n', line)) = line.split_last() {
consumed += line.len() + 1;
write_warning(line);
}
}
if consumed > 0 && consumed < self.bytes_buffered {
// Remove the consumed bytes from buffer
buffer.copy_within(consumed.., 0);
}
self.bytes_buffered -= consumed;
}
res => {
// End of stream: flush remaining data and bail.
if self.bytes_buffered > 0 {
write_warning(&buffer[..self.bytes_buffered]);
}
if let Err(err) = res {
write_warning(
format!("Failed to read from child stderr: {err}").as_bytes(),
);
}
self.inner.take();
break true;
}
}
}
} else {
true
}
}
#[cfg(feature = "parallel")]
pub(crate) fn set_non_blocking(&mut self) -> Result<(), Error> {
assert!(!self.is_non_blocking);
#[cfg(unix)]
if let Some((stderr, _)) = self.inner.as_ref() {
crate::parallel::stderr::set_non_blocking(stderr)?;
}
self.is_non_blocking = true;
Ok(())
}
#[cfg(feature = "parallel")]
pub(crate) fn forward_all(&mut self) {
while !self.forward_available() {}
}
#[cfg(not(feature = "parallel"))]
fn forward_all(&mut self) {
let forward_result = self.forward_available();
assert!(forward_result, "Should have consumed all data");
}
}
fn write_warning(line: &[u8]) {
let stdout = io::stdout();
let mut stdout = stdout.lock();
stdout.write_all(b"cargo:warning=").unwrap();
stdout.write_all(line).unwrap();
stdout.write_all(b"\n").unwrap();
}
fn wait_on_child(
cmd: &Command,
child: &mut Child,
cargo_output: &CargoOutput,
) -> Result<(), Error> {
StderrForwarder::new(child).forward_all();
let status = match child.wait() {
Ok(s) => s,
Err(e) => {
return Err(Error::new(
ErrorKind::ToolExecError,
format!("failed to wait on spawned child process `{cmd:?}`: {e}"),
));
}
};
cargo_output.print_debug(&status);
if status.success() {
Ok(())
} else {
Err(Error::new(
ErrorKind::ToolExecError,
format!("command did not execute successfully (status code {status}): {cmd:?}"),
))
}
}
/// Find the destination object path for each file in the input source files,
/// and store them in the output Object.
pub(crate) fn objects_from_files(files: &[Arc<Path>], dst: &Path) -> Result<Vec<Object>, Error> {
let mut objects = Vec::with_capacity(files.len());
for file in files {
let basename = file
.file_name()
.ok_or_else(|| {
Error::new(
ErrorKind::InvalidArgument,
"No file_name for object file path!",
)
})?
.to_string_lossy();
let dirname = file
.parent()
.ok_or_else(|| {
Error::new(
ErrorKind::InvalidArgument,
"No parent for object file path!",
)
})?
.to_string_lossy();
// Hash the dirname. This should prevent conflicts if we have multiple
// object files with the same filename in different subfolders.
let mut hasher = hash_map::DefaultHasher::new();
// Make the dirname relative (if possible) to avoid full system paths influencing the sha
// and making the output system-dependent
let dirname = if let Some(root) = cargo_env_var_os("CARGO_MANIFEST_DIR") {
let root = root.to_string_lossy();
Cow::Borrowed(dirname.strip_prefix(&*root).unwrap_or(&dirname))
} else {
dirname
};
hasher.write(dirname.as_bytes());
if let Some(extension) = file.extension() {
hasher.write(extension.to_string_lossy().as_bytes());
}
let obj = dst
.join(format!("{:016x}-{}", hasher.finish(), basename))
.with_extension("o");
match obj.parent() {
Some(s) => fs::create_dir_all(s)?,
None => {
return Err(Error::new(
ErrorKind::InvalidArgument,
"dst is an invalid path with no parent",
));
}
};
objects.push(Object::new(file.to_path_buf(), obj));
}
Ok(objects)
}
pub(crate) fn run(cmd: &mut Command, cargo_output: &CargoOutput) -> Result<(), Error> {
let mut child = spawn(cmd, cargo_output)?;
wait_on_child(cmd, &mut child, cargo_output)
}
/// Like [`run`], but stderr is only forwarded as `cargo:warning=` when the
/// command succeeds. On failure, stderr is silently discarded.
///
/// Useful for probe commands where failure is expected and the error
/// message is not actionable.
pub(crate) fn run_silent_on_error(
cmd: &mut Command,
cargo_output: &CargoOutput,
) -> Result<(), Error> {
let Output {
status,
stdout: _,
stderr,
} = spawn_and_wait_for_output(cmd, cargo_output)?;
cargo_output.print_debug(&status);
if status.success() {
if cargo_output.warnings {
stderr
.split(|&b| b == b'\n')
.map(|line| line.strip_suffix(b"\r").unwrap_or(line))
.filter(|line| !line.is_empty())
.for_each(write_warning);
}
Ok(())
} else {
Err(Error::new(
ErrorKind::ToolExecError,
format!("command did not execute successfully (status code {status}): {cmd:?}"),
))
}
}
pub(crate) fn spawn_and_wait_for_output(
cmd: &mut Command,
cargo_output: &CargoOutput,
) -> Result<Output, Error> {
// We specifically need the output to be captured, so override default
let mut captured_cargo_output = cargo_output.clone();
captured_cargo_output.output = OutputKind::Capture;
spawn(cmd, &captured_cargo_output)?
.wait_with_output()
.map_err(|e| {
Error::new(
ErrorKind::ToolExecError,
format!("failed to wait on spawned child process `{cmd:?}`: {e}"),
)
})
}
pub(crate) fn run_output(cmd: &mut Command, cargo_output: &CargoOutput) -> Result<Vec<u8>, Error> {
let Output {
status,
stdout,
stderr,
} = spawn_and_wait_for_output(cmd, cargo_output)?;
stderr
.split(|&b| b == b'\n')
.filter(|part| !part.is_empty())
.for_each(write_warning);
cargo_output.print_debug(&status);
if status.success() {
Ok(stdout)
} else {
Err(Error::new(
ErrorKind::ToolExecError,
format!("command did not execute successfully (status code {status}): {cmd:?}"),
))
}
}
pub(crate) fn spawn(cmd: &mut Command, cargo_output: &CargoOutput) -> Result<Child, Error> {
struct ResetStderr<'cmd>(&'cmd mut Command);
impl Drop for ResetStderr<'_> {
fn drop(&mut self) {
// Reset stderr to default to release pipe_writer so that print thread will
// not block forever.
self.0.stderr(Stdio::inherit());
}
}
cargo_output.print_debug(&format_args!("running: {cmd:?}"));
let cmd = ResetStderr(cmd);
let child = cmd
.0
.stderr(cargo_output.stdio_for_warnings())
.stdout(cargo_output.stdio_for_output())
.spawn();
match child {
Ok(child) => Ok(child),
Err(ref e) if e.kind() == io::ErrorKind::NotFound => {
let extra = if cfg!(windows) {
" (see https://docs.rs/cc/latest/cc/#compile-time-requirements for help)"
} else {
""
};
Err(Error::new(
ErrorKind::ToolNotFound,
format!("failed to find tool {:?}: {e}{extra}", cmd.0.get_program()),
))
}
Err(e) => Err(Error::new(
ErrorKind::ToolExecError,
format!("command `{:?}` failed to start: {e}", cmd.0),
)),
}
}
pub(crate) struct CmdAddOutputFileArgs {
pub(crate) cuda: bool,
pub(crate) is_assembler_msvc: bool,
pub(crate) msvc: bool,
pub(crate) clang: bool,
pub(crate) gnu: bool,
pub(crate) is_asm: bool,
pub(crate) is_arm: bool,
}
pub(crate) fn command_add_output_file(cmd: &mut Command, dst: &Path, args: CmdAddOutputFileArgs) {
if args.is_assembler_msvc
|| !(!args.msvc || args.clang || args.gnu || args.cuda || (args.is_asm && args.is_arm))
{
let mut s = OsString::from("-Fo");
s.push(dst);
cmd.arg(s);
} else {
cmd.arg("-o").arg(dst);
}
}

View file

@ -0,0 +1,15 @@
#ifdef __clang__
#pragma message "clang"
#endif
#ifdef __GNUC__
#pragma message "gcc"
#endif
#ifdef __EMSCRIPTEN__
#pragma message "emscripten"
#endif
#ifdef __VXWORKS__
#pragma message "VxWorks"
#endif

563
http/vendor/cc/src/flags.rs vendored Normal file
View file

@ -0,0 +1,563 @@
use crate::target::TargetInfo;
use crate::{Build, Error, ErrorKind, Tool, ToolFamily};
use std::borrow::Cow;
use std::ffi::OsString;
#[derive(Debug, PartialEq, Default)]
pub(crate) struct RustcCodegenFlags<'a> {
branch_protection: Option<&'a str>,
code_model: Option<&'a str>,
no_vectorize_loops: bool,
no_vectorize_slp: bool,
profile_generate: Option<&'a str>,
profile_use: Option<&'a str>,
control_flow_guard: Option<&'a str>,
lto: Option<&'a str>,
relocation_model: Option<&'a str>,
embed_bitcode: Option<bool>,
force_frame_pointers: Option<bool>,
no_redzone: Option<bool>,
soft_float: Option<bool>,
dwarf_version: Option<u32>,
stack_protector: Option<&'a str>,
linker_plugin_lto: Option<bool>,
}
impl<'this> RustcCodegenFlags<'this> {
// Parse flags obtained from CARGO_ENCODED_RUSTFLAGS
pub(crate) fn parse(rustflags_env: &'this str) -> Result<Self, Error> {
fn is_flag_prefix(flag: &str) -> bool {
[
"-Z",
"-C",
"--codegen",
"-L",
"-l",
"-o",
"-W",
"--warn",
"-A",
"--allow",
"-D",
"--deny",
"-F",
"--forbid",
]
.contains(&flag)
}
fn handle_flag_prefix<'a>(prev: &'a str, curr: &'a str) -> (&'a str, &'a str) {
match prev {
"--codegen" | "-C" => ("-C", curr),
// Handle flags passed like --codegen=code-model=small
_ if curr.starts_with("--codegen=") => ("-C", &curr[10..]),
"-Z" => ("-Z", curr),
"-L" | "-l" | "-o" => (prev, curr),
// Handle lint flags
"-W" | "--warn" => ("-W", curr),
"-A" | "--allow" => ("-A", curr),
"-D" | "--deny" => ("-D", curr),
"-F" | "--forbid" => ("-F", curr),
_ => ("", curr),
}
}
let mut codegen_flags = Self::default();
let mut prev_prefix = None;
for curr in rustflags_env.split("\u{1f}") {
let prev = prev_prefix.take().unwrap_or("");
if prev.is_empty() && is_flag_prefix(curr) {
prev_prefix = Some(curr);
continue;
}
let (prefix, rustc_flag) = handle_flag_prefix(prev, curr);
codegen_flags.set_rustc_flag(prefix, rustc_flag)?;
}
Ok(codegen_flags)
}
fn set_rustc_flag(&mut self, prefix: &str, flag: &'this str) -> Result<(), Error> {
// Convert a textual representation of a bool-like rustc flag argument into an actual bool
fn arg_to_bool(arg: impl AsRef<str>) -> Option<bool> {
match arg.as_ref() {
"y" | "yes" | "on" | "true" => Some(true),
"n" | "no" | "off" | "false" => Some(false),
_ => None,
}
}
fn arg_to_u32(arg: impl AsRef<str>) -> Option<u32> {
arg.as_ref().parse().ok()
}
let (flag, value) = if let Some((flag, value)) = flag.split_once('=') {
(flag, Some(value))
} else {
(flag, None)
};
let flag = if prefix.is_empty() {
Cow::Borrowed(flag)
} else {
Cow::Owned(format!("{prefix}{flag}"))
};
let flag = flag.as_ref();
fn flag_not_empty_generic<T>(
flag: &str,
flag_value: Option<T>,
) -> Result<Option<T>, Error> {
if let Some(flag_value) = flag_value {
Ok(Some(flag_value))
} else {
Err(Error::new(
ErrorKind::InvalidFlag,
format!("{flag} must have a value"),
))
}
}
let flag_not_empty = |flag_value| flag_not_empty_generic(flag, flag_value);
match flag {
// https://doc.rust-lang.org/rustc/codegen-options/index.html#code-model
"-Ccode-model" => {
self.code_model = flag_not_empty(value)?;
}
// https://doc.rust-lang.org/rustc/codegen-options/index.html#no-vectorize-loops
"-Cno-vectorize-loops" => self.no_vectorize_loops = true,
// https://doc.rust-lang.org/rustc/codegen-options/index.html#no-vectorize-slp
"-Cno-vectorize-slp" => self.no_vectorize_slp = true,
// https://doc.rust-lang.org/rustc/codegen-options/index.html#profile-generate
"-Cprofile-generate" => {
self.profile_generate = flag_not_empty(value)?;
}
// https://doc.rust-lang.org/rustc/codegen-options/index.html#profile-use
"-Cprofile-use" => {
self.profile_use = flag_not_empty(value)?;
}
// https://doc.rust-lang.org/rustc/codegen-options/index.html#control-flow-guard
"-Ccontrol-flow-guard" => self.control_flow_guard = value.or(Some("true")),
// https://doc.rust-lang.org/rustc/codegen-options/index.html#lto
//
// This variable is currently unused, we just keep it in case we need it in future
"-Clto" => self.lto = value.or(Some("true")),
// https://doc.rust-lang.org/rustc/linker-plugin-lto.html
"-Clinker-plugin-lto" => self.linker_plugin_lto = Some(true),
// https://doc.rust-lang.org/rustc/codegen-options/index.html#relocation-model
"-Crelocation-model" => {
self.relocation_model = flag_not_empty(value)?;
}
// https://doc.rust-lang.org/rustc/codegen-options/index.html#embed-bitcode
"-Cembed-bitcode" => self.embed_bitcode = value.map_or(Some(true), arg_to_bool),
// https://doc.rust-lang.org/rustc/codegen-options/index.html#force-frame-pointers
"-Cforce-frame-pointers" => {
self.force_frame_pointers = value.map_or(Some(true), arg_to_bool)
}
// https://doc.rust-lang.org/rustc/codegen-options/index.html#no-redzone
"-Cno-redzone" => self.no_redzone = value.map_or(Some(true), arg_to_bool),
// https://doc.rust-lang.org/rustc/codegen-options/index.html#soft-float
// Note: This flag is now deprecated in rustc.
"-Csoft-float" => self.soft_float = value.map_or(Some(true), arg_to_bool),
// https://doc.rust-lang.org/beta/unstable-book/compiler-flags/branch-protection.html
// FIXME: Drop the -Z variant and update the doc link once the option is stabilised
"-Zbranch-protection" | "-Cbranch-protection" => {
self.branch_protection = flag_not_empty(value)?;
}
// https://doc.rust-lang.org/beta/rustc/codegen-options/index.html#dwarf-version
"-Cdwarf-version" => {
self.dwarf_version = flag_not_empty_generic(flag, value.and_then(arg_to_u32))?;
}
// https://github.com/rust-lang/rust/issues/114903
// FIXME: Drop the -Z variant and update the doc link once the option is stabilized
"-Zstack-protector" | "-Cstack-protector" => {
self.stack_protector = flag_not_empty(value)?;
}
_ => {}
}
Ok(())
}
// Rust and clang/cc don't agree on what equivalent flags should look like.
pub(crate) fn cc_flags(&self, build: &Build, tool: &mut Tool, target: &TargetInfo<'_>) {
let family = tool.family;
// Push `flag` to `flags` if it is supported by the currently used CC
let mut push_if_supported = |flag: OsString| {
if build
.is_flag_supported_inner(&flag, tool, target)
.unwrap_or(false)
{
tool.args.push(flag);
} else {
build.cargo_output.print_warning(&format!(
"Inherited flag {flag:?} is not supported by the currently used CC"
));
}
};
let clang_or_gnu =
matches!(family, ToolFamily::Clang { .. }) || matches!(family, ToolFamily::Gnu);
// Flags shared between clang and gnu
if clang_or_gnu {
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mbranch-protection
// https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html#index-mbranch-protection (Aarch64)
// https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html#index-mbranch-protection-1 (ARM)
// https://developer.arm.com/documentation/101754/0619/armclang-Reference/armclang-Command-line-Options/-mbranch-protection
if let Some(value) = self.branch_protection {
push_if_supported(
format!("-mbranch-protection={}", value.replace(",", "+")).into(),
);
}
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mcmodel
// https://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html (several archs, search for `-mcmodel=`).
// FIXME(madsmtm): Parse the model, to make sure we pass the correct value (depending on arch).
if let Some(value) = self.code_model {
push_if_supported(format!("-mcmodel={value}").into());
}
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fno-vectorize
// https://gcc.gnu.org/onlinedocs/gnat_ugn/Vectorization-of-loops.html
if self.no_vectorize_loops {
push_if_supported("-fno-vectorize".into());
}
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fno-slp-vectorize
// https://gcc.gnu.org/onlinedocs/gnat_ugn/Vectorization-of-loops.html
if self.no_vectorize_slp {
push_if_supported("-fno-slp-vectorize".into());
}
if let Some(value) = self.relocation_model {
let cc_flag = match value {
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fPIC
// https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fPIC
"pic" => Some("-fPIC"),
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fPIE
// https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fPIE
"pie" => Some("-fPIE"),
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mdynamic-no-pic
// https://gcc.gnu.org/onlinedocs/gcc/RS_002f6000-and-PowerPC-Options.html#index-mdynamic-no-pic
"dynamic-no-pic" => Some("-mdynamic-no-pic"),
_ => None,
};
if let Some(cc_flag) = cc_flag {
push_if_supported(cc_flag.into());
}
}
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fno-omit-frame-pointer
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fomit-frame-pointer
// https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fomit-frame-pointer
if let Some(value) = self.force_frame_pointers {
let cc_flag = if value {
"-fno-omit-frame-pointer"
} else {
"-fomit-frame-pointer"
};
push_if_supported(cc_flag.into());
}
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mno-red-zone
// https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html#index-mno-red-zone
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mred-zone
// https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html#index-mred-zone
if let Some(value) = self.no_redzone {
let cc_flag = if value { "-mno-red-zone" } else { "-mred-zone" };
push_if_supported(cc_flag.into());
}
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-msoft-float
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mhard-float
// https://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html (several archs, search for `-msoft-float`).
// https://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html (several archs, search for `-mhard-float`).
if let Some(value) = self.soft_float {
let cc_flag = if value {
"-msoft-float"
} else {
// Do not use -mno-soft-float, that's basically just an alias for -mno-implicit-float.
"-mhard-float"
};
push_if_supported(cc_flag.into());
}
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-gdwarf-2
// https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html#index-gdwarf
if let Some(value) = self.dwarf_version {
push_if_supported(format!("-gdwarf-{value}").into());
}
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fstack-protector
// https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fstack-protector
if let Some(value) = self.stack_protector {
// don't need to propagate stack-protector on MSVC since /GS is already the default
// https://learn.microsoft.com/en-us/cpp/build/reference/gs-buffer-security-check?view=msvc-170
//
// Do NOT `stack-protector=none` since it weakens security for C code,
// and `-Zstack-protector=basic` is deprecated and will be removed soon.
let cc_flag = match value {
"strong" => Some("-fstack-protector-strong"),
"all" => Some("-fstack-protector-all"),
_ => None,
};
if let Some(cc_flag) = cc_flag {
push_if_supported(cc_flag.into());
}
}
}
// Compiler-exclusive flags
match family {
ToolFamily::Clang { .. } => {
// GNU and Clang compilers both support the same PGO flags, but they use different libraries and
// different formats for the profile files which are not compatible.
// clang and rustc both internally use llvm, so we want to inherit the PGO flags only for clang.
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fprofile-generate
if let Some(value) = self.profile_generate {
push_if_supported(format!("-fprofile-generate={value}").into());
}
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fprofile-use
if let Some(value) = self.profile_use {
push_if_supported(format!("-fprofile-use={value}").into());
}
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fembed-bitcode
if let Some(value) = self.embed_bitcode {
let cc_val = if value { "all" } else { "off" };
push_if_supported(format!("-fembed-bitcode={cc_val}").into());
}
// https://doc.rust-lang.org/rustc/linker-plugin-lto.html
if self.linker_plugin_lto.unwrap_or(false) {
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-flto
// In order to use linker-plugin-lto to achieve cross-lang lto, cc has to use thin LTO
// to compile the c/c++ libraries because llvm linker plugin/lld uses thin LTO by default.
// And for thin LTO in linker plugin to work, the archive also has to be compiled using thin LTO,
// since thin LTO generates extra information that fat LTO does not generate that
// is required for thin LTO process.
push_if_supported("-flto=thin".into());
}
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mguard
if let Some(value) = self.control_flow_guard {
let cc_val = match value {
"y" | "yes" | "on" | "true" | "checks" => Some("cf"),
"nochecks" => Some("cf-nochecks"),
"n" | "no" | "off" | "false" => Some("none"),
_ => None,
};
if let Some(cc_val) = cc_val {
push_if_supported(format!("-mguard={cc_val}").into());
}
}
}
ToolFamily::Gnu => {}
ToolFamily::Msvc { .. } => {
// https://learn.microsoft.com/en-us/cpp/build/reference/guard-enable-control-flow-guard
if let Some(value) = self.control_flow_guard {
let cc_val = match value {
"y" | "yes" | "on" | "true" | "checks" => Some("cf"),
"n" | "no" | "off" | "false" => Some("cf-"),
_ => None,
};
if let Some(cc_val) = cc_val {
push_if_supported(format!("/guard:{cc_val}").into());
}
}
// https://learn.microsoft.com/en-us/cpp/build/reference/oy-frame-pointer-omission
if let Some(value) = self.force_frame_pointers {
// Flag is unsupported on 64-bit arches
if !target.arch.contains("64") {
let cc_flag = if value { "/Oy-" } else { "/Oy" };
push_if_supported(cc_flag.into());
}
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[track_caller]
fn check(env: &str, expected: &RustcCodegenFlags) {
let actual = RustcCodegenFlags::parse(env).unwrap();
assert_eq!(actual, *expected);
}
#[test]
fn codegen_type() {
let expected = RustcCodegenFlags {
code_model: Some("tiny"),
..RustcCodegenFlags::default()
};
check("-Ccode-model=tiny", &expected);
check("-C\u{1f}code-model=tiny", &expected);
check("--codegen\u{1f}code-model=tiny", &expected);
check("--codegen=code-model=tiny", &expected);
}
#[test]
fn precedence() {
check(
"-ccode-model=tiny\u{1f}-Ccode-model=small",
&RustcCodegenFlags {
code_model: Some("small"),
..RustcCodegenFlags::default()
},
);
}
#[test]
fn two_valid_prefixes() {
let expected = RustcCodegenFlags::default();
check("-L\u{1f}-Clto", &expected);
}
#[test]
fn stack_protector() {
let expected = RustcCodegenFlags {
stack_protector: Some("strong"),
..RustcCodegenFlags::default()
};
check("-Zstack-protector=strong", &expected);
check("-Cstack-protector=strong", &expected);
}
#[test]
fn three_valid_prefixes() {
let expected = RustcCodegenFlags {
lto: Some("true"),
..RustcCodegenFlags::default()
};
check("-L\u{1f}-L\u{1f}-Clto", &expected);
}
#[test]
fn all_rustc_flags() {
// Throw all possible flags at the parser to catch false positives
let flags = [
// Set all the flags we recognise first
"-Ccode-model=tiny",
"-Ccontrol-flow-guard=yes",
"-Cembed-bitcode=no",
"-Cforce-frame-pointers=yes",
"-Clto=false",
"-Clink-dead-code=yes",
"-Cno-redzone=yes",
"-Cno-vectorize-loops",
"-Cno-vectorize-slp",
"-Cprofile-generate=fooprofile",
"-Cprofile-use=fooprofile",
"-Crelocation-model=pic",
"-Csoft-float=yes",
"-Zbranch-protection=bti,pac-ret,leaf",
"-Cdwarf-version=5",
"-Zstack-protector=strong",
// Set flags we don't recognise but rustc supports next
// rustc flags
"--cfg",
"a",
"--check-cfg 'cfg(verbose)",
"-L",
"/usr/lib/foo",
"-l",
"static:+whole-archive=mylib",
"--crate-type=dylib",
"--crate-name=foo",
"--edition=2021",
"--emit=asm",
"--print=crate-name",
"-g",
"-O",
"-o",
"foooutput",
"--out-dir",
"foooutdir",
"--target",
"aarch64-unknown-linux-gnu",
"-W",
"missing-docs",
"-D",
"unused-variables",
"--force-warn",
"dead-code",
"-A",
"unused",
"-F",
"unused",
"--cap-lints",
"warn",
"--version",
"--verbose",
"-v",
"--extern",
"foocrate",
"--sysroot",
"fooroot",
"--error-format",
"human",
"--color",
"auto",
"--diagnostic-width",
"80",
"--remap-path-prefix",
"foo=bar",
"--json=artifact",
// Codegen flags
"-Car",
"-Ccodegen-units=1",
"-Ccollapse-macro-debuginfo=yes",
"-Cdebug-assertions=yes",
"-Cdebuginfo=1",
"-Cdefault-linker-libraries=yes",
"-Cdlltool=foo",
"-Cextra-filename=foo",
"-Cforce-unwind-tables=yes",
"-Cincremental=foodir",
"-Cinline-threshold=6",
"-Cinstrument-coverage",
"-Clink-arg=-foo",
"-Clink-args=-foo",
"-Clink-self-contained=yes",
"-Clinker=lld",
"-Clinker-flavor=ld.lld",
"-Clinker-plugin-lto=/path",
"-Cllvm-args=foo",
"-Cmetadata=foo",
"-Cno-prepopulate-passes",
"-Cno-stack-check",
"-Copt-level=3",
"-Coverflow-checks=yes",
"-Cpanic=abort",
"-Cpasses=foopass",
"-Cprefer-dynamic=yes",
"-Crelro-level=partial",
"-Cremark=all",
"-Crpath=yes",
"-Csave-temps=yes",
"-Csplit-debuginfo=packed",
"-Cstrip=symbols",
"-Csymbol-mangling-version=v0",
"-Ctarget-cpu=native",
"-Ctarget-feature=+sve",
// Unstable options
"-Ztune-cpu=machine",
];
check(
&flags.join("\u{1f}"),
&RustcCodegenFlags {
code_model: Some("tiny"),
control_flow_guard: Some("yes"),
embed_bitcode: Some(false),
force_frame_pointers: Some(true),
lto: Some("false"),
no_redzone: Some(true),
no_vectorize_loops: true,
no_vectorize_slp: true,
profile_generate: Some("fooprofile"),
profile_use: Some("fooprofile"),
relocation_model: Some("pic"),
soft_float: Some(true),
branch_protection: Some("bti,pac-ret,leaf"),
dwarf_version: Some(5),
stack_protector: Some("strong"),
linker_plugin_lto: Some(true),
},
);
}
}

4547
http/vendor/cc/src/lib.rs vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,118 @@
use std::{
cell::Cell,
future::Future,
pin::Pin,
ptr,
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
thread,
time::Duration,
};
use crate::Error;
const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(
// Cloning just returns a new no-op raw waker
|_| NOOP_RAW_WAKER,
// `wake` does nothing
|_| {},
// `wake_by_ref` does nothing
|_| {},
// Dropping does nothing as we don't allocate anything
|_| {},
);
const NOOP_RAW_WAKER: RawWaker = RawWaker::new(ptr::null(), &NOOP_WAKER_VTABLE);
#[derive(Default)]
pub(crate) struct YieldOnce(bool);
impl Future for YieldOnce {
type Output = ();
fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<()> {
let flag = &mut std::pin::Pin::into_inner(self).0;
if !*flag {
*flag = true;
Poll::Pending
} else {
Poll::Ready(())
}
}
}
/// Execute the futures and return when they are all done.
///
/// Here we use our own homebrew async executor since cc is used in the build
/// script of many popular projects, pulling in additional dependencies would
/// significantly slow down its compilation.
pub(crate) fn block_on<Fut1, Fut2>(
mut fut1: Fut1,
mut fut2: Fut2,
has_made_progress: &Cell<bool>,
) -> Result<(), Error>
where
Fut1: Future<Output = Result<(), Error>>,
Fut2: Future<Output = Result<(), Error>>,
{
// Shadows the future so that it can never be moved and is guaranteed
// to be pinned.
//
// The same trick used in `pin!` macro.
//
// TODO: Once MSRV is bumped to 1.68, replace this with `std::pin::pin!`
let mut fut1 = Some(unsafe { Pin::new_unchecked(&mut fut1) });
let mut fut2 = Some(unsafe { Pin::new_unchecked(&mut fut2) });
// TODO: Once `Waker::noop` stablised and our MSRV is bumped to the version
// which it is stablised, replace this with `Waker::noop`.
let waker = unsafe { Waker::from_raw(NOOP_RAW_WAKER) };
let mut context = Context::from_waker(&waker);
let mut backoff_cnt = 0;
loop {
has_made_progress.set(false);
if let Some(fut) = fut2.as_mut() {
if let Poll::Ready(res) = fut.as_mut().poll(&mut context) {
fut2 = None;
res?;
}
}
if let Some(fut) = fut1.as_mut() {
if let Poll::Ready(res) = fut.as_mut().poll(&mut context) {
fut1 = None;
res?;
}
}
if fut1.is_none() && fut2.is_none() {
return Ok(());
}
if !has_made_progress.get() {
if backoff_cnt > 3 {
// We have yielded at least three times without making'
// any progress, so we will sleep for a while.
let duration = Duration::from_millis(100 * (backoff_cnt - 3).min(10));
thread::sleep(duration);
} else {
// Given that we spawned a lot of compilation tasks, it is unlikely
// that OS cannot find other ready task to execute.
//
// If all of them are done, then we will yield them and spawn more,
// or simply return.
//
// Thus this will not be turned into a busy-wait loop and it will not
// waste CPU resource.
thread::yield_now();
}
}
backoff_cnt = if has_made_progress.get() {
0
} else {
backoff_cnt + 1
};
}
}

View file

@ -0,0 +1,175 @@
use std::{
cell::Cell,
io::{self, Write as _},
process::{Child, Command},
};
use crate::{
parallel::{
async_executor::{block_on, YieldOnce},
job_token,
},
spawn, CargoOutput, Error, ErrorKind, StderrForwarder,
};
struct KillOnDrop(Child, StderrForwarder);
impl Drop for KillOnDrop {
fn drop(&mut self) {
let child = &mut self.0;
child.kill().ok();
}
}
fn cell_update<T, F>(cell: &Cell<T>, f: F)
where
T: Default,
F: FnOnce(T) -> T,
{
let old = cell.take();
let new = f(old);
cell.set(new);
}
fn try_wait_on_child(
cmd: &Command,
child: &mut Child,
mut stdout: impl io::Write,
stderr_forwarder: &mut StderrForwarder,
) -> Result<Option<()>, Error> {
stderr_forwarder.forward_available();
match child.try_wait() {
Ok(Some(status)) => {
stderr_forwarder.forward_all();
let _ = writeln!(stdout, "{}", status);
if status.success() {
Ok(Some(()))
} else {
Err(Error::new(
ErrorKind::ToolExecError,
format!("command did not execute successfully (status code {status}): {cmd:?}"),
))
}
}
Ok(None) => Ok(None),
Err(e) => {
stderr_forwarder.forward_all();
Err(Error::new(
ErrorKind::ToolExecError,
format!("failed to wait on spawned child process `{cmd:?}`: {e}"),
))
}
}
}
pub(crate) fn run_commands_in_parallel(
cargo_output: &CargoOutput,
cmds: &mut dyn Iterator<Item = Result<Command, Error>>,
) -> Result<(), Error> {
// Limit our parallelism globally with a jobserver.
let mut tokens = job_token::ActiveJobTokenServer::new();
// When compiling objects in parallel we do a few dirty tricks to speed
// things up:
//
// * First is that we use the `jobserver` crate to limit the parallelism
// of this build script. The `jobserver` crate will use a jobserver
// configured by Cargo for build scripts to ensure that parallelism is
// coordinated across C compilations and Rust compilations. Before we
// compile anything we make sure to wait until we acquire a token.
//
// Note that this jobserver is cached globally so we only used one per
// process and only worry about creating it once.
//
// * Next we use spawn the process to actually compile objects in
// parallel after we've acquired a token to perform some work
//
// With all that in mind we compile all objects in a loop here, after we
// acquire the appropriate tokens, Once all objects have been compiled
// we wait on all the processes and propagate the results of compilation.
let pendings = Cell::new(Vec::<(Command, KillOnDrop, job_token::JobToken)>::new());
let is_disconnected = Cell::new(false);
let has_made_progress = Cell::new(false);
let wait_future = async {
let mut error = None;
// Buffer the stdout
let mut stdout = io::BufWriter::with_capacity(128, io::stdout());
loop {
// If the other end of the pipe is already disconnected, then we're not gonna get any new jobs,
// so it doesn't make sense to reuse the tokens; in fact,
// releasing them as soon as possible (once we know that the other end is disconnected) is beneficial.
// Imagine that the last file built takes an hour to finish; in this scenario,
// by not releasing the tokens before that last file is done we would effectively block other processes from
// starting sooner - even though we only need one token for that last file, not N others that were acquired.
let mut pendings_is_empty = false;
cell_update(&pendings, |mut pendings| {
// Try waiting on them.
pendings.retain_mut(|(cmd, child, _token)| {
match try_wait_on_child(cmd, &mut child.0, &mut stdout, &mut child.1) {
Ok(Some(())) => {
// Task done, remove the entry
has_made_progress.set(true);
false
}
Ok(None) => true, // Task still not finished, keep the entry
Err(err) => {
// Task fail, remove the entry.
// Since we can only return one error, log the error to make
// sure users always see all the compilation failures.
has_made_progress.set(true);
if cargo_output.warnings {
let _ = writeln!(stdout, "cargo:warning={}", err);
}
error = Some(err);
false
}
}
});
pendings_is_empty = pendings.is_empty();
pendings
});
if pendings_is_empty && is_disconnected.get() {
break if let Some(err) = error {
Err(err)
} else {
Ok(())
};
}
YieldOnce::default().await;
}
};
let spawn_future = async {
for res in cmds {
let mut cmd = res?;
let token = tokens.acquire().await?;
let mut child = spawn(&mut cmd, cargo_output)?;
let mut stderr_forwarder = StderrForwarder::new(&mut child);
stderr_forwarder.set_non_blocking()?;
cell_update(&pendings, |mut pendings| {
pendings.push((cmd, KillOnDrop(child, stderr_forwarder), token));
pendings
});
has_made_progress.set(true);
}
is_disconnected.set(true);
Ok::<_, Error>(())
};
block_on(wait_future, spawn_future, &has_made_progress)
}

262
http/vendor/cc/src/parallel/job_token.rs vendored Normal file
View file

@ -0,0 +1,262 @@
use std::marker::PhantomData;
use crate::{utilities::OnceLock, Error};
pub(crate) struct JobToken(PhantomData<()>);
impl JobToken {
fn new() -> Self {
Self(PhantomData)
}
}
impl Drop for JobToken {
fn drop(&mut self) {
match JobTokenServer::new() {
JobTokenServer::Inherited(jobserver) => jobserver.release_token_raw(),
JobTokenServer::InProcess(jobserver) => jobserver.release_token_raw(),
}
}
}
enum JobTokenServer {
Inherited(inherited_jobserver::JobServer),
InProcess(inprocess_jobserver::JobServer),
}
impl JobTokenServer {
/// This function returns a static reference to the jobserver because
/// - creating a jobserver from env is a bit fd-unsafe (e.g. the fd might
/// be closed by other jobserver users in the process) and better do it
/// at the start of the program.
/// - in case a jobserver cannot be created from env (e.g. it's not
/// present), we will create a global in-process only jobserver
/// that has to be static so that it will be shared by all cc
/// compilation.
fn new() -> &'static Self {
// TODO: Replace with a OnceLock once MSRV is 1.70
static JOBSERVER: OnceLock<JobTokenServer> = OnceLock::new();
JOBSERVER.get_or_init(|| {
unsafe { inherited_jobserver::JobServer::from_env() }
.map(Self::Inherited)
.unwrap_or_else(|| Self::InProcess(inprocess_jobserver::JobServer::new()))
})
}
}
pub(crate) enum ActiveJobTokenServer {
Inherited(inherited_jobserver::ActiveJobServer<'static>),
InProcess(&'static inprocess_jobserver::JobServer),
}
impl ActiveJobTokenServer {
pub(crate) fn new() -> Self {
match JobTokenServer::new() {
JobTokenServer::Inherited(inherited_jobserver) => {
Self::Inherited(inherited_jobserver.enter_active())
}
JobTokenServer::InProcess(inprocess_jobserver) => Self::InProcess(inprocess_jobserver),
}
}
pub(crate) async fn acquire(&mut self) -> Result<JobToken, Error> {
match self {
Self::Inherited(jobserver) => jobserver.acquire().await,
Self::InProcess(jobserver) => Ok(jobserver.acquire().await),
}
}
}
mod inherited_jobserver {
use super::JobToken;
use crate::{parallel::async_executor::YieldOnce, Error, ErrorKind};
use std::{
io, mem,
sync::{mpsc, Mutex, MutexGuard, PoisonError},
};
pub(super) struct JobServer {
/// Implicit token for this process which is obtained and will be
/// released in parent. Since `JobTokens` only give back what they got,
/// there should be at most one global implicit token in the wild.
///
/// Since Rust does not execute any `Drop` for global variables,
/// we can't just put it back to jobserver and then re-acquire it at
/// the end of the process.
///
/// Use `Mutex` to avoid race between acquire and release.
/// If an `AtomicBool` is used, then it's possible for:
/// - `release_token_raw`: Tries to set `global_implicit_token` to true, but it is already
/// set to `true`, continue to release it to jobserver
/// - `acquire` takes the global implicit token, set `global_implicit_token` to false
/// - `release_token_raw` now writes the token back into the jobserver, while
/// `global_implicit_token` is `false`
///
/// If the program exits here, then cc effectively increases parallelism by one, which is
/// incorrect, hence we use a `Mutex` here.
global_implicit_token: Mutex<bool>,
inner: jobserver::Client,
}
impl JobServer {
pub(super) unsafe fn from_env() -> Option<Self> {
jobserver::Client::from_env().map(|inner| Self {
inner,
global_implicit_token: Mutex::new(true),
})
}
fn get_global_implicit_token(&self) -> MutexGuard<'_, bool> {
self.global_implicit_token
.lock()
.unwrap_or_else(PoisonError::into_inner)
}
/// All tokens except for the global implicit token will be put back into the jobserver
/// immediately and they cannot be cached, since Rust does not call `Drop::drop` on
/// global variables.
pub(super) fn release_token_raw(&self) {
let mut global_implicit_token = self.get_global_implicit_token();
if *global_implicit_token {
// There's already a global implicit token, so this token must
// be released back into jobserver.
//
// `release_raw` should not block
let _ = self.inner.release_raw();
} else {
*global_implicit_token = true;
}
}
pub(super) fn enter_active(&self) -> ActiveJobServer<'_> {
ActiveJobServer {
jobserver: self,
helper_thread: None,
}
}
}
struct HelperThread {
inner: jobserver::HelperThread,
/// When rx is dropped, all the token stored within it will be dropped.
rx: mpsc::Receiver<io::Result<jobserver::Acquired>>,
}
impl HelperThread {
fn new(jobserver: &JobServer) -> Result<Self, Error> {
let (tx, rx) = mpsc::channel();
Ok(Self {
rx,
inner: jobserver.inner.clone().into_helper_thread(move |res| {
let _ = tx.send(res);
})?,
})
}
}
pub(crate) struct ActiveJobServer<'a> {
jobserver: &'a JobServer,
helper_thread: Option<HelperThread>,
}
impl ActiveJobServer<'_> {
pub(super) async fn acquire(&mut self) -> Result<JobToken, Error> {
let mut has_requested_token = false;
loop {
// Fast path
if mem::replace(&mut *self.jobserver.get_global_implicit_token(), false) {
break Ok(JobToken::new());
}
match self.jobserver.inner.try_acquire() {
Ok(Some(acquired)) => {
acquired.drop_without_releasing();
break Ok(JobToken::new());
}
Ok(None) => YieldOnce::default().await,
Err(err) if err.kind() == io::ErrorKind::Unsupported => {
// Fallback to creating a help thread with blocking acquire
let helper_thread = if let Some(thread) = self.helper_thread.as_ref() {
thread
} else {
self.helper_thread
.insert(HelperThread::new(self.jobserver)?)
};
match helper_thread.rx.try_recv() {
Ok(res) => {
let acquired = res?;
acquired.drop_without_releasing();
break Ok(JobToken::new());
}
Err(mpsc::TryRecvError::Disconnected) => break Err(Error::new(
ErrorKind::JobserverHelpThreadError,
"jobserver help thread has returned before ActiveJobServer is dropped",
)),
Err(mpsc::TryRecvError::Empty) => {
if !has_requested_token {
helper_thread.inner.request_token();
has_requested_token = true;
}
YieldOnce::default().await
}
}
}
Err(err) => break Err(err.into()),
}
}
}
}
}
mod inprocess_jobserver {
use super::JobToken;
use crate::{parallel::async_executor::YieldOnce, utilities::cargo_env_var_os};
use std::sync::atomic::{
AtomicU32,
Ordering::{AcqRel, Acquire},
};
pub(crate) struct JobServer(AtomicU32);
impl JobServer {
pub(super) fn new() -> Self {
// Use `NUM_JOBS` if set (it's configured by Cargo) and otherwise
// just fall back to the number of cores on the local machine, or a reasonable
// default if that cannot be determined.
let parallelism = cargo_env_var_os("NUM_JOBS")
.and_then(|j| j.to_str()?.parse::<u32>().ok())
.or_else(|| Some(std::thread::available_parallelism().ok()?.get() as u32))
.unwrap_or(4);
Self(AtomicU32::new(parallelism))
}
pub(super) async fn acquire(&self) -> JobToken {
loop {
let res = self
.0
.fetch_update(AcqRel, Acquire, |tokens| tokens.checked_sub(1));
if res.is_ok() {
break JobToken::new();
}
YieldOnce::default().await
}
}
pub(super) fn release_token_raw(&self) {
self.0.fetch_add(1, AcqRel);
}
}
}

6
http/vendor/cc/src/parallel/mod.rs vendored Normal file
View file

@ -0,0 +1,6 @@
mod async_executor;
mod command_runner;
mod job_token;
pub(crate) mod stderr;
pub(crate) use command_runner::run_commands_in_parallel;

91
http/vendor/cc/src/parallel/stderr.rs vendored Normal file
View file

@ -0,0 +1,91 @@
#![cfg_attr(target_family = "wasm", allow(unused))]
/// Helpers functions for [`ChildStderr`].
use std::{convert::TryInto, process::ChildStderr};
use crate::{Error, ErrorKind};
#[cfg(all(not(unix), not(windows), not(target_family = "wasm")))]
compile_error!("Only unix and windows support non-blocking pipes! For other OSes, disable the parallel feature.");
#[cfg(unix)]
fn get_flags(fd: std::os::unix::io::RawFd) -> Result<i32, Error> {
let flags = unsafe { libc::fcntl(fd, libc::F_GETFL, 0) };
if flags == -1 {
Err(Error::new(
ErrorKind::IOError,
format!(
"Failed to get flags for pipe {}: {}",
fd,
std::io::Error::last_os_error()
),
))
} else {
Ok(flags)
}
}
#[cfg(unix)]
fn set_flags(fd: std::os::unix::io::RawFd, flags: std::os::raw::c_int) -> Result<(), Error> {
if unsafe { libc::fcntl(fd, libc::F_SETFL, flags) } == -1 {
Err(Error::new(
ErrorKind::IOError,
format!(
"Failed to set flags for pipe {}: {}",
fd,
std::io::Error::last_os_error()
),
))
} else {
Ok(())
}
}
#[cfg(unix)]
pub fn set_non_blocking(pipe: &impl std::os::unix::io::AsRawFd) -> Result<(), Error> {
// On Unix, switch the pipe to non-blocking mode.
// On Windows, we have a different way to be non-blocking.
let fd = pipe.as_raw_fd();
let flags = get_flags(fd)?;
set_flags(fd, flags | libc::O_NONBLOCK)
}
pub fn bytes_available(stderr: &mut ChildStderr) -> Result<usize, Error> {
let mut bytes_available = 0;
#[cfg(windows)]
{
use ::find_msvc_tools::windows_sys::PeekNamedPipe;
use std::os::windows::io::AsRawHandle;
use std::ptr::null_mut;
if unsafe {
PeekNamedPipe(
stderr.as_raw_handle(),
null_mut(),
0,
null_mut(),
&mut bytes_available,
null_mut(),
)
} == 0
{
return Err(Error::new(
ErrorKind::IOError,
format!(
"PeekNamedPipe failed with {}",
std::io::Error::last_os_error()
),
));
}
}
#[cfg(unix)]
{
use std::os::unix::io::AsRawFd;
if unsafe { libc::ioctl(stderr.as_raw_fd(), libc::FIONREAD, &mut bytes_available) } != 0 {
return Err(Error::new(
ErrorKind::IOError,
format!("ioctl failed with {}", std::io::Error::last_os_error()),
));
}
}
Ok(bytes_available.try_into().unwrap())
}

41
http/vendor/cc/src/target.rs vendored Normal file
View file

@ -0,0 +1,41 @@
//! Parsing of `rustc` target names to match the values exposed to Cargo
//! build scripts (`CARGO_CFG_*`).
mod apple;
mod generated;
mod llvm;
mod parser;
pub(crate) use parser::TargetInfoParser;
/// Information specific to a `rustc` target.
///
/// See <https://doc.rust-lang.org/cargo/appendix/glossary.html#target>.
#[derive(Debug, PartialEq, Clone)]
pub(crate) struct TargetInfo<'a> {
/// The full architecture, including the subarchitecture.
///
/// This differs from `cfg!(target_arch)`, which only specifies the
/// overall architecture, which is too coarse for certain cases.
pub full_arch: &'a str,
/// The overall target architecture.
///
/// This is the same as the value of `cfg!(target_arch)`.
pub arch: &'a str,
/// The target vendor.
///
/// This is the same as the value of `cfg!(target_vendor)`.
pub vendor: &'a str,
/// The operating system, or `none` on bare-metal targets.
///
/// This is the same as the value of `cfg!(target_os)`.
pub os: &'a str,
/// The environment on top of the operating system.
///
/// This is the same as the value of `cfg!(target_env)`.
pub env: &'a str,
/// The ABI on top of the operating system.
///
/// This is the same as the value of `cfg!(target_abi)`.
pub abi: &'a str,
}

86
http/vendor/cc/src/tempfile.rs vendored Normal file
View file

@ -0,0 +1,86 @@
#![cfg_attr(target_family = "wasm", allow(unused))]
use std::{
collections::hash_map::RandomState,
fs::{remove_file, File, OpenOptions},
hash::{BuildHasher, Hasher},
io, os,
path::{Path, PathBuf},
};
#[cfg(not(any(unix, target_family = "wasm", windows)))]
compile_error!("Your system is not supported since cc cannot create named tempfile");
fn rand() -> u64 {
RandomState::new().build_hasher().finish()
}
fn tmpname(suffix: &str) -> String {
format!("{}{}", rand(), suffix)
}
fn create_named(path: &Path) -> io::Result<File> {
let mut open_options = OpenOptions::new();
open_options.read(true).write(true).create_new(true);
#[cfg(all(unix, not(target_os = "wasi")))]
<OpenOptions as os::unix::fs::OpenOptionsExt>::mode(&mut open_options, 0o600);
#[cfg(windows)]
<OpenOptions as os::windows::fs::OpenOptionsExt>::custom_flags(
&mut open_options,
::find_msvc_tools::windows_sys::FILE_ATTRIBUTE_TEMPORARY,
);
open_options.open(path)
}
pub(super) struct NamedTempfile {
path: PathBuf,
file: Option<File>,
}
impl NamedTempfile {
pub(super) fn new(base: &Path, suffix: &str) -> io::Result<Self> {
for _ in 0..10 {
let path = base.join(tmpname(suffix));
match create_named(&path) {
Ok(file) => {
return Ok(Self {
file: Some(file),
path,
})
}
Err(e) if e.kind() == io::ErrorKind::AlreadyExists => continue,
Err(e) => return Err(e),
};
}
Err(io::Error::new(
io::ErrorKind::AlreadyExists,
format!(
"too many temporary files exist in base `{}` with suffix `{}`",
base.display(),
suffix
),
))
}
pub(super) fn path(&self) -> &Path {
&self.path
}
pub(super) fn take_file(&mut self) -> Option<File> {
self.file.take()
}
}
impl Drop for NamedTempfile {
fn drop(&mut self) {
// On Windows you have to close all handle to it before
// removing the file.
self.file.take();
let _ = remove_file(&self.path);
}
}

595
http/vendor/cc/src/tool.rs vendored Normal file
View file

@ -0,0 +1,595 @@
use crate::{
command_helpers::{run_output, spawn_and_wait_for_output, CargoOutput},
run,
tempfile::NamedTempfile,
Error, ErrorKind, OutputKind,
};
use std::{
borrow::Cow,
collections::HashMap,
env,
ffi::{OsStr, OsString},
io::Write,
path::{Path, PathBuf},
process::{Command, Output, Stdio},
sync::RwLock,
};
pub(crate) type CompilerFamilyLookupCache = HashMap<Box<[Box<OsStr>]>, ToolFamily>;
/// Configuration used to represent an invocation of a C compiler.
///
/// This can be used to figure out what compiler is in use, what the arguments
/// to it are, and what the environment variables look like for the compiler.
/// This can be used to further configure other build systems (e.g. forward
/// along CC and/or CFLAGS) or the `to_command` method can be used to run the
/// compiler itself.
#[derive(Clone, Debug)]
#[allow(missing_docs)]
pub struct Tool {
pub(crate) path: PathBuf,
pub(crate) cc_wrapper_path: Option<PathBuf>,
pub(crate) cc_wrapper_args: Vec<OsString>,
pub(crate) args: Vec<OsString>,
pub(crate) env: Vec<(OsString, OsString)>,
pub(crate) family: ToolFamily,
pub(crate) cuda: bool,
pub(crate) removed_args: Vec<OsString>,
pub(crate) has_internal_target_arg: bool,
}
impl Tool {
pub(crate) fn from_find_msvc_tools(tool: ::find_msvc_tools::Tool) -> Self {
let mut cc_tool = Self::with_family(
tool.path().into(),
ToolFamily::Msvc {
clang_cl: tool.is_clang_cl(),
},
);
cc_tool.env = tool
.env()
.into_iter()
.map(|(k, v)| (k.clone(), v.clone()))
.collect();
cc_tool
}
pub(crate) fn new(
path: PathBuf,
cached_compiler_family: &RwLock<CompilerFamilyLookupCache>,
cargo_output: &CargoOutput,
out_dir: Option<&Path>,
) -> Self {
Self::with_features(
path,
vec![],
false,
cached_compiler_family,
cargo_output,
out_dir,
)
}
pub(crate) fn with_args(
path: PathBuf,
args: Vec<String>,
cached_compiler_family: &RwLock<CompilerFamilyLookupCache>,
cargo_output: &CargoOutput,
out_dir: Option<&Path>,
) -> Self {
Self::with_features(
path,
args,
false,
cached_compiler_family,
cargo_output,
out_dir,
)
}
/// Explicitly set the `ToolFamily`, skipping name-based detection.
pub(crate) fn with_family(path: PathBuf, family: ToolFamily) -> Self {
Self {
path,
cc_wrapper_path: None,
cc_wrapper_args: Vec::new(),
args: Vec::new(),
env: Vec::new(),
family,
cuda: false,
removed_args: Vec::new(),
has_internal_target_arg: false,
}
}
pub(crate) fn with_features(
path: PathBuf,
args: Vec<String>,
cuda: bool,
cached_compiler_family: &RwLock<CompilerFamilyLookupCache>,
cargo_output: &CargoOutput,
out_dir: Option<&Path>,
) -> Self {
fn is_zig_cc(path: &Path, cargo_output: &CargoOutput) -> bool {
run_output(
Command::new(path).arg("--version"),
// tool detection issues should always be shown as warnings
cargo_output,
)
.map(|o| String::from_utf8_lossy(&o).contains("ziglang"))
.unwrap_or_default()
|| {
match path.file_name().map(OsStr::to_string_lossy) {
Some(fname) => fname.contains("zig"),
_ => false,
}
}
}
fn guess_family_from_stdout(
stdout: &str,
path: &Path,
args: &[String],
cargo_output: &CargoOutput,
) -> Result<ToolFamily, Error> {
cargo_output.print_debug(&stdout);
// https://gitlab.kitware.com/cmake/cmake/-/blob/69a2eeb9dff5b60f2f1e5b425002a0fd45b7cadb/Modules/CMakeDetermineCompilerId.cmake#L267-271
// stdin is set to null to ensure that the help output is never paginated.
let accepts_cl_style_flags = run(
Command::new(path).args(args).arg("-?").stdin(Stdio::null()),
&{
// the errors are not errors!
let mut cargo_output = cargo_output.clone();
cargo_output.warnings = cargo_output.debug;
cargo_output.output = OutputKind::Discard;
cargo_output
},
)
.is_ok();
let clang = stdout.contains(r#""clang""#);
let gcc = stdout.contains(r#""gcc""#);
let emscripten = stdout.contains(r#""emscripten""#);
let vxworks = stdout.contains(r#""VxWorks""#);
match (clang, accepts_cl_style_flags, gcc, emscripten, vxworks) {
(clang_cl, true, _, false, false) => Ok(ToolFamily::Msvc { clang_cl }),
(true, _, _, _, false) | (_, _, _, true, false) => Ok(ToolFamily::Clang {
zig_cc: is_zig_cc(path, cargo_output),
}),
(false, false, true, _, false) | (_, _, _, _, true) => Ok(ToolFamily::Gnu),
(false, false, false, false, false) => {
cargo_output.print_warning(&"Compiler family detection failed since it does not define `__clang__`, `__GNUC__`, `__EMSCRIPTEN__` or `__VXWORKS__`, also does not accept cl style flag `-?`, fallback to treating it as GNU");
Err(Error::new(
ErrorKind::ToolFamilyMacroNotFound,
"Expects macro `__clang__`, `__GNUC__` or `__EMSCRIPTEN__`, `__VXWORKS__` or accepts cl style flag `-?`, but found none",
))
}
}
}
fn detect_family_inner(
path: &Path,
args: &[String],
cargo_output: &CargoOutput,
out_dir: Option<&Path>,
) -> Result<ToolFamily, Error> {
let out_dir = out_dir
.map(Cow::Borrowed)
.unwrap_or_else(|| Cow::Owned(env::temp_dir()));
// Ensure all the parent directories exist otherwise temp file creation
// will fail
std::fs::create_dir_all(&out_dir).map_err(|err| Error {
kind: ErrorKind::IOError,
message: format!("failed to create OUT_DIR '{}': {}", out_dir.display(), err)
.into(),
})?;
let mut tmp =
NamedTempfile::new(&out_dir, "detect_compiler_family.c").map_err(|err| Error {
kind: ErrorKind::IOError,
message: format!(
"failed to create detect_compiler_family.c temp file in '{}': {}",
out_dir.display(),
err
)
.into(),
})?;
let mut tmp_file = tmp.take_file().unwrap();
tmp_file.write_all(include_bytes!("detect_compiler_family.c"))?;
// Close the file handle *now*, otherwise the compiler may fail to open it on Windows
// (#1082). The file stays on disk and its path remains valid until `tmp` is dropped.
tmp_file.flush()?;
tmp_file.sync_data()?;
drop(tmp_file);
// When expanding the file, the compiler prints a lot of information to stderr
// that it is not an error, but related to expanding itself.
//
// cc would have to disable warning here to prevent generation of too many warnings.
let mut compiler_detect_output = cargo_output.clone();
compiler_detect_output.warnings = compiler_detect_output.debug;
let mut cmd = Command::new(path);
cmd.arg("-E").arg(tmp.path());
// The -Wslash-u-filename warning is normally part of stdout.
// But with clang-cl it can be part of stderr instead and exit with a
// non-zero exit code.
let mut captured_cargo_output = compiler_detect_output.clone();
captured_cargo_output.warnings = true;
let Output {
status,
stdout,
stderr,
} = spawn_and_wait_for_output(&mut cmd, &captured_cargo_output)?;
let stdout = if [&stdout, &stderr]
.iter()
.any(|o| String::from_utf8_lossy(o).contains("-Wslash-u-filename"))
{
run_output(
Command::new(path).arg("-E").arg("--").arg(tmp.path()),
&compiler_detect_output,
)?
} else {
if !status.success() {
return Err(Error::new(
ErrorKind::ToolExecError,
format!(
"command did not execute successfully (status code {status}): {cmd:?}"
),
));
}
stdout
};
let stdout = String::from_utf8_lossy(&stdout);
guess_family_from_stdout(&stdout, path, args, cargo_output)
}
let detect_family = |path: &Path, args: &[String]| -> Result<ToolFamily, Error> {
let cache_key = [path.as_os_str()]
.iter()
.cloned()
.chain(args.iter().map(OsStr::new))
.map(Into::into)
.collect();
if let Some(family) = cached_compiler_family.read().unwrap().get(&cache_key) {
return Ok(*family);
}
let family = detect_family_inner(path, args, cargo_output, out_dir)?;
cached_compiler_family
.write()
.unwrap()
.insert(cache_key, family);
Ok(family)
};
let family = detect_family(&path, &args).unwrap_or_else(|e| {
cargo_output.print_warning(&format_args!(
"Compiler family detection failed due to error: {e}"
));
match path.file_name().map(OsStr::to_string_lossy) {
Some(fname) if fname.contains("clang-cl") => ToolFamily::Msvc { clang_cl: true },
Some(fname) if fname.ends_with("cl") || fname == "cl.exe" => {
ToolFamily::Msvc { clang_cl: false }
}
Some(fname) if fname.contains("clang") => {
let is_clang_cl = args
.iter()
.any(|a| a.strip_prefix("--driver-mode=") == Some("cl"));
if is_clang_cl {
ToolFamily::Msvc { clang_cl: true }
} else {
ToolFamily::Clang {
zig_cc: is_zig_cc(&path, cargo_output),
}
}
}
Some(fname) if fname.contains("zig") => ToolFamily::Clang { zig_cc: true },
_ => ToolFamily::Gnu,
}
});
Tool {
path,
cc_wrapper_path: None,
cc_wrapper_args: Vec::new(),
args: Vec::new(),
env: Vec::new(),
family,
cuda,
removed_args: Vec::new(),
has_internal_target_arg: false,
}
}
/// Add an argument to be stripped from the final command arguments.
pub(crate) fn remove_arg(&mut self, flag: OsString) {
self.removed_args.push(flag);
}
/// Push an "exotic" flag to the end of the compiler's arguments list.
///
/// Nvidia compiler accepts only the most common compiler flags like `-D`,
/// `-I`, `-c`, etc. Options meant specifically for the underlying
/// host C++ compiler have to be prefixed with `-Xcompiler`.
/// [Another possible future application for this function is passing
/// clang-specific flags to clang-cl, which otherwise accepts only
/// MSVC-specific options.]
pub(crate) fn push_cc_arg(&mut self, flag: OsString) {
if self.cuda {
self.args.push("-Xcompiler".into());
}
self.args.push(flag);
}
/// Checks if an argument or flag has already been specified or conflicts.
///
/// Currently only checks optimization flags.
pub(crate) fn is_duplicate_opt_arg(&self, flag: &OsString) -> bool {
let flag = flag.to_str().unwrap();
let mut chars = flag.chars();
// Only duplicate check compiler flags
if self.is_like_msvc() {
if chars.next() != Some('/') {
return false;
}
} else if (self.is_like_gnu() || self.is_like_clang()) && chars.next() != Some('-') {
return false;
}
// Check for existing optimization flags (-O, /O)
if chars.next() == Some('O') {
return self
.args()
.iter()
.any(|a| a.to_str().unwrap_or("").chars().nth(1) == Some('O'));
}
// TODO Check for existing -m..., -m...=..., /arch:... flags
false
}
/// Don't push optimization arg if it conflicts with existing args.
pub(crate) fn push_opt_unless_duplicate(&mut self, flag: OsString) {
if self.is_duplicate_opt_arg(&flag) {
eprintln!("Info: Ignoring duplicate arg {:?}", &flag);
} else {
self.push_cc_arg(flag);
}
}
/// Converts this compiler into a `Command` that's ready to be run.
///
/// This is useful for when the compiler needs to be executed and the
/// command returned will already have the initial arguments and environment
/// variables configured.
pub fn to_command(&self) -> Command {
let mut cmd = match self.cc_wrapper_path {
Some(ref cc_wrapper_path) => {
let mut cmd = Command::new(cc_wrapper_path);
cmd.arg(&self.path);
cmd
}
None => Command::new(&self.path),
};
cmd.args(&self.cc_wrapper_args);
cmd.args(self.args.iter().filter(|a| !self.removed_args.contains(a)));
for (k, v) in self.env.iter() {
cmd.env(k, v);
}
cmd
}
/// Returns the path for this compiler.
///
/// Note that this may not be a path to a file on the filesystem, e.g. "cc",
/// but rather something which will be resolved when a process is spawned.
pub fn path(&self) -> &Path {
&self.path
}
/// Returns the default set of arguments to the compiler needed to produce
/// executables for the target this compiler generates.
pub fn args(&self) -> &[OsString] {
&self.args
}
/// Returns the set of environment variables needed for this compiler to
/// operate.
///
/// This is typically only used for MSVC compilers currently.
pub fn env(&self) -> &[(OsString, OsString)] {
&self.env
}
/// Returns the compiler command in format of CC environment variable.
/// Or empty string if CC env was not present
///
/// This is typically used by configure script
pub fn cc_env(&self) -> OsString {
match self.cc_wrapper_path {
Some(ref cc_wrapper_path) => {
let mut cc_env = cc_wrapper_path.as_os_str().to_owned();
cc_env.push(" ");
cc_env.push(self.path.to_path_buf().into_os_string());
for arg in self.cc_wrapper_args.iter() {
cc_env.push(" ");
cc_env.push(arg);
}
cc_env
}
None => OsString::from(""),
}
}
/// Returns the compiler flags in format of CFLAGS environment variable.
/// Important here - this will not be CFLAGS from env, its internal gcc's flags to use as CFLAGS
/// This is typically used by configure script
pub fn cflags_env(&self) -> OsString {
let mut flags = OsString::new();
for (i, arg) in self.args.iter().enumerate() {
if i > 0 {
flags.push(" ");
}
flags.push(arg);
}
flags
}
/// Whether the tool is GNU Compiler Collection-like.
pub fn is_like_gnu(&self) -> bool {
self.family == ToolFamily::Gnu
}
/// Whether the tool is Clang-like.
pub fn is_like_clang(&self) -> bool {
matches!(self.family, ToolFamily::Clang { .. })
}
/// Whether the tool is AppleClang under .xctoolchain
#[cfg(target_vendor = "apple")]
pub(crate) fn is_xctoolchain_clang(&self) -> bool {
let path = self.path.to_string_lossy();
path.contains(".xctoolchain/")
}
#[cfg(not(target_vendor = "apple"))]
pub(crate) fn is_xctoolchain_clang(&self) -> bool {
false
}
/// Whether the tool is MSVC-like.
pub fn is_like_msvc(&self) -> bool {
matches!(self.family, ToolFamily::Msvc { .. })
}
/// Whether the tool is `clang-cl`-based MSVC-like.
pub fn is_like_clang_cl(&self) -> bool {
matches!(self.family, ToolFamily::Msvc { clang_cl: true })
}
/// Supports using `--` delimiter to separate arguments and path to source files.
pub(crate) fn supports_path_delimiter(&self) -> bool {
// homebrew clang and zig-cc does not support this while stock version does
matches!(self.family, ToolFamily::Msvc { clang_cl: true }) && !self.cuda
}
}
/// Represents the family of tools this tool belongs to.
///
/// Each family of tools differs in how and what arguments they accept.
///
/// Detection of a family is done on best-effort basis and may not accurately reflect the tool.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ToolFamily {
/// Tool is GNU Compiler Collection-like.
Gnu,
/// Tool is Clang-like. It differs from the GCC in a sense that it accepts superset of flags
/// and its cross-compilation approach is different.
Clang { zig_cc: bool },
/// Tool is the MSVC cl.exe.
Msvc { clang_cl: bool },
}
impl ToolFamily {
/// What the flag to request debug info for this family of tools look like
pub(crate) fn add_debug_flags(
&self,
cmd: &mut Tool,
debug_opt: &str,
dwarf_version: Option<u32>,
) {
match *self {
ToolFamily::Msvc { .. } => {
cmd.push_cc_arg("-Z7".into());
}
ToolFamily::Gnu | ToolFamily::Clang { .. } => {
match debug_opt {
// From https://doc.rust-lang.org/cargo/reference/profiles.html#debug
"" | "0" | "false" | "none" => {
debug_assert!(
false,
"earlier check should have avoided calling add_debug_flags"
);
}
// line-directives-only is LLVM-specific; for GCC we have to treat it like "1"
"line-directives-only" if cmd.is_like_clang() => {
cmd.push_cc_arg("-gline-directives-only".into());
}
// Clang has -gline-tables-only, but it's an alias for -g1 anyway.
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-gline-tables-only
"1" | "limited" | "line-tables-only" | "line-directives-only" => {
cmd.push_cc_arg("-g1".into());
}
"2" | "true" | "full" => {
cmd.push_cc_arg("-g".into());
}
_ => {
// Err on the side of including too much info rather than too little.
cmd.push_cc_arg("-g".into());
}
}
if let Some(v) = dwarf_version {
cmd.push_cc_arg(format!("-gdwarf-{v}").into());
}
}
}
}
/// What the flag to force frame pointers.
pub(crate) fn add_force_frame_pointer(&self, cmd: &mut Tool) {
match *self {
ToolFamily::Gnu | ToolFamily::Clang { .. } => {
cmd.push_cc_arg("-fno-omit-frame-pointer".into());
}
_ => (),
}
}
/// What the flags to enable all warnings
pub(crate) fn warnings_flags(&self) -> &'static str {
match *self {
ToolFamily::Msvc { .. } => "-W4",
ToolFamily::Gnu | ToolFamily::Clang { .. } => "-Wall",
}
}
pub(crate) fn warnings_suppression_flags(&self) -> &'static str {
match *self {
ToolFamily::Msvc { .. } => "-W0",
ToolFamily::Gnu | ToolFamily::Clang { .. } => "-w",
}
}
/// What the flags to enable extra warnings
pub(crate) fn extra_warnings_flags(&self) -> Option<&'static str> {
match *self {
ToolFamily::Msvc { .. } => None,
ToolFamily::Gnu | ToolFamily::Clang { .. } => Some("-Wextra"),
}
}
/// What the flag to turn warning into errors
pub(crate) fn warnings_to_errors_flag(&self) -> &'static str {
match *self {
ToolFamily::Msvc { .. } => "-WX",
ToolFamily::Gnu | ToolFamily::Clang { .. } => "-Werror",
}
}
pub(crate) fn verbose_stderr(&self) -> bool {
matches!(*self, ToolFamily::Clang { .. })
}
}

160
http/vendor/cc/src/utilities.rs vendored Normal file
View file

@ -0,0 +1,160 @@
use std::{
cell::UnsafeCell,
ffi::{OsStr, OsString},
fmt::{self, Write},
marker::PhantomData,
mem::MaybeUninit,
panic::{RefUnwindSafe, UnwindSafe},
path::Path,
sync::Once,
};
use crate::{Error, ErrorKind};
pub(super) struct JoinOsStrs<'a, T> {
pub(super) slice: &'a [T],
pub(super) delimiter: char,
}
impl<T> fmt::Display for JoinOsStrs<'_, T>
where
T: AsRef<OsStr>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let len = self.slice.len();
for (index, os_str) in self.slice.iter().enumerate() {
// TODO: Use OsStr::display once it is stablised,
// Path and OsStr has the same `Display` impl
write!(f, "{}", Path::new(os_str).display())?;
if index + 1 < len {
f.write_char(self.delimiter)?;
}
}
Ok(())
}
}
pub(super) struct OptionOsStrDisplay<T>(pub(super) Option<T>);
impl<T> fmt::Display for OptionOsStrDisplay<T>
where
T: AsRef<OsStr>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// TODO: Use OsStr::display once it is stablised
// Path and OsStr has the same `Display` impl
if let Some(os_str) = self.0.as_ref() {
write!(f, "Some({})", Path::new(os_str).display())
} else {
f.write_str("None")
}
}
}
pub(crate) struct OnceLock<T> {
once: Once,
value: UnsafeCell<MaybeUninit<T>>,
_marker: PhantomData<T>,
}
impl<T> Default for OnceLock<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> OnceLock<T> {
pub(crate) const fn new() -> Self {
Self {
once: Once::new(),
value: UnsafeCell::new(MaybeUninit::uninit()),
_marker: PhantomData,
}
}
#[inline]
fn is_initialized(&self) -> bool {
self.once.is_completed()
}
unsafe fn get_unchecked(&self) -> &T {
debug_assert!(self.is_initialized());
#[allow(clippy::needless_borrow)]
#[allow(unused_unsafe)]
unsafe {
(&*self.value.get()).assume_init_ref()
}
}
pub(crate) fn get_or_init(&self, f: impl FnOnce() -> T) -> &T {
self.once.call_once(|| {
unsafe { &mut *self.value.get() }.write(f());
});
unsafe { self.get_unchecked() }
}
pub(crate) fn get(&self) -> Option<&T> {
if self.is_initialized() {
// Safe b/c checked is_initialized
Some(unsafe { self.get_unchecked() })
} else {
None
}
}
}
impl<T: fmt::Debug> fmt::Debug for OnceLock<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut d = f.debug_tuple("OnceLock");
match self.get() {
Some(v) => d.field(v),
None => d.field(&format_args!("<uninit>")),
};
d.finish()
}
}
unsafe impl<T: Sync + Send> Sync for OnceLock<T> {}
unsafe impl<T: Send> Send for OnceLock<T> {}
impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceLock<T> {}
impl<T: UnwindSafe> UnwindSafe for OnceLock<T> {}
impl<T> Drop for OnceLock<T> {
#[inline]
fn drop(&mut self) {
if self.once.is_completed() {
// SAFETY: The cell is initialized and being dropped, so it can't
// be accessed again.
unsafe { self.value.get_mut().assume_init_drop() };
}
}
}
/// Access an environment variable that's set by Cargo.
///
/// <https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts>
///
/// Cargo doesn't need to be told about these with `rerun-if-env-changed`, and
/// that we don't want to allow overwriting them with `Build::env`.
#[allow(clippy::disallowed_methods)] // Cargo env, no need for cache busting.
pub(crate) fn cargo_env_var_os(key: &str) -> Option<OsString> {
std::env::var_os(key)
}
pub(crate) fn cargo_env_var(key: &str) -> Result<String, Error> {
if let Some(value) = cargo_env_var_os(key) {
match value.into_string() {
Ok(value) => Ok(value),
Err(value) => Err(Error::new(
ErrorKind::EnvVarNotFound,
format!("environment variable {key} is not valid utf-8: {value:?}"),
)),
}
} else {
Err(Error::new(
ErrorKind::EnvVarNotFound,
format!("environment variable {key} not defined"),
))
}
}

View file

@ -0,0 +1 @@
{"files":{".cargo_vcs_info.json":"65840ba044457862e25b2d7d53f4a2de232adf933bd31aba8f2bd6a1f51a6881",".github/dependabot.yml":"828e3ecefdc555a5210a5bdffd5621ef3625ceb35c7fc91a0b4faef6f9921b75",".github/workflows/main.yaml":"6612a51b1f1479eabac7d3bd14aa609811d4afd2df2d454b9a1f6d6f3748f5b2",".github/workflows/publish.yaml":"1417805078704eecbaeea8611c5a44df575bfe1908d6969d909224a6e5e26ca8","CHANGELOG.md":"08ba7340057565b338afaa29b36bd2a1c46f5495b043bc49d12230a6a82d5f76","Cargo.lock":"26922b9384045e5a3d496f21ec7c355da585d0caa1d13b887b634527d36fc450","Cargo.toml":"281d508beb1fe3927cf03d3f2f8c9a5117b1e4fe97ae21b9026cf318e8c35273","Cargo.toml.orig":"5a17ee17da78f5179373b8324a1180e71efe2bcf3e3c9ca18c1bdb1e3faa9792","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"cd565d563a2c70d197bb6fee1678e122214e22af7bdb046b80f52c1d953cd72f","src/lib.rs":"c09723e0890d15810374009e96b20bf0eb2f65f383006516f34db36240835c85","tests/xcrate.rs":"bcec148e69db81b1a618bdd6f96a25d9a0442e6ecc692fe28f1206d9bffc006a"},"package":"9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"}

View file

@ -0,0 +1,6 @@
{
"git": {
"sha1": "3510ca6abea34cbbc702509a4e50ea9709925eda"
},
"path_in_vcs": ""
}

View file

@ -0,0 +1,14 @@
version: 2
updates:
- package-ecosystem: cargo
directory: "/"
schedule:
interval: daily
time: "08:00"
open-pull-requests-limit: 10
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 3

View file

@ -0,0 +1,48 @@
name: CI
on: [push, pull_request]
permissions:
contents: read
env:
RUSTDOCFLAGS: -Dwarnings
RUSTFLAGS: -Dwarnings
jobs:
test:
name: Test
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- "1.32" # msrv
- stable
- beta
- nightly
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Install Rust ${{ matrix.rust }}
run: |
rustup self update
rustup update ${{ matrix.rust }}
rustup default ${{ matrix.rust }}
rustc -vV
- name: Run tests
run: |
set -eux
# Remove `-Dwarnings` at the MSRV since lints may be different
[ "${{ matrix.rust }}" = "1.32" ] && export RUSTFLAGS="--cfg msrv_test"
cargo test
rustfmt:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Install Rust Stable
run: |
rustup update stable
rustup default stable
rustup component add rustfmt
- name: Run rustfmt
run: cargo fmt -- --check

View file

@ -0,0 +1,25 @@
name: Release-plz
permissions:
pull-requests: write
contents: write
on:
push: { branches: [main] }
jobs:
release-plz:
name: Release-plz
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Install Rust (rustup)
run: rustup update nightly --no-self-update && rustup default nightly
- name: Run release-plz
uses: MarcoIeni/release-plz-action@v0.5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

29
http/vendor/cfg-if/CHANGELOG.md vendored Normal file
View file

@ -0,0 +1,29 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.0.4](https://github.com/rust-lang/cfg-if/compare/v1.0.3...v1.0.4) - 2025-10-15
- Support `cfg(true)` and `cfg(false)` ([#99](https://github.com/rust-lang/cfg-if/pull/99))
- Set and test a MSRV of 1.32
- Have a single top-level rule
## [1.0.3](https://github.com/rust-lang/cfg-if/compare/v1.0.2...v1.0.3) - 2025-08-19
- Revert "Remove `@__identity` rule."
## [1.0.2](https://github.com/rust-lang/cfg-if/compare/v1.0.1...v1.0.2) - 2025-08-19
- Remove `@__identity` rule.
## [1.0.1](https://github.com/rust-lang/cfg-if/compare/v1.0.0...v1.0.1) - 2025-06-09
- Remove `compiler-builtins` from `rustc-dep-of-std` dependencies
- Remove redundant configuration from Cargo.toml
- More readable formatting and identifier names. ([#39](https://github.com/rust-lang/cfg-if/pull/39))
- Add expanded example to readme ([#38](https://github.com/rust-lang/cfg-if/pull/38))

16
http/vendor/cfg-if/Cargo.lock generated vendored Normal file
View file

@ -0,0 +1,16 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "cfg-if"
version = "1.0.4"
dependencies = [
"rustc-std-workspace-core 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-std-workspace-core"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum rustc-std-workspace-core 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9c45b374136f52f2d6311062c7146bff20fec063c3f5d46a410bd937746955"

47
http/vendor/cfg-if/Cargo.toml vendored Normal file
View file

@ -0,0 +1,47 @@
# 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.32"
name = "cfg-if"
version = "1.0.4"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
build = false
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = """
A macro to ergonomically define an item depending on a large number of #[cfg]
parameters. Structured like an if-else chain, the first matching branch is the
item that gets emitted.
"""
readme = "README.md"
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/cfg-if"
[features]
rustc-dep-of-std = ["core"]
[lib]
name = "cfg_if"
path = "src/lib.rs"
[[test]]
name = "xcrate"
path = "tests/xcrate.rs"
[dependencies.core]
version = "1.0.0"
optional = true
package = "rustc-std-workspace-core"

20
http/vendor/cfg-if/Cargo.toml.orig vendored Normal file
View file

@ -0,0 +1,20 @@
[package]
name = "cfg-if"
version = "1.0.4"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
license = "MIT OR Apache-2.0"
readme = "README.md"
repository = "https://github.com/rust-lang/cfg-if"
description = """
A macro to ergonomically define an item depending on a large number of #[cfg]
parameters. Structured like an if-else chain, the first matching branch is the
item that gets emitted.
"""
edition = "2018"
rust-version = "1.32"
[dependencies]
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
[features]
rustc-dep-of-std = ["core"]

201
http/vendor/cfg-if/LICENSE-APACHE vendored Normal file
View file

@ -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.

25
http/vendor/cfg-if/LICENSE-MIT vendored Normal file
View file

@ -0,0 +1,25 @@
Copyright (c) 2014 Alex Crichton
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

56
http/vendor/cfg-if/README.md vendored Normal file
View file

@ -0,0 +1,56 @@
# cfg-if
[Documentation](https://docs.rs/cfg-if)
A macro to ergonomically define an item depending on a large number of #[cfg]
parameters. Structured like an if-else chain, the first matching branch is the
item that gets emitted.
```toml
[dependencies]
cfg-if = "1.0"
```
## Example
```rust
cfg_if::cfg_if! {
if #[cfg(unix)] {
fn foo() { /* unix specific functionality */ }
} else if #[cfg(target_pointer_width = "32")] {
fn foo() { /* non-unix, 32-bit functionality */ }
} else {
fn foo() { /* fallback implementation */ }
}
}
fn main() {
foo();
}
```
The `cfg_if!` block above is expanded to:
```rust
#[cfg(unix)]
fn foo() { /* unix specific functionality */ }
#[cfg(all(target_pointer_width = "32", not(unix)))]
fn foo() { /* non-unix, 32-bit functionality */ }
#[cfg(not(any(unix, target_pointer_width = "32")))]
fn foo() { /* fallback implementation */ }
```
# License
This project is licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
https://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
https://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in `cfg-if` by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.

212
http/vendor/cfg-if/src/lib.rs vendored Normal file
View file

@ -0,0 +1,212 @@
//! A macro for defining `#[cfg]` if-else statements.
//!
//! The macro provided by this crate, `cfg_if`, is similar to the `if/elif` C
//! preprocessor macro by allowing definition of a cascade of `#[cfg]` cases,
//! emitting the implementation which matches first.
//!
//! This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
//! without having to rewrite each clause multiple times.
//!
//! # Example
//!
//! ```
//! cfg_if::cfg_if! {
//! if #[cfg(unix)] {
//! fn foo() { /* unix specific functionality */ }
//! } else if #[cfg(target_pointer_width = "32")] {
//! fn foo() { /* non-unix, 32-bit functionality */ }
//! } else {
//! fn foo() { /* fallback implementation */ }
//! }
//! }
//!
//! # fn main() {}
//! ```
#![no_std]
#![doc(html_root_url = "https://docs.rs/cfg-if")]
#![deny(missing_docs)]
#![cfg_attr(test, allow(unexpected_cfgs))] // we test with features that do not exist
/// The main macro provided by this crate. See crate documentation for more
/// information.
#[macro_export]
macro_rules! cfg_if {
(
if #[cfg( $($i_meta:tt)+ )] { $( $i_tokens:tt )* }
$(
else if #[cfg( $($ei_meta:tt)+ )] { $( $ei_tokens:tt )* }
)*
$(
else { $( $e_tokens:tt )* }
)?
) => {
$crate::cfg_if! {
@__items () ;
(( $($i_meta)+ ) ( $( $i_tokens )* )),
$(
(( $($ei_meta)+ ) ( $( $ei_tokens )* )),
)*
$(
(() ( $( $e_tokens )* )),
)?
}
};
// Internal and recursive macro to emit all the items
//
// Collects all the previous cfgs in a list at the beginning, so they can be
// negated. After the semicolon are all the remaining items.
(@__items ( $( ($($_:tt)*) , )* ) ; ) => {};
(
@__items ( $( ($($no:tt)+) , )* ) ;
(( $( $($yes:tt)+ )? ) ( $( $tokens:tt )* )),
$( $rest:tt , )*
) => {
// Emit all items within one block, applying an appropriate #[cfg]. The
// #[cfg] will require all `$yes` matchers specified and must also negate
// all previous matchers.
#[cfg(all(
$( $($yes)+ , )?
not(any( $( $($no)+ ),* ))
))]
// Subtle: You might think we could put `$( $tokens )*` here. But if
// that contains multiple items then the `#[cfg(all(..))]` above would
// only apply to the first one. By wrapping `$( $tokens )*` in this
// macro call, we temporarily group the items into a single thing (the
// macro call) that will be included/excluded by the `#[cfg(all(..))]`
// as appropriate. If the `#[cfg(all(..))]` succeeds, the macro call
// will be included, and then evaluated, producing `$( $tokens )*`. See
// also the "issue #90" test below.
$crate::cfg_if! { @__temp_group $( $tokens )* }
// Recurse to emit all other items in `$rest`, and when we do so add all
// our `$yes` matchers to the list of `$no` matchers as future emissions
// will have to negate everything we just matched as well.
$crate::cfg_if! {
@__items ( $( ($($no)+) , )* $( ($($yes)+) , )? ) ;
$( $rest , )*
}
};
// See the "Subtle" comment above.
(@__temp_group $( $tokens:tt )* ) => {
$( $tokens )*
};
}
#[cfg(test)]
mod tests {
cfg_if! {
if #[cfg(test)] {
use core::option::Option as Option2;
fn works1() -> Option2<u32> { Some(1) }
} else {
fn works1() -> Option<u32> { None }
}
}
cfg_if! {
if #[cfg(foo)] {
fn works2() -> bool { false }
} else if #[cfg(test)] {
fn works2() -> bool { true }
} else {
fn works2() -> bool { false }
}
}
cfg_if! {
if #[cfg(foo)] {
fn works3() -> bool { false }
} else {
fn works3() -> bool { true }
}
}
cfg_if! {
if #[cfg(test)] {
use core::option::Option as Option3;
fn works4() -> Option3<u32> { Some(1) }
}
}
cfg_if! {
if #[cfg(foo)] {
fn works5() -> bool { false }
} else if #[cfg(test)] {
fn works5() -> bool { true }
}
}
// In issue #90 there was a bug that caused only the first item within a
// block to be annotated with the produced `#[cfg(...)]`. In this example,
// it meant that the first `type _B` wasn't being omitted as it should have
// been, which meant we had two `type _B`s, which caused an error. See also
// the "Subtle" comment above.
cfg_if!(
if #[cfg(target_os = "no-such-operating-system-good-sir!")] {
type _A = usize;
type _B = usize;
} else {
type _A = i32;
type _B = i32;
}
);
#[cfg(not(msrv_test))]
cfg_if! {
if #[cfg(false)] {
fn works6() -> bool { false }
} else if #[cfg(true)] {
fn works6() -> bool { true }
} else if #[cfg(false)] {
fn works6() -> bool { false }
}
}
#[test]
fn it_works() {
assert!(works1().is_some());
assert!(works2());
assert!(works3());
assert!(works4().is_some());
assert!(works5());
#[cfg(not(msrv_test))]
assert!(works6());
}
#[test]
#[allow(clippy::assertions_on_constants)]
fn test_usage_within_a_function() {
cfg_if! {
if #[cfg(debug_assertions)] {
// we want to put more than one thing here to make sure that they
// all get configured properly.
assert!(cfg!(debug_assertions));
assert_eq!(4, 2 + 2);
} else {
assert!(works1().is_some());
assert_eq!(10, 5 + 5);
}
}
}
#[allow(dead_code)]
trait Trait {
fn blah(&self);
}
#[allow(dead_code)]
struct Struct;
impl Trait for Struct {
cfg_if! {
if #[cfg(feature = "blah")] {
fn blah(&self) { unimplemented!(); }
} else {
fn blah(&self) { unimplemented!(); }
}
}
}
}

16
http/vendor/cfg-if/tests/xcrate.rs vendored Normal file
View file

@ -0,0 +1,16 @@
#![allow(unexpected_cfgs)] // `foo` doesn't exist
cfg_if::cfg_if! {
if #[cfg(foo)] {
fn works() -> bool { false }
} else if #[cfg(test)] {
fn works() -> bool { true }
} else {
fn works() -> bool { false }
}
}
#[test]
fn smoke() {
assert!(works());
}

View file

@ -0,0 +1 @@
{"files":{".cargo_vcs_info.json":"a6a00e4fc7a085688fcd4550501bc164e55a5f6b84225a5a744d4124dd493e3d","CHANGELOG.md":"d8241689c2a2901c42c6c2284659915ed85e4c36216c1d5d771fa0be9c64a4a9","Cargo.lock":"ee3c45e2461f086b0122abd500f2c55bf9d05876ea6323b951578080cd158838","Cargo.toml":"1162710613011a622ba62b035b570cc13584516082f9cf579cfaf2f144a77a76","Cargo.toml.orig":"3941ba1194442678125b6ca4221a07ac27ac64f7dadd7467490e55e39cc205f9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"5e7b2b1f5ffc1da7695d3e151a2d4d0b8f681e65a24ddf85a353d4bcfa81967a","src/com.rs":"d71a248866e04a19c62221999f7f120890cb98bc74ea7fd0b714f766d3e0dd81","src/find_tools.rs":"4b97e6f518943d4754ac73c77bc5932025bd1b48d10ed310694ed7d7449ae256","src/lib.rs":"56b0350126ad84accee5fd3d160c6a04a32d17012013fc6f687caf4b59a76ce8","src/registry.rs":"ccbb665b60517a62d249dbe708675ea915c423c14bea786e17efee27453afd41","src/setup_config.rs":"5fee84b80d089ae4a92f10080b072ea2bb32c2edbcdc759cb9072e380404fc46","src/tool.rs":"83e805a8354278837c474c0907b8dd80c496ae4812b2f777f2b2e4266ba68032","src/vs_instances.rs":"10a4433ff6799b11dc01da568ba20af9153aa645d9dc4154cf1c0da15308577c","src/winapi.rs":"d486d80ebe222f3bf61bba50038cf63b258585325b29b89d149de8b5a489c2b5","src/windows_link.rs":"5b4648ebc22b028caca9f4b4bf8881fe2d094b7bec217264ba2e6e2c49d1ccee","src/windows_sys.rs":"c3c803c6408795eb3a2bb3feaf3dc83a8d3049d76f026a4d25d21162fdb890dd"},"package":"5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"}

View file

@ -0,0 +1,6 @@
{
"git": {
"sha1": "0767349e1d1253e6849b4c2af2059db661f54343"
},
"path_in_vcs": "find-msvc-tools"
}

View file

@ -0,0 +1,65 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [0.1.9](https://github.com/rust-lang/cc-rs/compare/find-msvc-tools-v0.1.8...find-msvc-tools-v0.1.9) - 2026-01-30
### Other
- Add `find_windows_sdk` API ([#1663](https://github.com/rust-lang/cc-rs/pull/1663))
## [0.1.8](https://github.com/rust-lang/cc-rs/compare/find-msvc-tools-v0.1.7...find-msvc-tools-v0.1.8) - 2026-01-16
### Other
- Regenerate windows sys bindings ([#1653](https://github.com/rust-lang/cc-rs/pull/1653))
## [0.1.7](https://github.com/rust-lang/cc-rs/compare/find-msvc-tools-v0.1.6...find-msvc-tools-v0.1.7) - 2026-01-09
### Other
- Fix tool existence check in find_tool method ([#1645](https://github.com/rust-lang/cc-rs/pull/1645))
- Fix SdkInfo::find_tool to check for executable extension ([#1644](https://github.com/rust-lang/cc-rs/pull/1644))
## [0.1.6](https://github.com/rust-lang/cc-rs/compare/find-msvc-tools-v0.1.5...find-msvc-tools-v0.1.6) - 2025-12-26
### Other
- Update Readmes ([#1641](https://github.com/rust-lang/cc-rs/pull/1641))
## [0.1.5](https://github.com/rust-lang/cc-rs/compare/find-msvc-tools-v0.1.4...find-msvc-tools-v0.1.5) - 2025-11-14
### Other
- Add Visual Studio 2026 support ([#1609](https://github.com/rust-lang/cc-rs/pull/1609))
## [0.1.4](https://github.com/rust-lang/cc-rs/compare/find-msvc-tools-v0.1.3...find-msvc-tools-v0.1.4) - 2025-10-10
### Other
- Allow using VCToolsVersion to request a specific msvc version ([#1589](https://github.com/rust-lang/cc-rs/pull/1589))
- Regenerate windows sys bindings ([#1591](https://github.com/rust-lang/cc-rs/pull/1591))
## [0.1.3](https://github.com/rust-lang/cc-rs/compare/find-msvc-tools-v0.1.2...find-msvc-tools-v0.1.3) - 2025-10-03
### Other
- Regenerate windows sys bindings ([#1572](https://github.com/rust-lang/cc-rs/pull/1572))
## [0.1.2](https://github.com/rust-lang/cc-rs/compare/find-msvc-tools-v0.1.1...find-msvc-tools-v0.1.2) - 2025-09-19
### Other
- [win] Search the Windows SDK for tools as well ([#1553](https://github.com/rust-lang/cc-rs/pull/1553))
## [0.1.1](https://github.com/rust-lang/cc-rs/compare/find-msvc-tools-v0.1.0...find-msvc-tools-v0.1.1) - 2025-09-05
### Other
- Regenerate windows sys bindings ([#1548](https://github.com/rust-lang/cc-rs/pull/1548))
- Add fn get_ucrt_dir for find-msvc-tools ([#1546](https://github.com/rust-lang/cc-rs/pull/1546))

7
http/vendor/find-msvc-tools/Cargo.lock generated vendored Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "find-msvc-tools"
version = "0.1.9"

40
http/vendor/find-msvc-tools/Cargo.toml vendored Normal file
View file

@ -0,0 +1,40 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
rust-version = "1.63"
name = "find-msvc-tools"
version = "0.1.9"
build = false
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "Find windows-specific tools, read MSVC versions from the registry and from COM interfaces"
documentation = "https://docs.rs/find-msvc-tools"
readme = "README.md"
keywords = ["build-dependencies"]
categories = ["development-tools::build-utils"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/cc-rs"
[lib]
name = "find_msvc_tools"
path = "src/lib.rs"
[dependencies]
[lints.rust.unexpected_cfgs]
level = "allow"
priority = 0
check-cfg = ["cfg(disable_clang_cl_tests)"]

View file

@ -0,0 +1,18 @@
[package]
name = "find-msvc-tools"
version = "0.1.9"
edition = "2018"
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/cc-rs"
documentation = "https://docs.rs/find-msvc-tools"
description = "Find windows-specific tools, read MSVC versions from the registry and from COM interfaces"
keywords = ["build-dependencies"]
categories = ["development-tools::build-utils"]
rust-version = "1.63"
[dependencies]
[lints.rust]
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(disable_clang_cl_tests)'] }

View file

@ -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.

25
http/vendor/find-msvc-tools/LICENSE-MIT vendored Normal file
View file

@ -0,0 +1,25 @@
Copyright (c) 2014 Alex Crichton
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

30
http/vendor/find-msvc-tools/README.md vendored Normal file
View file

@ -0,0 +1,30 @@
# find-msvc-tools
> This crate is maintained by the library team, primarily for use by the `cc`
> crate and not intended for external use (except as a transitive dependency).
> This crate may make major changes to its APIs or be deprecated without
> warning.
An internal use library for finding windows-specific tools, reading MSVC
versions from the registry and from COM interfaces.
Refer to the [documentation](https://docs.rs/find-msvc-tools) for detailed usage
instructions.
## License
This project is licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
https://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
https://opensource.org/license/mit)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution transitively
intentionally submitted for inclusion in find-msvc-tools by you, as defined in
the Apache-2.0 license, shall be dual licensed as above, without any additional
terms or conditions.

110
http/vendor/find-msvc-tools/src/com.rs vendored Normal file
View file

@ -0,0 +1,110 @@
// Copyright © 2017 winapi-rs developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// All files in the project carrying such notice may not be copied, modified, or distributed
// except according to those terms.
use crate::{
winapi::{IUnknown, Interface},
windows_sys::{
CoInitializeEx, SysFreeString, SysStringLen, BSTR, COINIT_MULTITHREADED, HRESULT, S_FALSE,
S_OK,
},
};
use std::{
convert::TryInto,
ffi::OsString,
ops::Deref,
os::windows::ffi::OsStringExt,
ptr::{null, null_mut},
slice::from_raw_parts,
};
pub fn initialize() -> Result<(), HRESULT> {
let err = unsafe { CoInitializeEx(null(), COINIT_MULTITHREADED.try_into().unwrap()) };
if err != S_OK && err != S_FALSE {
// S_FALSE just means COM is already initialized
Err(err)
} else {
Ok(())
}
}
pub struct ComPtr<T>(*mut T)
where
T: Interface;
impl<T> ComPtr<T>
where
T: Interface,
{
/// Creates a `ComPtr` to wrap a raw pointer.
/// It takes ownership over the pointer which means it does __not__ call `AddRef`.
/// `T` __must__ be a COM interface that inherits from `IUnknown`.
pub unsafe fn from_raw(ptr: *mut T) -> ComPtr<T> {
assert!(!ptr.is_null());
ComPtr(ptr)
}
/// For internal use only.
fn as_unknown(&self) -> &IUnknown {
unsafe { &*(self.0 as *mut IUnknown) }
}
/// Performs `QueryInterface` fun.
pub fn cast<U>(&self) -> Result<ComPtr<U>, i32>
where
U: Interface,
{
let mut obj = null_mut();
let err = unsafe { self.as_unknown().QueryInterface(&U::uuidof(), &mut obj) };
if err < 0 {
return Err(err);
}
Ok(unsafe { ComPtr::from_raw(obj as *mut U) })
}
}
impl<T> Deref for ComPtr<T>
where
T: Interface,
{
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.0 }
}
}
impl<T> Clone for ComPtr<T>
where
T: Interface,
{
fn clone(&self) -> Self {
unsafe {
self.as_unknown().AddRef();
ComPtr::from_raw(self.0)
}
}
}
impl<T> Drop for ComPtr<T>
where
T: Interface,
{
fn drop(&mut self) {
unsafe {
self.as_unknown().Release();
}
}
}
pub struct BStr(BSTR);
impl BStr {
pub unsafe fn from_raw(s: BSTR) -> BStr {
BStr(s)
}
pub fn to_osstring(&self) -> OsString {
let len = unsafe { SysStringLen(self.0) };
let slice = unsafe { from_raw_parts(self.0, len as usize) };
OsStringExt::from_wide(slice)
}
}
impl Drop for BStr {
fn drop(&mut self) {
unsafe { SysFreeString(self.0) };
}
}

File diff suppressed because it is too large Load diff

28
http/vendor/find-msvc-tools/src/lib.rs vendored Normal file
View file

@ -0,0 +1,28 @@
//! These modules are all glue to support reading the MSVC version from
//! the registry and from COM interfaces.
// This is used in the crate's public API, so don't use #[cfg(windows)]
mod find_tools;
pub use find_tools::*;
mod tool;
pub use tool::*;
#[cfg(windows)]
#[doc(hidden)]
pub mod windows_link;
#[cfg(windows)]
#[doc(hidden)]
pub mod windows_sys;
#[cfg(windows)]
mod registry;
#[cfg(windows)]
#[macro_use]
mod winapi;
#[cfg(windows)]
mod com;
#[cfg(windows)]
mod setup_config;
#[cfg(windows)]
mod vs_instances;

View file

@ -0,0 +1,191 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::windows_sys::{
RegCloseKey, RegEnumKeyExW, RegOpenKeyExW, RegQueryValueExW, ERROR_NO_MORE_ITEMS,
ERROR_SUCCESS, HKEY, HKEY_LOCAL_MACHINE, KEY_READ, KEY_WOW64_32KEY, REG_SZ,
};
use std::{
ffi::{OsStr, OsString},
io,
ops::RangeFrom,
os::windows::prelude::*,
ptr::null_mut,
};
/// Must never be `HKEY_PERFORMANCE_DATA`.
pub(crate) struct RegistryKey(Repr);
#[allow(clippy::upper_case_acronyms)]
type DWORD = u32;
struct OwnedKey(HKEY);
/// Note: must not encode `HKEY_PERFORMANCE_DATA` or one of its subkeys.
enum Repr {
/// `HKEY_LOCAL_MACHINE`.
LocalMachine,
/// A subkey of `HKEY_LOCAL_MACHINE`.
Owned(OwnedKey),
}
pub struct Iter<'a> {
idx: RangeFrom<DWORD>,
key: &'a RegistryKey,
}
unsafe impl Sync for Repr {}
unsafe impl Send for Repr {}
pub(crate) const LOCAL_MACHINE: RegistryKey = RegistryKey(Repr::LocalMachine);
impl RegistryKey {
fn raw(&self) -> HKEY {
match self.0 {
Repr::LocalMachine => HKEY_LOCAL_MACHINE,
Repr::Owned(ref val) => val.0,
}
}
/// Open a sub-key of `self`.
pub fn open(&self, key: &OsStr) -> io::Result<RegistryKey> {
let key = key.encode_wide().chain(Some(0)).collect::<Vec<_>>();
let mut ret = null_mut();
let err = unsafe {
RegOpenKeyExW(
self.raw(),
key.as_ptr(),
0,
KEY_READ | KEY_WOW64_32KEY,
&mut ret,
)
};
if err == ERROR_SUCCESS {
Ok(RegistryKey(Repr::Owned(OwnedKey(ret))))
} else {
Err(io::Error::from_raw_os_error(err as i32))
}
}
pub fn iter(&self) -> Iter<'_> {
Iter {
idx: 0..,
key: self,
}
}
pub fn query_str(&self, name: &str) -> io::Result<OsString> {
let name: &OsStr = name.as_ref();
let name = name.encode_wide().chain(Some(0)).collect::<Vec<_>>();
let mut len = 0;
let mut kind = 0;
unsafe {
let err = RegQueryValueExW(
self.raw(),
name.as_ptr(),
null_mut(),
&mut kind,
null_mut(),
&mut len,
);
if err != ERROR_SUCCESS {
return Err(io::Error::from_raw_os_error(err as i32));
}
if kind != REG_SZ {
return Err(io::Error::new(
io::ErrorKind::Other,
"registry key wasn't a string",
));
}
// The length here is the length in bytes, but we're using wide
// characters so we need to be sure to halve it for the length
// passed in.
assert!(len % 2 == 0, "impossible wide string size: {} bytes", len);
let vlen = len as usize / 2;
// Defensively initialized, see comment about
// `HKEY_PERFORMANCE_DATA` below.
let mut v = vec![0u16; vlen];
let err = RegQueryValueExW(
self.raw(),
name.as_ptr(),
null_mut(),
null_mut(),
v.as_mut_ptr() as *mut _,
&mut len,
);
// We don't check for `ERROR_MORE_DATA` (which would if the value
// grew between the first and second call to `RegQueryValueExW`),
// both because it's extremely unlikely, and this is a bit more
// defensive more defensive against weird types of registry keys.
if err != ERROR_SUCCESS {
return Err(io::Error::from_raw_os_error(err as i32));
}
// The length is allowed to change, but should still be even, as
// well as smaller.
assert!(len % 2 == 0, "impossible wide string size: {} bytes", len);
// If the length grew but returned a success code, it *probably*
// indicates we're `HKEY_PERFORMANCE_DATA` or a subkey(?). We
// consider this UB, since those keys write "undefined" or
// "unpredictable" values to len, and need to use a completely
// different loop structure. This should be impossible (and enforce
// it in the API to the best of our ability), but to mitigate the
// damage we do some smoke-checks on the len, and ensure `v` has
// been fully initialized (rather than trusting the result of
// `RegQueryValueExW`).
let actual_len = len as usize / 2;
assert!(actual_len <= v.len());
v.truncate(actual_len);
// Some registry keys may have a terminating nul character, but
// we're not interested in that, so chop it off if it's there.
if !v.is_empty() && v[v.len() - 1] == 0 {
v.pop();
}
Ok(OsString::from_wide(&v))
}
}
}
impl Drop for OwnedKey {
fn drop(&mut self) {
unsafe {
RegCloseKey(self.0);
}
}
}
impl<'a> Iterator for Iter<'a> {
type Item = io::Result<OsString>;
fn next(&mut self) -> Option<io::Result<OsString>> {
self.idx.next().and_then(|i| unsafe {
let mut v = Vec::with_capacity(256);
let mut len = v.capacity() as DWORD;
let ret = RegEnumKeyExW(
self.key.raw(),
i,
v.as_mut_ptr(),
&mut len,
null_mut(),
null_mut(),
null_mut(),
null_mut(),
);
if ret == ERROR_NO_MORE_ITEMS {
None
} else if ret != ERROR_SUCCESS {
Some(Err(io::Error::from_raw_os_error(ret as i32)))
} else {
v.set_len(len as usize);
Some(Ok(OsString::from_wide(&v)))
}
})
}
}

View file

@ -0,0 +1,283 @@
// Copyright © 2017 winapi-rs developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// All files in the project carrying such notice may not be copied, modified, or distributed
// except according to those terms.
#![allow(bad_style)]
#![allow(unused)]
use crate::{
com::{BStr, ComPtr},
winapi::{
IUnknown, IUnknownVtbl, Interface, LCID, LPCOLESTR, LPCWSTR, LPFILETIME, LPSAFEARRAY,
PULONGLONG, ULONG,
},
windows_sys::{CoCreateInstance, BSTR, CLSCTX_ALL, HRESULT, S_FALSE},
};
use std::{
ffi::OsString,
ptr::{null, null_mut},
};
// Bindings to the Setup.Configuration stuff
pub type InstanceState = u32;
pub const eNone: InstanceState = 0;
pub const eLocal: InstanceState = 1;
pub const eRegistered: InstanceState = 2;
pub const eNoRebootRequired: InstanceState = 4;
pub const eComplete: InstanceState = -1i32 as u32;
RIDL! {#[uuid(0xb41463c3, 0x8866, 0x43b5, 0xbc, 0x33, 0x2b, 0x06, 0x76, 0xf7, 0xf4, 0x2e)]
interface ISetupInstance(ISetupInstanceVtbl): IUnknown(IUnknownVtbl) {
fn GetInstanceId(
pbstrInstanceId: *mut BSTR,
) -> HRESULT,
fn GetInstallDate(
pInstallDate: LPFILETIME,
) -> HRESULT,
fn GetInstallationName(
pbstrInstallationName: *mut BSTR,
) -> HRESULT,
fn GetInstallationPath(
pbstrInstallationPath: *mut BSTR,
) -> HRESULT,
fn GetInstallationVersion(
pbstrInstallationVersion: *mut BSTR,
) -> HRESULT,
fn GetDisplayName(
lcid: LCID,
pbstrDisplayName: *mut BSTR,
) -> HRESULT,
fn GetDescription(
lcid: LCID,
pbstrDescription: *mut BSTR,
) -> HRESULT,
fn ResolvePath(
pwszRelativePath: LPCOLESTR,
pbstrAbsolutePath: *mut BSTR,
) -> HRESULT,
}}
RIDL! {#[uuid(0x89143c9a, 0x05af, 0x49b0, 0xb7, 0x17, 0x72, 0xe2, 0x18, 0xa2, 0x18, 0x5c)]
interface ISetupInstance2(ISetupInstance2Vtbl): ISetupInstance(ISetupInstanceVtbl) {
fn GetState(
pState: *mut InstanceState,
) -> HRESULT,
fn GetPackages(
ppsaPackages: *mut LPSAFEARRAY,
) -> HRESULT,
fn GetProduct(
ppPackage: *mut *mut ISetupPackageReference,
) -> HRESULT,
fn GetProductPath(
pbstrProductPath: *mut BSTR,
) -> HRESULT,
}}
RIDL! {#[uuid(0x6380bcff, 0x41d3, 0x4b2e, 0x8b, 0x2e, 0xbf, 0x8a, 0x68, 0x10, 0xc8, 0x48)]
interface IEnumSetupInstances(IEnumSetupInstancesVtbl): IUnknown(IUnknownVtbl) {
fn Next(
celt: ULONG,
rgelt: *mut *mut ISetupInstance,
pceltFetched: *mut ULONG,
) -> HRESULT,
fn Skip(
celt: ULONG,
) -> HRESULT,
fn Reset() -> HRESULT,
fn Clone(
ppenum: *mut *mut IEnumSetupInstances,
) -> HRESULT,
}}
RIDL! {#[uuid(0x42843719, 0xdb4c, 0x46c2, 0x8e, 0x7c, 0x64, 0xf1, 0x81, 0x6e, 0xfd, 0x5b)]
interface ISetupConfiguration(ISetupConfigurationVtbl): IUnknown(IUnknownVtbl) {
fn EnumInstances(
ppEnumInstances: *mut *mut IEnumSetupInstances,
) -> HRESULT,
fn GetInstanceForCurrentProcess(
ppInstance: *mut *mut ISetupInstance,
) -> HRESULT,
fn GetInstanceForPath(
wzPath: LPCWSTR,
ppInstance: *mut *mut ISetupInstance,
) -> HRESULT,
}}
RIDL! {#[uuid(0x26aab78c, 0x4a60, 0x49d6, 0xaf, 0x3b, 0x3c, 0x35, 0xbc, 0x93, 0x36, 0x5d)]
interface ISetupConfiguration2(ISetupConfiguration2Vtbl):
ISetupConfiguration(ISetupConfigurationVtbl) {
fn EnumAllInstances(
ppEnumInstances: *mut *mut IEnumSetupInstances,
) -> HRESULT,
}}
RIDL! {#[uuid(0xda8d8a16, 0xb2b6, 0x4487, 0xa2, 0xf1, 0x59, 0x4c, 0xcc, 0xcd, 0x6b, 0xf5)]
interface ISetupPackageReference(ISetupPackageReferenceVtbl): IUnknown(IUnknownVtbl) {
fn GetId(
pbstrId: *mut BSTR,
) -> HRESULT,
fn GetVersion(
pbstrVersion: *mut BSTR,
) -> HRESULT,
fn GetChip(
pbstrChip: *mut BSTR,
) -> HRESULT,
fn GetLanguage(
pbstrLanguage: *mut BSTR,
) -> HRESULT,
fn GetBranch(
pbstrBranch: *mut BSTR,
) -> HRESULT,
fn GetType(
pbstrType: *mut BSTR,
) -> HRESULT,
fn GetUniqueId(
pbstrUniqueId: *mut BSTR,
) -> HRESULT,
}}
RIDL! {#[uuid(0x42b21b78, 0x6192, 0x463e, 0x87, 0xbf, 0xd5, 0x77, 0x83, 0x8f, 0x1d, 0x5c)]
interface ISetupHelper(ISetupHelperVtbl): IUnknown(IUnknownVtbl) {
fn ParseVersion(
pwszVersion: LPCOLESTR,
pullVersion: PULONGLONG,
) -> HRESULT,
fn ParseVersionRange(
pwszVersionRange: LPCOLESTR,
pullMinVersion: PULONGLONG,
pullMaxVersion: PULONGLONG,
) -> HRESULT,
}}
DEFINE_GUID! {CLSID_SetupConfiguration,
0x177f0c4a, 0x1cd3, 0x4de7, 0xa3, 0x2c, 0x71, 0xdb, 0xbb, 0x9f, 0xa3, 0x6d}
// Safe wrapper around the COM interfaces
pub struct SetupConfiguration(ComPtr<ISetupConfiguration>);
impl SetupConfiguration {
pub fn new() -> Result<SetupConfiguration, i32> {
let mut obj = null_mut();
let err = unsafe {
CoCreateInstance(
&CLSID_SetupConfiguration,
null_mut(),
CLSCTX_ALL,
&ISetupConfiguration::uuidof(),
&mut obj,
)
};
if err < 0 {
return Err(err);
}
let obj = unsafe { ComPtr::from_raw(obj as *mut ISetupConfiguration) };
Ok(SetupConfiguration(obj))
}
pub fn get_instance_for_current_process(&self) -> Result<SetupInstance, i32> {
let mut obj = null_mut();
let err = unsafe { self.0.GetInstanceForCurrentProcess(&mut obj) };
if err < 0 {
return Err(err);
}
Ok(unsafe { SetupInstance::from_raw(obj) })
}
pub fn enum_instances(&self) -> Result<EnumSetupInstances, i32> {
let mut obj = null_mut();
let err = unsafe { self.0.EnumInstances(&mut obj) };
if err < 0 {
return Err(err);
}
Ok(unsafe { EnumSetupInstances::from_raw(obj) })
}
pub fn enum_all_instances(&self) -> Result<EnumSetupInstances, i32> {
let mut obj = null_mut();
let this = self.0.cast::<ISetupConfiguration2>()?;
let err = unsafe { this.EnumAllInstances(&mut obj) };
if err < 0 {
return Err(err);
}
Ok(unsafe { EnumSetupInstances::from_raw(obj) })
}
}
pub struct SetupInstance(ComPtr<ISetupInstance>);
impl SetupInstance {
pub unsafe fn from_raw(obj: *mut ISetupInstance) -> SetupInstance {
SetupInstance(ComPtr::from_raw(obj))
}
pub fn instance_id(&self) -> Result<OsString, i32> {
let mut s = null();
let err = unsafe { self.0.GetInstanceId(&mut s) };
let bstr = unsafe { BStr::from_raw(s) };
if err < 0 {
return Err(err);
}
Ok(bstr.to_osstring())
}
pub fn installation_name(&self) -> Result<OsString, i32> {
let mut s = null();
let err = unsafe { self.0.GetInstallationName(&mut s) };
let bstr = unsafe { BStr::from_raw(s) };
if err < 0 {
return Err(err);
}
Ok(bstr.to_osstring())
}
pub fn installation_path(&self) -> Result<OsString, i32> {
let mut s = null();
let err = unsafe { self.0.GetInstallationPath(&mut s) };
let bstr = unsafe { BStr::from_raw(s) };
if err < 0 {
return Err(err);
}
Ok(bstr.to_osstring())
}
pub fn installation_version(&self) -> Result<OsString, i32> {
let mut s = null();
let err = unsafe { self.0.GetInstallationVersion(&mut s) };
let bstr = unsafe { BStr::from_raw(s) };
if err < 0 {
return Err(err);
}
Ok(bstr.to_osstring())
}
pub fn product_path(&self) -> Result<OsString, i32> {
let mut s = null();
let this = self.0.cast::<ISetupInstance2>()?;
let err = unsafe { this.GetProductPath(&mut s) };
let bstr = unsafe { BStr::from_raw(s) };
if err < 0 {
return Err(err);
}
Ok(bstr.to_osstring())
}
}
pub struct EnumSetupInstances(ComPtr<IEnumSetupInstances>);
impl EnumSetupInstances {
pub unsafe fn from_raw(obj: *mut IEnumSetupInstances) -> EnumSetupInstances {
EnumSetupInstances(ComPtr::from_raw(obj))
}
}
impl Iterator for EnumSetupInstances {
type Item = Result<SetupInstance, i32>;
fn next(&mut self) -> Option<Result<SetupInstance, i32>> {
let mut obj = null_mut();
let err = unsafe { self.0.Next(1, &mut obj, null_mut()) };
if err < 0 {
return Some(Err(err));
}
if err == S_FALSE {
return None;
}
Some(Ok(unsafe { SetupInstance::from_raw(obj) }))
}
}

45
http/vendor/find-msvc-tools/src/tool.rs vendored Normal file
View file

@ -0,0 +1,45 @@
use std::{
ffi::OsString,
path::{Path, PathBuf},
process::Command,
};
/// `Tool` found by `find-msvc-tools`
#[derive(Clone, Debug)]
pub struct Tool {
pub(crate) tool: PathBuf,
pub(crate) is_clang_cl: bool,
pub(crate) env: Vec<(OsString, OsString)>,
}
impl Tool {
/// Converts this compiler into a `Command` that's ready to be run.
///
/// This is useful for when the compiler needs to be executed and the
/// command returned will already have the initial arguments and environment
/// variables configured.
pub fn to_command(&self) -> Command {
let mut cmd = Command::new(&self.tool);
for (k, v) in self.env.iter() {
cmd.env(k, v);
}
cmd
}
/// Check is the tool clang-cl related
pub fn is_clang_cl(&self) -> bool {
self.is_clang_cl
}
/// Get path to the tool
pub fn path(&self) -> &Path {
&self.tool
}
/// Get environment variables for the tools
pub fn env(&self) -> impl IntoIterator<Item = &(OsString, OsString)> {
&self.env
}
}

View file

@ -0,0 +1,199 @@
use std::borrow::Cow;
use std::collections::HashMap;
use std::convert::TryFrom;
use std::io::BufRead;
use std::path::PathBuf;
use crate::setup_config::{EnumSetupInstances, SetupInstance};
pub enum VsInstance {
Com(SetupInstance),
Vswhere(VswhereInstance),
}
impl VsInstance {
pub fn installation_name(&self) -> Option<Cow<'_, str>> {
match self {
VsInstance::Com(s) => s
.installation_name()
.ok()
.and_then(|s| s.into_string().ok())
.map(Cow::from),
VsInstance::Vswhere(v) => v.map.get("installationName").map(Cow::from),
}
}
pub fn installation_path(&self) -> Option<PathBuf> {
match self {
VsInstance::Com(s) => s.installation_path().ok().map(PathBuf::from),
VsInstance::Vswhere(v) => v.map.get("installationPath").map(PathBuf::from),
}
}
pub fn installation_version(&self) -> Option<Cow<'_, str>> {
match self {
VsInstance::Com(s) => s
.installation_version()
.ok()
.and_then(|s| s.into_string().ok())
.map(Cow::from),
VsInstance::Vswhere(v) => v.map.get("installationVersion").map(Cow::from),
}
}
}
pub enum VsInstances {
ComBased(EnumSetupInstances),
VswhereBased(VswhereInstance),
}
impl IntoIterator for VsInstances {
type Item = VsInstance;
#[allow(bare_trait_objects)]
type IntoIter = Box<Iterator<Item = Self::Item>>;
fn into_iter(self) -> Self::IntoIter {
match self {
VsInstances::ComBased(e) => {
Box::new(e.into_iter().filter_map(Result::ok).map(VsInstance::Com))
}
VsInstances::VswhereBased(v) => Box::new(std::iter::once(VsInstance::Vswhere(v))),
}
}
}
#[derive(Debug)]
pub struct VswhereInstance {
map: HashMap<String, String>,
}
impl TryFrom<&Vec<u8>> for VswhereInstance {
type Error = &'static str;
fn try_from(output: &Vec<u8>) -> Result<Self, Self::Error> {
let map: HashMap<_, _> = output
.lines()
.map_while(Result::ok)
.filter_map(|s| {
let mut splitn = s.splitn(2, ": ");
Some((splitn.next()?.to_owned(), splitn.next()?.to_owned()))
})
.collect();
if !map.contains_key("installationName")
|| !map.contains_key("installationPath")
|| !map.contains_key("installationVersion")
{
return Err("required properties not found");
}
Ok(Self { map })
}
}
#[cfg(test)]
mod tests_ {
use std::borrow::Cow;
use std::convert::TryFrom;
use std::path::PathBuf;
#[test]
fn it_parses_vswhere_output_correctly() {
let output = br"instanceId: 58104422
installDate: 21/02/2021 21:50:33
installationName: VisualStudio/16.9.2+31112.23
installationPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools
installationVersion: 16.9.31112.23
productId: Microsoft.VisualStudio.Product.BuildTools
productPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\LaunchDevCmd.bat
state: 4294967295
isComplete: 1
isLaunchable: 1
isPrerelease: 0
isRebootRequired: 0
displayName: Visual Studio Build Tools 2019
description: The Visual Studio Build Tools allows you to build native and managed MSBuild-based applications without requiring the Visual Studio IDE. There are options to install the Visual C++ compilers and libraries, MFC, ATL, and C++/CLI support.
channelId: VisualStudio.16.Release
channelUri: https://aka.ms/vs/16/release/channel
enginePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service
releaseNotes: https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-v16.9#16.9.2
thirdPartyNotices: https://go.microsoft.com/fwlink/?LinkId=660909
updateDate: 2021-03-17T21:16:46.5963702Z
catalog_buildBranch: d16.9
catalog_buildVersion: 16.9.31112.23
catalog_id: VisualStudio/16.9.2+31112.23
catalog_localBuild: build-lab
catalog_manifestName: VisualStudio
catalog_manifestType: installer
catalog_productDisplayVersion: 16.9.2
catalog_productLine: Dev16
catalog_productLineVersion: 2019
catalog_productMilestone: RTW
catalog_productMilestoneIsPreRelease: False
catalog_productName: Visual Studio
catalog_productPatchVersion: 2
catalog_productPreReleaseMilestoneSuffix: 1.0
catalog_productSemanticVersion: 16.9.2+31112.23
catalog_requiredEngineVersion: 2.9.3365.38425
properties_campaignId: 156063665.1613940062
properties_channelManifestId: VisualStudio.16.Release/16.9.2+31112.23
properties_nickname:
properties_setupEngineFilePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installershell.exe
"
.to_vec();
let vswhere_instance = super::VswhereInstance::try_from(&output);
assert!(vswhere_instance.is_ok());
let vs_instance = super::VsInstance::Vswhere(vswhere_instance.unwrap());
assert_eq!(
vs_instance.installation_name(),
Some(Cow::from("VisualStudio/16.9.2+31112.23"))
);
assert_eq!(
vs_instance.installation_path(),
Some(PathBuf::from(
r"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools"
))
);
assert_eq!(
vs_instance.installation_version(),
Some(Cow::from("16.9.31112.23"))
);
}
#[test]
fn it_returns_an_error_for_empty_output() {
let output = b"".to_vec();
let vswhere_instance = super::VswhereInstance::try_from(&output);
assert!(vswhere_instance.is_err());
}
#[test]
fn it_returns_an_error_for_output_consisting_of_empty_lines() {
let output = br"
"
.to_vec();
let vswhere_instance = super::VswhereInstance::try_from(&output);
assert!(vswhere_instance.is_err());
}
#[test]
fn it_returns_an_error_for_output_without_required_properties() {
let output = br"instanceId: 58104422
installDate: 21/02/2021 21:50:33
productId: Microsoft.VisualStudio.Product.BuildTools
productPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\LaunchDevCmd.bat
"
.to_vec();
let vswhere_instance = super::VswhereInstance::try_from(&output);
assert!(vswhere_instance.is_err());
}
}

View file

@ -0,0 +1,146 @@
// Copyright © 2015-2017 winapi-rs developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// All files in the project carrying such notice may not be copied, modified, or distributed
// except according to those terms.
#![allow(bad_style, clippy::upper_case_acronyms)]
use std::os::raw;
pub type wchar_t = u16;
pub use crate::windows_sys::{FILETIME, GUID, HRESULT, SAFEARRAY};
pub type REFIID = *const IID;
pub type IID = GUID;
pub type ULONG = raw::c_ulong;
pub type DWORD = u32;
pub type LPFILETIME = *mut FILETIME;
pub type OLECHAR = WCHAR;
pub type WCHAR = wchar_t;
pub type LPCOLESTR = *const OLECHAR;
pub type LCID = DWORD;
pub type LPCWSTR = *const WCHAR;
pub type PULONGLONG = *mut ULONGLONG;
pub type ULONGLONG = u64;
pub trait Interface {
fn uuidof() -> GUID;
}
pub type LPSAFEARRAY = *mut SAFEARRAY;
macro_rules! DEFINE_GUID {
(
$name:ident, $l:expr, $w1:expr, $w2:expr,
$b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr
) => {
pub const $name: $crate::winapi::GUID = $crate::winapi::GUID {
data1: $l,
data2: $w1,
data3: $w2,
data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8],
};
};
}
macro_rules! RIDL {
(#[uuid($($uuid:expr),+)]
interface $interface:ident ($vtbl:ident) {$(
fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty,
)+}) => (
#[repr(C)]
pub struct $vtbl {
$(pub $method: unsafe extern "system" fn(
This: *mut $interface,
$($p: $t),*
) -> $rtr,)+
}
#[repr(C)]
pub struct $interface {
pub lpVtbl: *const $vtbl,
}
RIDL!{@impl $interface {$(fn $method($($p: $t,)*) -> $rtr,)+}}
RIDL!{@uuid $interface $($uuid),+}
);
(#[uuid($($uuid:expr),+)]
interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {
}) => (
#[repr(C)]
pub struct $vtbl {
pub parent: $pvtbl,
}
#[repr(C)]
pub struct $interface {
pub lpVtbl: *const $vtbl,
}
RIDL!{@deref $interface $pinterface}
RIDL!{@uuid $interface $($uuid),+}
);
(#[uuid($($uuid:expr),+)]
interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {$(
fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty,
)+}) => (
#[repr(C)]
pub struct $vtbl {
pub parent: $pvtbl,
$(pub $method: unsafe extern "system" fn(
This: *mut $interface,
$($p: $t,)*
) -> $rtr,)+
}
#[repr(C)]
pub struct $interface {
pub lpVtbl: *const $vtbl,
}
RIDL!{@impl $interface {$(fn $method($($p: $t,)*) -> $rtr,)+}}
RIDL!{@deref $interface $pinterface}
RIDL!{@uuid $interface $($uuid),+}
);
(@deref $interface:ident $pinterface:ident) => (
impl ::std::ops::Deref for $interface {
type Target = $pinterface;
#[inline]
fn deref(&self) -> &$pinterface {
unsafe { &*(self as *const $interface as *const $pinterface) }
}
}
);
(@impl $interface:ident {$(
fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty,
)+}) => (
impl $interface {
$(#[inline] pub unsafe fn $method(&self, $($p: $t,)*) -> $rtr {
((*self.lpVtbl).$method)(self as *const _ as *mut _, $($p,)*)
})+
}
);
(@uuid $interface:ident
$l:expr, $w1:expr, $w2:expr,
$b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr
) => (
impl $crate::winapi::Interface for $interface {
#[inline]
fn uuidof() -> $crate::winapi::GUID {
$crate::winapi::GUID {
data1: $l,
data2: $w1,
data3: $w2,
data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8],
}
}
}
);
}
RIDL! {#[uuid(0x00000000, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)]
interface IUnknown(IUnknownVtbl) {
fn QueryInterface(
riid: REFIID,
ppvObject: *mut *mut raw::c_void,
) -> HRESULT,
fn AddRef() -> ULONG,
fn Release() -> ULONG,
}}

View file

@ -0,0 +1,19 @@
//! Provides the `link!` macro used by the generated windows bindings.
//!
//! This is a simple wrapper around an `extern` block with a `#[link]` attribute.
//! It's very roughly equivalent to the windows-targets crate.
macro_rules! link_macro {
($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
// Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't
// have in this repo. So instead we always link kernel32.lib and add the rest of the import
// libraries below by using an empty extern block. This works because extern blocks are not
// connected to the library given in the #[link] attribute.
#[link(name = "kernel32")]
extern $abi {
$(#[link_name=$link_name])?
pub fn $($function)*;
}
)
}
pub(crate) use link_macro as link;

View file

@ -0,0 +1,139 @@
// This file is autogenerated.
//
// To add bindings, edit windows_sys.lst then run:
//
// ```
// cd dev-tools/generate-windows-sys/
// cargo run
// ```
// Bindings generated by `windows-bindgen` 0.66.0
#![allow(
non_snake_case,
non_upper_case_globals,
non_camel_case_types,
dead_code,
clippy::all
)]
windows_link::link!("ole32.dll" "system" fn CoCreateInstance(rclsid : *const GUID, punkouter : * mut core::ffi::c_void, dwclscontext : CLSCTX, riid : *const GUID, ppv : *mut *mut core::ffi::c_void) -> HRESULT);
windows_link::link!("ole32.dll" "system" fn CoInitializeEx(pvreserved : *const core::ffi::c_void, dwcoinit : u32) -> HRESULT);
windows_link::link!("kernel32.dll" "system" fn FreeLibrary(hlibmodule : HMODULE) -> BOOL);
windows_link::link!("kernel32.dll" "system" fn GetMachineTypeAttributes(machine : u16, machinetypeattributes : *mut MACHINE_ATTRIBUTES) -> HRESULT);
windows_link::link!("kernel32.dll" "system" fn GetProcAddress(hmodule : HMODULE, lpprocname : PCSTR) -> FARPROC);
windows_link::link!("kernel32.dll" "system" fn LoadLibraryA(lplibfilename : PCSTR) -> HMODULE);
windows_link::link!("kernel32.dll" "system" fn OpenSemaphoreA(dwdesiredaccess : u32, binherithandle : BOOL, lpname : PCSTR) -> HANDLE);
windows_link::link!("kernel32.dll" "system" fn PeekNamedPipe(hnamedpipe : HANDLE, lpbuffer : *mut core::ffi::c_void, nbuffersize : u32, lpbytesread : *mut u32, lptotalbytesavail : *mut u32, lpbytesleftthismessage : *mut u32) -> BOOL);
windows_link::link!("advapi32.dll" "system" fn RegCloseKey(hkey : HKEY) -> WIN32_ERROR);
windows_link::link!("advapi32.dll" "system" fn RegEnumKeyExW(hkey : HKEY, dwindex : u32, lpname : PWSTR, lpcchname : *mut u32, lpreserved : *const u32, lpclass : PWSTR, lpcchclass : *mut u32, lpftlastwritetime : *mut FILETIME) -> WIN32_ERROR);
windows_link::link!("advapi32.dll" "system" fn RegOpenKeyExW(hkey : HKEY, lpsubkey : PCWSTR, uloptions : u32, samdesired : REG_SAM_FLAGS, phkresult : *mut HKEY) -> WIN32_ERROR);
windows_link::link!("advapi32.dll" "system" fn RegQueryValueExW(hkey : HKEY, lpvaluename : PCWSTR, lpreserved : *const u32, lptype : *mut REG_VALUE_TYPE, lpdata : *mut u8, lpcbdata : *mut u32) -> WIN32_ERROR);
windows_link::link!("kernel32.dll" "system" fn ReleaseSemaphore(hsemaphore : HANDLE, lreleasecount : i32, lppreviouscount : *mut i32) -> BOOL);
windows_link::link!("oleaut32.dll" "system" fn SysFreeString(bstrstring : BSTR));
windows_link::link!("oleaut32.dll" "system" fn SysStringLen(pbstr : BSTR) -> u32);
windows_link::link!("kernel32.dll" "system" fn WaitForSingleObject(hhandle : HANDLE, dwmilliseconds : u32) -> WAIT_EVENT);
pub type ADVANCED_FEATURE_FLAGS = u16;
pub type BOOL = i32;
pub type BSTR = *const u16;
pub type CLSCTX = u32;
pub const CLSCTX_ALL: CLSCTX = 23u32;
pub type COINIT = i32;
pub const COINIT_MULTITHREADED: COINIT = 0i32;
pub const ERROR_NO_MORE_ITEMS: WIN32_ERROR = 259u32;
pub const ERROR_SUCCESS: WIN32_ERROR = 0u32;
pub const FALSE: BOOL = 0i32;
pub type FARPROC = Option<unsafe extern "system" fn() -> isize>;
#[repr(C)]
#[derive(Clone, Copy, Default)]
pub struct FILETIME {
pub dwLowDateTime: u32,
pub dwHighDateTime: u32,
}
pub const FILE_ATTRIBUTE_TEMPORARY: FILE_FLAGS_AND_ATTRIBUTES = 256u32;
pub type FILE_FLAGS_AND_ATTRIBUTES = u32;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct GUID {
pub data1: u32,
pub data2: u16,
pub data3: u16,
pub data4: [u8; 8],
}
impl GUID {
pub const fn from_u128(uuid: u128) -> Self {
Self {
data1: (uuid >> 96) as u32,
data2: (uuid >> 80 & 0xffff) as u16,
data3: (uuid >> 64 & 0xffff) as u16,
data4: (uuid as u64).to_be_bytes(),
}
}
}
pub type HANDLE = *mut core::ffi::c_void;
pub type HINSTANCE = *mut core::ffi::c_void;
pub type HKEY = *mut core::ffi::c_void;
pub const HKEY_LOCAL_MACHINE: HKEY = -2147483646i32 as _;
pub type HMODULE = *mut core::ffi::c_void;
pub type HRESULT = i32;
pub type IMAGE_FILE_MACHINE = u16;
pub const IMAGE_FILE_MACHINE_AMD64: IMAGE_FILE_MACHINE = 34404u16;
pub const IID_IUnknown: GUID = GUID::from_u128(0x00000000_0000_0000_c000_000000000046);
#[repr(C)]
pub struct IUnknown_Vtbl {
pub QueryInterface: unsafe extern "system" fn(
this: *mut core::ffi::c_void,
iid: *const GUID,
interface: *mut *mut core::ffi::c_void,
) -> HRESULT,
pub AddRef: unsafe extern "system" fn(this: *mut core::ffi::c_void) -> u32,
pub Release: unsafe extern "system" fn(this: *mut core::ffi::c_void) -> u32,
}
pub const KEY_READ: REG_SAM_FLAGS = 131097u32;
pub const KEY_WOW64_32KEY: REG_SAM_FLAGS = 512u32;
pub type MACHINE_ATTRIBUTES = i32;
pub type PCSTR = *const u8;
pub type PCWSTR = *const u16;
pub type PWSTR = *mut u16;
pub type REG_SAM_FLAGS = u32;
pub const REG_SZ: REG_VALUE_TYPE = 1u32;
pub type REG_VALUE_TYPE = u32;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct SAFEARRAY {
pub cDims: u16,
pub fFeatures: ADVANCED_FEATURE_FLAGS,
pub cbElements: u32,
pub cLocks: u32,
pub pvData: *mut core::ffi::c_void,
pub rgsabound: [SAFEARRAYBOUND; 1],
}
impl Default for SAFEARRAY {
fn default() -> Self {
unsafe { core::mem::zeroed() }
}
}
#[repr(C)]
#[derive(Clone, Copy, Default)]
pub struct SAFEARRAYBOUND {
pub cElements: u32,
pub lLbound: i32,
}
pub const SEMAPHORE_MODIFY_STATE: SYNCHRONIZATION_ACCESS_RIGHTS = 2u32;
pub type SYNCHRONIZATION_ACCESS_RIGHTS = u32;
pub const S_FALSE: HRESULT = 0x1_u32 as _;
pub const S_OK: HRESULT = 0x0_u32 as _;
pub type THREAD_ACCESS_RIGHTS = u32;
pub const THREAD_SYNCHRONIZE: THREAD_ACCESS_RIGHTS = 1048576u32;
pub const UserEnabled: MACHINE_ATTRIBUTES = 1i32;
pub const WAIT_ABANDONED: WAIT_EVENT = 128u32;
pub type WAIT_EVENT = u32;
pub const WAIT_FAILED: WAIT_EVENT = 4294967295u32;
pub const WAIT_OBJECT_0: WAIT_EVENT = 0u32;
pub const WAIT_TIMEOUT: WAIT_EVENT = 258u32;
pub type WIN32_ERROR = u32;
#[link(name = "advapi32")]
#[link(name = "ole32")]
#[link(name = "oleaut32")]
extern "C" {}
use super::windows_link;

View file

@ -0,0 +1 @@
{"files":{".cargo_vcs_info.json":"fd2b1c20ac76771233208d762a77f301fe47646ff0dcfcdfc414fcffbf2b88fc","CHANGELOG.md":"265048f136f2faa5418cb775377c1b43d03afa22d0d5f5a70aee5819381e5703","Cargo.lock":"cd8ab626b9db5d90d3c83048ee9f41892ff4d888a35038efdc4725e2d2c33c1d","Cargo.toml":"032d84ffe843860402ec2339ae4179be20fd6f432109e595a3fa83be54893ec7","Cargo.toml.orig":"850cb9e629142ded23e40a80943fc19b559b09931bb71df35cef2ae7f6152c14","LICENSE-APACHE":"aaff376532ea30a0cd5330b9502ad4a4c8bf769c539c87ffe78819d188a18ebf","LICENSE-MIT":"42fa16951ce7f24b5a467a40e5b449a1d41e662f97ca779864f053f39e097737","README.md":"543f0efa922ff55d3cdc1c96a188dff669f57a2ff3b7dfa0c95368b8e646b5dd","SECURITY.md":"816ea79f8c7937888ab5a972a1efb270c4bada028b448953a195359fe11d526e","benches/buffer.rs":"242f56eaeecd1d0a0f6f9419d1bf312b8d211215355022bd4aef5e5e0f53e2a5","src/apple-other.rs":"75f2c3319068e06ec27135d516953ab645cc7c45033f045cba44136236ef5601","src/custom.rs":"ae5dc94bc12a4a284762e99891b013c509942b1a802ea559e04e572ed44479dc","src/error.rs":"ab5b82ddb8304e8ad75d905d7dc5ba8deec92096930e81e87d7a28f3da382dee","src/error_impls.rs":"4c068e81d876237a7e0a0e91519896bd670c2f999ca729f7fb970caf888cab46","src/espidf.rs":"50f70136fe46f9fe9a728aa7881cdc8144f430620168cf42519c2666a8edc11f","src/fuchsia.rs":"535ed84250cfe8f176494eba226d1c1df9687b5c30cf52d5949f56a591947656","src/getentropy.rs":"5beb52344a9b71c75426bbc56eb989f5fcb81642772737d52e92578b315615a1","src/getrandom.rs":"aad70b8e54710deef974d04d6f5473bf1b47b6fef16c751046b87f2a30a1dbe2","src/hermit.rs":"c9d9d5c78e0e435c2678ef43d1296aef885fd62957d6b454d758ca475cd4e544","src/js.rs":"4306b7a49441e0da2a0737f92f56d3258ddcd1566ec3aea4a4f4a865bbf0ff87","src/lazy.rs":"21764d7cffe5177a331ec37758cc550c6e3be8c5f6fdfb7606053dafbe6a994b","src/lib.rs":"50dbe3913bc42b354bfedd773b54540d569215cc4615140f549fd6be7266f24d","src/linux_android.rs":"92c71e68adcb9bc4ee39e6b2db730e06af1e0c8db0389712b5ea8a1d86991277","src/linux_android_with_fallback.rs":"620577d889d92916aeed62ac0e4f711725fddb7e7bb331f02474160104354e8e","src/netbsd.rs":"765e6820c840d1a6931b7f0d60f373d46a7bca472e5bb1bb9a0b8fcf64b93688","src/rdrand.rs":"ffbe1bfb8f5b30a95f462fa85db07e251f63248c6c0daf3b5f586034cedfa976","src/solaris.rs":"ea2482d6e99a7f18c21c76327c2c61cd462ffa9811e04107ada36dfee42baf7d","src/solid.rs":"a5a6e4b2b43400548b36035b9a513e70ec17809d521757e7228d2214352d24ed","src/use_file.rs":"9a743fbf324120cfb4fd23c925f6b756edb3898f269654bc50dc5a73d6329266","src/util.rs":"e2c1b86ea97ca5c61d562182890cbe24c7eaa37ff8945c17fcfa665b767da1b0","src/util_libc.rs":"39fddfc06948dbd65c4dc696f71d32cf158c5ca91632afa78cbc4c22e0192502","src/vxworks.rs":"3c132cd52df3a8cf903f430ce90d3432c4b4bb99bf069f5546dee43f4f10a555","src/wasi.rs":"45b95d98766cfdc0495cfe5da6c3b63e99dda34c334deee779cf146a29350344","src/windows.rs":"695666d2bf31257e4a02cf970dee50a9a1f83c118b88b67d1a261cc5f7c1a66f","tests/common/mod.rs":"b9a36043d71963ba43a9e2899ba8eea80ff9f3284d243d9b9b9f941afa4f4aa4","tests/custom.rs":"1e944ae523b62dba53fe3daf1b964a2498c8fdd21dfa7afe53781bff2fcf276e","tests/normal.rs":"9e1c4b1e468a09ed0225370dfb6608f8b8135e0fabb09bbc1a718105164aade6","tests/rdrand.rs":"fcf3f78e3078e1b262d0efae8f3c4a730f3fbf68df656fceb78e22ee4cc98990"},"package":"ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"}

View file

@ -0,0 +1,6 @@
{
"git": {
"sha1": "b625985d852600a3eeb68556811e59e7c9a6a098"
},
"path_in_vcs": ""
}

508
http/vendor/getrandom/CHANGELOG.md vendored Normal file
View file

@ -0,0 +1,508 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.2.17] - 2026-01-12
### Fixed
- Use `doc_cfg` instead of `doc_auto_cfg` (partial backport of [#732]) [#768]
- `BCryptGenRandom` signature [#778]
[#732]: https://github.com/rust-random/getrandom/pull/732
[#768]: https://github.com/rust-random/getrandom/pull/768
[#778]: https://github.com/rust-random/getrandom/pull/778
## [0.2.16] - 2025-04-22
### Added
- Cygwin support (backport of [#626]) [#654]
[#626]: https://github.com/rust-random/getrandom/pull/626
[#654]: https://github.com/rust-random/getrandom/pull/654
## [0.2.15] - 2024-05-06
### Added
- Apple visionOS support [#410]
### Changed
- Use `libc::getrandom` on DragonflyBSD, FreeBSD, illumos, and Solaris [#411] [#416] [#417] [#420]
- Unify `libc::getentropy`-based implementations [#418]
[#410]: https://github.com/rust-random/getrandom/pull/410
[#411]: https://github.com/rust-random/getrandom/pull/411
[#416]: https://github.com/rust-random/getrandom/pull/416
[#417]: https://github.com/rust-random/getrandom/pull/417
[#418]: https://github.com/rust-random/getrandom/pull/418
[#420]: https://github.com/rust-random/getrandom/pull/420
## [0.2.14] - 2024-04-08
### Fixed
- Enable `/dev/urandom` fallback for MUSL-based Linux targets [#408]
[#408]: https://github.com/rust-random/getrandom/pull/408
## [0.2.13] - 2024-04-06
### Added
- `linux_disable_fallback` crate feature to disable `/dev/urandom`-based fallback on Linux and
Android targets. Enabling this feature bumps minimum supported Linux kernel version to 3.17 and
Android API level to 23 (Marshmallow). [#396]
### Changed
- Disable `/dev/urandom` fallback for Linux targets outside of the following `target_arch`es:
`aarch64`, `arm`, `powerpc`, `powerpc64`, `s390x`, `x86`, `x86_64` [#396]
- Do not catch `EPERM` error code on Android while checking availability of
the `getrandom` syscall [#396]
[#396]: https://github.com/rust-random/getrandom/pull/396
## [0.2.12] - 2024-01-09
### Fixed
- Custom backend for targets without atomics [#385]
### Changed
- Improve robustness of the Hermit backend and `sys_fill_exact` [#386]
- Raise minimum supported Apple OS versions to macOS 10.12 and iOS 10 [#388]
### Added
- Document platform support policy [#387]
[#385]: https://github.com/rust-random/getrandom/pull/385
[#386]: https://github.com/rust-random/getrandom/pull/386
[#387]: https://github.com/rust-random/getrandom/pull/387
[#388]: https://github.com/rust-random/getrandom/pull/388
## [0.2.11] - 2023-11-08
### Added
- GNU/Hurd support [#370]
### Changed
- Renamed `__getrandom_internal` to `__GETRANDOM_INTERNAL` [#369]
- Updated link to Hermit docs [#374]
[#369]: https://github.com/rust-random/getrandom/pull/369
[#370]: https://github.com/rust-random/getrandom/pull/370
[#374]: https://github.com/rust-random/getrandom/pull/374
## [0.2.10] - 2023-06-06
### Added
- Support for PS Vita (`armv7-sony-vita-newlibeabihf`) [#359]
### Changed
- Use getentropy from libc on Emscripten targets [#362]
[#359]: https://github.com/rust-random/getrandom/pull/359
[#362]: https://github.com/rust-random/getrandom/pull/362
## [0.2.9] - 2023-04-06
### Added
- AIX support [#282]
- `getrandom_uninit` function [#291]
- `wasm64-unknown-unknown` support [#303]
- tvOS and watchOS support [#317]
- QNX/nto support [#325]
- Support for `getrandom` syscall on NetBSD ≥ 10.0 [#331]
- `RtlGenRandom` fallback for non-UWP Windows [#337]
### Breaking Changes
- Update MSRV to 1.36 [#291]
### Fixed
- Solaris/OpenBSD/Dragonfly build [#301]
### Changed
- Update MSRV to 1.36 [#291]
- Use getentropy on Emscripten [#307]
- Solaris: consistantly use `/dev/random` source [#310]
- Move 3ds selection above rdrand/js/custom fallback [#312]
- Remove buffer zeroing from Node.js implementation [#315]
- Use `open` instead of `open64` [#326]
- Remove #cfg from bsd_arandom.rs [#332]
- Hermit: use `sys_read_entropy` syscall [#333]
- Eliminate potential panic in sys_fill_exact [#334]
- rdrand: Remove checking for 0 and !0 and instead check CPU family and do a self-test [#335]
- Move `__getrandom_custom` definition into a const block [#344]
- Switch the custom backend to Rust ABI [#347]
[#282]: https://github.com/rust-random/getrandom/pull/282
[#291]: https://github.com/rust-random/getrandom/pull/291
[#301]: https://github.com/rust-random/getrandom/pull/301
[#303]: https://github.com/rust-random/getrandom/pull/303
[#307]: https://github.com/rust-random/getrandom/pull/307
[#310]: https://github.com/rust-random/getrandom/pull/310
[#312]: https://github.com/rust-random/getrandom/pull/312
[#315]: https://github.com/rust-random/getrandom/pull/315
[#317]: https://github.com/rust-random/getrandom/pull/317
[#325]: https://github.com/rust-random/getrandom/pull/325
[#326]: https://github.com/rust-random/getrandom/pull/326
[#331]: https://github.com/rust-random/getrandom/pull/331
[#332]: https://github.com/rust-random/getrandom/pull/332
[#333]: https://github.com/rust-random/getrandom/pull/333
[#334]: https://github.com/rust-random/getrandom/pull/334
[#335]: https://github.com/rust-random/getrandom/pull/335
[#337]: https://github.com/rust-random/getrandom/pull/337
[#344]: https://github.com/rust-random/getrandom/pull/344
[#347]: https://github.com/rust-random/getrandom/pull/347
## [0.2.8] - 2022-10-20
### Changed
- The [Web Cryptography API] will now be preferred on `wasm32-unknown-unknown`
when using the `"js"` feature, even on Node.js [#284] [#295]
### Added
- Added benchmarks to track buffer initialization cost [#272]
### Fixed
- Use `$crate` in `register_custom_getrandom!` [#270]
### Documentation
- Add information about enabling `"js"` feature [#280]
- Fix link to `wasm-bindgen` [#278]
- Document the varied implementations for underlying randomness sources [#276]
[Web Cryptography API]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API
[#284]: https://github.com/rust-random/getrandom/pull/284
[#295]: https://github.com/rust-random/getrandom/pull/295
[#272]: https://github.com/rust-random/getrandom/pull/272
[#270]: https://github.com/rust-random/getrandom/pull/270
[#280]: https://github.com/rust-random/getrandom/pull/280
[#278]: https://github.com/rust-random/getrandom/pull/278
[#276]: https://github.com/rust-random/getrandom/pull/276
## [0.2.7] - 2022-06-14
### Changed
- Update `wasi` dependency to `0.11` [#253]
### Fixed
- Use `AtomicPtr` instead of `AtomicUsize` for Strict Provenance compatibility. [#263]
### Documentation
- Add comments explaining use of fallback mechanisms [#257] [#260]
[#263]: https://github.com/rust-random/getrandom/pull/263
[#260]: https://github.com/rust-random/getrandom/pull/260
[#253]: https://github.com/rust-random/getrandom/pull/253
[#257]: https://github.com/rust-random/getrandom/pull/257
## [0.2.6] - 2022-03-28
### Added
- Nintendo 3DS (`armv6k-nintendo-3ds`) support [#248]
### Changed
- Retry `open` when interrupted [#252]
[#248]: https://github.com/rust-random/getrandom/pull/248
[#252]: https://github.com/rust-random/getrandom/pull/252
## [0.2.5] - 2022-02-22
### Added
- ESP-IDF targets (`*espidf`) support [#245]
### Fixed
- Webpack warning caused by dynamic require [#234]
- Error checking on iOS for `SecRandomCopyBytes` [#244]
[#234]: https://github.com/rust-random/getrandom/pull/234
[#244]: https://github.com/rust-random/getrandom/pull/244
[#245]: https://github.com/rust-random/getrandom/pull/245
## [0.2.4] - 2021-12-13
### Changed
- Use explicit imports in the `js` backend [#220]
- Use `/dev/urandom` on Redox instead of `rand:` [#222]
- Use `NonZeroU32::new_unchecked` to convert wasi error [#233]
### Added
- SOLID targets (`*-kmc-solid_*`) support [#235]
- Limited Hermit (`x86_64-unknown-hermit`) support [#236]
[#220]: https://github.com/rust-random/getrandom/pull/220
[#222]: https://github.com/rust-random/getrandom/pull/222
[#233]: https://github.com/rust-random/getrandom/pull/233
[#235]: https://github.com/rust-random/getrandom/pull/235
[#236]: https://github.com/rust-random/getrandom/pull/236
## [0.2.3] - 2021-04-10
### Changed
- Replace build.rs with link attributes. [#205]
- Add support for getrandom syscall on DragonFly BSD. [#210]
- Improve Node.js detection. [#215]
[#205]: https://github.com/rust-random/getrandom/pull/205
[#210]: https://github.com/rust-random/getrandom/pull/210
[#215]: https://github.com/rust-random/getrandom/pull/215
## [0.2.2] - 2021-01-19
### Changed
- Forward `rustc-dep-of-std` to dependencies. [#198]
- Highlight feature-dependent functionality in documentation using the `doc_cfg` feature. [#200]
[#198]: https://github.com/rust-random/getrandom/pull/198
[#200]: https://github.com/rust-random/getrandom/pull/200
## [0.2.1] - 2021-01-03
### Changed
- Update `cfg-if` to v1.0. [#166]
- Update `wasi` to v0.10. [#167]
### Fixed
- Multithreaded WASM support. [#165]
### Removed
- Windows XP support. [#177]
- Direct `stdweb` support. [#178]
- CloudABI support. [#184]
[#165]: https://github.com/rust-random/getrandom/pull/165
[#166]: https://github.com/rust-random/getrandom/pull/166
[#167]: https://github.com/rust-random/getrandom/pull/167
[#177]: https://github.com/rust-random/getrandom/pull/177
[#178]: https://github.com/rust-random/getrandom/pull/178
[#184]: https://github.com/rust-random/getrandom/pull/184
## [0.2.0] - 2020-09-10
### Features for using getrandom on unsupported targets
The following (off by default) Cargo features have been added:
- `"rdrand"` - use the RDRAND instruction on `no_std` `x86`/`x86_64` targets [#133]
- `"js"` - use JavaScript calls on `wasm32-unknown-unknown` [#149]
- Replaces the `stdweb` and `wasm-bindgen` features (which are removed)
- `"custom"` - allows a user to specify a custom implementation [#109]
### Breaking Changes
- Unsupported targets no longer compile [#107]
- Change/Add `Error` constants [#120]
- Only impl `std` traits when the `"std"` Cargo feature is specified [#106]
- Remove official support for Hermit, L4Re, and UEFI [#133]
- Remove optional `"log"` dependency [#131]
- Update minimum supported Linux kernel to 2.6.32 [#153]
- Update MSRV to 1.34 [#159]
[#106]: https://github.com/rust-random/getrandom/pull/106
[#107]: https://github.com/rust-random/getrandom/pull/107
[#109]: https://github.com/rust-random/getrandom/pull/109
[#120]: https://github.com/rust-random/getrandom/pull/120
[#131]: https://github.com/rust-random/getrandom/pull/131
[#133]: https://github.com/rust-random/getrandom/pull/133
[#149]: https://github.com/rust-random/getrandom/pull/149
[#153]: https://github.com/rust-random/getrandom/pull/153
[#159]: https://github.com/rust-random/getrandom/pull/159
## [0.1.16] - 2020-12-31
### Changed
- Update `cfg-if` to v1.0. [#173]
- Implement `std::error::Error` for the `Error` type on additional targets. [#169]
### Fixed
- Multithreaded WASM support. [#171]
[#173]: https://github.com/rust-random/getrandom/pull/173
[#171]: https://github.com/rust-random/getrandom/pull/171
[#169]: https://github.com/rust-random/getrandom/pull/169
## [0.1.15] - 2020-09-10
### Changed
- Added support for Internet Explorer 11 [#139]
- Fix Webpack require warning with `wasm-bindgen` [#137]
[#137]: https://github.com/rust-random/getrandom/pull/137
[#139]: https://github.com/rust-random/getrandom/pull/139
## [0.1.14] - 2020-01-07
### Changed
- Remove use of spin-locks in the `use_file` module. [#125]
- Update `wasi` to v0.9. [#126]
- Do not read errno value on DragonFlyBSD to fix compilation failure. [#129]
[#125]: https://github.com/rust-random/getrandom/pull/125
[#126]: https://github.com/rust-random/getrandom/pull/126
[#129]: https://github.com/rust-random/getrandom/pull/129
## [0.1.13] - 2019-08-25
### Added
- VxWorks targets support. [#86]
### Changed
- If zero-length slice is passed to the `getrandom` function, always return
`Ok(())` immediately without doing any calls to the underlying operating
system. [#104]
- Use the `kern.arandom` sysctl on NetBSD. [#115]
### Fixed
- Bump `cfg-if` minimum version from 0.1.0 to 0.1.2. [#112]
- Typos and bad doc links. [#117]
[#86]: https://github.com/rust-random/getrandom/pull/86
[#104]: https://github.com/rust-random/getrandom/pull/104
[#112]: https://github.com/rust-random/getrandom/pull/112
[#115]: https://github.com/rust-random/getrandom/pull/115
[#117]: https://github.com/rust-random/getrandom/pull/117
## [0.1.12] - 2019-08-18
### Changed
- Update wasi dependency from v0.5 to v0.7. [#100]
[#100]: https://github.com/rust-random/getrandom/pull/100
## [0.1.11] - 2019-08-25
### Fixed
- Implement `std`-dependent traits for selected targets even if `std`
feature is disabled. (backward compatibility with v0.1.8) [#96]
[#96]: https://github.com/rust-random/getrandom/pull/96
## [0.1.10] - 2019-08-18 [YANKED]
### Changed
- Use the dummy implementation on `wasm32-unknown-unknown` even with the
disabled `dummy` feature. [#90]
### Fixed
- Fix CSP error for `wasm-bindgen`. [#92]
[#90]: https://github.com/rust-random/getrandom/pull/90
[#92]: https://github.com/rust-random/getrandom/pull/92
## [0.1.9] - 2019-08-14 [YANKED]
### Changed
- Remove `std` dependency for opening and reading files. [#58]
- Use `wasi` instead of `libc` on WASI target. [#64]
- By default emit a compile-time error when built for an unsupported target.
This behaviour can be disabled by using the `dummy` feature. [#71]
### Added
- Add support for UWP targets. [#69]
- Add unstable `rustc-dep-of-std` feature. [#78]
[#58]: https://github.com/rust-random/getrandom/pull/58
[#64]: https://github.com/rust-random/getrandom/pull/64
[#69]: https://github.com/rust-random/getrandom/pull/69
[#71]: https://github.com/rust-random/getrandom/pull/71
[#78]: https://github.com/rust-random/getrandom/pull/78
## [0.1.8] - 2019-07-29
### Changed
- Explicitly specify types to arguments of 'libc::syscall'. [#74]
[#74]: https://github.com/rust-random/getrandom/pull/74
## [0.1.7] - 2019-07-29
### Added
- Support for hermit and l4re. [#61]
- `Error::raw_os_error` method, `Error::INTERNAL_START` and
`Error::CUSTOM_START` constants. Use `libc` for retrieving OS error descriptions. [#54]
### Changed
- Remove `lazy_static` dependency and use custom structures for lock-free
initialization. [#51] [#52]
- Try `getrandom()` first on FreeBSD. [#57]
### Removed
- Bitrig support. [#56]
### Deprecated
- `Error::UNKNOWN`, `Error::UNAVAILABLE`. [#54]
[#51]: https://github.com/rust-random/getrandom/pull/51
[#52]: https://github.com/rust-random/getrandom/pull/52
[#54]: https://github.com/rust-random/getrandom/pull/54
[#56]: https://github.com/rust-random/getrandom/pull/56
[#57]: https://github.com/rust-random/getrandom/pull/57
[#61]: https://github.com/rust-random/getrandom/pull/61
## [0.1.6] - 2019-06-30
### Changed
- Minor change of RDRAND AMD bug handling. [#48]
[#48]: https://github.com/rust-random/getrandom/pull/48
## [0.1.5] - 2019-06-29
### Fixed
- Use shared `File` instead of shared file descriptor. [#44]
- Workaround for RDRAND hardware bug present on some AMD CPUs. [#43]
### Changed
- Try `getentropy` and then fallback to `/dev/random` on macOS. [#38]
[#38]: https://github.com/rust-random/getrandom/issues/38
[#43]: https://github.com/rust-random/getrandom/pull/43
[#44]: https://github.com/rust-random/getrandom/issues/44
## [0.1.4] - 2019-06-28
### Added
- Add support for `x86_64-unknown-uefi` target by using RDRAND with CPUID
feature detection. [#30]
### Fixed
- Fix long buffer issues on Windows and Linux. [#31] [#32]
- Check `EPERM` in addition to `ENOSYS` on Linux. [#37]
### Changed
- Improve efficiency by sharing file descriptor across threads. [#13]
- Remove `cloudabi`, `winapi`, and `fuchsia-cprng` dependencies. [#40]
- Improve RDRAND implementation. [#24]
- Don't block during syscall detection on Linux. [#26]
- Increase consistency with libc implementation on FreeBSD. [#36]
- Apply `rustfmt`. [#39]
[#30]: https://github.com/rust-random/getrandom/pull/30
[#13]: https://github.com/rust-random/getrandom/issues/13
[#40]: https://github.com/rust-random/getrandom/pull/40
[#26]: https://github.com/rust-random/getrandom/pull/26
[#24]: https://github.com/rust-random/getrandom/pull/24
[#39]: https://github.com/rust-random/getrandom/pull/39
[#36]: https://github.com/rust-random/getrandom/pull/36
[#31]: https://github.com/rust-random/getrandom/issues/31
[#32]: https://github.com/rust-random/getrandom/issues/32
[#37]: https://github.com/rust-random/getrandom/issues/37
## [0.1.3] - 2019-05-15
- Update for `wasm32-unknown-wasi` being renamed to `wasm32-wasi`, and for
WASI being categorized as an OS.
## [0.1.2] - 2019-04-06
- Add support for `wasm32-unknown-wasi` target.
## [0.1.1] - 2019-04-05
- Enable std functionality for CloudABI by default.
## [0.1.0] - 2019-03-23
Publish initial implementation.
## [0.0.0] - 2019-01-19
Publish an empty template library.
[0.2.17]: https://github.com/rust-random/getrandom/compare/v0.2.16...v0.2.17
[0.2.16]: https://github.com/rust-random/getrandom/compare/v0.2.15...v0.2.16
[0.2.15]: https://github.com/rust-random/getrandom/compare/v0.2.14...v0.2.15
[0.2.14]: https://github.com/rust-random/getrandom/compare/v0.2.13...v0.2.14
[0.2.13]: https://github.com/rust-random/getrandom/compare/v0.2.12...v0.2.13
[0.2.12]: https://github.com/rust-random/getrandom/compare/v0.2.11...v0.2.12
[0.2.11]: https://github.com/rust-random/getrandom/compare/v0.2.10...v0.2.11
[0.2.10]: https://github.com/rust-random/getrandom/compare/v0.2.9...v0.2.10
[0.2.9]: https://github.com/rust-random/getrandom/compare/v0.2.8...v0.2.9
[0.2.8]: https://github.com/rust-random/getrandom/compare/v0.2.7...v0.2.8
[0.2.7]: https://github.com/rust-random/getrandom/compare/v0.2.6...v0.2.7
[0.2.6]: https://github.com/rust-random/getrandom/compare/v0.2.5...v0.2.6
[0.2.5]: https://github.com/rust-random/getrandom/compare/v0.2.4...v0.2.5
[0.2.4]: https://github.com/rust-random/getrandom/compare/v0.2.3...v0.2.4
[0.2.3]: https://github.com/rust-random/getrandom/compare/v0.2.2...v0.2.3
[0.2.2]: https://github.com/rust-random/getrandom/compare/v0.2.1...v0.2.2
[0.2.1]: https://github.com/rust-random/getrandom/compare/v0.2.0...v0.2.1
[0.2.0]: https://github.com/rust-random/getrandom/compare/v0.1.15...v0.2.0
[0.1.16]: https://github.com/rust-random/getrandom/compare/v0.1.15...v0.1.16
[0.1.15]: https://github.com/rust-random/getrandom/compare/v0.1.14...v0.1.15
[0.1.14]: https://github.com/rust-random/getrandom/compare/v0.1.13...v0.1.14
[0.1.13]: https://github.com/rust-random/getrandom/compare/v0.1.12...v0.1.13
[0.1.12]: https://github.com/rust-random/getrandom/compare/v0.1.11...v0.1.12
[0.1.11]: https://github.com/rust-random/getrandom/compare/v0.1.10...v0.1.11
[0.1.10]: https://github.com/rust-random/getrandom/compare/v0.1.9...v0.1.10
[0.1.9]: https://github.com/rust-random/getrandom/compare/v0.1.8...v0.1.9
[0.1.8]: https://github.com/rust-random/getrandom/compare/v0.1.7...v0.1.8
[0.1.7]: https://github.com/rust-random/getrandom/compare/v0.1.6...v0.1.7
[0.1.6]: https://github.com/rust-random/getrandom/compare/v0.1.5...v0.1.6
[0.1.5]: https://github.com/rust-random/getrandom/compare/v0.1.4...v0.1.5
[0.1.4]: https://github.com/rust-random/getrandom/compare/v0.1.3...v0.1.4
[0.1.3]: https://github.com/rust-random/getrandom/compare/v0.1.2...v0.1.3
[0.1.2]: https://github.com/rust-random/getrandom/compare/v0.1.1...v0.1.2
[0.1.1]: https://github.com/rust-random/getrandom/compare/v0.1.0...v0.1.1
[0.1.0]: https://github.com/rust-random/getrandom/compare/v0.0.0...v0.1.0
[0.0.0]: https://github.com/rust-random/getrandom/releases/tag/v0.0.0

413
http/vendor/getrandom/Cargo.lock generated vendored Normal file
View file

@ -0,0 +1,413 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "async-trait"
version = "0.1.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bumpalo"
version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
[[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.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3"
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 = "compiler_builtins"
version = "0.1.160"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6376049cfa92c0aa8b9ac95fae22184b981c658208d4ed8a1dc553cd83612895"
[[package]]
name = "find-msvc-tools"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41"
[[package]]
name = "getrandom"
version = "0.2.17"
dependencies = [
"cfg-if",
"compiler_builtins",
"js-sys",
"libc",
"rustc-std-workspace-core",
"wasi",
"wasm-bindgen",
"wasm-bindgen-test",
]
[[package]]
name = "itoa"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]]
name = "js-sys"
version = "0.3.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.180"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
dependencies = [
"rustc-std-workspace-core",
]
[[package]]
name = "libm"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
[[package]]
name = "memchr"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
[[package]]
name = "minicov"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4869b6a491569605d66d3952bcdf03df789e5b536e5f0cf7758a7f08a55ae24d"
dependencies = [
"cc",
"walkdir",
]
[[package]]
name = "nu-ansi-term"
version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [
"windows-sys",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
"libm",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "oorandom"
version = "11.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
[[package]]
name = "proc-macro2"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustc-std-workspace-alloc"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d441c3b2ebf55cebf796bfdc265d67fa09db17b7bb6bd4be75c509e1e8fec3"
[[package]]
name = "rustc-std-workspace-core"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa9c45b374136f52f2d6311062c7146bff20fec063c3f5d46a410bd937746955"
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[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",
"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.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[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 = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
dependencies = [
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c"
dependencies = [
"cfg-if",
"js-sys",
"once_cell",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4"
dependencies = [
"unicode-ident",
]
[[package]]
name = "wasm-bindgen-test"
version = "0.3.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25e90e66d265d3a1efc0e72a54809ab90b9c0c515915c67cdf658689d2c22c6c"
dependencies = [
"async-trait",
"cast",
"js-sys",
"libm",
"minicov",
"nu-ansi-term",
"num-traits",
"oorandom",
"serde",
"serde_json",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-bindgen-test-macro",
]
[[package]]
name = "wasm-bindgen-test-macro"
version = "0.3.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7150335716dce6028bead2b848e72f47b45e7b9422f64cccdc23bedca89affc1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "web-sys"
version = "0.3.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[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 = "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 = "zmij"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fc5a66a20078bf1251bde995aa2fdcc4b800c70b5d92dd2c62abc5c60f679f8"

121
http/vendor/getrandom/Cargo.toml vendored Normal file
View file

@ -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 = "2018"
name = "getrandom"
version = "0.2.17"
authors = ["The Rand Project Developers"]
build = false
exclude = [".*"]
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "A small cross-platform library for retrieving random data from system source"
documentation = "https://docs.rs/getrandom"
readme = "README.md"
categories = [
"os",
"no-std",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-random/getrandom"
[package.metadata.docs.rs]
features = [
"std",
"custom",
]
rustdoc-args = [
"--cfg",
"docsrs",
]
[package.metadata.cross.target.x86_64-unknown-netbsd]
pre-build = [
"mkdir -p /tmp/netbsd",
"curl https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.2/amd64/binary/sets/base.tar.xz -O",
"tar -C /tmp/netbsd -xJf base.tar.xz",
"cp /tmp/netbsd/usr/lib/libexecinfo.so /usr/local/x86_64-unknown-netbsd/lib",
"rm base.tar.xz",
"rm -rf /tmp/netbsd",
]
[features]
custom = []
js = [
"wasm-bindgen",
"js-sys",
]
linux_disable_fallback = []
rdrand = []
rustc-dep-of-std = [
"compiler_builtins",
"core",
"libc/rustc-dep-of-std",
"wasi/rustc-dep-of-std",
]
std = []
test-in-browser = []
[lib]
name = "getrandom"
path = "src/lib.rs"
[[test]]
name = "custom"
path = "tests/custom.rs"
[[test]]
name = "normal"
path = "tests/normal.rs"
[[test]]
name = "rdrand"
path = "tests/rdrand.rs"
[[bench]]
name = "buffer"
path = "benches/buffer.rs"
[dependencies.cfg-if]
version = "1"
[dependencies.compiler_builtins]
version = "0.1"
optional = true
[dependencies.core]
version = "1.0"
optional = true
package = "rustc-std-workspace-core"
[target.'cfg(all(any(target_arch = "wasm32", target_arch = "wasm64"), target_os = "unknown"))'.dependencies.js-sys]
version = "0.3"
optional = true
[target.'cfg(all(any(target_arch = "wasm32", target_arch = "wasm64"), target_os = "unknown"))'.dependencies.wasm-bindgen]
version = "0.2.62"
optional = true
default-features = false
[target.'cfg(all(any(target_arch = "wasm32", target_arch = "wasm64"), target_os = "unknown"))'.dev-dependencies.wasm-bindgen-test]
version = "0.3.18"
[target.'cfg(target_os = "wasi")'.dependencies.wasi]
version = "0.11"
default-features = false
[target."cfg(unix)".dependencies.libc]
version = "0.2.154"
default-features = false

67
http/vendor/getrandom/Cargo.toml.orig vendored Normal file
View file

@ -0,0 +1,67 @@
[package]
name = "getrandom"
version = "0.2.17" # Also update html_root_url in lib.rs when bumping this
edition = "2018"
authors = ["The Rand Project Developers"]
license = "MIT OR Apache-2.0"
description = "A small cross-platform library for retrieving random data from system source"
documentation = "https://docs.rs/getrandom"
repository = "https://github.com/rust-random/getrandom"
categories = ["os", "no-std"]
exclude = [".*"]
[dependencies]
cfg-if = "1"
# When built as part of libstd
compiler_builtins = { version = "0.1", optional = true }
core = { version = "1.0", optional = true, package = "rustc-std-workspace-core" }
[target.'cfg(unix)'.dependencies]
libc = { version = "0.2.154", default-features = false }
[target.'cfg(target_os = "wasi")'.dependencies]
wasi = { version = "0.11", default-features = false }
[target.'cfg(all(any(target_arch = "wasm32", target_arch = "wasm64"), target_os = "unknown"))'.dependencies]
wasm-bindgen = { version = "0.2.62", default-features = false, optional = true }
js-sys = { version = "0.3", optional = true }
[target.'cfg(all(any(target_arch = "wasm32", target_arch = "wasm64"), target_os = "unknown"))'.dev-dependencies]
wasm-bindgen-test = "0.3.18"
[features]
# Implement std-only traits for getrandom::Error
std = []
# Disable `/dev/urandom` fallback for Linux and Android targets.
# Bumps minimum supported Linux kernel version to 3.17 and Android API level to 23 (Marshmallow).
linux_disable_fallback = []
# Feature to enable fallback RDRAND-based implementation on x86/x86_64
rdrand = []
# Feature to enable JavaScript bindings on wasm*-unknown-unknown
js = ["wasm-bindgen", "js-sys"]
# Feature to enable custom RNG implementations
custom = []
# Unstable feature to support being a libstd dependency
rustc-dep-of-std = [
"compiler_builtins",
"core",
"libc/rustc-dep-of-std",
"wasi/rustc-dep-of-std",
]
# Unstable/test-only feature to run wasm-bindgen tests in a browser
test-in-browser = []
[package.metadata.docs.rs]
features = ["std", "custom"]
rustdoc-args = ["--cfg", "docsrs"]
# workaround for https://github.com/cross-rs/cross/issues/1345
[package.metadata.cross.target.x86_64-unknown-netbsd]
pre-build = [
"mkdir -p /tmp/netbsd",
"curl https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.2/amd64/binary/sets/base.tar.xz -O",
"tar -C /tmp/netbsd -xJf base.tar.xz",
"cp /tmp/netbsd/usr/lib/libexecinfo.so /usr/local/x86_64-unknown-netbsd/lib",
"rm base.tar.xz",
"rm -rf /tmp/netbsd",
]

201
http/vendor/getrandom/LICENSE-APACHE vendored Normal file
View file

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
https://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
https://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.

26
http/vendor/getrandom/LICENSE-MIT vendored Normal file
View file

@ -0,0 +1,26 @@
Copyright (c) 2018-2024 The rust-random Project Developers
Copyright (c) 2014 The Rust Project Developers
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

81
http/vendor/getrandom/README.md vendored Normal file
View file

@ -0,0 +1,81 @@
# getrandom
[![Build Status]][GitHub Actions] [![Crate]][crates.io] [![Documentation]][docs.rs] [![Dependency Status]][deps.rs] [![Downloads]][crates.io] [![License]][LICENSE-MIT]
[GitHub Actions]: https://github.com/rust-random/getrandom/actions?query=workflow:Tests+branch:master
[Build Status]: https://github.com/rust-random/getrandom/actions/workflows/tests.yml/badge.svg?branch=master
[crates.io]: https://crates.io/crates/getrandom
[Crate]: https://img.shields.io/crates/v/getrandom
[docs.rs]: https://docs.rs/getrandom
[Documentation]: https://docs.rs/getrandom/badge.svg
[deps.rs]: https://deps.rs/repo/github/rust-random/getrandom
[Dependency Status]: https://deps.rs/repo/github/rust-random/getrandom/status.svg
[Downloads]: https://img.shields.io/crates/d/getrandom
[LICENSE-MIT]: https://raw.githubusercontent.com/rust-random/getrandom/master/LICENSE-MIT
[License]: https://img.shields.io/crates/l/getrandom
A Rust library for retrieving random data from (operating) system sources. It is
assumed that the system always provides high-quality cryptographically secure random
data, ideally backed by hardware entropy sources. This crate derives its name
from Linux's `getrandom` function, but is cross-platform, roughly supporting
the same set of platforms as Rust's `std` lib.
This is a low-level API. Most users should prefer using high-level random-number
library like [`rand`].
[`rand`]: https://crates.io/crates/rand
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
getrandom = "0.2"
```
Then invoke the `getrandom` function:
```rust
fn get_random_buf() -> Result<[u8; 32], getrandom::Error> {
let mut buf = [0u8; 32];
getrandom::getrandom(&mut buf)?;
Ok(buf)
}
```
For more information about supported targets, entropy sources, `no_std` targets,
crate features, WASM support and Custom RNGs see the
[`getrandom` documentation](https://docs.rs/getrandom/latest) and
[`getrandom::Error` documentation](https://docs.rs/getrandom/latest/getrandom/struct.Error.html).
## Minimum Supported Rust Version
This crate requires Rust 1.36.0 or later.
## Platform Support
This crate generally supports the same operating system and platform versions that the Rust standard library does.
Additional targets may be supported using pluggable custom implementations.
This means that as Rust drops support for old versions of operating systems (such as old Linux kernel versions, Android API levels, etc)
in stable releases, `getrandom` may create new patch releases (`0.N.x`) that remove support for outdated platform versions.
## License
The `getrandom` library is distributed under either of
* [Apache License, Version 2.0][LICENSE-APACHE]
* [MIT license][LICENSE-MIT]
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.
[LICENSE-APACHE]: https://github.com/rust-random/getrandom/blob/master/LICENSE-APACHE
[LICENSE-MIT]: https://github.com/rust-random/getrandom/blob/master/LICENSE-MIT

13
http/vendor/getrandom/SECURITY.md vendored Normal file
View file

@ -0,0 +1,13 @@
# Security Policy
## Supported Versions
Security updates are applied only to the latest release.
## Reporting a Vulnerability
If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
Please disclose it at [security advisory](https://github.com/rust-random/getrandom/security/advisories/new).
This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure.

71
http/vendor/getrandom/benches/buffer.rs vendored Normal file
View file

@ -0,0 +1,71 @@
#![feature(test, maybe_uninit_uninit_array_transpose)]
extern crate test;
use std::mem::MaybeUninit;
// Call getrandom on a zero-initialized stack buffer
#[inline(always)]
fn bench_getrandom<const N: usize>() {
let mut buf = [0u8; N];
getrandom::getrandom(&mut buf).unwrap();
test::black_box(&buf as &[u8]);
}
// Call getrandom_uninit on an uninitialized stack buffer
#[inline(always)]
fn bench_getrandom_uninit<const N: usize>() {
let mut uninit = [MaybeUninit::uninit(); N];
let buf: &[u8] = getrandom::getrandom_uninit(&mut uninit).unwrap();
test::black_box(buf);
}
// We benchmark using #[inline(never)] "inner" functions for two reasons:
// - Avoiding inlining reduces a source of variance when running benchmarks.
// - It is _much_ easier to get the assembly or IR for the inner loop.
//
// For example, using cargo-show-asm (https://github.com/pacak/cargo-show-asm),
// we can get the assembly for a particular benchmark's inner loop by running:
// cargo asm --bench buffer --release buffer::p384::bench_getrandom::inner
macro_rules! bench {
( $name:ident, $size:expr ) => {
pub mod $name {
#[bench]
pub fn bench_getrandom(b: &mut test::Bencher) {
#[inline(never)]
fn inner() {
super::bench_getrandom::<{ $size }>()
}
b.bytes = $size as u64;
b.iter(inner);
}
#[bench]
pub fn bench_getrandom_uninit(b: &mut test::Bencher) {
#[inline(never)]
fn inner() {
super::bench_getrandom_uninit::<{ $size }>()
}
b.bytes = $size as u64;
b.iter(inner);
}
}
};
}
// 16 bytes (128 bits) is the size of an 128-bit AES key/nonce.
bench!(aes128, 128 / 8);
// 32 bytes (256 bits) is the seed sized used for rand::thread_rng
// and the `random` value in a ClientHello/ServerHello for TLS.
// This is also the size of a 256-bit AES/HMAC/P-256/Curve25519 key
// and/or nonce.
bench!(p256, 256 / 8);
// A P-384/HMAC-384 key and/or nonce.
bench!(p384, 384 / 8);
// Initializing larger buffers is not the primary use case of this library, as
// this should normally be done by a userspace CSPRNG. However, we have a test
// here to see the effects of a lower (amortized) syscall overhead.
bench!(page, 4096);

View file

@ -0,0 +1,24 @@
//! Implementation for iOS, tvOS, and watchOS where `getentropy` is unavailable.
use crate::Error;
use core::{ffi::c_void, mem::MaybeUninit};
// libsystem contains the libc of Darwin, and every binary ends up linked against it either way. This
// makes it a more lightweight choice compared to `Security.framework`.
extern "C" {
// This RNG uses a thread-local CSPRNG to provide data, which is seeded by the operating system's root CSPRNG.
// Its the best option after `getentropy` on modern Darwin-based platforms that also avoids the
// high startup costs and linking of Security.framework.
//
// While its just an implementation detail, `Security.framework` just calls into this anyway.
fn CCRandomGenerateBytes(bytes: *mut c_void, size: usize) -> i32;
}
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
let ret = unsafe { CCRandomGenerateBytes(dest.as_mut_ptr() as *mut c_void, dest.len()) };
// kCCSuccess (from CommonCryptoError.h) is always zero.
if ret != 0 {
Err(Error::IOS_SEC_RANDOM)
} else {
Ok(())
}
}

105
http/vendor/getrandom/src/custom.rs vendored Normal file
View file

@ -0,0 +1,105 @@
//! An implementation which calls out to an externally defined function.
use crate::{util::uninit_slice_fill_zero, Error};
use core::{mem::MaybeUninit, num::NonZeroU32};
/// Register a function to be invoked by `getrandom` on unsupported targets.
///
/// ## Writing a custom `getrandom` implementation
///
/// The function to register must have the same signature as
/// [`getrandom::getrandom`](crate::getrandom). The function can be defined
/// wherever you want, either in root crate or a dependent crate.
///
/// For example, if we wanted a `failure-getrandom` crate containing an
/// implementation that always fails, we would first depend on `getrandom`
/// (for the [`Error`] type) in `failure-getrandom/Cargo.toml`:
/// ```toml
/// [dependencies]
/// getrandom = "0.2"
/// ```
/// Note that the crate containing this function does **not** need to enable the
/// `"custom"` Cargo feature.
///
/// Next, in `failure-getrandom/src/lib.rs`, we define our function:
/// ```rust
/// use core::num::NonZeroU32;
/// use getrandom::Error;
///
/// // Some application-specific error code
/// const MY_CUSTOM_ERROR_CODE: u32 = Error::CUSTOM_START + 42;
/// pub fn always_fail(buf: &mut [u8]) -> Result<(), Error> {
/// let code = NonZeroU32::new(MY_CUSTOM_ERROR_CODE).unwrap();
/// Err(Error::from(code))
/// }
/// ```
///
/// ## Registering a custom `getrandom` implementation
///
/// Functions can only be registered in the root binary crate. Attempting to
/// register a function in a non-root crate will result in a linker error.
/// This is similar to
/// [`#[panic_handler]`](https://doc.rust-lang.org/nomicon/panic-handler.html) or
/// [`#[global_allocator]`](https://doc.rust-lang.org/edition-guide/rust-2018/platform-and-target-support/global-allocators.html),
/// where helper crates define handlers/allocators but only the binary crate
/// actually _uses_ the functionality.
///
/// To register the function, we first depend on `failure-getrandom` _and_
/// `getrandom` in `Cargo.toml`:
/// ```toml
/// [dependencies]
/// failure-getrandom = "0.1"
/// getrandom = { version = "0.2", features = ["custom"] }
/// ```
///
/// Then, we register the function in `src/main.rs`:
/// ```rust
/// # mod failure_getrandom { pub fn always_fail(_: &mut [u8]) -> Result<(), getrandom::Error> { unimplemented!() } }
/// use failure_getrandom::always_fail;
/// use getrandom::register_custom_getrandom;
///
/// register_custom_getrandom!(always_fail);
/// ```
///
/// Now any user of `getrandom` (direct or indirect) on this target will use the
/// registered function. As noted in the
/// [top-level documentation](index.html#custom-implementations) this
/// registration only has an effect on unsupported targets.
#[macro_export]
macro_rules! register_custom_getrandom {
($path:path) => {
// TODO(MSRV 1.37): change to unnamed block
const __GETRANDOM_INTERNAL: () = {
// We use Rust ABI to be safe against potential panics in the passed function.
#[no_mangle]
unsafe fn __getrandom_custom(dest: *mut u8, len: usize) -> u32 {
// Make sure the passed function has the type of getrandom::getrandom
type F = fn(&mut [u8]) -> ::core::result::Result<(), $crate::Error>;
let _: F = $crate::getrandom;
let f: F = $path;
let slice = ::core::slice::from_raw_parts_mut(dest, len);
match f(slice) {
Ok(()) => 0,
Err(e) => e.code().get(),
}
}
};
};
}
#[allow(dead_code)]
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
extern "Rust" {
fn __getrandom_custom(dest: *mut u8, len: usize) -> u32;
}
// Previously we always passed a valid, initialized slice to
// `__getrandom_custom`. Ensure `dest` has been initialized for backward
// compatibility with implementations that rely on that (e.g. Rust
// implementations that construct a `&mut [u8]` slice from `dest` and
// `len`).
let dest = uninit_slice_fill_zero(dest);
let ret = unsafe { __getrandom_custom(dest.as_mut_ptr(), dest.len()) };
match NonZeroU32::new(ret) {
None => Ok(()),
Some(code) => Err(Error::from(code)),
}
}

189
http/vendor/getrandom/src/error.rs vendored Normal file
View file

@ -0,0 +1,189 @@
use core::{fmt, num::NonZeroU32};
/// A small and `no_std` compatible error type
///
/// The [`Error::raw_os_error()`] will indicate if the error is from the OS, and
/// if so, which error code the OS gave the application. If such an error is
/// encountered, please consult with your system documentation.
///
/// Internally this type is a NonZeroU32, with certain values reserved for
/// certain purposes, see [`Error::INTERNAL_START`] and [`Error::CUSTOM_START`].
///
/// *If this crate's `"std"` Cargo feature is enabled*, then:
/// - [`getrandom::Error`][Error] implements
/// [`std::error::Error`](https://doc.rust-lang.org/std/error/trait.Error.html)
/// - [`std::io::Error`](https://doc.rust-lang.org/std/io/struct.Error.html) implements
/// [`From<getrandom::Error>`](https://doc.rust-lang.org/std/convert/trait.From.html).
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Error(NonZeroU32);
const fn internal_error(n: u16) -> Error {
// SAFETY: code > 0 as INTERNAL_START > 0 and adding n won't overflow a u32.
let code = Error::INTERNAL_START + (n as u32);
Error(unsafe { NonZeroU32::new_unchecked(code) })
}
impl Error {
/// This target/platform is not supported by `getrandom`.
pub const UNSUPPORTED: Error = internal_error(0);
/// The platform-specific `errno` returned a non-positive value.
pub const ERRNO_NOT_POSITIVE: Error = internal_error(1);
/// Encountered an unexpected situation which should not happen in practice.
pub const UNEXPECTED: Error = internal_error(2);
/// Call to [`CCRandomGenerateBytes`](https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60074/include/CommonRandom.h.auto.html) failed
/// on iOS, tvOS, or waatchOS.
// TODO: Update this constant name in the next breaking release.
pub const IOS_SEC_RANDOM: Error = internal_error(3);
/// Call to Windows [`RtlGenRandom`](https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom) failed.
pub const WINDOWS_RTL_GEN_RANDOM: Error = internal_error(4);
/// RDRAND instruction failed due to a hardware issue.
pub const FAILED_RDRAND: Error = internal_error(5);
/// RDRAND instruction unsupported on this target.
pub const NO_RDRAND: Error = internal_error(6);
/// The environment does not support the Web Crypto API.
pub const WEB_CRYPTO: Error = internal_error(7);
/// Calling Web Crypto API `crypto.getRandomValues` failed.
pub const WEB_GET_RANDOM_VALUES: Error = internal_error(8);
/// On VxWorks, call to `randSecure` failed (random number generator is not yet initialized).
pub const VXWORKS_RAND_SECURE: Error = internal_error(11);
/// Node.js does not have the `crypto` CommonJS module.
pub const NODE_CRYPTO: Error = internal_error(12);
/// Calling Node.js function `crypto.randomFillSync` failed.
pub const NODE_RANDOM_FILL_SYNC: Error = internal_error(13);
/// Called from an ES module on Node.js. This is unsupported, see:
/// <https://docs.rs/getrandom#nodejs-es-module-support>.
pub const NODE_ES_MODULE: Error = internal_error(14);
/// Codes below this point represent OS Errors (i.e. positive i32 values).
/// Codes at or above this point, but below [`Error::CUSTOM_START`] are
/// reserved for use by the `rand` and `getrandom` crates.
pub const INTERNAL_START: u32 = 1 << 31;
/// Codes at or above this point can be used by users to define their own
/// custom errors.
pub const CUSTOM_START: u32 = (1 << 31) + (1 << 30);
/// Extract the raw OS error code (if this error came from the OS)
///
/// This method is identical to [`std::io::Error::raw_os_error()`][1], except
/// that it works in `no_std` contexts. If this method returns `None`, the
/// error value can still be formatted via the `Display` implementation.
///
/// [1]: https://doc.rust-lang.org/std/io/struct.Error.html#method.raw_os_error
#[inline]
pub fn raw_os_error(self) -> Option<i32> {
if self.0.get() < Self::INTERNAL_START {
match () {
#[cfg(target_os = "solid_asp3")]
// On SOLID, negate the error code again to obtain the original
// error code.
() => Some(-(self.0.get() as i32)),
#[cfg(not(target_os = "solid_asp3"))]
() => Some(self.0.get() as i32),
}
} else {
None
}
}
/// Extract the bare error code.
///
/// This code can either come from the underlying OS, or be a custom error.
/// Use [`Error::raw_os_error()`] to disambiguate.
#[inline]
pub const fn code(self) -> NonZeroU32 {
self.0
}
}
cfg_if! {
if #[cfg(unix)] {
fn os_err(errno: i32, buf: &mut [u8]) -> Option<&str> {
let buf_ptr = buf.as_mut_ptr() as *mut libc::c_char;
if unsafe { libc::strerror_r(errno, buf_ptr, buf.len()) } != 0 {
return None;
}
// Take up to trailing null byte
let n = buf.len();
let idx = buf.iter().position(|&b| b == 0).unwrap_or(n);
core::str::from_utf8(&buf[..idx]).ok()
}
} else {
fn os_err(_errno: i32, _buf: &mut [u8]) -> Option<&str> {
None
}
}
}
impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut dbg = f.debug_struct("Error");
if let Some(errno) = self.raw_os_error() {
dbg.field("os_error", &errno);
let mut buf = [0u8; 128];
if let Some(err) = os_err(errno, &mut buf) {
dbg.field("description", &err);
}
} else if let Some(desc) = internal_desc(*self) {
dbg.field("internal_code", &self.0.get());
dbg.field("description", &desc);
} else {
dbg.field("unknown_code", &self.0.get());
}
dbg.finish()
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(errno) = self.raw_os_error() {
let mut buf = [0u8; 128];
match os_err(errno, &mut buf) {
Some(err) => err.fmt(f),
None => write!(f, "OS Error: {}", errno),
}
} else if let Some(desc) = internal_desc(*self) {
f.write_str(desc)
} else {
write!(f, "Unknown Error: {}", self.0.get())
}
}
}
impl From<NonZeroU32> for Error {
fn from(code: NonZeroU32) -> Self {
Self(code)
}
}
fn internal_desc(error: Error) -> Option<&'static str> {
match error {
Error::UNSUPPORTED => Some("getrandom: this target is not supported"),
Error::ERRNO_NOT_POSITIVE => Some("errno: did not return a positive value"),
Error::UNEXPECTED => Some("unexpected situation"),
Error::IOS_SEC_RANDOM => Some("SecRandomCopyBytes: iOS Security framework failure"),
Error::WINDOWS_RTL_GEN_RANDOM => Some("RtlGenRandom: Windows system function failure"),
Error::FAILED_RDRAND => Some("RDRAND: failed multiple times: CPU issue likely"),
Error::NO_RDRAND => Some("RDRAND: instruction not supported"),
Error::WEB_CRYPTO => Some("Web Crypto API is unavailable"),
Error::WEB_GET_RANDOM_VALUES => Some("Calling Web API crypto.getRandomValues failed"),
Error::VXWORKS_RAND_SECURE => Some("randSecure: VxWorks RNG module is not initialized"),
Error::NODE_CRYPTO => Some("Node.js crypto CommonJS module is unavailable"),
Error::NODE_RANDOM_FILL_SYNC => Some("Calling Node.js API crypto.randomFillSync failed"),
Error::NODE_ES_MODULE => Some("Node.js ES modules are not directly supported, see https://docs.rs/getrandom#nodejs-es-module-support"),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::Error;
use core::mem::size_of;
#[test]
fn test_size() {
assert_eq!(size_of::<Error>(), 4);
assert_eq!(size_of::<Result<(), Error>>(), 4);
}
}

View file

@ -0,0 +1,15 @@
extern crate std;
use crate::Error;
use std::io;
impl From<Error> for io::Error {
fn from(err: Error) -> Self {
match err.raw_os_error() {
Some(errno) => io::Error::from_raw_os_error(errno),
None => io::Error::new(io::ErrorKind::Other, err),
}
}
}
impl std::error::Error for Error {}

18
http/vendor/getrandom/src/espidf.rs vendored Normal file
View file

@ -0,0 +1,18 @@
//! Implementation for ESP-IDF
use crate::Error;
use core::{ffi::c_void, mem::MaybeUninit};
extern "C" {
fn esp_fill_random(buf: *mut c_void, len: usize) -> u32;
}
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// Not that NOT enabling WiFi, BT, or the voltage noise entropy source (via `bootloader_random_enable`)
// will cause ESP-IDF to return pseudo-random numbers based on the voltage noise entropy, after the initial boot process:
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html
//
// However tracking if some of these entropy sources is enabled is way too difficult to implement here
unsafe { esp_fill_random(dest.as_mut_ptr().cast(), dest.len()) };
Ok(())
}

13
http/vendor/getrandom/src/fuchsia.rs vendored Normal file
View file

@ -0,0 +1,13 @@
//! Implementation for Fuchsia Zircon
use crate::Error;
use core::mem::MaybeUninit;
#[link(name = "zircon")]
extern "C" {
fn zx_cprng_draw(buffer: *mut u8, length: usize);
}
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
unsafe { zx_cprng_draw(dest.as_mut_ptr() as *mut u8, dest.len()) }
Ok(())
}

21
http/vendor/getrandom/src/getentropy.rs vendored Normal file
View file

@ -0,0 +1,21 @@
//! Implementation using getentropy(2)
//!
//! Available since:
//! - macOS 10.12
//! - OpenBSD 5.6
//! - Emscripten 2.0.5
//! - vita newlib since Dec 2021
//!
//! For these targets, we use getentropy(2) because getrandom(2) doesn't exist.
use crate::{util_libc::last_os_error, Error};
use core::mem::MaybeUninit;
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
for chunk in dest.chunks_mut(256) {
let ret = unsafe { libc::getentropy(chunk.as_mut_ptr() as *mut libc::c_void, chunk.len()) };
if ret != 0 {
return Err(last_os_error());
}
}
Ok(())
}

25
http/vendor/getrandom/src/getrandom.rs vendored Normal file
View file

@ -0,0 +1,25 @@
//! Implementation using getrandom(2).
//!
//! Available since:
//! - Linux Kernel 3.17, Glibc 2.25, Musl 1.1.20
//! - Android API level 23 (Marshmallow)
//! - NetBSD 10.0
//! - FreeBSD 12.0
//! - illumos since Dec 2018
//! - DragonFly 5.7
//! - Hurd Glibc 2.31
//! - shim-3ds since Feb 2022
//!
//! For these platforms, we always use the default pool and never set the
//! GRND_RANDOM flag to use the /dev/random pool. On Linux/Android/Hurd, using
//! GRND_RANDOM is not recommended. On NetBSD/FreeBSD/Dragonfly/3ds, it does
//! nothing. On illumos, the default pool is used to implement getentropy(2),
//! so we assume it is acceptable here.
use crate::{util_libc::sys_fill_exact, Error};
use core::mem::MaybeUninit;
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
sys_fill_exact(dest, |buf| unsafe {
libc::getrandom(buf.as_mut_ptr() as *mut libc::c_void, buf.len(), 0)
})
}

29
http/vendor/getrandom/src/hermit.rs vendored Normal file
View file

@ -0,0 +1,29 @@
//! Implementation for Hermit
use crate::Error;
use core::{mem::MaybeUninit, num::NonZeroU32};
/// Minimum return value which we should get from syscalls in practice,
/// because Hermit uses positive `i32`s for error codes:
/// https://github.com/hermitcore/libhermit-rs/blob/main/src/errno.rs
const MIN_RET_CODE: isize = -(i32::MAX as isize);
extern "C" {
fn sys_read_entropy(buffer: *mut u8, length: usize, flags: u32) -> isize;
}
pub fn getrandom_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
while !dest.is_empty() {
let res = unsafe { sys_read_entropy(dest.as_mut_ptr() as *mut u8, dest.len(), 0) };
// Positive `isize`s can be safely casted to `usize`
if res > 0 && (res as usize) <= dest.len() {
dest = &mut dest[res as usize..];
} else {
let err = match res {
MIN_RET_CODE..=-1 => NonZeroU32::new(-res as u32).unwrap().into(),
_ => Error::UNEXPECTED,
};
return Err(err);
}
}
Ok(())
}

155
http/vendor/getrandom/src/js.rs vendored Normal file
View file

@ -0,0 +1,155 @@
//! Implementation for WASM based on Web and Node.js
use crate::Error;
extern crate std;
use std::{mem::MaybeUninit, thread_local};
use js_sys::{global, Function, Uint8Array};
use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};
// Size of our temporary Uint8Array buffer used with WebCrypto methods
// Maximum is 65536 bytes see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
const WEB_CRYPTO_BUFFER_SIZE: usize = 256;
// Node.js's crypto.randomFillSync requires the size to be less than 2**31.
const NODE_MAX_BUFFER_SIZE: usize = (1 << 31) - 1;
enum RngSource {
Node(NodeCrypto),
Web(WebCrypto, Uint8Array),
}
// JsValues are always per-thread, so we initialize RngSource for each thread.
// See: https://github.com/rustwasm/wasm-bindgen/pull/955
thread_local!(
static RNG_SOURCE: Result<RngSource, Error> = getrandom_init();
);
pub(crate) fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
RNG_SOURCE.with(|result| {
let source = result.as_ref().map_err(|&e| e)?;
match source {
RngSource::Node(n) => {
for chunk in dest.chunks_mut(NODE_MAX_BUFFER_SIZE) {
// SAFETY: chunk is never used directly, the memory is only
// modified via the Uint8Array view, which is passed
// directly to JavaScript. Also, crypto.randomFillSync does
// not resize the buffer. We know the length is less than
// u32::MAX because of the chunking above.
// Note that this uses the fact that JavaScript doesn't
// have a notion of "uninitialized memory", this is purely
// a Rust/C/C++ concept.
let res = n.random_fill_sync(unsafe {
Uint8Array::view_mut_raw(chunk.as_mut_ptr() as *mut u8, chunk.len())
});
if res.is_err() {
return Err(Error::NODE_RANDOM_FILL_SYNC);
}
}
}
RngSource::Web(crypto, buf) => {
// getRandomValues does not work with all types of WASM memory,
// so we initially write to browser memory to avoid exceptions.
for chunk in dest.chunks_mut(WEB_CRYPTO_BUFFER_SIZE) {
// The chunk can be smaller than buf's length, so we call to
// JS to create a smaller view of buf without allocation.
let sub_buf = buf.subarray(0, chunk.len() as u32);
if crypto.get_random_values(&sub_buf).is_err() {
return Err(Error::WEB_GET_RANDOM_VALUES);
}
// SAFETY: `sub_buf`'s length is the same length as `chunk`
unsafe { sub_buf.raw_copy_to_ptr(chunk.as_mut_ptr() as *mut u8) };
}
}
};
Ok(())
})
}
fn getrandom_init() -> Result<RngSource, Error> {
let global: Global = global().unchecked_into();
// Get the Web Crypto interface if we are in a browser, Web Worker, Deno,
// or another environment that supports the Web Cryptography API. This
// also allows for user-provided polyfills in unsupported environments.
let crypto = match global.crypto() {
// Standard Web Crypto interface
c if c.is_object() => c,
// Node.js CommonJS Crypto module
_ if is_node(&global) => {
// If module.require isn't a valid function, we are in an ES module.
match Module::require_fn().and_then(JsCast::dyn_into::<Function>) {
Ok(require_fn) => match require_fn.call1(&global, &JsValue::from_str("crypto")) {
Ok(n) => return Ok(RngSource::Node(n.unchecked_into())),
Err(_) => return Err(Error::NODE_CRYPTO),
},
Err(_) => return Err(Error::NODE_ES_MODULE),
}
}
// IE 11 Workaround
_ => match global.ms_crypto() {
c if c.is_object() => c,
_ => return Err(Error::WEB_CRYPTO),
},
};
let buf = Uint8Array::new_with_length(WEB_CRYPTO_BUFFER_SIZE as u32);
Ok(RngSource::Web(crypto, buf))
}
// Taken from https://www.npmjs.com/package/browser-or-node
fn is_node(global: &Global) -> bool {
let process = global.process();
if process.is_object() {
let versions = process.versions();
if versions.is_object() {
return versions.node().is_string();
}
}
false
}
#[wasm_bindgen]
extern "C" {
// Return type of js_sys::global()
type Global;
// Web Crypto API: Crypto interface (https://www.w3.org/TR/WebCryptoAPI/)
type WebCrypto;
// Getters for the WebCrypto API
#[wasm_bindgen(method, getter)]
fn crypto(this: &Global) -> WebCrypto;
#[wasm_bindgen(method, getter, js_name = msCrypto)]
fn ms_crypto(this: &Global) -> WebCrypto;
// Crypto.getRandomValues()
#[wasm_bindgen(method, js_name = getRandomValues, catch)]
fn get_random_values(this: &WebCrypto, buf: &Uint8Array) -> Result<(), JsValue>;
// Node JS crypto module (https://nodejs.org/api/crypto.html)
type NodeCrypto;
// crypto.randomFillSync()
#[wasm_bindgen(method, js_name = randomFillSync, catch)]
fn random_fill_sync(this: &NodeCrypto, buf: Uint8Array) -> Result<(), JsValue>;
// Ideally, we would just use `fn require(s: &str)` here. However, doing
// this causes a Webpack warning. So we instead return the function itself
// and manually invoke it using call1. This also lets us to check that the
// function actually exists, allowing for better error messages. See:
// https://github.com/rust-random/getrandom/issues/224
// https://github.com/rust-random/getrandom/issues/256
type Module;
#[wasm_bindgen(getter, static_method_of = Module, js_class = module, js_name = require, catch)]
fn require_fn() -> Result<JsValue, JsValue>;
// Node JS process Object (https://nodejs.org/api/process.html)
#[wasm_bindgen(method, getter)]
fn process(this: &Global) -> Process;
type Process;
#[wasm_bindgen(method, getter)]
fn versions(this: &Process) -> Versions;
type Versions;
#[wasm_bindgen(method, getter)]
fn node(this: &Versions) -> JsValue;
}

Some files were not shown because too many files have changed in this diff Show more