commit 417601ef64f2d17b668d2fe8002e87b225544006
parent 0904c9bbf0df6bd5c331c5722b9349ff9fa7648c
Author: Sebastian <sebastian@sebsite.pw>
Date: Sun, 1 Dec 2024 20:07:16 -0500
unix::signal: change handle interface to use default args
While here, fix the types of the SA_* constants in rt:: on non-linux,
and also change the flag enum to be backed by u64 on +linux, so we don't
need to cast to/from int.
This is a breaking change.
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
7 files changed, 84 insertions(+), 116 deletions(-)
diff --git a/rt/+freebsd/types.ha b/rt/+freebsd/types.ha
@@ -25,13 +25,13 @@ export type sigset = struct {
__bits: [4]u32,
};
-export def SA_ONSTACK: u64 = 0x0001;
-export def SA_RESTART: u64 = 0x0002;
-export def SA_RESETHAND: u64 = 0x0004;
-export def SA_NOCLDSTOP: u64 = 0x0008;
-export def SA_NODEFER: u64 = 0x0010;
-export def SA_NOCLDWAIT: u64 = 0x0020;
-export def SA_SIGINFO: u64 = 0x0040;
+export def SA_ONSTACK: int = 0x0001;
+export def SA_RESTART: int = 0x0002;
+export def SA_RESETHAND: int = 0x0004;
+export def SA_NOCLDSTOP: int = 0x0008;
+export def SA_NODEFER: int = 0x0010;
+export def SA_NOCLDWAIT: int = 0x0020;
+export def SA_SIGINFO: int = 0x0040;
export def SIG_ERR: uintptr = -1;
export def SIG_DFL: uintptr = 0;
diff --git a/rt/+netbsd/types.ha b/rt/+netbsd/types.ha
@@ -33,13 +33,13 @@ export type sigset = struct {
__bits: [4]u32,
};
-export def SA_ONSTACK: u64 = 0x0001;
-export def SA_RESTART: u64 = 0x0002;
-export def SA_RESETHAND: u64 = 0x0004;
-export def SA_NOCLDSTOP: u64 = 0x0008;
-export def SA_NODEFER: u64 = 0x0010;
-export def SA_NOCLDWAIT: u64 = 0x0020;
-export def SA_SIGINFO: u64 = 0x0040;
+export def SA_ONSTACK: int = 0x0001;
+export def SA_RESTART: int = 0x0002;
+export def SA_RESETHAND: int = 0x0004;
+export def SA_NOCLDSTOP: int = 0x0008;
+export def SA_NODEFER: int = 0x0010;
+export def SA_NOCLDWAIT: int = 0x0020;
+export def SA_SIGINFO: int = 0x0040;
export def SIG_ERR: uintptr = -1;
export def SIG_DFL: uintptr = 0;
diff --git a/test/+test.ha b/test/+test.ha
@@ -205,7 +205,7 @@ fn reset(ctx: *context) void = {
fn do_test(ctx: *context, test: test) void = {
signal::handle(signal::sig::SEGV, &handle_segv,
- signal::flag::NODEFER, signal::flag::ONSTACK);
+ signal::flag::NODEFER | signal::flag::ONSTACK);
memio::reset(&ctx.stdout);
memio::reset(&ctx.stderr);
diff --git a/unix/signal/+freebsd.ha b/unix/signal/+freebsd.ha
@@ -15,33 +15,24 @@ export fn alarm(sec: uint) uint = {
// Configures a new signal handler, returning the old details (which can be
// passed to [[restore]] to restore its behavior).
-//
-// The variadic parameters specify either [[flag]]s to enable or a signal mask
-// to use via [[sigset]]; if the latter is provided no more than one may be
-// used.
export fn handle(
signum: sig,
handler: *handler,
- opt: (flag | sigset)...
+ flags: flag = flag::NONE,
+ mask: nullable *sigset = null,
) sigaction = {
- let sa_mask = newsigset();
-
- let sa_flags = rt::SA_SIGINFO: int, nmask = 0;
- for (let i = 0z; i < len(opt); i += 1) {
- match (opt[i]) {
- case let flag: flag =>
- sa_flags |= flag: int;
- case let mask: sigset =>
- assert(nmask == 0, "Multiple signal masks provided to signal::handle");
- nmask += 1;
- sa_mask = mask;
- };
+ flags |= rt::SA_SIGINFO: flag;
+ let mask = match (mask) {
+ case null =>
+ yield newsigset();
+ case let set: *sigset =>
+ yield *set;
};
let new = rt::sigact {
sa_sigaction = handler: *fn(int, *rt::siginfo, *opaque) void,
- sa_mask = sa_mask,
- sa_flags = sa_flags,
+ sa_mask = mask,
+ sa_flags = flags,
};
let old = rt::sigact {
sa_sigaction = null: *fn(int, *rt::siginfo, *opaque) void,
@@ -362,27 +353,28 @@ export type code = enum int {
// Flags used to configure the behavior of a signal handler.
export type flag = enum int {
+ NONE = 0,
// For use with sig::CHLD. Prevents notifications when child processes
// stop (e.g. via sig::STOP) or resume (i.e. sig::CONT).
- NOCLDSTOP = rt::SA_NOCLDSTOP: int,
+ NOCLDSTOP = rt::SA_NOCLDSTOP,
// For use with sig::CHLD. Do not transform children into zombies when
// they terminate. Note that POSIX leaves the delivery of sig::CHLD
// unspecified when this flag is present; some systems will still
// deliver a signal and others may not.
- NOCLDWAIT = rt::SA_NOCLDWAIT: int,
+ NOCLDWAIT = rt::SA_NOCLDWAIT,
// Uses an alternate stack when handling this signal. See
// [[setaltstack]] and [[getaltstack]] for details.
- ONSTACK = rt::SA_ONSTACK: int,
+ ONSTACK = rt::SA_ONSTACK,
// Do not add the signal to the signal mask while executing the signal
// handler. This can cause the same signal to be delivered again during
// the execution of the signal handler.
- NODEFER = rt::SA_NODEFER: int,
+ NODEFER = rt::SA_NODEFER,
// Restore the signal handler to the default behavior upon entering the
// signal handler.
- RESETHAND = rt::SA_RESETHAND: int,
+ RESETHAND = rt::SA_RESETHAND,
// Makes certain system calls restartable across signals. See signal(7)
// or similar documentation for your local system for details.
- RESTART = rt::SA_RESTART: int,
+ RESTART = rt::SA_RESTART,
};
// All possible signals.
diff --git a/unix/signal/+linux.ha b/unix/signal/+linux.ha
@@ -16,33 +16,24 @@ export fn alarm(sec: uint) uint = {
// Configures a new signal handler, returning the old details (which can be
// passed to [[restore]] to restore its behavior).
-//
-// The variadic parameters specify either [[flag]]s to enable or a signal mask
-// to use via [[sigset]]; if the latter is provided no more than one may be
-// used.
export fn handle(
signum: sig,
handler: *handler,
- opt: (flag | sigset)...
+ flags: flag = flag::NONE,
+ mask: nullable *sigset = null,
) sigaction = {
- let sa_mask = newsigset();
-
- let sa_flags = rt::SA_SIGINFO, nmask = 0;
- for (let i = 0z; i < len(opt); i += 1) {
- match (opt[i]) {
- case let flag: flag =>
- sa_flags |= flag: u64;
- case let mask: sigset =>
- assert(nmask == 0, "Multiple signal masks provided to signal::handle");
- nmask += 1;
- sa_mask = mask;
- };
+ flags |= rt::SA_SIGINFO: flag;
+ let mask = match (mask) {
+ case null =>
+ yield newsigset();
+ case let set: *sigset =>
+ yield *set;
};
let new = rt::sigact {
sa_sigaction = handler: *fn(int, *rt::siginfo, *opaque) void,
- sa_mask = sa_mask,
- sa_flags = sa_flags,
+ sa_mask = mask,
+ sa_flags = flags,
// Filled in by rt:
sa_restorer = null: *fn () void,
};
@@ -367,28 +358,29 @@ export type code = enum int {
};
// Flags used to configure the behavior of a signal handler.
-export type flag = enum int {
+export type flag = enum u64 {
+ NONE = 0,
// For use with sig::CHLD. Prevents notifications when child processes
// stop (e.g. via sig::STOP) or resume (i.e. sig::CONT).
- NOCLDSTOP = rt::SA_NOCLDSTOP: int,
+ NOCLDSTOP = rt::SA_NOCLDSTOP,
// For use with sig::CHLD. Do not transform children into zombies when
// they terminate. Note that POSIX leaves the delivery of sig::CHLD
// unspecified when this flag is present; some systems will still
// deliver a signal and others may not.
- NOCLDWAIT = rt::SA_NOCLDWAIT: int,
+ NOCLDWAIT = rt::SA_NOCLDWAIT,
// Uses an alternate stack when handling this signal. See
// [[setaltstack]] and [[getaltstack]] for details.
- ONSTACK = rt::SA_ONSTACK: int,
+ ONSTACK = rt::SA_ONSTACK,
// Makes certain system calls restartable across signals. See signal(7)
// or similar documentation for your local system for details.
- RESTART = rt::SA_RESTART: int,
+ RESTART = rt::SA_RESTART,
// Do not add the signal to the signal mask while executing the signal
// handler. This can cause the same signal to be delivered again during
// the execution of the signal handler.
- NODEFER = rt::SA_NODEFER: int,
+ NODEFER = rt::SA_NODEFER,
// Restore the signal handler to the default behavior upon entering the
// signal handler.
- RESETHAND = rt::SA_RESETHAND: int,
+ RESETHAND = rt::SA_RESETHAND,
};
// All possible signals.
diff --git a/unix/signal/+netbsd.ha b/unix/signal/+netbsd.ha
@@ -15,33 +15,24 @@ export fn alarm(sec: uint) uint = {
// Configures a new signal handler, returning the old details (which can be
// passed to [[restore]] to restore its behavior).
-//
-// The variadic parameters specify either [[flag]]s to enable or a signal mask
-// to use via [[sigset]]; if the latter is provided no more than one may be
-// used.
export fn handle(
signum: sig,
handler: *handler,
- opt: (flag | sigset)...
+ flags: flag = flag::NONE,
+ mask: nullable *sigset = null,
) sigaction = {
- let sa_mask = newsigset();
-
- let sa_flags = rt::SA_SIGINFO: int, nmask = 0;
- for (let i = 0z; i < len(opt); i += 1) {
- match (opt[i]) {
- case let flag: flag =>
- sa_flags |= flag: int;
- case let mask: sigset =>
- assert(nmask == 0, "Multiple signal masks provided to signal::handle");
- nmask += 1;
- sa_mask = mask;
- };
+ flags |= rt::SA_SIGINFO: flag;
+ let mask = match (mask) {
+ case null =>
+ yield newsigset();
+ case let set: *sigset =>
+ yield *set;
};
let new = rt::sigact {
sa_sigaction = handler: *fn(int, *rt::siginfo, *opaque) void,
- sa_mask = sa_mask,
- sa_flags = sa_flags,
+ sa_mask = mask,
+ sa_flags = flags,
};
let old = rt::sigact {
sa_sigaction = null: *fn(int, *rt::siginfo, *opaque) void,
@@ -362,27 +353,28 @@ export type code = enum int {
// Flags used to configure the behavior of a signal handler.
export type flag = enum int {
+ NONE = 0,
// For use with sig::CHLD. Prevents notifications when child processes
// stop (e.g. via sig::STOP) or resume (i.e. sig::CONT).
- NOCLDSTOP = rt::SA_NOCLDSTOP: int,
+ NOCLDSTOP = rt::SA_NOCLDSTOP,
// For use with sig::CHLD. Do not transform children into zombies when
// they terminate. Note that POSIX leaves the delivery of sig::CHLD
// unspecified when this flag is present; some systems will still
// deliver a signal and others may not.
- NOCLDWAIT = rt::SA_NOCLDWAIT: int,
+ NOCLDWAIT = rt::SA_NOCLDWAIT,
// Uses an alternate stack when handling this signal. See
// [[setaltstack]] and [[getaltstack]] for details.
- ONSTACK = rt::SA_ONSTACK: int,
+ ONSTACK = rt::SA_ONSTACK,
// Do not add the signal to the signal mask while executing the signal
// handler. This can cause the same signal to be delivered again during
// the execution of the signal handler.
- NODEFER = rt::SA_NODEFER: int,
+ NODEFER = rt::SA_NODEFER,
// Restore the signal handler to the default behavior upon entering the
// signal handler.
- RESETHAND = rt::SA_RESETHAND: int,
+ RESETHAND = rt::SA_RESETHAND,
// Makes certain system calls restartable across signals. See signal(7)
// or similar documentation for your local system for details.
- RESTART = rt::SA_RESTART: int,
+ RESTART = rt::SA_RESTART,
};
// All possible signals.
diff --git a/unix/signal/+openbsd.ha b/unix/signal/+openbsd.ha
@@ -14,33 +14,24 @@ export fn alarm(sec: uint) uint = {
// Configures a new signal handler, returning the old details (which can be
// passed to [[restore]] to restore its behavior).
-//
-// The variadic parameters specify either [[flag]]s to enable or a signal mask
-// to use via [[sigset]]; if the latter is provided no more than one may be
-// used.
export fn handle(
signum: sig,
handler: *handler,
- opt: (flag | sigset)...
+ flags: flag = flag::NONE,
+ mask: nullable *sigset = null,
) sigaction = {
- let sa_mask = newsigset();
-
- let sa_flags = rt::SA_SIGINFO: int, nmask = 0;
- for (let i = 0z; i < len(opt); i += 1) {
- match (opt[i]) {
- case let flag: flag =>
- sa_flags |= flag: int;
- case let mask: sigset =>
- assert(nmask == 0, "Multiple signal masks provided to signal::handle");
- nmask += 1;
- sa_mask = mask;
- };
+ flags |= rt::SA_SIGINFO: flag;
+ let mask = match (mask) {
+ case null =>
+ yield newsigset();
+ case let set: *sigset =>
+ yield *set;
};
let new = rt::sigact {
sa_sigaction = handler: *fn(int, *rt::siginfo, *opaque) void,
- sa_mask = sa_mask,
- sa_flags = sa_flags,
+ sa_mask = mask,
+ sa_flags = flags,
};
let old = rt::sigact {
sa_sigaction = null: *fn(int, *rt::siginfo, *opaque) void,
@@ -282,27 +273,28 @@ export type code = enum int {
};
export type flag = enum int {
+ NONE = 0,
// For use with sig::CHLD. Prevents notifications when child processes
// stop (e.g. via sig::STOP) or resume (i.e. sig::CONT).
- NOCLDSTOP = rt::SA_NOCLDSTOP: int,
+ NOCLDSTOP = rt::SA_NOCLDSTOP,
// For use with sig::CHLD. Do not transform children into zombies when
// they terminate. Note that POSIX leaves the delivery of sig::CHLD
// unspecified when this flag is present; some systems will still
// deliver a signal and others may not.
- NOCLDWAIT = rt::SA_NOCLDWAIT: int,
+ NOCLDWAIT = rt::SA_NOCLDWAIT,
// Uses an alternate stack when handling this signal. See
// [[setaltstack]] and [[getaltstack]] for details.
- ONSTACK = rt::SA_ONSTACK: int,
+ ONSTACK = rt::SA_ONSTACK,
// Do not add the signal to the signal mask while executing the signal
// handler. This can cause the same signal to be delivered again during
// the execution of the signal handler.
- NODEFER = rt::SA_NODEFER: int,
+ NODEFER = rt::SA_NODEFER,
// Restore the signal handler to the default behavior upon entering the
// signal handler.
- RESETHAND = rt::SA_RESETHAND: int,
+ RESETHAND = rt::SA_RESETHAND,
// Makes certain system calls restartable across signals. See signal(7)
// or similar documentation for your local system for details.
- RESTART = rt::SA_RESTART: int,
+ RESTART = rt::SA_RESTART,
};
// All possible signals.