Maybe actually fix execvpe stuff
Some checks failed
/ check (push) Failing after 4m2s
/ dev-shell (push) Successful in 45s
/ rust-packages (push) Successful in 1m9s
/ terraform-providers (push) Successful in 52s
/ systems (push) Successful in 22m41s

This commit is contained in:
Kaare Hoff Skovgaard 2025-08-05 22:10:46 +02:00
parent 3ad3a21eed
commit 18651b63ed
Signed by: khs
GPG key ID: C7D890804F01E9F0

View file

@ -1,10 +1,7 @@
#[cfg(target_os = "linux")]
use nix::unistd::execvpe;
use std::{ use std::{
collections::{BTreeMap, BTreeSet}, collections::{BTreeMap, BTreeSet},
ffi::{CString, OsString}, ffi::{CString, OsString},
}; };
#[cfg(target_os = "macos")]
use std::{ use std::{
convert::Infallible, convert::Infallible,
ffi::{CStr, OsStr}, ffi::{CStr, OsStr},
@ -93,6 +90,34 @@ fn wrap_program(wrap_program: WrapProgram) -> anyhow::Result<()> {
Ok(()) Ok(())
} }
#[cfg(not(target_os = "macos"))]
/// Safety: No other threads may read or write environment variables when this function is called.
/// The easiest way to ensure this is using a single threaded program.
/// Note: On Linux specifically this safety requirement is not needed
unsafe fn execvpe<SA: AsRef<CStr>, SEK: AsRef<OsStr>, SEV: AsRef<OsStr>>(
filename: &CStr,
args: &[SA],
environ: &[(SEK, SEV)],
) -> anyhow::Result<Infallible> {
let environ = environ
.iter()
.map(|(k, v)| {
CString::new(format!(
"{k}={v}",
k = k.as_ref().display(),
v = v.as_ref().display()
))
.with_context(|| {
format!(
"Environment variable {k} contains null bytes",
k = k.as_ref().display()
)
})
})
.collect::<anyhow::Result<Vec<CString>>>()?;
Ok(nix::unistd::execvpe(filename, args, &environ)?)
}
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
/// Safety: No other threads may read or write environment variables when this function is called. /// Safety: No other threads may read or write environment variables when this function is called.
/// The easiest way to ensure this is using a single threaded program. /// The easiest way to ensure this is using a single threaded program.