| //! 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) | |
| } | |
| } |