1//go:build windows
2
3package cmd
4
5import (
6 "fmt"
7 "math"
8 "os"
9
10 "golang.org/x/sys/windows"
11)
12
13// acquireSpawnLock takes an exclusive lock on the given file (creating
14// it if necessary) using LockFileEx, and returns a release function
15// that unlocks and closes the file. Blocks until the lock is acquired.
16func acquireSpawnLock(path string) (func(), error) {
17 f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0o600)
18 if err != nil {
19 return nil, fmt.Errorf("open spawn lock %q: %v", path, err)
20 }
21 h := windows.Handle(f.Fd())
22 ol := new(windows.Overlapped)
23 if err := windows.LockFileEx(h, windows.LOCKFILE_EXCLUSIVE_LOCK, 0, math.MaxUint32, math.MaxUint32, ol); err != nil {
24 _ = f.Close()
25 return nil, fmt.Errorf("LockFileEx spawn lock %q: %v", path, err)
26 }
27 return func() {
28 ol := new(windows.Overlapped)
29 _ = windows.UnlockFileEx(windows.Handle(f.Fd()), 0, math.MaxUint32, math.MaxUint32, ol)
30 _ = f.Close()
31 }, nil
32}