| // 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 |
| } |
| } |