hare

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

commit fd24f6da73c219596b9167e8996a6e2f277f7d33
parent f48bb4f864e5dd33cc0a919f5e769b32ed86f159
Author: Jose Lombera <jose@lombera.dev>
Date:   Sat, 18 Jun 2022 20:35:29 -0500

rt: signal: return error for invalid signal numbers

- Validate that signal number is >= 1.
- Return actual rt::errno for invalid signal numbers.
- Add tests to cover these changes.

Signed-off-by: Jose Lombera <jose@lombera.dev>

Diffstat:
Mrt/+freebsd/signal.ha | 12++++++------
Mrt/+linux/signal.ha | 12++++++------
Art/+test/signal.ha | 47+++++++++++++++++++++++++++++++++++++++++++++++
Mscripts/gen-stdlib | 1+
Mstdlib.mk | 2++
5 files changed, 62 insertions(+), 12 deletions(-)

diff --git a/rt/+freebsd/signal.ha b/rt/+freebsd/signal.ha @@ -11,8 +11,8 @@ export fn sigemptyset(set: *sigset) int = { }; export fn sigaddset(set: *sigset, signum: int) (int | errno) = { - if (signum > NSIG) { - return EINVAL; + if (signum < 1 || signum > NSIG) { + return wrap_errno(EINVAL); }; signum -= 1; set.__bits[signum >> 5] |= (1 << signum): u32; @@ -20,8 +20,8 @@ export fn sigaddset(set: *sigset, signum: int) (int | errno) = { }; export fn sigdelset(set: *sigset, signum: int) (int | errno) = { - if (signum > NSIG) { - return EINVAL; + if (signum < 1 || signum > NSIG) { + return wrap_errno(EINVAL); }; signum -= 1; set.__bits[signum >> 5] &= ~(1 << signum: u32); @@ -29,8 +29,8 @@ export fn sigdelset(set: *sigset, signum: int) (int | errno) = { }; export fn sigismember(set: *sigset, signum: int) (int | errno) = { - if (signum > NSIG) { - return EINVAL; + if (signum < 1 || signum > NSIG) { + return wrap_errno(EINVAL); }; signum -= 1; if ((set.__bits[signum >> 5] & (1 << signum: u32)) != 0) { diff --git a/rt/+linux/signal.ha b/rt/+linux/signal.ha @@ -12,8 +12,8 @@ export fn sigemptyset(set: *sigset) int = { }; export fn sigaddset(set: *sigset, signum: int) (int | errno) = { - if (signum > NSIG) { - return EINVAL; + if (signum < 1 || signum > NSIG) { + return wrap_errno(EINVAL); }; signum -= 1; set.__val[0] |= (1 << signum): u64; @@ -21,8 +21,8 @@ export fn sigaddset(set: *sigset, signum: int) (int | errno) = { }; export fn sigdelset(set: *sigset, signum: int) (int | errno) = { - if (signum > NSIG) { - return EINVAL; + if (signum < 1 || signum > NSIG) { + return wrap_errno(EINVAL); }; signum -= 1; set.__val[0] &= ~(1 << signum: u64); @@ -30,8 +30,8 @@ export fn sigdelset(set: *sigset, signum: int) (int | errno) = { }; export fn sigismember(set: *sigset, signum: int) (int | errno) = { - if (signum > NSIG) { - return EINVAL; + if (signum < 1 || signum > NSIG) { + return wrap_errno(EINVAL); }; signum -= 1; if ((set.__val[0] & (1 << signum: u64)) != 0) { diff --git a/rt/+test/signal.ha b/rt/+test/signal.ha @@ -0,0 +1,47 @@ +// License: MPL-2.0 +// (c) 2022 Jose Lombera <jose@lombera.dev> + +// Test sigset operations do not fail for valid signal numbers. +@test fn sigset_valid_signum() void = { + let set = sigset { ... }; + sigemptyset(&set); + + assert(!(sigismember(&set, 1) is errno), "Unexpected error"); + assert(!(sigismember(&set, 15) is errno), "Unexpected error"); + assert(!(sigismember(&set, NSIG) is errno), "Unexpected error"); + + assert(!(sigaddset(&set, 1) is errno), "Unexpected error"); + assert(!(sigaddset(&set, 15) is errno), "Unexpected error"); + assert(!(sigaddset(&set, NSIG) is errno), "Unexpected error"); + + // It's ok to add a signal that is already present in the set. + assert(!(sigaddset(&set, 1) is errno), "Unexpected error"); + + assert(!(sigdelset(&set, 1) is errno), "Unexpected error"); + assert(!(sigdelset(&set, 15) is errno), "Unexpected error"); + assert(!(sigdelset(&set, NSIG) is errno), "Unexpected error"); + + // It's ok to delete a signal that is not present in the set. + assert(!(sigdelset(&set, 10) is errno), "Unexpected error"); + + // sigfillset() always succeeds. + assert(!(sigfillset(&set) is errno), "Unexpected error"); +}; + +// Test sigset operations fail for invalid signal numbers. +@test fn sigset_invalid_signum() void = { + let set = sigset { ... }; + sigemptyset(&set); + + assert(sigismember(&set, -1) is errno, "Expected error"); + assert(sigismember(&set, 0) is errno, "Expected error"); + assert(sigismember(&set, NSIG + 1) is errno, "Expected error"); + + assert(sigaddset(&set, -1) is errno, "Expected error"); + assert(sigaddset(&set, 0) is errno, "Expected error"); + assert(sigaddset(&set, NSIG + 1) is errno, "Expected error"); + + assert(sigdelset(&set, -1) is errno, "Expected error"); + assert(sigdelset(&set, 0) is errno, "Expected error"); + assert(sigdelset(&set, NSIG + 1) is errno, "Expected error"); +}; diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -84,6 +84,7 @@ rt() { '+test/+$(PLATFORM).ha' \ +test/cstring.ha \ +test/run.ha \ + +test/signal.ha \ +test/ztos.ha fi gen_ssa -plinux rt diff --git a/stdlib.mk b/stdlib.mk @@ -2192,6 +2192,7 @@ testlib_rt_linux_srcs = \ $(STDLIB)/rt/+test/+$(PLATFORM).ha \ $(STDLIB)/rt/+test/cstring.ha \ $(STDLIB)/rt/+test/run.ha \ + $(STDLIB)/rt/+test/signal.ha \ $(STDLIB)/rt/+test/ztos.ha # rt (+freebsd) @@ -2222,6 +2223,7 @@ testlib_rt_freebsd_srcs = \ $(STDLIB)/rt/+test/+$(PLATFORM).ha \ $(STDLIB)/rt/+test/cstring.ha \ $(STDLIB)/rt/+test/run.ha \ + $(STDLIB)/rt/+test/signal.ha \ $(STDLIB)/rt/+test/ztos.ha $(TESTCACHE)/rt/rt-linux.ssa: $(testlib_rt_linux_srcs) $(testlib_rt)