commit e4509be8d41f51b4e6cccb96128381a9ac685f5d
parent 7a5099eec86b80c037aadd2dc5638049863d75ab
Author: Autumn! <autumnull@posteo.net>
Date: Sun, 7 May 2023 21:50:19 +0000
io: implement lock()
Signed-off-by: Autumn! <autumnull@posteo.net>
Diffstat:
8 files changed, 76 insertions(+), 3 deletions(-)
diff --git a/io/+freebsd/platform_lock.ha b/io/+freebsd/platform_lock.ha
@@ -0,0 +1,15 @@
+// License: MPL-2.0
+use errors;
+use rt;
+
+fn platform_lock(fd: file, flags: int) (bool | error) = {
+ match (rt::flock(fd: int, flags)) {
+ case void => return true;
+ case let e: rt::errno =>
+ if (e == rt::EWOULDBLOCK: rt::errno) {
+ return false;
+ } else {
+ return errors::errno(e);
+ };
+ };
+};
diff --git a/io/+linux/platform_lock.ha b/io/+linux/platform_lock.ha
@@ -0,0 +1,15 @@
+// License: MPL-2.0
+use errors;
+use rt;
+
+fn platform_lock(fd: file, flags: int) (bool | error) = {
+ match (rt::flock(fd: int, flags)) {
+ case void => return true;
+ case let e: rt::errno =>
+ if (e == rt::EWOULDBLOCK: rt::errno) {
+ return false;
+ } else {
+ return errors::errno(e);
+ };
+ };
+};
diff --git a/io/lock.ha b/io/lock.ha
@@ -0,0 +1,20 @@
+// License: MPL-2.0
+use rt;
+
+// Lock operation to use with [[lock]].
+export type lockop = enum int {
+ // shared file lock
+ SHARED = rt::LOCK_SH,
+ // exclusive file lock
+ EXCLUSIVE = rt::LOCK_EX,
+ // unlock file
+ UNLOCK = rt::LOCK_UN,
+};
+
+// Apply or remove an advisory lock on an open file. If block is true, the request will block while waiting
+// for the lock.
+export fn lock(fd: file, block: bool, op: lockop) (bool | error) = {
+ let flags = op: int;
+ if (!block) flags |= rt::LOCK_NB;
+ return platform_lock(fd, flags);
+};
diff --git a/rt/+freebsd/syscalls.ha b/rt/+freebsd/syscalls.ha
@@ -514,6 +514,11 @@ export fn posix_fallocate(fd: int, off: i64, ln: i64) (void | errno) = {
fd: u64, off: u64, ln: u64))?;
};
+export fn flock(fd: int, op: int) (void | errno) = {
+ wrap_return(syscall2(SYS_flock,
+ fd: u64, op: u64))?;
+};
+
export fn shmat(id: int, addr: *const void, flag: int) *void = {
return syscall3(SYS_shmat, id: u64, addr: uintptr: u64,
flag: u64): uintptr: *void;
diff --git a/rt/+freebsd/types.ha b/rt/+freebsd/types.ha
@@ -434,3 +434,9 @@ export def STDERR_FILENO: int = 2;
export def SEEK_SET: int = 0;
export def SEEK_CUR: int = 1;
export def SEEK_END: int = 2;
+
+// Flock operations
+export def LOCK_SH: int = 1;
+export def LOCK_EX: int = 2;
+export def LOCK_NB: int = 4;
+export def LOCK_UN: int = 8;
diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha
@@ -896,9 +896,9 @@ export fn posix_fallocate(fd: int, off: i64, ln: i64) (void | errno) = {
fallocate(fd, 0, off, ln)?;
};
-export fn flock(fd: int, op: int) (int | errno) = {
- return wrap_return(syscall2(SYS_flock,
- fd: u64, op: u64))?: int;
+export fn flock(fd: int, op: int) (void | errno) = {
+ wrap_return(syscall2(SYS_flock,
+ fd: u64, op: u64))?;
};
export fn inotify_init() (int | errno) = {
diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib
@@ -891,12 +891,14 @@ gensrcs_io() {
'arch+$(ARCH).ha' \
+linux/file.ha \
+linux/mmap.ha \
+ +linux/platform_lock.ha \
+linux/vector.ha \
copy.ha \
drain.ha \
empty.ha \
handle.ha \
limit.ha \
+ lock.ha \
stream.ha \
tee.ha \
types.ha \
@@ -907,12 +909,14 @@ gensrcs_io() {
'arch+$(ARCH).ha' \
+freebsd/file.ha \
+freebsd/mmap.ha \
+ +freebsd/platform_lock.ha \
+freebsd/vector.ha \
copy.ha \
drain.ha \
empty.ha \
handle.ha \
limit.ha \
+ lock.ha \
stream.ha \
tee.ha \
types.ha \
diff --git a/stdlib.mk b/stdlib.mk
@@ -1461,12 +1461,14 @@ stdlib_io_linux_srcs = \
$(STDLIB)/io/arch+$(ARCH).ha \
$(STDLIB)/io/+linux/file.ha \
$(STDLIB)/io/+linux/mmap.ha \
+ $(STDLIB)/io/+linux/platform_lock.ha \
$(STDLIB)/io/+linux/vector.ha \
$(STDLIB)/io/copy.ha \
$(STDLIB)/io/drain.ha \
$(STDLIB)/io/empty.ha \
$(STDLIB)/io/handle.ha \
$(STDLIB)/io/limit.ha \
+ $(STDLIB)/io/lock.ha \
$(STDLIB)/io/stream.ha \
$(STDLIB)/io/tee.ha \
$(STDLIB)/io/types.ha \
@@ -1478,12 +1480,14 @@ stdlib_io_freebsd_srcs = \
$(STDLIB)/io/arch+$(ARCH).ha \
$(STDLIB)/io/+freebsd/file.ha \
$(STDLIB)/io/+freebsd/mmap.ha \
+ $(STDLIB)/io/+freebsd/platform_lock.ha \
$(STDLIB)/io/+freebsd/vector.ha \
$(STDLIB)/io/copy.ha \
$(STDLIB)/io/drain.ha \
$(STDLIB)/io/empty.ha \
$(STDLIB)/io/handle.ha \
$(STDLIB)/io/limit.ha \
+ $(STDLIB)/io/lock.ha \
$(STDLIB)/io/stream.ha \
$(STDLIB)/io/tee.ha \
$(STDLIB)/io/types.ha \
@@ -3719,12 +3723,14 @@ testlib_io_linux_srcs = \
$(STDLIB)/io/arch+$(ARCH).ha \
$(STDLIB)/io/+linux/file.ha \
$(STDLIB)/io/+linux/mmap.ha \
+ $(STDLIB)/io/+linux/platform_lock.ha \
$(STDLIB)/io/+linux/vector.ha \
$(STDLIB)/io/copy.ha \
$(STDLIB)/io/drain.ha \
$(STDLIB)/io/empty.ha \
$(STDLIB)/io/handle.ha \
$(STDLIB)/io/limit.ha \
+ $(STDLIB)/io/lock.ha \
$(STDLIB)/io/stream.ha \
$(STDLIB)/io/tee.ha \
$(STDLIB)/io/types.ha \
@@ -3738,12 +3744,14 @@ testlib_io_freebsd_srcs = \
$(STDLIB)/io/arch+$(ARCH).ha \
$(STDLIB)/io/+freebsd/file.ha \
$(STDLIB)/io/+freebsd/mmap.ha \
+ $(STDLIB)/io/+freebsd/platform_lock.ha \
$(STDLIB)/io/+freebsd/vector.ha \
$(STDLIB)/io/copy.ha \
$(STDLIB)/io/drain.ha \
$(STDLIB)/io/empty.ha \
$(STDLIB)/io/handle.ha \
$(STDLIB)/io/limit.ha \
+ $(STDLIB)/io/lock.ha \
$(STDLIB)/io/stream.ha \
$(STDLIB)/io/tee.ha \
$(STDLIB)/io/types.ha \