hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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:
Aio/+freebsd/platform_lock.ha | 15+++++++++++++++
Aio/+linux/platform_lock.ha | 15+++++++++++++++
Aio/lock.ha | 20++++++++++++++++++++
Mrt/+freebsd/syscalls.ha | 5+++++
Mrt/+freebsd/types.ha | 6++++++
Mrt/+linux/syscalls.ha | 6+++---
Mscripts/gen-stdlib | 4++++
Mstdlib.mk | 8++++++++
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 \