Add vault locking and a cross-platform build script
Commands that change the vault hold an exclusive lock on DIR/.lock and readers hold a shared one, taken after the passphrase prompt. A blocked process says it is waiting. Unix uses fcntl locks and Windows uses LockFileEx, both released by the OS if the process dies. Plan 9 and WebAssembly fall back to an exclusive lock file. build.sh cross-compiles static binaries for every Go target that builds without cgo (43 today, armv6 and armv7 for 32-bit ARM Linux) and writes SHA256SUMS.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
// Copyright 2026 The vault Authors.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
//go:build unix
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// acquireLock uses fcntl record locks, which the kernel releases if the
|
||||
// process dies, and which also work on NFS.
|
||||
func acquireLock(path string, exclusive bool, waiting func()) (func(), error) {
|
||||
f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0o600)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lk := unix.Flock_t{Type: unix.F_RDLCK, Whence: io.SeekStart}
|
||||
if exclusive {
|
||||
lk.Type = unix.F_WRLCK
|
||||
}
|
||||
err = unix.FcntlFlock(f.Fd(), unix.F_SETLK, &lk)
|
||||
if errors.Is(err, unix.EAGAIN) || errors.Is(err, unix.EACCES) {
|
||||
waiting()
|
||||
for err = unix.EINTR; errors.Is(err, unix.EINTR); {
|
||||
err = unix.FcntlFlock(f.Fd(), unix.F_SETLKW, &lk)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
f.Close()
|
||||
return nil, err
|
||||
}
|
||||
return func() { f.Close() }, nil
|
||||
}
|
||||
Reference in New Issue
Block a user