Skip to content

Commit

Permalink
Merge pull request #13146 from tklauser/filelock-x-sys-windows
Browse files Browse the repository at this point in the history
client/pkg/fileutil: use `golang.org/x/sys/windows` for `FileLockEx`
  • Loading branch information
ptabor authored Jul 1, 2021
2 parents 7271ade + c3fe63a commit 40da254
Showing 1 changed file with 8 additions and 36 deletions.
44 changes: 8 additions & 36 deletions client/pkg/fileutil/lock_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,18 @@ import (
"fmt"
"os"
"syscall"
"unsafe"
)

var (
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
procLockFileEx = modkernel32.NewProc("LockFileEx")

errLocked = errors.New("the process cannot access the file because another process has locked a portion of the file")
"golang.org/x/sys/windows"
)

const (
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx
LOCKFILE_EXCLUSIVE_LOCK = 2
LOCKFILE_FAIL_IMMEDIATELY = 1

// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
errLockViolation syscall.Errno = 0x21
)
var errLocked = errors.New("the process cannot access the file because another process has locked a portion of the file")

func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
f, err := open(path, flag, perm)
if err != nil {
return nil, err
}
if err := lockFile(syscall.Handle(f.Fd()), LOCKFILE_FAIL_IMMEDIATELY); err != nil {
if err := lockFile(windows.Handle(f.Fd()), windows.LOCKFILE_FAIL_IMMEDIATELY); err != nil {
f.Close()
return nil, err
}
Expand All @@ -58,7 +45,7 @@ func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
if err != nil {
return nil, err
}
if err := lockFile(syscall.Handle(f.Fd()), 0); err != nil {
if err := lockFile(windows.Handle(f.Fd()), 0); err != nil {
f.Close()
return nil, err
}
Expand Down Expand Up @@ -95,32 +82,17 @@ func open(path string, flag int, perm os.FileMode) (*os.File, error) {
return os.NewFile(uintptr(fd), path), nil
}

func lockFile(fd syscall.Handle, flags uint32) error {
var flag uint32 = LOCKFILE_EXCLUSIVE_LOCK
flag |= flags
if fd == syscall.InvalidHandle {
func lockFile(fd windows.Handle, flags uint32) error {
if fd == windows.InvalidHandle {
return nil
}
err := lockFileEx(fd, flag, 1, 0, &syscall.Overlapped{})
err := windows.LockFileEx(fd, flags|windows.LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &windows.Overlapped{})
if err == nil {
return nil
} else if err.Error() == errLocked.Error() {
return ErrLocked
} else if err != errLockViolation {
} else if err != windows.ERROR_LOCK_VIOLATION {
return err
}
return nil
}

func lockFileEx(h syscall.Handle, flags, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) {
var reserved uint32 = 0
r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(h), uintptr(flags), uintptr(reserved), uintptr(locklow), uintptr(lockhigh), uintptr(unsafe.Pointer(ol)))
if r1 == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return err
}

0 comments on commit 40da254

Please sign in to comment.