[Pre-RFC / ACP (?)] Windows freeze file times

I'm not sure if it's supposed to be a RFC or an ACP...

Problem

On Windows you can use SetFileTime to prevent the time metadata (last access and last write) of a file to being modified when access is made on the file by passing 0xFFFFFFFF to revelent parameters. To being effective this call must be made just after the file handler is created and before any access is made on this handler. The problem is that the standard library is performing a manual truncation when we have truncate(true):

Which result in following code to not work as expected:

let mut file = File::create(path)?; // use truncate
freeze_file_time(&file)?;
file.write_all(b"Hello")?;
freeze_file_time
fn freeze_file_time<T>(file: &T) -> io::Result<()>
where
    T: AsRawHandle + ?Sized,
{
    let filetime = FILETIME {
        dwLowDateTime: 0xFFFFFFFF,
        dwHighDateTime: 0xFFFFFFFF,
    };

    let result = unsafe {
        SetFileTime(
            file.as_raw_handle(),
            core::ptr::null(),
            &filetime,
            &filetime,
        )
    };

    if result == 0 {
        Err(io::Error::last_os_error())
    } else {
        Ok(())
    }
}

Expected solution

I don't know if there is equivalent API on others OS for this, but for Windows we can use OpenOptionsExt in std::os::windows::fs - Rust to add two new flags:freeze_last_access_time and freeze_last_write_time (names bikesheddable). When one or the other is enabled, just after the call to CreateFileW, a call to SetFileTime is made to freeze the file times.

Workaround

It is still possible to workaround the problem by opening the file with truncate(false), call freeze_file_time, then call file.set_len(0). But it less ergonomic.

1 Like

Seems like a reasonable Windows-specific addition. Please do file an ACP.

ACP posted: Freeze file times on Windows · Issue #708 · rust-lang/libs-team · GitHub

1 Like