[klibc] [PATCH 3/5] fix non-RT sigsuspend()

Thorsten Glaser tg at mirbsd.org
Tue May 15 09:05:15 PDT 2012


The user-space signature of the sigsuspend() function differs
a lot from the Linux syscall sigsuspend one. Unfortunately,
it differs across the architectures, as well. Also, while the
RT signal functions are available on all Linux architectures,
they cannot be used on all architectures by klibc because the
kernel headers do not expose everything as needed by them.

This patch switches the mips architectures to RT signals and
fixes sigsuspend() on all other klibc architectures by renaming
the syscall to __n_sigsuspend() and writing an appropriate
wrapper function.

Signed-off-by: Thorsten Glaser <tg at mirbsd.org>
---
 usr/include/arch/alpha/klibc/archconfig.h   |    1 +
 usr/include/arch/arm/klibc/archconfig.h     |    2 ++
 usr/include/arch/cris/klibc/archconfig.h    |    2 ++
 usr/include/arch/i386/klibc/archconfig.h    |    1 +
 usr/include/arch/m68k/klibc/archconfig.h    |    2 ++
 usr/include/arch/mips/klibc/archconfig.h    |    3 +++
 usr/include/arch/mips64/klibc/archconfig.h  |    3 +++
 usr/include/arch/ppc/klibc/archconfig.h     |    2 +-
 usr/include/arch/s390/klibc/archconfig.h    |    2 ++
 usr/include/arch/sh/klibc/archconfig.h      |    2 +-
 usr/include/arch/sparc/klibc/archconfig.h   |    1 +
 usr/include/arch/sparc64/klibc/archconfig.h |    1 +
 usr/include/klibc/sysconfig.h               |   32 +++++++++++++++++++++++++++
 usr/klibc/SYSCALLS.def                      |   13 ++++++++++-
 usr/klibc/sigsuspend.c                      |   27 ++++++++++++++++++++++
 15 files changed, 91 insertions(+), 3 deletions(-)

diff --git a/usr/include/arch/alpha/klibc/archconfig.h b/usr/include/arch/alpha/klibc/archconfig.h
index 272fee0..be6ef39 100644
--- a/usr/include/arch/alpha/klibc/archconfig.h
+++ b/usr/include/arch/alpha/klibc/archconfig.h
@@ -11,5 +11,6 @@
 
 #define _KLIBC_USE_RT_SIG 1
 #define _KLIBC_STATFS_F_TYPE_64 0
+#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_L_1
 
 #endif				/* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/arm/klibc/archconfig.h b/usr/include/arch/arm/klibc/archconfig.h
index 36e9ab5..a0b5e96 100644
--- a/usr/include/arch/arm/klibc/archconfig.h
+++ b/usr/include/arch/arm/klibc/archconfig.h
@@ -15,4 +15,6 @@
 # define _KLIBC_ARM_USE_BX 1
 #endif
 
+#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_I_IUL1
+
 #endif				/* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/cris/klibc/archconfig.h b/usr/include/arch/cris/klibc/archconfig.h
index 0206078..f61a074 100644
--- a/usr/include/arch/cris/klibc/archconfig.h
+++ b/usr/include/arch/cris/klibc/archconfig.h
@@ -12,4 +12,6 @@
 /* cris uses 13 as the page shift factor for sys_mmap2 */
 #define _KLIBC_MMAP2_SHIFT	13
 
+#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_I_1
+
 #endif				/* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/i386/klibc/archconfig.h b/usr/include/arch/i386/klibc/archconfig.h
index b409a21..6e926e1 100644
--- a/usr/include/arch/i386/klibc/archconfig.h
+++ b/usr/include/arch/i386/klibc/archconfig.h
@@ -11,5 +11,6 @@
 
 /* The i386 <asm/signal.h> is still not clean enough for this... */
 #define _KLIBC_USE_RT_SIG 0
+#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_I_II1
 
 #endif				/* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/m68k/klibc/archconfig.h b/usr/include/arch/m68k/klibc/archconfig.h
index 10ef62e..ebb3420 100644
--- a/usr/include/arch/m68k/klibc/archconfig.h
+++ b/usr/include/arch/m68k/klibc/archconfig.h
@@ -12,4 +12,6 @@
 /* On m68k, sys_mmap2 uses the current page size as the shift factor */
 #define _KLIBC_MMAP2_SHIFT	__getpageshift()
 
