[klibc] Use rt_sig*() system calls on i386

On i386, only part of the signal space is accessible through the legacy
calls.  In order to use the rt_sig*() calls, however, we have to implement
our own signal header file instead of relying on <asm/signal.h>.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
diff --git a/include/arch/i386/klibc/archconfig.h b/include/arch/i386/klibc/archconfig.h
index 8e075e4..782fce7 100644
--- a/include/arch/i386/klibc/archconfig.h
+++ b/include/arch/i386/klibc/archconfig.h
@@ -9,6 +9,9 @@
 #ifndef _KLIBC_ARCHCONFIG_H
 #define _KLIBC_ARCHCONFIG_H
 
+/* On i386, only half the signals are accessible using the legacy calls. */
+#define _KLIBC_USE_RT_SIG 1
+
 /* The stock i386 kernel is fine, but a whole string of Fedora kernels
    had a broken default restorer.  It's easier to enable this here. */
 #define _KLIBC_NEEDS_SA_RESTORER 1
diff --git a/include/arch/i386/klibc/archsignal.h b/include/arch/i386/klibc/archsignal.h
index bfa0d95..5d59a1a 100644
--- a/include/arch/i386/klibc/archsignal.h
+++ b/include/arch/i386/klibc/archsignal.h
@@ -8,7 +8,107 @@
 #ifndef _KLIBC_ARCHSIGNAL_H
 #define _KLIBC_ARCHSIGNAL_H
 
-#include <asm/signal.h>
-/* No special stuff for this architecture */
+/* The in-kernel headers for i386 still have libc5
+   crap in them.  Reconsider using <asm/signal.h>
+   when/if it gets cleaned up; for now, duplicate
+   the definitions here. */
+
+#define _NSIG           64
+#define _NSIG_BPW       32
+#define _NSIG_WORDS     (_NSIG / _NSIG_BPW)
+
+typedef struct {
+        unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#define SIGHUP           1
+#define SIGINT           2
+#define SIGQUIT          3
+#define SIGILL           4
+#define SIGTRAP          5
+#define SIGABRT          6
+#define SIGIOT           6
+#define SIGBUS           7
+#define SIGFPE           8
+#define SIGKILL          9
+#define SIGUSR1         10
+#define SIGSEGV         11
+#define SIGUSR2         12
+#define SIGPIPE         13
+#define SIGALRM         14
+#define SIGTERM         15
+#define SIGSTKFLT       16
+#define SIGCHLD         17
+#define SIGCONT         18
+#define SIGSTOP         19
+#define SIGTSTP         20
+#define SIGTTIN         21
+#define SIGTTOU         22
+#define SIGURG          23
+#define SIGXCPU         24
+#define SIGXFSZ         25
+#define SIGVTALRM       26
+#define SIGPROF         27
+#define SIGWINCH        28
+#define SIGIO           29
+#define SIGPOLL         SIGIO
+#define SIGPWR          30
+#define SIGSYS          31
+#define SIGUNUSED       31
+
+#define SIGRTMIN        32
+#define SIGRTMAX        _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001u
+#define SA_NOCLDWAIT	0x00000002u
+#define SA_SIGINFO	0x00000004u
+#define SA_ONSTACK	0x08000000u
+#define SA_RESTART	0x10000000u
+#define SA_NODEFER	0x40000000u
+#define SA_RESETHAND	0x80000000u
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+#define SA_RESTORER	0x04000000
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#include <asm-generic/signal.h>
+
+/* This uses gcc anonymous union support... */
+struct siginfo;
+
+struct sigaction {
+	union {
+		__sighandler_t	sa_handler;
+		void (*sa_sigaction)(int, struct siginfo *, void *);
+	};
+	unsigned long	sa_flags;
+	__sigrestore_t	sa_restorer;
+	sigset_t	sa_mask;
+};
 
 #endif