Repository: astral-sh/uv
File: crates/uv-fs/src/locked_file.rs (Rust)

Code before:
        #[allow(clippy::disallowed_types)]
        use std::{fs::File, os::unix::fs::PermissionsExt};
        use tempfile::NamedTempFile;

        #[allow(clippy::disallowed_types)]
        fn try_set_permissions(file: &File) {
            if let Err(err) = file.set_permissions(std::fs::Permissions::from_mode(0o666)) {
                warn!("Failed to set permissions on temporary file: {err}");
            }
        }

        // If path already exists, return it.
        if let Ok(file) = fs_err::OpenOptions::new()
            .read(true)
            .write(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`.
        let file = if let Some(parent) = path.as_ref().parent() {
            NamedTempFile::new_in(parent)
        } else {
            NamedTempFile::new()
        }
        .map_err(CreateLockedFileError::CreateTemporary)?;
        try_set_permissions(file.as_file());

        // Try to move the file to path, but if path exists now, just open path
        match file.persist_noclobber(path.as_ref()) {
            Ok(file) => Ok(fs_err::File::from_parts(file, path.as_ref())),
            Err(err) => {
                if err.error.kind() == std::io::ErrorKind::AlreadyExists {
                    fs_err::OpenOptions::new()
                        .read(true)
                        .write(true)
                        .open(path.as_ref())
                        .map_err(CreateLockedFileError::OpenExisting)
                } else if matches!(
                    Errno::from_io_error(&err.error),
                    Some(Errno::NOTSUP | Errno::INVAL)
                ) {
                    // Fallback in case `persist_noclobber`, which uses `renameat2` or
                    // `renameatx_np` under the hood, is not supported by the FS. Linux reports this
                    // with `EINVAL` and MacOS with `ENOTSUP`.

                    // There is a race here where another process has just created the file, and we
                    // try to open it and get permission errors because the other process hasn't set
                    // the permission bits yet. This will lead to a transient failure, but unlike

Review comment (suggestion):
You mentioned something about `io::ErrorKind` not capturing these, can you add a comment about this and potentially file an issue with rust-lang/rust? I looked for both NOTSUP and INVAL but found no results.

Code after:
            return Ok(file);
        }

        // Otherwise, create a temporary file with 666 permissions. We must set
        // permissions _after_ creating the file, to override the `umask`.
        let file = if let Some(parent) = path.as_ref().parent() {
            NamedTempFile::new_in(parent)
        } else {
            NamedTempFile::new()
        }
        .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()) {
            Ok(file) => Ok(fs_err::File::from_parts(file, path.as_ref())),
            Err(err) => {
                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!(
                    Errno::from_io_error(&err.error),
                    Some(Errno::NOTSUP | Errno::INVAL)
                ) {
                    // Fallback in case `persist_noclobber`, which uses `renameat2` or
                    // `renameatx_np` under the hood, is not supported by the FS. Linux reports this
                    // with `EINVAL` and MacOS with `ENOTSUP`. For these reasons and many others,
                    // there isn't an ErrorKind we can use here, and in fact on MacOS `ENOTSUP` gets
                    // mapped to `ErrorKind::Other`

                    // There is a race here where another process has just created the file, and we
                    // try to open it and get permission errors because the other process hasn't set
                    // the permission bits yet. This will lead to a transient failure, but unlike
                    // alternative approaches it won't ever lead to a situation where two processes
                    // 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)
                        .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