diff --git a/src/uucore/src/lib/features.rs b/src/uucore/src/lib/features.rs index 42d8ffbe7..546cbea87 100644 --- a/src/uucore/src/lib/features.rs +++ b/src/uucore/src/lib/features.rs @@ -10,7 +10,7 @@ pub mod fsext; pub mod ringbuffer; // * (platform-specific) feature-gated modules -// ** non-windows +// ** non-windows (i.e. Unix + Fuchsia) #[cfg(all(not(windows), feature = "mode"))] pub mod mode; diff --git a/src/uucore/src/lib/features/mode.rs b/src/uucore/src/lib/features/mode.rs index 02e78ba9b..72083e799 100644 --- a/src/uucore/src/lib/features/mode.rs +++ b/src/uucore/src/lib/features/mode.rs @@ -143,6 +143,13 @@ pub fn parse_mode(mode: &str) -> Result { } pub fn get_umask() -> u32 { + // There's no portable way to read the umask without changing it. + // We have to replace it and then quickly set it back, hopefully before + // some other thread is affected. + // On modern Linux kernels the current umask could instead be read + // from /proc/self/status. But that's a lot of work. + // SAFETY: umask always succeeds and doesn't operate on memory. Races are + // possible but it can't violate Rust's guarantees. let mask = unsafe { umask(0) }; unsafe { umask(mask) }; mask as u32 diff --git a/src/uucore/src/lib/lib.rs b/src/uucore/src/lib/lib.rs index 79cc2afc3..3d2d867bd 100644 --- a/src/uucore/src/lib/lib.rs +++ b/src/uucore/src/lib/lib.rs @@ -41,7 +41,7 @@ pub use crate::features::fsext; pub use crate::features::ringbuffer; // * (platform-specific) feature-gated modules -// ** non-windows +// ** non-windows (i.e. Unix + Fuchsia) #[cfg(all(not(windows), feature = "mode"))] pub use crate::features::mode; // ** unix-only