diff --git a/src/env/environment_impl.rs b/src/env/environment_impl.rs index ae2c26349..96b03e2af 100644 --- a/src/env/environment_impl.rs +++ b/src/env/environment_impl.rs @@ -8,6 +8,7 @@ use crate::flog::FLOG; use crate::global_safety::RelaxedAtomicBool; use crate::history::{history_session_id_from_var, History}; use crate::kill::kill_entries; +use crate::nix::umask; use crate::null_terminated_array::OwningNullTerminatedArray; use crate::reader::{commandline_get_state, reader_status_count}; use crate::threads::{is_forked_child, is_main_thread}; @@ -84,8 +85,7 @@ fn set_umask(list_val: &[WString]) -> EnvStackSetResult { return EnvStackSetResult::Invalid; } // Do not actually create a umask variable. On env_stack_t::get() it will be calculated. - // SAFETY: umask cannot fail. - unsafe { libc::umask(mask as libc::mode_t) }; + umask(mask as libc::mode_t); EnvStackSetResult::Ok } @@ -408,10 +408,9 @@ impl EnvScopedImpl { // value. Thus we have to call it twice, to reset the value. The env_lock protects // against races. Guess what the umask is; if we guess right we don't need to reset it. let guess: libc::mode_t = 0o022; - // Safety: umask cannot error. - let res: libc::mode_t = unsafe { libc::umask(guess) }; + let res: libc::mode_t = umask(guess); if res != guess { - unsafe { libc::umask(res) }; + umask(res); } Some(EnvVar::new_from_name(L!("umask"), sprintf!("0%0.3o", res))) } else { @@ -625,12 +624,12 @@ impl EnvScopedImpl { Self::get_exported(&self.globals, &mut vals); Self::get_exported(&self.locals, &mut vals); - let uni = uvars().get_names(true, false); - for key in uni { - let var = uvars().get(&key).unwrap(); - // Only insert if not already present, as uvars have lowest precedence. - // TODO: a longstanding bug is that an unexported local variable will not mask an exported uvar. - vals.entry(key).or_insert(var); + for (key, var) in uvars().get_table() { + if var.exports() { + // Only insert if not already present, as uvars have lowest precedence. + // TODO: a longstanding bug is that an unexported local variable will not mask an exported uvar. + vals.entry(key.clone()).or_insert(var.clone()); + } } // Dorky way to add our single exported computed variable. diff --git a/src/nix.rs b/src/nix.rs index 41687ba11..8c9a97d5c 100644 --- a/src/nix.rs +++ b/src/nix.rs @@ -3,6 +3,7 @@ use std::time::Duration; use crate::wutil::perror; +use libc::mode_t; #[allow(clippy::unnecessary_cast)] pub const fn timeval_to_duration(val: &libc::timeval) -> Duration { @@ -75,3 +76,7 @@ pub fn getrusage(resource: RUsage) -> libc::rusage { } } } + +pub fn umask(mask: mode_t) -> mode_t { + unsafe { libc::umask(mask) } +}