aboutsummaryrefslogtreecommitdiff
path: root/src/syscall
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2017-12-06 18:20:26 +0000
committerBrad Fitzpatrick <bradfitz@golang.org>2017-12-07 19:32:24 +0000
commit7c46b62d0a6e2353db68da963c390b094e359a92 (patch)
tree244f7f0deaa066c3ee65a3d8bc109f30e20ef7b7 /src/syscall
parent9ce6b5c2ed5d3d5251b9a6a0c548d5fb2c8567e8 (diff)
downloadgo-7c46b62d0a6e2353db68da963c390b094e359a92.tar.xz
syscall: make Seek use SetFilePointerEx on Windows, allowing large seek offsets
Fixes #21681 Updates #21728 Change-Id: I79cf4564c1355ecab891102d4215cbbffd8eb0ce Reviewed-on: https://go-review.googlesource.com/82535 Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/syscall')
-rw-r--r--src/syscall/syscall_windows.go30
1 files changed, 23 insertions, 7 deletions
diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go
index 21d5ecfcb3..9026fcdacf 100644
--- a/src/syscall/syscall_windows.go
+++ b/src/syscall/syscall_windows.go
@@ -332,6 +332,27 @@ func Write(fd Handle, p []byte) (n int, err error) {
var ioSync int64
+var procSetFilePointerEx = modkernel32.NewProc("SetFilePointerEx")
+
+const ptrSize = unsafe.Sizeof(uintptr(0))
+
+// setFilePointerEx calls SetFilePointerEx.
+// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365542(v=vs.85).aspx
+func setFilePointerEx(handle Handle, distToMove int64, newFilePointer *int64, whence uint32) error {
+ var e1 Errno
+ if ptrSize == 8 {
+ _, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 4, uintptr(handle), uintptr(distToMove), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence), 0, 0)
+ } else {
+ // distToMove is a LARGE_INTEGER:
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/aa383713(v=vs.85).aspx
+ _, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 5, uintptr(handle), uintptr(distToMove), uintptr(distToMove>>32), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence), 0)
+ }
+ if e1 != 0 {
+ return errnoErr(e1)
+ }
+ return nil
+}
+
func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) {
var w uint32
switch whence {
@@ -342,18 +363,13 @@ func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) {
case 2:
w = FILE_END
}
- hi := int32(offset >> 32)
- lo := int32(offset)
// use GetFileType to check pipe, pipe can't do seek
ft, _ := GetFileType(fd)
if ft == FILE_TYPE_PIPE {
return 0, ESPIPE
}
- rlo, e := SetFilePointer(fd, lo, &hi, w)
- if e != nil {
- return 0, e
- }
- return int64(hi)<<32 + int64(rlo), nil
+ err = setFilePointerEx(fd, offset, &newoffset, w)
+ return
}
func Close(fd Handle) (err error) {