aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2020-08-25 01:05:28 +0100
committerBen Hutchings <ben@decadent.org.uk>2020-08-27 15:00:33 +0100
commit2a2a0b6b79c2470f529daabd5c193f58fe188337 (patch)
treeb842494f240cd9482d189c558a719e618886f9bb
parentccc5c14c44f3fa76f61b8aae947cf3b853a6c833 (diff)
downloadklibc-2a2a0b6b79c2470f529daabd5c193f58fe188337.tar.gz
[klibc] signal: Add sysconfig setting to force SA_SIGINFO on
On alpha, arm, i386, m68k, powerpc, s390, sh, and sparc (32-bit), the kernel sets up the signal stack frame differently depending on the SA_SIGINFO flag, not whether the sigaction() or rt_sigaction() system call was used to install the handler. On alpha and sparc, we are going to start providing our own restorer that will call rt_sigaction(), so will need to ensure this flag is always set. Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--usr/include/klibc/sysconfig.h14
-rw-r--r--usr/klibc/sigaction.c21
2 files changed, 28 insertions, 7 deletions
diff --git a/usr/include/klibc/sysconfig.h b/usr/include/klibc/sysconfig.h
index 4e38b1fd1e1ddd..5722e04f8c57b3 100644
--- a/usr/include/klibc/sysconfig.h
+++ b/usr/include/klibc/sysconfig.h
@@ -163,6 +163,20 @@
/*
+ * _KLIBC_NEEDS_SA_SIGINFO:
+ *
+ * On some architectures, the signal stack frame is set up for
+ * either sigreturn() or rt_sigreturn() depending on whether
+ * SA_SIGINFO is set. Where this is the case, and we provide our
+ * own restorer function, this must also be set so that the
+ * restorer can always use rt_sigreturn().
+ */
+#ifndef _KLIBC_NEEDS_SA_SIGINFO
+# define _KLIBC_NEEDS_SA_SIGINFO 0
+#endif
+
+
+/*
* _KLIBC_STATFS_F_TYPE_64:
*
* This indicates that the f_type, f_bsize, f_namelen,
diff --git a/usr/klibc/sigaction.c b/usr/klibc/sigaction.c
index 966bc1c6f6c3a8..0d7c5c9dac35fe 100644
--- a/usr/klibc/sigaction.c
+++ b/usr/klibc/sigaction.c
@@ -22,19 +22,26 @@ __extern int __rt_sigaction(int, const struct sigaction *, struct sigaction *,
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
- int rv;
-
+ unsigned int needed_flags = 0
#if _KLIBC_NEEDS_SA_RESTORER
+ | SA_RESTORER
+#endif
+#if _KLIBC_NEEDS_SA_SIGINFO
+ | SA_SIGINFO
+#endif
+ ;
struct sigaction sa;
+ int rv;
- if (act && !(act->sa_flags & SA_RESTORER)) {
+ if (act && (act->sa_flags & needed_flags) != needed_flags) {
sa = *act;
+ sa.sa_flags |= needed_flags;
+#if _KLIBC_NEEDS_SA_RESTORER
+ if (!(act->sa_flags & SA_RESTORER))
+ sa.sa_restorer = &__sigreturn;
+#endif
act = &sa;
-
- sa.sa_flags |= SA_RESTORER;
- sa.sa_restorer = &__sigreturn;
}
-#endif
#if _KLIBC_USE_RT_SIG
/* Check that we have the right signal API definitions */