diff options
| author | Ophestra <cat@gensokyo.uk> | 2026-10-13 20:57:16 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2026-10-13 20:57:16 +0900 |
| commit | 9e95987536f895ef1a989fcd9e69ab84a1b94a17 (patch) | |
| tree | 304aec06573103329df9caf3adea58d1b7025700 /internal/lockedfile | |
| parent | 0abf367b1334b76f5e8f989cf0c07b5d00b25868 (diff) | |
internal/lockedfile: optionally force write lock
For acquiring a write lock on a directory.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/lockedfile')
| -rw-r--r-- | internal/lockedfile/lockedfile.go | 19 | ||||
| -rw-r--r-- | internal/lockedfile/lockedfile_filelock.go | 6 | ||||
| -rw-r--r-- | internal/lockedfile/lockedfile_plan9.go | 2 |
3 files changed, 20 insertions, 7 deletions
diff --git a/internal/lockedfile/lockedfile.go b/internal/lockedfile/lockedfile.go index f48124ff..c7baff60 100644 --- a/internal/lockedfile/lockedfile.go +++ b/internal/lockedfile/lockedfile.go @@ -34,15 +34,12 @@ type osFile struct { *os.File } -// OpenFile is like os.OpenFile, but returns a locked file. -// If flag includes os.O_WRONLY or os.O_RDWR, the file is write-locked; -// otherwise, it is read-locked. -func OpenFile(name string, flag int, perm fs.FileMode) (*File, error) { +func openFile(name string, flag int, perm fs.FileMode, w bool) (*File, error) { var ( f = new(File) err error ) - f.osFile.File, err = openFile(name, flag, perm) + f.osFile.File, err = osOpenFile(name, flag, perm, w) if err != nil { return nil, err } @@ -59,11 +56,23 @@ func OpenFile(name string, flag int, perm fs.FileMode) (*File, error) { return f, nil } +// OpenFile is like os.OpenFile, but returns a locked file. +// If flag includes os.O_WRONLY or os.O_RDWR, the file is write-locked; +// otherwise, it is read-locked. +func OpenFile(name string, flag int, perm fs.FileMode) (*File, error) { + return openFile(name, flag, perm, false) +} + // Open is like os.Open, but returns a read-locked file. func Open(name string) (*File, error) { return OpenFile(name, os.O_RDONLY, 0) } +// OpenDir is like Open, but returns a write-locked directory. +func OpenDir(name string) (*File, error) { + return openFile(name, os.O_RDONLY, 0, true) +} + // Create is like os.Create, but returns a write-locked file. func Create(name string) (*File, error) { return OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) diff --git a/internal/lockedfile/lockedfile_filelock.go b/internal/lockedfile/lockedfile_filelock.go index 9fc16a9b..1f5ca310 100644 --- a/internal/lockedfile/lockedfile_filelock.go +++ b/internal/lockedfile/lockedfile_filelock.go @@ -13,7 +13,7 @@ import ( "hakurei.app/internal/lockedfile/internal/filelock" ) -func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) { +func osOpenFile(name string, flag int, perm fs.FileMode, w bool) (*os.File, error) { // On BSD systems, we could add the O_SHLOCK or O_EXLOCK flag to the OpenFile // call instead of locking separately, but we have to support separate locking // calls for Linux and Windows anyway, so it's simpler to use that approach @@ -24,6 +24,10 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) { return nil, err } + if w { + flag |= os.O_WRONLY + } + switch flag & (os.O_RDONLY | os.O_WRONLY | os.O_RDWR) { case os.O_WRONLY, os.O_RDWR: err = filelock.Lock(f) diff --git a/internal/lockedfile/lockedfile_plan9.go b/internal/lockedfile/lockedfile_plan9.go index a2ce794b..45e2b87c 100644 --- a/internal/lockedfile/lockedfile_plan9.go +++ b/internal/lockedfile/lockedfile_plan9.go @@ -42,7 +42,7 @@ func isLocked(err error) bool { return false } -func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) { +func osOpenFile(name string, flag int, perm fs.FileMode, _ bool) (*os.File, error) { // Plan 9 uses a mode bit instead of explicit lock/unlock syscalls. // // Per http://man.cat-v.org/plan_9/5/stat: “Exclusive use files may be open |
