diff options
| author | bors <bors@rust-lang.org> | 2022-08-01 06:44:43 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-08-01 06:44:43 +0000 |
| commit | 1f5d8d49eb6111931091f700d07518cd2b80bc18 (patch) | |
| tree | 82ad9931fc0f0bcb4e4cbdac234cea0c74858607 /library/std/src/sys/windows | |
| parent | 25bb1c13bd472b75ceebee3b8dcf4dcbc431a8be (diff) | |
| parent | f8061ddb03f6b07108b0d041742f4faf0b3d5339 (diff) | |
| download | rust-1f5d8d49eb6111931091f700d07518cd2b80bc18.tar.gz rust-1f5d8d49eb6111931091f700d07518cd2b80bc18.zip | |
Auto merge of #98246 - joshtriplett:times, r=m-ou-se
Support setting file accessed/modified timestamps Add `struct FileTimes` to contain the relevant file timestamps, since most platforms require setting all of them at once. (This also allows for future platform-specific extensions such as setting creation time.) Add `File::set_file_time` to set the timestamps for a `File`. Implement the `sys` backends for UNIX, macOS (which needs to fall back to `futimes` before macOS 10.13 because it lacks `futimens`), Windows, and WASI.
Diffstat (limited to 'library/std/src/sys/windows')
| -rw-r--r-- | library/std/src/sys/windows/c.rs | 8 | ||||
| -rw-r--r-- | library/std/src/sys/windows/fs.rs | 31 | ||||
| -rw-r--r-- | library/std/src/sys/windows/time.rs | 7 |
3 files changed, 45 insertions, 1 deletions
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index e9c20850420..478068c73ba 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -620,7 +620,7 @@ pub struct SOCKADDR { } #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug, Default)] pub struct FILETIME { pub dwLowDateTime: DWORD, pub dwHighDateTime: DWORD, @@ -888,6 +888,12 @@ extern "system" { pub fn GetSystemDirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT; pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL; pub fn SetFileAttributesW(lpFileName: LPCWSTR, dwFileAttributes: DWORD) -> BOOL; + pub fn SetFileTime( + hFile: BorrowedHandle<'_>, + lpCreationTime: Option<&FILETIME>, + lpLastAccessTime: Option<&FILETIME>, + lpLastWriteTime: Option<&FILETIME>, + ) -> BOOL; pub fn SetLastError(dwErrCode: DWORD); pub fn GetCommandLineW() -> LPWSTR; pub fn GetTempPathW(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD; diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index c96bcf41d51..aed082b3e0a 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -83,6 +83,12 @@ pub struct FilePermissions { attrs: c::DWORD, } +#[derive(Copy, Clone, Debug, Default)] +pub struct FileTimes { + accessed: Option<c::FILETIME>, + modified: Option<c::FILETIME>, +} + #[derive(Debug)] pub struct DirBuilder; @@ -536,6 +542,21 @@ impl File { })?; Ok(()) } + + pub fn set_times(&self, times: FileTimes) -> io::Result<()> { + let is_zero = |t: c::FILETIME| t.dwLowDateTime == 0 && t.dwHighDateTime == 0; + if times.accessed.map_or(false, is_zero) || times.modified.map_or(false, is_zero) { + return Err(io::const_io_error!( + io::ErrorKind::InvalidInput, + "Cannot set file timestamp to 0", + )); + } + cvt(unsafe { + c::SetFileTime(self.as_handle(), None, times.accessed.as_ref(), times.modified.as_ref()) + })?; + Ok(()) + } + /// Get only basic file information such as attributes and file times. fn basic_info(&self) -> io::Result<c::FILE_BASIC_INFO> { unsafe { @@ -903,6 +924,16 @@ impl FilePermissions { } } +impl FileTimes { + pub fn set_accessed(&mut self, t: SystemTime) { + self.accessed = Some(t.into_inner()); + } + + pub fn set_modified(&mut self, t: SystemTime) { + self.modified = Some(t.into_inner()); + } +} + impl FileType { fn new(attrs: c::DWORD, reparse_tag: c::DWORD) -> FileType { FileType { attributes: attrs, reparse_tag } diff --git a/library/std/src/sys/windows/time.rs b/library/std/src/sys/windows/time.rs index 8f46781c753..b8209a85445 100644 --- a/library/std/src/sys/windows/time.rs +++ b/library/std/src/sys/windows/time.rs @@ -2,6 +2,7 @@ use crate::cmp::Ordering; use crate::fmt; use crate::mem; use crate::sys::c; +use crate::sys_common::IntoInner; use crate::time::Duration; use core::hash::{Hash, Hasher}; @@ -136,6 +137,12 @@ impl From<c::FILETIME> for SystemTime { } } +impl IntoInner<c::FILETIME> for SystemTime { + fn into_inner(self) -> c::FILETIME { + self.t + } +} + impl Hash for SystemTime { fn hash<H: Hasher>(&self, state: &mut H) { self.intervals().hash(state) |
