aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2012-05-15 11:53:40 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2012-05-15 11:53:40 -0700
commitc9386db2f81259069d8615667b56bd76e6233a56 (patch)
tree3be4f4c749ddd2ac31262960e6193a80667a2333
parentf665e35d18ff16781e50e74efd24d843b1f1d2f0 (diff)
downloadklibc-c9386db2f81259069d8615667b56bd76e6233a56.tar.gz
[klibc] Handle legacy sigsuspend() correctly
Legacy sigsuspend() doesn't look anything like the user space prototype. There are two variants, and make sure we use the right one. This ignores type differences which do not matter. Originally-by: Thorsten Glaser <tg@mirbsd.org> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--usr/klibc/SYSCALLS.def12
-rw-r--r--usr/klibc/sigsuspend.c18
2 files changed, 29 insertions, 1 deletions
diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def
index 12aef49e9a580..b6f9ea50ad809 100644
--- a/usr/klibc/SYSCALLS.def
+++ b/usr/klibc/SYSCALLS.def
@@ -206,9 +206,19 @@ int rt_sigprocmask::__rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t);
<sparc64> void rt_sigreturn::__sigreturn();
#else
int sigaction::__sigaction(int, const struct sigaction *, struct sigaction *);
-int sigsuspend(const sigset_t *);
int sigpending(sigset_t *);
int sigprocmask(int, const sigset_t *, sigset_t *);
+/*
+ * There is no single calling convention for the old sigsuspend.
+ * If your architecture is not listed here, building klibc shall
+ * rather fail than use a broken calling convention.
+ * You better switch to RT signals on those architectures:
+ * blackfin h8300 microblaze mips.
+ *
+ * The arguments other than the sigset_t are assumed ignored.
+ */
+<cris,sh,sparc,alpha,powerpc,sparc64> int sigsuspend::__sigsuspend_s(sigset_t);
+<arm,frv,i386,m68k,mn10300,s390> int sigsuspend::__sigsuspend_xxs(int, int, sigset_t);
#endif
int kill(pid_t, int);
<?> unsigned int alarm(unsigned int);
diff --git a/usr/klibc/sigsuspend.c b/usr/klibc/sigsuspend.c
index 4d910d54cfb99..26a521a94cf7d 100644
--- a/usr/klibc/sigsuspend.c
+++ b/usr/klibc/sigsuspend.c
@@ -5,6 +5,7 @@
#include <signal.h>
#include <sys/syscall.h>
#include <klibc/sysconfig.h>
+#include <klibc/havesyscall.h>
#if _KLIBC_USE_RT_SIG
@@ -15,4 +16,21 @@ int sigsuspend(const sigset_t * mask)
return __rt_sigsuspend(mask, sizeof *mask);
}
+#else
+
+extern int __sigsuspend_s(sigset_t);
+extern int __sigsuspend_xxs(int, int, sigset_t);
+
+int
+sigsuspend(const sigset_t *maskp)
+{
+#ifdef _KLIBC_HAVE_SYSCALL___sigsuspend_s
+ return __sigsuspend_s(*maskp);
+#elif defined(_KLIBC_HAVE_SYSCALL___sigsuspend_xxs)
+ return __sigsuspend_xxs(0, 0, *maskp);
+#else
+# error "Unknown sigsuspend implementation"
+#endif
+}
+
#endif