+++ /dev/null
-/*
- * Copyright (C) 2004 PathScale, Inc
- * Licensed under the GPL
- */
-
-#ifndef __I386_SIGNAL_H_
-#define __I386_SIGNAL_H_
-
-#include <signal.h>
-
-#define ARCH_SIGHDLR_PARAM int sig
-
-#define ARCH_GET_SIGCONTEXT(sc, sig) \
-       do sc = (struct sigcontext *) (&sig + 1); while(0)
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
 
+++ /dev/null
-/*
- * Copyright (C) 2004 PathScale, Inc
- * Licensed under the GPL
- */
-
-#ifndef __X86_64_SIGNAL_H_
-#define __X86_64_SIGNAL_H_
-
-#define ARCH_SIGHDLR_PARAM int sig
-
-#define ARCH_GET_SIGCONTEXT(sc, sig_addr) \
-       do { \
-               struct ucontext *__uc; \
-               asm("movq %%rdx, %0" : "=r" (__uc)); \
-               sc = (struct sigcontext *) &__uc->uc_mcontext; \
-       } while(0)
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
 
 
 void os_set_ioignore(void)
 {
-       set_handler(SIGIO, SIG_IGN, 0, -1);
+       signal(SIGIO, SIG_IGN);
 }
 
 void init_irq_signals(int on_sigstack)
 
 
 static void last_ditch_exit(int sig)
 {
-       signal(SIGINT, SIG_DFL);
-       signal(SIGTERM, SIG_DFL);
-       signal(SIGHUP, SIG_DFL);
        uml_cleanup();
        exit(1);
 }
 
+static void install_fatal_handler(int sig)
+{
+       struct sigaction action;
+
+       /* All signals are enabled in this handler ... */
+       sigemptyset(&action.sa_mask);
+
+       /* ... including the signal being handled, plus we want the
+        * handler reset to the default behavior, so that if an exit
+        * handler is hanging for some reason, the UML will just die
+        * after this signal is sent a second time.
+        */
+       action.sa_flags = SA_RESETHAND | SA_NODEFER;
+       action.sa_restorer = NULL;
+       action.sa_handler = last_ditch_exit;
+       if(sigaction(sig, &action, NULL) < 0){
+               printf("failed to install handler for signal %d - errno = %d\n",
+                      errno);
+               exit(1);
+       }
+}
+
 #define UML_LIB_PATH   ":/usr/lib/uml"
 
 static void setup_env_path(void)
        }
        new_argv[argc] = NULL;
 
-       set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
-       set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
-       set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
+       /* Allow these signals to bring down a UML if all other
+        * methods of control fail.
+        */
+       install_fatal_handler(SIGINT);
+       install_fatal_handler(SIGTERM);
+       install_fatal_handler(SIGHUP);
 
        scan_elf_aux( envp);
 
 
                set_sigstack(sig_stack, pages * page_size());
                flags = SA_ONSTACK;
        }
-       if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
+       if(usr1_handler){
+               struct sigaction sa;
+
+               sa.sa_handler = usr1_handler;
+               sigemptyset(&sa.sa_mask);
+               sa.sa_flags = flags;
+               sa.sa_restorer = NULL;
+               if(sigaction(SIGUSR1, &sa, NULL) < 0)
+                       panic("init_new_thread_stack - sigaction failed - "
+                             "errno = %d\n", errno);
+       }
 }
 
 void init_new_thread_signals(void)
 
 #include "user.h"
 #include "signal_kern.h"
 #include "sysdep/sigcontext.h"
-#include "sysdep/signal.h"
 #include "sigcontext.h"
 #include "mode.h"
 #include "os.h"
 static int signals_enabled = 1;
 static int pending = 0;
 
