Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1185: Provide clearenv() r=asomers a=jgallagher Maybe closes #481. "Maybe" for a couple reasons that are discussed on that issue: * The issue mentions adding the other environment-variable-related functions (`setenv`, `getenv`, etc.), but I omitted those because they're already covered by `std::env` AFAICT, plus they're wildly unthreadsafe. It looks like `std::env` avoids the thread unsafety via a library-level lock and a warning to be careful when using ffi functions that might modify the environment concurrently. * I opted to return `Error::UnsupportedOperation` in the (impossible?) case of `libc::clearenv()` returning non-zero instead of having the function return a `Result<(), ()>`. The latter seems like it would be onerous (since every other possibly-failing function in nix returns a `nix::Result`), but if you'd prefer a different error return I'm not going to put up any argument. Co-authored-by: John Gallagher <jgallagher@bignerdranch.com>
- Loading branch information
Showing
5 changed files
with
73 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
use {Error, Result}; | ||
|
||
/// 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 | ||
/// `Error::UnsupportedOperation`. | ||
/// | ||
/// 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() -> Result<()> { | ||
let ret; | ||
cfg_if! { | ||
if #[cfg(any(target_os = "fuchsia", | ||
target_os = "wasi", | ||
target_env = "wasi", | ||
target_env = "uclibc", | ||
target_os = "linux", | ||
target_os = "android", | ||
target_os = "emscripten"))] { | ||
ret = libc::clearenv(); | ||
} else { | ||
use std::env; | ||
for (name, _) in env::vars_os() { | ||
env::remove_var(name); | ||
} | ||
ret = 0; | ||
} | ||
} | ||
|
||
if ret == 0 { | ||
Ok(()) | ||
} else { | ||
Err(Error::UnsupportedOperation) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
extern crate nix; | ||
|
||
use std::env; | ||
|
||
#[test] | ||
fn clearenv() { | ||
env::set_var("FOO", "BAR"); | ||
unsafe { nix::env::clearenv() }.unwrap(); | ||
assert_eq!(env::var("FOO").unwrap_err(), env::VarError::NotPresent); | ||
assert_eq!(env::vars().count(), 0); | ||
} |