diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/nix/src/env.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/nix/src/env.rs')
-rw-r--r-- | third_party/rust/nix/src/env.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/third_party/rust/nix/src/env.rs b/third_party/rust/nix/src/env.rs new file mode 100644 index 0000000000..95177a1d2a --- /dev/null +++ b/third_party/rust/nix/src/env.rs @@ -0,0 +1,64 @@ +//! Environment variables +use cfg_if::cfg_if; +use std::fmt; + +/// Indicates that [`clearenv`] failed for some unknown reason +#[derive(Clone, Copy, Debug)] +pub struct ClearEnvError; + +impl fmt::Display for ClearEnvError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "clearenv failed") + } +} + +impl std::error::Error for ClearEnvError {} + +/// Clear the environment of all name-value pairs. +/// +/// On platforms where libc provides `clearenv()`, it will be used. libc's +/// `clearenv()` is documented to return an error code but not set errno; if the +/// return value indicates a failure, this function will return +/// [`ClearEnvError`]. +/// +/// On platforms where libc does not provide `clearenv()`, a fallback +/// implementation will be used that iterates over all environment variables and +/// removes them one-by-one. +/// +/// # Safety +/// +/// This function is not threadsafe and can cause undefined behavior in +/// combination with `std::env` or other program components that access the +/// environment. See, for example, the discussion on `std::env::remove_var`; this +/// function is a case of an "inherently unsafe non-threadsafe API" dealing with +/// the environment. +/// +/// The caller must ensure no other threads access the process environment while +/// this function executes and that no raw pointers to an element of libc's +/// `environ` is currently held. The latter is not an issue if the only other +/// environment access in the program is via `std::env`, but the requirement on +/// thread safety must still be upheld. +pub unsafe fn clearenv() -> std::result::Result<(), ClearEnvError> { + cfg_if! { + if #[cfg(any(target_os = "fuchsia", + target_os = "wasi", + target_env = "uclibc", + target_os = "linux", + target_os = "android", + target_os = "emscripten"))] { + let ret = libc::clearenv(); + } else { + use std::env; + for (name, _) in env::vars_os() { + env::remove_var(name); + } + let ret = 0; + } + } + + if ret == 0 { + Ok(()) + } else { + Err(ClearEnvError) + } +} |