1//! Environment variables 2use cfg_if::cfg_if; 3use std::fmt; 4 5/// Indicates that [`clearenv`] failed for some unknown reason 6#[derive(Clone, Copy, Debug)] 7pub struct ClearEnvError; 8 9impl fmt::Display for ClearEnvError { 10 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 11 write!(f, "clearenv failed") 12 } 13} 14 15impl std::error::Error for ClearEnvError {} 16 17/// Clear the environment of all name-value pairs. 18/// 19/// On platforms where libc provides `clearenv()`, it will be used. libc's 20/// `clearenv()` is documented to return an error code but not set errno; if the 21/// return value indicates a failure, this function will return 22/// [`ClearEnvError`]. 23/// 24/// On platforms where libc does not provide `clearenv()`, a fallback 25/// implementation will be used that iterates over all environment variables and 26/// removes them one-by-one. 27/// 28/// # Safety 29/// 30/// This function is not threadsafe and can cause undefined behavior in 31/// combination with `std::env` or other program components that access the 32/// environment. See, for example, the discussion on `std::env::remove_var`; this 33/// function is a case of an "inherently unsafe non-threadsafe API" dealing with 34/// the environment. 35/// 36/// The caller must ensure no other threads access the process environment while 37/// this function executes and that no raw pointers to an element of libc's 38/// `environ` is currently held. The latter is not an issue if the only other 39/// environment access in the program is via `std::env`, but the requirement on 40/// thread safety must still be upheld. 41pub unsafe fn clearenv() -> std::result::Result<(), ClearEnvError> { 42 cfg_if! { 43 if #[cfg(any(target_os = "fuchsia", 44 target_os = "wasi", 45 target_env = "uclibc", 46 target_os = "linux", 47 target_os = "android", 48 target_os = "emscripten"))] { 49 let ret = libc::clearenv(); 50 } else { 51 use std::env; 52 for (name, _) in env::vars_os() { 53 env::remove_var(name); 54 } 55 let ret = 0; 56 } 57 } 58 59 if ret == 0 { 60 Ok(()) 61 } else { 62 Err(ClearEnvError) 63 } 64} 65