+#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_I_II1
+
 #endif				/* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/mips/klibc/archconfig.h b/usr/include/arch/mips/klibc/archconfig.h
index ff0afb5..194fee1 100644
--- a/usr/include/arch/mips/klibc/archconfig.h
+++ b/usr/include/arch/mips/klibc/archconfig.h
@@ -18,4 +18,7 @@
 /* MIPS has nonstandard socket definitions */
 #define _KLIBC_HAS_ARCHSOCKET_H 1
 
+/* signal.h seems clean enough for RT signals; non-RT are broken */
+#define _KLIBC_USE_RT_SIG 1
+
 #endif				/* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/mips64/klibc/archconfig.h b/usr/include/arch/mips64/klibc/archconfig.h
index 9071cb4..a26addc 100644
--- a/usr/include/arch/mips64/klibc/archconfig.h
+++ b/usr/include/arch/mips64/klibc/archconfig.h
@@ -12,4 +12,7 @@
 /* MIPS has nonstandard socket definitions */
 #define _KLIBC_HAS_ARCHSOCKET_H 1
 
+/* signal.h seems clean enough for RT signals; non-RT are broken */
+#define _KLIBC_USE_RT_SIG 1
+
 #endif				/* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/ppc/klibc/archconfig.h b/usr/include/arch/ppc/klibc/archconfig.h
index ce04eee..aa32bcd 100644
--- a/usr/include/arch/ppc/klibc/archconfig.h
+++ b/usr/include/arch/ppc/klibc/archconfig.h
@@ -9,6 +9,6 @@
 #ifndef _KLIBC_ARCHCONFIG_H
 #define _KLIBC_ARCHCONFIG_H
 
-/* All defaults */
+#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_L_1
 
 #endif				/* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/s390/klibc/archconfig.h b/usr/include/arch/s390/klibc/archconfig.h
index d7a71a4..d2a9fb3 100644
--- a/usr/include/arch/s390/klibc/archconfig.h
+++ b/usr/include/arch/s390/klibc/archconfig.h
@@ -12,4 +12,6 @@
 /* Both s390 and s390x use the "32-bit" version of this structure */
 #define _KLIBC_STATFS_F_TYPE_64 0
 
+#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_L_II1
+
 #endif				/* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/sh/klibc/archconfig.h b/usr/include/arch/sh/klibc/archconfig.h
index 9c9e3d8..83752f5 100644
--- a/usr/include/arch/sh/klibc/archconfig.h
+++ b/usr/include/arch/sh/klibc/archconfig.h
@@ -9,6 +9,6 @@
 #ifndef _KLIBC_ARCHCONFIG_H
 #define _KLIBC_ARCHCONFIG_H
 
-/* All defaults */
+#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_I_1
 
 #endif				/* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/sparc/klibc/archconfig.h b/usr/include/arch/sparc/klibc/archconfig.h
index 70d5ef0..ab52362 100644
--- a/usr/include/arch/sparc/klibc/archconfig.h
+++ b/usr/include/arch/sparc/klibc/archconfig.h
@@ -11,5 +11,6 @@
 
 #define _KLIBC_USE_RT_SIG 1	/* Use rt_* signals */
 #define _KLIBC_SYS_SOCKETCALL 1 /* Use sys_socketcall unconditionally */
+#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_I_1
 
 #endif				/* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/sparc64/klibc/archconfig.h b/usr/include/arch/sparc64/klibc/archconfig.h
index 794d15b..b2eb203 100644
--- a/usr/include/arch/sparc64/klibc/archconfig.h
+++ b/usr/include/arch/sparc64/klibc/archconfig.h
@@ -12,5 +12,6 @@
 #define _KLIBC_USE_RT_SIG 1	/* Use rt_* signals */
 #define _KLIBC_NEEDS_SA_RESTORER 1 /* Need a restorer function */
 #define _KLIBC_SYS_SOCKETCALL 1 /* Use sys_socketcall unconditionally */
+#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_I_1
 
 #endif				/* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/klibc/sysconfig.h b/usr/include/klibc/sysconfig.h
index 5fa9b60..523e484 100644
--- a/usr/include/klibc/sysconfig.h
+++ b/usr/include/klibc/sysconfig.h
@@ -8,6 +8,24 @@
 #ifndef _KLIBC_SYSCONFIG_H
 #define _KLIBC_SYSCONFIG_H
 
