This repository has been archived on 2026-08-16. You can view files and clone it, but cannot push or open issues or pull requests.
ollie-core/pkg/tools/execute/flock.go

57 lines
1.1 KiB
Go

package execute
import (
"os"
"path/filepath"
"strings"
"syscall"
)
// acquireFlock opens (or creates) a lock file in dir named name and acquires
// LOCK_SH (exclusive=false) or LOCK_EX (exclusive=true).
// Returns nil, nil when dir is empty (locking disabled).
// Caller must Close the returned file to release the lock.
func acquireFlock(dir, name string, exclusive bool) (*os.File, error) {
if dir == "" {
return nil, nil
}
if err := os.MkdirAll(dir, 0700); err != nil {
return nil, err
}
how := syscall.LOCK_SH
if exclusive {
how = syscall.LOCK_EX
}
path := filepath.Join(dir, sanitizeLockName(name)+".lock")
f, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0600)
if err != nil {
return nil, err
}
if err := syscall.Flock(int(f.Fd()), how); err != nil {
f.Close()
return nil, err
}
return f, nil
}
func sanitizeLockName(s string) string {
var b strings.Builder
for _, r := range s {
switch r {
case '/', '\\', ':', '*', '?', '<', '>', '|', '"', ' ':
b.WriteRune('_')
default:
b.WriteRune(r)
}
}
name := b.String()
if len(name) > 64 {
name = name[:64]
}
if name == "" {
return "unnamed"
}
return name
}