aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-10-13 20:57:16 +0900
committerOphestra <cat@gensokyo.uk>2026-10-13 20:57:16 +0900
commit9e95987536f895ef1a989fcd9e69ab84a1b94a17 (patch)
tree304aec06573103329df9caf3adea58d1b7025700 /internal
parent0abf367b1334b76f5e8f989cf0c07b5d00b25868 (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')
-rw-r--r--internal/lockedfile/lockedfile.go19
-rw-r--r--internal/lockedfile/lockedfile_filelock.go6
-rw-r--r--internal/lockedfile/lockedfile_plan9.go2
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