hare

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

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:
Mrt/+freebsd/types.ha | 14+++++++-------
Mrt/+netbsd/types.ha | 14+++++++-------
Mtest/+test.ha | 2+-
Munix/signal/+freebsd.ha | 42+++++++++++++++++-------------------------
Munix/signal/+linux.ha | 44++++++++++++++++++--------------------------
Munix/signal/+netbsd.ha | 42+++++++++++++++++-------------------------
Munix/signal/+openbsd.ha | 42+++++++++++++++++-------------------------
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.