mirror of
https://github.com/golang/go
synced 2024-11-22 03:24:41 -07:00
syscall: implement windows version of Utimes()
R=golang-dev, r CC=golang-dev https://golang.org/cl/2215044
This commit is contained in:
parent
105c9136b8
commit
c10865ce53
@ -39,8 +39,8 @@ func setFileInfo(fi *FileInfo, name string, fa, sizehi, sizelo uint32, ctime, at
|
||||
fi.Size = int64(sizehi)<<32 + int64(sizelo)
|
||||
fi.Name = name
|
||||
fi.FollowedSymlink = false
|
||||
fi.Atime_ns = atime.Microseconds() * 1000
|
||||
fi.Mtime_ns = wtime.Microseconds() * 1000
|
||||
fi.Ctime_ns = ctime.Microseconds() * 1000
|
||||
fi.Atime_ns = atime.Nanoseconds()
|
||||
fi.Mtime_ns = wtime.Nanoseconds()
|
||||
fi.Ctime_ns = ctime.Nanoseconds()
|
||||
return fi
|
||||
}
|
||||
|
@ -70,12 +70,6 @@ func UTF16ToString(s []uint16) string {
|
||||
// the UTF-8 string s, with a terminating NUL added.
|
||||
func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] }
|
||||
|
||||
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||
tv.Sec = int32(nsec / 1e9)
|
||||
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||
return
|
||||
}
|
||||
|
||||
// dll helpers
|
||||
|
||||
// implemented in ../pkg/runtime/windows/syscall.cgo
|
||||
@ -147,6 +141,7 @@ func getSysProcAddr(m uint32, pname string) uintptr {
|
||||
//sys FreeEnvironmentStrings(envs *uint16) (ok bool, errno int) = kernel32.FreeEnvironmentStringsW
|
||||
//sys GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, errno int) = kernel32.GetEnvironmentVariableW
|
||||
//sys SetEnvironmentVariable(name *uint16, value *uint16) (ok bool, errno int) = kernel32.SetEnvironmentVariableW
|
||||
//sys SetFileTime(handle int32, ctime *Filetime, atime *Filetime, wtime *Filetime) (ok bool, errno int)
|
||||
|
||||
// syscall interface implementation for other packages
|
||||
|
||||
@ -394,10 +389,7 @@ func Ftruncate(fd int, length int64) (errno int) {
|
||||
func Gettimeofday(tv *Timeval) (errno int) {
|
||||
var ft Filetime
|
||||
GetSystemTimeAsFileTime(&ft)
|
||||
ms := ft.Microseconds()
|
||||
// split into sec / usec
|
||||
tv.Sec = int32(ms / 1e6)
|
||||
tv.Usec = int32(ms) - tv.Sec*1e6
|
||||
*tv = NsecToTimeval(ft.Nanoseconds())
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -419,9 +411,23 @@ func Pipe(p []int) (errno int) {
|
||||
return 0
|
||||
}
|
||||
|
||||
// TODO(brainman): implement Utimes, or rewrite os.file.Chtimes() instead
|
||||
func Utimes(path string, tv []Timeval) (errno int) {
|
||||
return EWINDOWS
|
||||
if len(tv) != 2 {
|
||||
return EINVAL
|
||||
}
|
||||
h, e := CreateFile(StringToUTF16Ptr(path),
|
||||
FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
|
||||
if e != 0 {
|
||||
return e
|
||||
}
|
||||
defer Close(int(h))
|
||||
a := NsecToFiletime(tv[0].Nanoseconds())
|
||||
w := NsecToFiletime(tv[1].Nanoseconds())
|
||||
if ok, e := SetFileTime(h, nil, &a, &w); !ok {
|
||||
return e
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// net api calls
|
||||
|
@ -57,6 +57,7 @@ var (
|
||||
procFreeEnvironmentStringsW = getSysProcAddr(modkernel32, "FreeEnvironmentStringsW")
|
||||
procGetEnvironmentVariableW = getSysProcAddr(modkernel32, "GetEnvironmentVariableW")
|
||||
procSetEnvironmentVariableW = getSysProcAddr(modkernel32, "SetEnvironmentVariableW")
|
||||
procSetFileTime = getSysProcAddr(modkernel32, "SetFileTime")
|
||||
procWSAStartup = getSysProcAddr(modwsock32, "WSAStartup")
|
||||
procWSACleanup = getSysProcAddr(modwsock32, "WSACleanup")
|
||||
procsocket = getSysProcAddr(modwsock32, "socket")
|
||||
@ -738,6 +739,21 @@ func SetEnvironmentVariable(name *uint16, value *uint16) (ok bool, errno int) {
|
||||
return
|
||||
}
|
||||
|
||||
func SetFileTime(handle int32, ctime *Filetime, atime *Filetime, wtime *Filetime) (ok bool, errno int) {
|
||||
r0, _, e1 := Syscall6(procSetFileTime, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0)
|
||||
ok = bool(r0 != 0)
|
||||
if !ok {
|
||||
if e1 != 0 {
|
||||
errno = int(e1)
|
||||
} else {
|
||||
errno = EINVAL
|
||||
}
|
||||
} else {
|
||||
errno = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func WSAStartup(verreq uint32, data *WSAData) (sockerrno int) {
|
||||
r0, _, _ := Syscall(procWSAStartup, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
|
||||
sockerrno = int(r0)
|
||||
|
@ -57,6 +57,7 @@ const (
|
||||
GENERIC_ALL = 0x10000000
|
||||
|
||||
FILE_APPEND_DATA = 0x00000004
|
||||
FILE_WRITE_ATTRIBUTES = 0x00000100
|
||||
|
||||
FILE_SHARE_READ = 0x00000001
|
||||
FILE_SHARE_WRITE = 0x00000002
|
||||
@ -155,6 +156,16 @@ type Timeval struct {
|
||||
Usec int32
|
||||
}
|
||||
|
||||
func (tv *Timeval) Nanoseconds() int64 {
|
||||
return (int64(tv.Sec)*1e6 + int64(tv.Usec)) * 1e3
|
||||
}
|
||||
|
||||
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||
tv.Sec = int32(nsec / 1e9)
|
||||
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||
return
|
||||
}
|
||||
|
||||
type Overlapped struct {
|
||||
Internal uint32
|
||||
InternalHigh uint32
|
||||
@ -168,14 +179,25 @@ type Filetime struct {
|
||||
HighDateTime uint32
|
||||
}
|
||||
|
||||
func (ft *Filetime) Microseconds() int64 {
|
||||
func (ft *Filetime) Nanoseconds() int64 {
|
||||
// 100-nanosecond intervals since January 1, 1601
|
||||
ms := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime)
|
||||
// convert into microseconds
|
||||
ms /= 10
|
||||
nsec := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime)
|
||||
// change starting time to the Epoch (00:00:00 UTC, January 1, 1970)
|
||||
ms -= 11644473600000000
|
||||
return ms
|
||||
nsec -= 116444736000000000
|
||||
// convert into nanoseconds
|
||||
nsec *= 100
|
||||
return nsec
|
||||
}
|
||||
|
||||
func NsecToFiletime(nsec int64) (ft Filetime) {
|
||||
// convert into 100-nanosecond
|
||||
nsec /= 100
|
||||
// change starting time to January 1, 1601
|
||||
nsec += 116444736000000000
|
||||
// split into high / low
|
||||
ft.LowDateTime = uint32(nsec & 0xffffffff)
|
||||
ft.HighDateTime = uint32(nsec >> 32 & 0xffffffff)
|
||||
return ft
|
||||
}
|
||||
|
||||
type Win32finddata struct {
|
||||
|
Loading…
Reference in New Issue
Block a user