hare

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

commit 1b10148532950e0fa9684a153966e18148c8f557
parent c18b4b62ea5bfb54af1e470946189ef004102add
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed, 13 Mar 2024 11:31:04 +0100

unix, rt: add alarm(2) support

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Mrt/+freebsd/signal.ha | 38++++++++++++++++++++++++++++++++++++++
Mrt/+linux/+x86_64.ha | 4----
Mrt/+linux/signal.ha | 31+++++++++++++++++++++++++++++++
Mrt/+openbsd/signal.ha | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Mrt/+openbsd/syscalls.ha | 2--
Munix/signal/+freebsd.ha | 7+++++++
Munix/signal/+linux.ha | 7+++++++
Munix/signal/+openbsd.ha | 7+++++++
8 files changed, 143 insertions(+), 6 deletions(-)

diff --git a/rt/+freebsd/signal.ha b/rt/+freebsd/signal.ha @@ -3,6 +3,44 @@ // TODO: work when _NSIG != 32 +export fn alarm(sec: uint) uint = { + let nval = itimerval { ... }; + let oval = itimerval { ... }; + nval.it_value.tv_sec = sec: time_t; + setitimer(ITIMER_REAL, &nval, &oval)!; + if (oval.it_value.tv_usec != 0) { + oval.it_value.tv_sec += 1; + }; + return oval.it_value.tv_sec: uint; +}; + +export def ITIMER_REAL: int = 0; +export def ITIMER_VIRTUAL: int = 1; +export def ITIMER_PROF: int = 2; + +export type itimerval = struct { + it_interval: timeval, + it_value: timeval, +}; + +export fn getitimer( + which: int, + cur: *itimerval, +) (void | errno) = { + wrap_return(syscall2(SYS_getitimer, which: u64, cur: uintptr: u64))?; +}; + +export fn setitimer( + which: int, + newval: *itimerval, + oldval: nullable *itimerval, +) (void | errno) = { + wrap_return(syscall3(SYS_setitimer, + which: u64, + newval: uintptr: u64, + oldval: uintptr: u64))?; +}; + export fn sigemptyset(set: *sigset) void = { for (let i = 0z; i < len(set.__bits); i += 1) { set.__bits[i] = 0; diff --git a/rt/+linux/+x86_64.ha b/rt/+linux/+x86_64.ha @@ -51,10 +51,6 @@ export type cpu_set = struct { __bits: [16]u64, }; -export fn alarm(seconds: uint) uint = { - return syscall1(SYS_alarm, seconds: u64): uint; -}; - export type ucontext = struct { uc_flags: u64, uc_link: *ucontext, diff --git a/rt/+linux/signal.ha b/rt/+linux/signal.ha @@ -3,6 +3,37 @@ // TODO: work when _NSIG != 64 +export fn alarm(sec: uint) uint = { + return syscall1(SYS_alarm, sec: u64): uint; +}; + +export def ITIMER_REAL: int = 0; +export def ITIMER_VIRTUAL: int = 1; +export def ITIMER_PROF: int = 2; + +export type itimerval = struct { + it_interval: timeval, + it_value: timeval, +}; + +export fn getitimer( + which: int, + cur: *itimerval, +) (void | errno) = { + wrap_return(syscall2(SYS_getitimer, which: u64, cur: uintptr: u64))?; +}; + +export fn setitimer( + which: int, + newval: *itimerval, + oldval: nullable *itimerval, +) (void | errno) = { + wrap_return(syscall3(SYS_setitimer, + which: u64, + newval: uintptr: u64, + oldval: uintptr: u64))?; +}; + export fn sigemptyset(set: *sigset) void = { set.__val[0] = 0; }; diff --git a/rt/+openbsd/signal.ha b/rt/+openbsd/signal.ha @@ -1,6 +1,59 @@ // SPDX-License-Identifier: MPL-2.0 // (c) Hare authors <https://harelang.org> +export fn alarm(sec: uint) uint = { + let nval = itimerval { ... }; + let oval = itimerval { ... }; + nval.it_value.tv_sec = sec: time_t; + setitimer(ITIMER_REAL, &nval, &oval)!; + if (oval.it_value.tv_usec != 0) { + oval.it_value.tv_sec += 1; + }; + return oval.it_value.tv_sec: uint; +}; + +export def ITIMER_REAL: int = 0; +export def ITIMER_VIRTUAL: int = 1; +export def ITIMER_PROF: int = 2; + +export type itimerval = struct { + it_interval: timeval, + it_value: timeval, +}; + +// setitimer + +@symbol("setitimer") fn libc_setitimer( + which: int, + newval: *itimerval, + oldval: nullable *itimerval, +) int; + +export fn setitimer( + which: int, + newval: *itimerval, + oldval: nullable *itimerval, +) (void | errno) = { + let res = libc_setitimer(which, newval, oldval); + if (res != -1) { + return *__errno(): errno; + }; +}; + +// getitimer + +@symbol("getitimer") fn libc_getitimer( + which: int, + cur: *itimerval, +) int; + +export fn getitimer(which: int, cur: *itimerval) (void | errno) = { + let res = libc_getitimer(which, cur); + if (res != -1) { + return *__errno(): errno; + }; +}; + export fn sigemptyset(set: *sigset) void = { *set = 0; }; diff --git a/rt/+openbsd/syscalls.ha b/rt/+openbsd/syscalls.ha @@ -493,8 +493,6 @@ export fn chroot(path: path) (void | errno) = { // vfork // gettimeofday // settimeofday -// setitimer -// getitimer // select // kevent diff --git a/unix/signal/+freebsd.ha b/unix/signal/+freebsd.ha @@ -5,6 +5,13 @@ use io; use rt; use unix; +// Requests that [[sig::ALRM]] is delivered to the calling process in (about) +// "sec" seconds. Returns the number of seconds until the previously scheduled +// alarm, or zero if none was scheduled. +export fn alarm(sec: uint) uint = { + return rt::alarm(sec); +}; + // Configures a new signal handler, returning the old details (which can be // passed to [[restore]] to restore its behavior). // diff --git a/unix/signal/+linux.ha b/unix/signal/+linux.ha @@ -6,6 +6,13 @@ use io; use rt; use unix; +// Requests that [[sig::ALRM]] is delivered to the calling process in (about) +// "sec" seconds. Returns the number of seconds until the previously scheduled +// alarm, or zero if none was scheduled. +export fn alarm(sec: uint) uint = { + return rt::alarm(sec); +}; + // Configures a new signal handler, returning the old details (which can be // passed to [[restore]] to restore its behavior). // diff --git a/unix/signal/+openbsd.ha b/unix/signal/+openbsd.ha @@ -5,6 +5,13 @@ use io; use rt; use unix; +// Requests that [[sig::ALRM]] is delivered to the calling process in (about) +// "sec" seconds. Returns the number of seconds until the previously scheduled +// alarm, or zero if none was scheduled. +export fn alarm(sec: uint) uint = { + return rt::alarm(sec); +}; + // Configures a new signal handler, returning the old details (which can be // passed to [[restore]] to restore its behavior). //