-void sig_handler(ARCH_SIGHDLR_PARAM)
+void sig_handler(int sig, struct sigcontext *sc)
 {
-       struct sigcontext *sc;
        int enabled;
 
-       /* Must be the first thing that this handler does - x86_64 stores
-        * the sigcontext in %rdx, and we need to save it before it has a
-        * chance to get trashed.
-        */
-
-       ARCH_GET_SIGCONTEXT(sc, sig);
-
        enabled = signals_enabled;
        if(!enabled && (sig == SIGIO)){
                pending |= SIGIO_MASK;
 
 }
 
-void alarm_handler(ARCH_SIGHDLR_PARAM)
+void alarm_handler(int sig, struct sigcontext *sc)
 {
-       struct sigcontext *sc;
        int enabled;
 
-       ARCH_GET_SIGCONTEXT(sc, sig);
-
        enabled = signals_enabled;
        if(!signals_enabled){
                if(sig == SIGVTALRM)
                panic("disabling signal stack failed, errno = %d\n", errno);
 }
 
+void (*handlers[_NSIG])(int sig, struct sigcontext *sc);
+
+extern void hard_handler(int sig);
+
 void set_handler(int sig, void (*handler)(int), int flags, ...)
 {
        struct sigaction action;
        sigset_t sig_mask;
        int mask;
 
-       va_start(ap, flags);
-       action.sa_handler = handler;
+       handlers[sig] = (void (*)(int, struct sigcontext *)) handler;
+       action.sa_handler = hard_handler;
+
        sigemptyset(&action.sa_mask);
-       while((mask = va_arg(ap, int)) != -1){
+
+       va_start(ap, flags);
+       while((mask = va_arg(ap, int)) != -1)
                sigaddset(&action.sa_mask, mask);
-       }
        va_end(ap);
+
        action.sa_flags = flags;
        action.sa_restorer = NULL;
        if(sigaction(sig, &action, NULL) < 0)
 
                }
        }
        if(!ptrace_faultinfo && (stack != NULL)){
+               struct sigaction sa;
+
                unsigned long v = UML_CONFIG_STUB_CODE +
                                  (unsigned long) stub_segv_handler -
                                  (unsigned long) &__syscall_stub_start;
 
                set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size());
-               set_handler(SIGSEGV, (void *) v, SA_ONSTACK,
-                           SIGIO, SIGWINCH, SIGALRM, SIGVTALRM,
-                           SIGUSR1, -1);
+               sigemptyset(&sa.sa_mask);
+               sigaddset(&sa.sa_mask, SIGIO);
+               sigaddset(&sa.sa_mask, SIGWINCH);
+               sigaddset(&sa.sa_mask, SIGALRM);
+               sigaddset(&sa.sa_mask, SIGVTALRM);
+               sigaddset(&sa.sa_mask, SIGUSR1);
+               sa.sa_flags = SA_ONSTACK;
+               sa.sa_handler = (void *) v;
+               sa.sa_restorer = NULL;
+               if(sigaction(SIGSEGV, &sa, NULL) < 0)
+                       panic("userspace_tramp - setting SIGSEGV handler "
+                             "failed - errno = %d\n", errno);
        }
 
        os_stop_process(os_getpid());
 
 # Licensed under the GPL
 #
 
-obj-$(CONFIG_MODE_SKAS) = registers.o tls.o
+obj-$(CONFIG_MODE_SKAS) = registers.o signal.o tls.o
 
 USER_OBJS := $(obj-y)
 
 
--- /dev/null
+/*
+ * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com)
+ * Licensed under the GPL
+ */
+
+#include <signal.h>
+
+extern void (*handlers[])(int sig, struct sigcontext *sc);
+
+void hard_handler(int sig)
+{
+       struct sigcontext *sc = (struct sigcontext *) (&sig + 1);
+
+       (*handlers[sig])(sig, sc);
+}
 
 # Licensed under the GPL
 #
 
-obj-$(CONFIG_MODE_SKAS) = registers.o
+obj-$(CONFIG_MODE_SKAS) = registers.o signal.o
 
 USER_OBJS := $(obj-y)
 
 
--- /dev/null
+/*
+ * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com)
+ * Licensed under the GPL
+ */
+
+#include <signal.h>
+
+extern void (*handlers[])(int sig, struct sigcontext *sc);
+
+void hard_handler(int sig)
+{
+       struct ucontext *uc;
+       asm("movq %%rdx, %0" : "=r" (uc));
+
+       (*handlers[sig])(sig, (struct sigcontext *) &uc->uc_mcontext);
+}
 
                printk("disnable_timer - setitimer failed, errno = %d\n",
                       errno);
        /* If there are signals already queued, after unblocking ignore them */
-       set_handler(SIGALRM, SIG_IGN, 0, -1);
-       set_handler(SIGVTALRM, SIG_IGN, 0, -1);
+       signal(SIGALRM, SIG_IGN);
+       signal(SIGVTALRM, SIG_IGN);
 }
 
 void switch_timers(int to_real)