diff --git a/crates/uv-fs/src/locked_file.rs b/crates/uv-fs/src/locked_file.rs index c85c5e5d0ecc8..42be71114c887 100644 --- a/crates/uv-fs/src/locked_file.rs +++ b/crates/uv-fs/src/locked_file.rs @@ -234,42 +234,26 @@ impl LockedFile { #[cfg(unix)] fn create(path: impl AsRef) -> Result { + use fs_err::os::unix::fs::OpenOptionsExt; use rustix::io::Errno; - #[expect(clippy::disallowed_types)] - use std::{fs::File, os::unix::fs::PermissionsExt}; - use tempfile::NamedTempFile; + use std::{fs::Permissions, os::unix::fs::PermissionsExt}; + use tempfile::Builder; - /// The permissions the lockfile should end up with - const DESIRED_MODE: u32 = 0o666; + const DESIRED_MODE: u32 = 0o444; - #[expect(clippy::disallowed_types)] - fn try_set_permissions(file: &File, path: &Path) { - if let Err(err) = file.set_permissions(std::fs::Permissions::from_mode(DESIRED_MODE)) { - warn!( - "Failed to set permissions on temporary file `{path}`: {err}", - path = path.user_display() - ); - } - } - - // If path already exists, return it. - if let Ok(file) = fs_err::OpenOptions::new() - .read(true) - .write(true) - .open(path.as_ref()) - { + // If path already exists (and we can read it), return it. + if let Ok(file) = fs_err::OpenOptions::new().read(true).open(path.as_ref()) { return Ok(file); } - // Otherwise, create a temporary file with 666 permissions. We must set - // permissions _after_ creating the file, to override the `umask`. + // Otherwise, create a temporary file with DESIRED_MODE in the same directory as path. + let perms = Permissions::from_mode(DESIRED_MODE); let file = if let Some(parent) = path.as_ref().parent() { - NamedTempFile::new_in(parent) + Builder::new().permissions(perms).tempfile_in(parent) } else { - NamedTempFile::new() + Builder::new().permissions(perms).tempfile() } .map_err(LockedFileError::CreateTemporary)?; - try_set_permissions(file.as_file(), file.path()); // Try to move the file to path, but if path exists now, just open path match file.persist_noclobber(path.as_ref()) { @@ -278,7 +262,6 @@ impl LockedFile { if err.error.kind() == std::io::ErrorKind::AlreadyExists { fs_err::OpenOptions::new() .read(true) - .write(true) .open(path.as_ref()) .map_err(Into::into) } else if matches!( @@ -298,22 +281,13 @@ impl LockedFile { // are locking two different files. Also, since `persist_noclobber` is more // likely to not be supported on special filesystems which don't have permission // bits, it's less likely to ever matter. + let file = fs_err::OpenOptions::new() .read(true) - .write(true) + .mode(DESIRED_MODE) .create(true) .open(path.as_ref())?; - // We don't want to `try_set_permissions` in cases where another user's process - // has already created the lockfile and changed its permissions because we might - // not have permission to change the permissions which would produce a confusing - // warning. - if file - .metadata() - .is_ok_and(|metadata| metadata.permissions().mode() != DESIRED_MODE) - { - try_set_permissions(file.file(), path.as_ref()); - } Ok(file) } else { let temp_path = err.file.into_temp_path();