commit ce852d5efd540cafdc52df94c82f36fd610b75c7
parent 96386617783f88e7931bb22260b8385eaf9877b3
Author: Mallory Adams <malloryadams@fastmail.com>
Date: Sun, 29 Dec 2024 09:43:31 -0500
NetBSD: fix rt::sigaction
Thanks to M. Levinson for a very detailed bug report! And thanks to
Lorenz and Drew for feedback on the patch.
Signed-off-by: Mallory Adams <malloryadams@fastmail.com>
Diffstat:
4 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/rt/+netbsd/syscall+x86_64.s b/rt/+netbsd/syscall+x86_64.s
@@ -79,3 +79,16 @@ rt.syscall6:
syscall
jc error
ret
+
+.section .text.rt.__sigtramp_siginfo_2
+.global rt.__sigtramp_siginfo_2
+rt.__sigtramp_siginfo_2:
+ movq %r15,%rdi
+ /* $308 = SYS_setcontext */
+ movq $308, %rax
+ syscall
+ movq $-1,%rdi
+ /* $1 = SYS_exit */
+ movq $1, %rax
+ syscall
+ ret
diff --git a/rt/+netbsd/syscalls.ha b/rt/+netbsd/syscalls.ha
@@ -8,6 +8,7 @@ fn syscall3(u64, u64, u64, u64) u64;
fn syscall4(u64, u64, u64, u64, u64) u64;
fn syscall5(u64, u64, u64, u64, u64, u64) u64;
fn syscall6(u64, u64, u64, u64, u64, u64, u64) u64;
+fn __sigtramp_siginfo_2(u64) u64;
let pathbuf: [PATH_MAX]u8 = [0...];
@@ -436,8 +437,10 @@ export fn sigaction(
act: *const sigact,
old: nullable *sigact,
) (int | errno) = {
- return wrap_return(syscall3(SYS___sigaction_sigtramp,
- signum: u64, act: uintptr: u64, old: uintptr: u64))?: int;
+ return wrap_return(syscall5(SYS___sigaction_sigtramp,
+ signum: u64, act: uintptr: u64, old: uintptr: u64,
+ &__sigtramp_siginfo_2: uintptr: u64,
+ __SIGTRAMP_SIGINFO_VERSION: u64))?: int;
};
export fn sigprocmask(
diff --git a/rt/+netbsd/types.ha b/rt/+netbsd/types.ha
@@ -658,3 +658,6 @@ export def MOUNT_SHMFS = MOUNT_TMPFS;
export def SHMFS_DIR_PATH = "/var/shm";
export def SHMFS_DIR_MODE = (S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO);
export def SHMFS_OBJ_PREFIX = ".shmobj_";
+
+// Signal
+export def __SIGTRAMP_SIGINFO_VERSION = 2;
diff --git a/unix/signal/signal+test.ha b/unix/signal/signal+test.ha
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: MPL-2.0
+// (c) Hare authors <https://harelang.org>
+
+use errors;
+use rt;
+use time;
+use unix;
+
+// Forward declaration to resolve signal => test => signal loop
+fn test::require(keywords: str...) void;
+
+let ok = false;
+
+fn handle_signal(
+ _sig: sig,
+ info: *siginfo,
+ ucontext: *opaque
+) void = {
+ ok = true;
+};
+
+@test fn test_handle() void = {
+ test::require("integration");
+ handle(sig::USR1, &handle_signal);
+ match (rt::kill(unix::getpid(), sig::USR1)) {
+ case let errno: rt::errno =>
+ abort(errors::strerror(errors::errno(errno)));
+ case void => void;
+ };
+
+ assert(ok);
+};