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:
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).
//