aboutsummaryrefslogtreecommitdiff
path: root/internal/lockedfile/internal/filelock/filelock_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/lockedfile/internal/filelock/filelock_windows.go')
-rw-r--r--internal/lockedfile/internal/filelock/filelock_windows.go67
1 files changed, 67 insertions, 0 deletions
diff --git a/internal/lockedfile/internal/filelock/filelock_windows.go b/internal/lockedfile/internal/filelock/filelock_windows.go
new file mode 100644
index 000000000..3273a8182
--- /dev/null
+++ b/internal/lockedfile/internal/filelock/filelock_windows.go
@@ -0,0 +1,67 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build windows
+// +build windows
+
+package filelock
+
+import (
+ "io/fs"
+
+ "golang.org/x/sys/windows"
+)
+
+type lockType uint32
+
+const (
+ readLock lockType = 0
+ writeLock lockType = windows.LOCKFILE_EXCLUSIVE_LOCK
+)
+
+const (
+ reserved = 0
+ allBytes = ^uint32(0)
+)
+
+func lock(f File, lt lockType) error {
+ // Per https://golang.org/issue/19098, “Programs currently expect the Fd
+ // method to return a handle that uses ordinary synchronous I/O.”
+ // However, LockFileEx still requires an OVERLAPPED structure,
+ // which contains the file offset of the beginning of the lock range.
+ // We want to lock the entire file, so we leave the offset as zero.
+ ol := new(windows.Overlapped)
+
+ err := windows.LockFileEx(windows.Handle(f.Fd()), uint32(lt), reserved, allBytes, allBytes, ol)
+ if err != nil {
+ return &fs.PathError{
+ Op: lt.String(),
+ Path: f.Name(),
+ Err: err,
+ }
+ }
+ return nil
+}
+
+func unlock(f File) error {
+ ol := new(windows.Overlapped)
+ err := windows.UnlockFileEx(windows.Handle(f.Fd()), reserved, allBytes, allBytes, ol)
+ if err != nil {
+ return &fs.PathError{
+ Op: "Unlock",
+ Path: f.Name(),
+ Err: err,
+ }
+ }
+ return nil
+}
+
+func isNotSupported(err error) bool {
+ switch err {
+ case windows.ERROR_NOT_SUPPORTED, windows.ERROR_CALL_NOT_IMPLEMENTED, ErrNotSupported:
+ return true
+ default:
+ return false
+ }
+}