os, syscall: permit setting mtime to Unix 0 on Windows

This edge case was accidentally broken by CL 219638.

Change-Id: I673b3b580fbe379a04f8650cf5969fe9bce83691
Reviewed-on: https://go-review.googlesource.com/c/go/+/495036
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
This commit is contained in:
Ian Lance Taylor 2023-05-15 13:53:21 -07:00 committed by Gopher Robot
parent 7213f2e720
commit 5f345e8eb9
3 changed files with 33 additions and 3 deletions

View file

@ -14,7 +14,8 @@ import (
"unsafe"
)
const _UTIME_OMIT = 0
// This matches the value in syscall/syscall_windows.go.
const _UTIME_OMIT = -1
// file is the real representation of *File.
// The extra level of indirection ensures that no clients of os

View file

@ -1568,6 +1568,32 @@ func testChtimes(t *testing.T, name string) {
}
}
func TestChtimesToUnixZero(t *testing.T) {
file := newFile("chtimes-to-unix-zero", t)
fn := file.Name()
defer Remove(fn)
if _, err := file.Write([]byte("hi")); err != nil {
t.Fatal(err)
}
if err := file.Close(); err != nil {
t.Fatal(err)
}
unixZero := time.Unix(0, 0)
if err := Chtimes(fn, unixZero, unixZero); err != nil {
t.Fatalf("Chtimes failed: %v", err)
}
st, err := Stat(fn)
if err != nil {
t.Fatal(err)
}
if mt := st.ModTime(); mt != unixZero {
t.Errorf("mtime is %v, want %v", mt, unixZero)
}
}
func TestFileChdir(t *testing.T) {
wd, err := Getwd()
if err != nil {

View file

@ -658,6 +658,9 @@ func Utimes(path string, tv []Timeval) (err error) {
return SetFileTime(h, nil, &a, &w)
}
// This matches the value in os/file_windows.go.
const _UTIME_OMIT = -1
func UtimesNano(path string, ts []Timespec) (err error) {
if len(ts) != 2 {
return EINVAL
@ -675,10 +678,10 @@ func UtimesNano(path string, ts []Timespec) (err error) {
defer Close(h)
a := Filetime{}
w := Filetime{}
if TimespecToNsec(ts[0]) != 0 {
if ts[0].Nsec != _UTIME_OMIT {
a = NsecToFiletime(TimespecToNsec(ts[0]))
}
if TimespecToNsec(ts[1]) != 0 {
if ts[1].Nsec != _UTIME_OMIT {
w = NsecToFiletime(TimespecToNsec(ts[1]))
}
return SetFileTime(h, nil, &a, &w)