+/*
+ * _KLIBC_SIGSUSPEND_TYPE_*:
+ *
+ *	Enumerates the various types of sigsuspend() syscall
+ *	we can use, for the architecture header to select one.
+ */
+
+/* int sigsuspend(sigset_t) */
+#define _KLIBC_SIGSUSPEND_TYPE_I_1	1
+/* long sigsuspend(sigset_t) */
+#define _KLIBC_SIGSUSPEND_TYPE_L_1	2
+/* int sigsuspend(int, int, sigset_t) */
+#define _KLIBC_SIGSUSPEND_TYPE_I_II1	3
+/* long sigsuspend(int, int, sigset_t) */
+#define _KLIBC_SIGSUSPEND_TYPE_L_II1	4
+/* int sigsuspend(int, unsigned long, sigset_t) */
+#define _KLIBC_SIGSUSPEND_TYPE_I_IUL1	5
+
 #include <klibc/archconfig.h>
 #include <asm/unistd.h>
 
@@ -216,4 +234,18 @@
 # define _KLIBC_ARM_USE_BX 0
 #endif
 
+/*
+ * _KLIBC_SIGSUSPEND_TYPE
+ *
+ *	Select which sigsuspend() type we have.
+ *	Default to RT if _KLIBC_USE_RT_SIG, otherwise error out,
+ *	as we cannot safely predict a non-RT type without the
+ *	architecture-specific includes telling us which one it is.
+ */
+#ifndef _KLIBC_SIGSUSPEND_TYPE
+# if !_KLIBC_USE_RT_SIG
+#  error Cannot use non-RT sigsuspend without knowing the type!
+# endif
+#endif
+
 #endif /* _KLIBC_SYSCONFIG_H */
diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def
index 6ed6bdf..7abab15 100644
--- a/usr/klibc/SYSCALLS.def
+++ b/usr/klibc/SYSCALLS.def
@@ -206,9 +206,20 @@ 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
+ */
+<cris,sh,sparc> int sigsuspend::__n_sigsuspend(sigset_t);
+<alpha,powerpc,sparc64> long sigsuspend::__n_sigsuspend(sigset_t);
+<arm> int sigsuspend::__n_sigsuspend(int, unsigned long, sigset_t);
+<frv,i386,m68k> int sigsuspend::__n_sigsuspend(int, int, sigset_t);
+<mn10300,s390> long sigsuspend::__n_sigsuspend(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 4d910d5..1b829c5 100644
--- a/usr/klibc/sigsuspend.c
+++ b/usr/klibc/sigsuspend.c
@@ -15,4 +15,31 @@ int sigsuspend(const sigset_t * mask)
 	return __rt_sigsuspend(mask, sizeof *mask);
 }
 
+#else
+
+#if _KLIBC_SIGSUSPEND_TYPE == _KLIBC_SIGSUSPEND_TYPE_I_1
+extern int __n_sigsuspend(sigset_t);
+#elif _KLIBC_SIGSUSPEND_TYPE == _KLIBC_SIGSUSPEND_TYPE_L_1
+extern long __n_sigsuspend(sigset_t);
+#elif _KLIBC_SIGSUSPEND_TYPE == _KLIBC_SIGSUSPEND_TYPE_I_II1
+extern int __n_sigsuspend(int, int, sigset_t);
+#elif _KLIBC_SIGSUSPEND_TYPE == _KLIBC_SIGSUSPEND_TYPE_L_II1
+extern long __n_sigsuspend(int, int, sigset_t);
+#elif _KLIBC_SIGSUSPEND_TYPE == _KLIBC_SIGSUSPEND_TYPE_I_IUL1
+extern int __n_sigsuspend(int, unsigned long, sigset_t);
+#else
+#error unknown architecture
+#endif
+
+int
+sigsuspend(const sigset_t *maskp)
+{
+#if (_KLIBC_SIGSUSPEND_TYPE == _KLIBC_SIGSUSPEND_TYPE_I_1) || \
+    (_KLIBC_SIGSUSPEND_TYPE == _KLIBC_SIGSUSPEND_TYPE_L_1)
+	return ((int)__n_sigsuspend(*maskp));
+#else
+	return ((int)__n_sigsuspend(0, 0, *maskp));
+#endif
+}
+
 #endif
-- 
1.7.10



More information about the klibc mailing list