Moved all signal support to a new platform-specific file.
Make use of the per-thread signal stack (Juergen Lock).
Fixed %fs in signal handler for non FS_sig case (Ulrich Weigand).

diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
index 6374ca7..8a88bdc 100644
--- a/dlls/ntdll/Makefile.in
+++ b/dlls/ntdll/Makefile.in
@@ -16,6 +16,7 @@
 	rtl.c \
 	rtlstr.c \
 	sec.c \
+	signal_i386.c \
 	sync.c \
 	time.c
 
diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c
index ef578fb..15adadb 100644
--- a/dlls/ntdll/exception.c
+++ b/dlls/ntdll/exception.c
@@ -12,7 +12,6 @@
 #include "global.h"
 #include "wine/exception.h"
 #include "stackframe.h"
-#include "sig_context.h"
 #include "miscemu.h"
 #include "debugtools.h"
 
@@ -25,10 +24,11 @@
     EXCEPTION_FRAME *prevFrame;
 } EXC_NESTED_FRAME;
 
+ 
 #ifdef __i386__
-# define GET_IP(context) ((LPVOID)EIP_reg(context))
+# define GET_IP(context) ((LPVOID)(context)->Eip)
 #else
-# define GET_IP(context) ((LPVOID)0)
+# error You must define GET_IP for this CPU
 #endif  /* __i386__ */
 
 /* Default hook for built-in debugger */
@@ -224,7 +224,7 @@
     PEXCEPTION_FRAME frame, dispatch;
 
 #ifdef __i386__
-    EAX_reg(context) = returnEax;
+    context->Eax = returnEax;
 #endif
 
     /* build an exception record, if we do not have one */
@@ -343,362 +343,3 @@
     REGS_FUNC(DebugBreak)( context );
 #endif  /* defined(__i386__) */
 }
-
-
-/***********************************************************************
- *           EXC_SaveContext
- *
- * Set the register values from a sigcontext. 
- */
-static void EXC_SaveContext( CONTEXT *context, const SIGCONTEXT *sigcontext )
-{
-#ifdef __i386__
-    EAX_reg(context) = EAX_sig(sigcontext);
-    EBX_reg(context) = EBX_sig(sigcontext);
-    ECX_reg(context) = ECX_sig(sigcontext);
-    EDX_reg(context) = EDX_sig(sigcontext);
-    ESI_reg(context) = ESI_sig(sigcontext);
-    EDI_reg(context) = EDI_sig(sigcontext);
-    EBP_reg(context) = EBP_sig(sigcontext);
-    EFL_reg(context) = EFL_sig(sigcontext);
-    EIP_reg(context) = EIP_sig(sigcontext);
-    ESP_reg(context) = ESP_sig(sigcontext);
-    CS_reg(context)  = LOWORD(CS_sig(sigcontext));
-    DS_reg(context)  = LOWORD(DS_sig(sigcontext));
-    ES_reg(context)  = LOWORD(ES_sig(sigcontext));
-    SS_reg(context)  = LOWORD(SS_sig(sigcontext));
-#ifdef FS_sig
-    FS_reg(context)  = LOWORD(FS_sig(sigcontext));
-#else
-    GET_FS( FS_reg(context) );
-    FS_reg(context) &= 0xffff;
-#endif
-#ifdef GS_sig
-    GS_reg(context)  = LOWORD(GS_sig(sigcontext));
-#else
-    GET_GS( GS_reg(context) );
-    GS_reg(context) &= 0xffff;
-#endif
-    if (ISV86(context)) V86BASE(context) = (DWORD)DOSMEM_MemoryBase(0);
-#endif  /* __i386__ */
-}
-
-
-/***********************************************************************
- *           EXC_RestoreContext
- *
- * Build a sigcontext from the register values.
- */
-static void EXC_RestoreContext( const CONTEXT *context, SIGCONTEXT *sigcontext )
-{
-#ifdef __i386__
-    EAX_sig(sigcontext) = EAX_reg(context);
-    EBX_sig(sigcontext) = EBX_reg(context);
-    ECX_sig(sigcontext) = ECX_reg(context);
-    EDX_sig(sigcontext) = EDX_reg(context);
-    ESI_sig(sigcontext) = ESI_reg(context);
-    EDI_sig(sigcontext) = EDI_reg(context);
-    EBP_sig(sigcontext) = EBP_reg(context);
-    EFL_sig(sigcontext) = EFL_reg(context);
-    EIP_sig(sigcontext) = EIP_reg(context);
-    ESP_sig(sigcontext) = ESP_reg(context);
-    CS_sig(sigcontext)  = CS_reg(context);
-    DS_sig(sigcontext)  = DS_reg(context);
-    ES_sig(sigcontext)  = ES_reg(context);
-    SS_sig(sigcontext)  = SS_reg(context);
-#ifdef FS_sig
-    FS_sig(sigcontext)  = FS_reg(context);
-#else
-    SET_FS( FS_reg(context) );
-#endif
-#ifdef GS_sig
-    GS_sig(sigcontext)  = GS_reg(context);
-#else
-    SET_GS( GS_reg(context) );
-#endif
-#endif  /* __i386__ */
-}
-
-
-/**********************************************************************
- *		EXC_segv
- *
- * Handler for SIGSEGV and related errors.
- */
-static HANDLER_DEF(EXC_segv)
-{
-    EXCEPTION_RECORD rec;
-    CONTEXT context;
-
-    HANDLER_INIT();
-
-#if defined(TRAP_sig) && defined(CR2_sig)
-    /* we want the page-fault case to be fast */
-    if (TRAP_sig(HANDLER_CONTEXT) == 14)
-        if (VIRTUAL_HandleFault( (LPVOID)CR2_sig(HANDLER_CONTEXT) )) return;
-#endif
-
-    EXC_SaveContext( &context, HANDLER_CONTEXT );
-    rec.ExceptionRecord  = NULL;
-    rec.ExceptionFlags   = 0;
-    rec.ExceptionAddress = GET_IP(&context);
-    rec.NumberParameters = 0;
-
-#ifdef TRAP_sig
-    switch(TRAP_sig(HANDLER_CONTEXT))
-    {
-    case 4:   /* Overflow exception */
-        rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
-        break;
-    case 5:   /* Bound range exception */
-        rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
-        break;
-    case 6:   /* Invalid opcode exception */
-        rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
-        break;
-    case 12:  /* Stack fault */
-        rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
-        break;
-    case 11:  /* Segment not present exception */
-    case 13:  /* General protection fault */
-        if (INSTR_EmulateInstruction( &context )) goto restore;
-        rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
-        break;
-    case 14:  /* Page fault */
-#ifdef CR2_sig
-        rec.NumberParameters = 2;
-#ifdef ERROR_sig
-        rec.ExceptionInformation[0] = (ERROR_sig(HANDLER_CONTEXT) & 2) != 0;
-#else
-        rec.ExceptionInformation[0] = 0;
-#endif /* ERROR_sig */
-        rec.ExceptionInformation[1] = CR2_sig(HANDLER_CONTEXT);
-#endif /* CR2_sig */
-        rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
-        break;
-    case 17:  /* Alignment check exception */
-        /* FIXME: pass through exception handler first? */
-    	if (EFL_reg(&context) & 0x00040000)
-        {
-            /* Disable AC flag, return */
-            EFL_reg(&context) &= ~0x00040000;
-            goto restore;
- 	}
-        rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
-        break;
-    default:
-        ERR( "Got unexpected trap %ld\n", TRAP_sig(HANDLER_CONTEXT) );
-        /* fall through */
-    case 2:   /* NMI interrupt */
-    case 7:   /* Device not available exception */
-    case 8:   /* Double fault exception */
-    case 10:  /* Invalid TSS exception */
-    case 15:  /* Unknown exception */
-    case 18:  /* Machine check exception */
-    case 19:  /* Cache flush exception */
-        rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
-        break;
-    }
-#else  /* TRAP_sig */
-# ifdef __i386__
-    if (INSTR_EmulateInstruction( &context )) goto restore;
-# endif
-    rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;  /* generic error */
-#endif  /* TRAP_sig */
-
-    REGS_FUNC(RtlRaiseException)( &rec, &context );
- restore:
-    EXC_RestoreContext( &context, HANDLER_CONTEXT );
-}
-
-
-/**********************************************************************
- *		EXC_trap
- *
- * Handler for SIGTRAP.
- */
-static HANDLER_DEF(EXC_trap)
-{
-    EXCEPTION_RECORD rec;
-    CONTEXT context;
-
-    HANDLER_INIT();
-
-#ifdef TRAP_sig
-    rec.ExceptionCode = (TRAP_sig(HANDLER_CONTEXT) == 1) ?
-                            EXCEPTION_SINGLE_STEP : EXCEPTION_BREAKPOINT;
-#else
-    rec.ExceptionCode = EXCEPTION_BREAKPOINT;
-#endif  /* TRAP_sig */
-
-    EXC_SaveContext( &context, HANDLER_CONTEXT );
-    rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
-    rec.ExceptionRecord  = NULL;
-    rec.ExceptionAddress = GET_IP(&context);
-    rec.NumberParameters = 0;
-    REGS_FUNC(RtlRaiseException)( &rec, &context );
-    EXC_RestoreContext( &context, HANDLER_CONTEXT );
-}
-
-
-/***********************************************************************
- *           EXC_SaveFPU
- *
- * Set the FPU context from a sigcontext. 
- */
-static void inline EXC_SaveFPU( CONTEXT *context, const SIGCONTEXT *sigcontext )
-{
-#ifdef __i386__
-# ifdef FPU_sig
-    if (FPU_sig(sigcontext))
-    {
-        context->FloatSave = *FPU_sig(sigcontext);
-        return;
-    }
-# endif  /* FPU_sig */
-# ifdef __GNUC__
-    __asm__ __volatile__( "fnsave %0; fwait" : "=m" (context->FloatSave) );
-# endif  /* __GNUC__ */
-#endif  /* __i386__ */
-}
-
-
-/***********************************************************************
- *           EXC_RestoreFPU
- *
- * Restore the FPU context to a sigcontext. 
- */
-static void inline EXC_RestoreFPU( CONTEXT *context, const SIGCONTEXT *sigcontext )
-{
-#ifdef __i386__
-# ifdef FPU_sig
-    if (FPU_sig(sigcontext))
-    {
-        *FPU_sig(sigcontext) = context->FloatSave;
-        return;
-    }
-# endif  /* FPU_sig */
-# ifdef __GNUC__
-    /* avoid nested exceptions */
-    context->FloatSave.StatusWord &= context->FloatSave.ControlWord | 0xffffff80;
-    __asm__ __volatile__( "frstor %0; fwait" : : "m" (context->FloatSave) );
-# endif  /* __GNUC__ */
-#endif  /* __i386__ */
-}
-
-
-/**********************************************************************
- *		EXC_GetFPUCode
- *
- * Get the FPU exception code from the FPU status.
- */
-static inline DWORD EXC_GetFPUCode( const CONTEXT *context )
-{
-#ifdef __i386__
-    DWORD status = context->FloatSave.StatusWord;
-
-    if (status & 0x01)  /* IE */
-    {
-        if (status & 0x40)  /* SF */
-            return EXCEPTION_FLT_STACK_CHECK;
-        else
-            return EXCEPTION_FLT_INVALID_OPERATION;
-    }
-    if (status & 0x02) return EXCEPTION_FLT_DENORMAL_OPERAND;  /* DE flag */
-    if (status & 0x04) return EXCEPTION_FLT_DIVIDE_BY_ZERO;    /* ZE flag */
-    if (status & 0x08) return EXCEPTION_FLT_OVERFLOW;          /* OE flag */
-    if (status & 0x10) return EXCEPTION_FLT_UNDERFLOW;         /* UE flag */
-    if (status & 0x20) return EXCEPTION_FLT_INEXACT_RESULT;    /* PE flag */
-#endif  /* __i386__ */
-    return EXCEPTION_FLT_INVALID_OPERATION;  /* generic error */
-}
-
-
-/**********************************************************************
- *		EXC_fpe
- *
- * Handler for SIGFPE.
- */
-static HANDLER_DEF(EXC_fpe)
-{
-    EXCEPTION_RECORD rec;
-    CONTEXT context;
-
-    HANDLER_INIT();
-
-    EXC_SaveFPU( &context, HANDLER_CONTEXT );
-
-#ifdef TRAP_sig
-    switch(TRAP_sig(HANDLER_CONTEXT))
-    {
-    case 0:   /* Division by zero exception */
-        rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
-        break;
-    case 9:   /* Coprocessor segment overrun */
-        rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
-        break;
-    case 16:  /* Floating point exception */
-        rec.ExceptionCode = EXC_GetFPUCode( &context );
-        break;
-    default:
-        ERR( "Got unexpected trap %ld\n", TRAP_sig(HANDLER_CONTEXT) );
-        rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
-        break;
-    }
-#else  /* TRAP_sig */
-    rec.ExceptionCode = EXC_GetFPUCode( &context );
-#endif  /* TRAP_sig */
-
-    EXC_SaveContext( &context, HANDLER_CONTEXT );
-    rec.ExceptionFlags   = 0;
-    rec.ExceptionRecord  = NULL;
-    rec.ExceptionAddress = GET_IP(&context);
-    rec.NumberParameters = 0;
-    REGS_FUNC(RtlRaiseException)( &rec, &context );
-    EXC_RestoreContext( &context, HANDLER_CONTEXT );
-    EXC_RestoreFPU( &context, HANDLER_CONTEXT );
-}
-
-
-/**********************************************************************
- *		EXC_int
- *
- * Handler for SIGINT.
- */
-static HANDLER_DEF(EXC_int)
-{
-    EXCEPTION_RECORD rec;
-    CONTEXT context;
-
-    HANDLER_INIT();
-
-    EXC_SaveContext( &context, HANDLER_CONTEXT );
-    rec.ExceptionCode    = CONTROL_C_EXIT;
-    rec.ExceptionFlags   = 0;
-    rec.ExceptionRecord  = NULL;
-    rec.ExceptionAddress = GET_IP(&context);
-    rec.NumberParameters = 0;
-    REGS_FUNC(RtlRaiseException)( &rec, &context );
-    EXC_RestoreContext( &context, HANDLER_CONTEXT );
-}
-
-
-/**********************************************************************
- *          EXC_InitHandlers
- *
- * Initialize the signal handlers for exception handling.
- */
-void EXC_InitHandlers(void)
-{
-    SIGNAL_SetHandler( SIGINT,  (void (*)())EXC_int );
-    SIGNAL_SetHandler( SIGFPE,  (void (*)())EXC_fpe );
-    SIGNAL_SetHandler( SIGSEGV, (void (*)())EXC_segv );
-    SIGNAL_SetHandler( SIGILL,  (void (*)())EXC_segv );
-#ifdef SIGBUS
-    SIGNAL_SetHandler( SIGBUS,  (void (*)())EXC_segv );
-#endif
-#ifdef SIGTRAP
-    SIGNAL_SetHandler( SIGTRAP, (void (*)())EXC_trap );
-#endif
-    return;
-}
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
new file mode 100644
index 0000000..37e7563
--- /dev/null
+++ b/dlls/ntdll/signal_i386.c
@@ -0,0 +1,680 @@
+/*
+ * i386 signal handling routines
+ * 
+ * Copyright 1999 Alexandre Julliard
+ */
+
+#ifdef __i386__
+
+#include "config.h"
+
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+#ifdef HAVE_SYSCALL_H
+# include <syscall.h>
+#else
+# ifdef HAVE_SYS_SYSCALL_H
+#  include <sys/syscall.h>
+# endif
+#endif
+
+#include "winnt.h"
+#include "stackframe.h"
+#include "global.h"
+#include "miscemu.h"
+#include "ntddk.h"
+#include "syslevel.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(seh)
+
+/***********************************************************************
+ * signal context platform-specific definitions
+ */
+
+#ifdef linux
+typedef struct
+{
+    unsigned short sc_gs, __gsh;
+    unsigned short sc_fs, __fsh;
+    unsigned short sc_es, __esh;
+    unsigned short sc_ds, __dsh;
+    unsigned long sc_edi;
+    unsigned long sc_esi;
+    unsigned long sc_ebp;
+    unsigned long sc_esp;
+    unsigned long sc_ebx;
+    unsigned long sc_edx;
+    unsigned long sc_ecx;
+    unsigned long sc_eax;
+    unsigned long sc_trapno;
+    unsigned long sc_err;
+    unsigned long sc_eip;
+    unsigned short sc_cs, __csh;
+    unsigned long sc_eflags;
+    unsigned long esp_at_signal;
+    unsigned short sc_ss, __ssh;
+    unsigned long i387;
+    unsigned long oldmask;
+    unsigned long cr2;
+} SIGCONTEXT;
+
+#define HANDLER_DEF(name) void name( int __signal, SIGCONTEXT __context )
+#define HANDLER_CONTEXT (&__context)
+
+/* this is the sigaction structure from the Linux 2.1.20 kernel.  */
+#undef sa_handler
+struct kernel_sigaction
+{
+    void (*sa_handler)();
+    unsigned long sa_mask;
+    unsigned long sa_flags;
+    void *sa_restorer;
+};
+
+/* Similar to the sigaction function in libc, except it leaves alone the
+   restorer field, which is used to specify the signal stack address */
+static inline int wine_sigaction( int sig, struct kernel_sigaction *new,
+                                  struct kernel_sigaction *old )
+{
+    __asm__ __volatile__( "pushl %%ebx\n\t"
+                          "movl %2,%%ebx\n\t"
+                          "int $0x80\n\t"
+                          "popl %%ebx"
+                          : "=a" (sig)
+                          : "0" (SYS_sigaction), "r" (sig), "c" (new), "d" (old) );
+    if (sig>=0) return 0;
+    errno = -sig;
+    return -1;
+}
+
+#endif  /* linux */
+
+#ifdef BSDI
+
+#define EAX_sig(context)     ((context)->tf_eax)
+#define EBX_sig(context)     ((context)->tf_ebx)
+#define ECX_sig(context)     ((context)->tf_ecx)
+#define EDX_sig(context)     ((context)->tf_edx)
+#define ESI_sig(context)     ((context)->tf_esi)
+#define EDI_sig(context)     ((context)->tf_edi)
+#define EBP_sig(context)     ((context)->tf_ebp)
+                            
+#define CS_sig(context)      ((context)->tf_cs)
+#define DS_sig(context)      ((context)->tf_ds)
+#define ES_sig(context)      ((context)->tf_es)
+#define SS_sig(context)      ((context)->tf_ss)
+
+#include <machine/frame.h>
+typedef struct trapframe SIGCONTEXT;
+
+#define HANDLER_DEF(name) void name( int __signal, int code, SIGCONTEXT *__context )
+#define HANDLER_CONTEXT __context
+
+#define EFL_sig(context)     ((context)->tf_eflags)
+
+#define EIP_sig(context)     (*((unsigned long*)&(context)->tf_eip))
+#define ESP_sig(context)     (*((unsigned long*)&(context)->tf_esp))
+
+#endif /* bsdi */
+
+#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+
+#include <signal.h>
+typedef struct sigcontext SIGCONTEXT;
+
+#define HANDLER_DEF(name) void name( int __signal, int code, SIGCONTEXT *__context )
+#define HANDLER_CONTEXT __context
+
+#endif  /* FreeBSD */
+
+#if defined(__svr4__) || defined(_SCO_DS) || defined(__sun)
+
+#include <signal.h>
+#ifdef _SCO_DS
+#include <sys/regset.h>
+#endif
+/* Solaris kludge */
+#undef ERR
+#include <sys/ucontext.h>
+#undef ERR
+typedef struct ucontext SIGCONTEXT;
+
+#define HANDLER_DEF(name) void name( int __signal, void *__siginfo, SIGCONTEXT *__context )
+#define HANDLER_CONTEXT __context
+
+#endif  /* svr4 || SCO_DS */
+
+#ifdef __EMX__
+
+typedef struct
+{
+    unsigned long ContextFlags;
+    FLOATING_SAVE_AREA sc_float;
+    unsigned long sc_gs;
+    unsigned long sc_fs;
+    unsigned long sc_es;
+    unsigned long sc_ds;
+    unsigned long sc_edi;
+    unsigned long sc_esi;
+    unsigned long sc_eax;
+    unsigned long sc_ebx;
+    unsigned long sc_ecx;
+    unsigned long sc_edx;
+    unsigned long sc_ebp;
+    unsigned long sc_eip;
+    unsigned long sc_cs;
+    unsigned long sc_eflags;
+    unsigned long sc_esp;
+    unsigned long sc_ss;
+} SIGCONTEXT;
+
+#endif  /* __EMX__ */
+
+
+#if defined(linux) || defined(__NetBSD__) || defined(__FreeBSD__) \
+ || defined(__OpenBSD__) || defined(__EMX__)
+
+#define EAX_sig(context)     ((context)->sc_eax)
+#define EBX_sig(context)     ((context)->sc_ebx)
+#define ECX_sig(context)     ((context)->sc_ecx)
+#define EDX_sig(context)     ((context)->sc_edx)
+#define ESI_sig(context)     ((context)->sc_esi)
+#define EDI_sig(context)     ((context)->sc_edi)
+#define EBP_sig(context)     ((context)->sc_ebp)
+                            
+#define CS_sig(context)      ((context)->sc_cs)
+#define DS_sig(context)      ((context)->sc_ds)
+#define ES_sig(context)      ((context)->sc_es)
+#define SS_sig(context)      ((context)->sc_ss)
+                            
+#ifdef linux
+/* FS and GS are now in the sigcontext struct of FreeBSD, but not 
+ * saved by the exception handling. duh.
+ */
+#define FS_sig(context)      ((context)->sc_fs)
+#define GS_sig(context)      ((context)->sc_gs)
+#define CR2_sig(context)     ((context)->cr2)
+#define TRAP_sig(context)    ((context)->sc_trapno)
+#define ERROR_sig(context)   ((context)->sc_err)
+#define FPU_sig(context)     ((FLOATING_SAVE_AREA*)((context)->i387))
+#endif
+
+#ifndef __FreeBSD__
+#define EFL_sig(context)     ((context)->sc_eflags)
+#else                       
+#define EFL_sig(context)     ((context)->sc_efl)
+/* FreeBSD, see i386/i386/traps.c::trap_pfault va->err kludge  */
+#define CR2_sig(context)     ((context)->sc_err)
+#endif                      
+
+#define EIP_sig(context)     (*((unsigned long*)&(context)->sc_eip))
+#define ESP_sig(context)     (*((unsigned long*)&(context)->sc_esp))
+
+#endif  /* linux || __NetBSD__ || __FreeBSD__ || __OpenBSD__ */
+
+#if defined(__svr4__) || defined(_SCO_DS) || defined(__sun)
+
+#ifdef _SCO_DS
+#define gregs regs
+#endif
+
+#define EAX_sig(context)     ((context)->uc_mcontext.gregs[EAX])
+#define EBX_sig(context)     ((context)->uc_mcontext.gregs[EBX])
+#define ECX_sig(context)     ((context)->uc_mcontext.gregs[ECX])
+#define EDX_sig(context)     ((context)->uc_mcontext.gregs[EDX])
+#define ESI_sig(context)     ((context)->uc_mcontext.gregs[ESI])
+#define EDI_sig(context)     ((context)->uc_mcontext.gregs[EDI])
+#define EBP_sig(context)     ((context)->uc_mcontext.gregs[EBP])
+                            
+#define CS_sig(context)      ((context)->uc_mcontext.gregs[CS])
+#define DS_sig(context)      ((context)->uc_mcontext.gregs[DS])
+#define ES_sig(context)      ((context)->uc_mcontext.gregs[ES])
+#define SS_sig(context)      ((context)->uc_mcontext.gregs[SS])
+                            
+#define FS_sig(context)      ((context)->uc_mcontext.gregs[FS])
+#define GS_sig(context)      ((context)->uc_mcontext.gregs[GS])
+
+#define EFL_sig(context)     ((context)->uc_mcontext.gregs[EFL])
+                            
+#define EIP_sig(context)     ((context)->uc_mcontext.gregs[EIP])
+#ifdef R_ESP
+#define ESP_sig(context)     ((context)->uc_mcontext.gregs[R_ESP])
+#else
+#define ESP_sig(context)     ((context)->uc_mcontext.gregs[ESP])
+#endif
+#ifdef TRAPNO
+#define TRAP_sig(context)     ((context)->uc_mcontext.gregs[TRAPNO])
+#endif
+
+#endif  /* svr4 || SCO_DS */
+                            
+
+extern void WINAPI REGS_FUNC(RtlRaiseException)( EXCEPTION_RECORD *rec, CONTEXT *context );
+
+
+/***********************************************************************
+ *           handler_init
+ *
+ * Initialization code for a signal handler.
+ * Restores the proper %fs value for the current thread.
+ */
+static inline void handler_init( CONTEXT *context, const SIGCONTEXT *sigcontext )
+{
+    WORD fs;
+    /* get %fs at time of the fault */
+#ifdef FS_sig
+    fs = FS_sig(sigcontext);
+#else
+    GET_FS(fs);
+#endif
+    context->SegFs = fs;
+    /* now restore a proper %fs for the fault handler */
+    if (!IS_SELECTOR_SYSTEM(CS_sig(sigcontext))) fs = SYSLEVEL_Win16CurrentTeb;
+    if (!fs) fs = SYSLEVEL_EmergencyTeb;
+    SET_FS(fs);
+}
+
+
+/***********************************************************************
+ *           save_context
+ *
+ * Set the register values from a sigcontext. 
+ */
+static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext )
+{
+    context->Eax    = EAX_sig(sigcontext);
+    context->Ebx    = EBX_sig(sigcontext);
+    context->Ecx    = ECX_sig(sigcontext);
+    context->Edx    = EDX_sig(sigcontext);
+    context->Esi    = ESI_sig(sigcontext);
+    context->Edi    = EDI_sig(sigcontext);
+    context->Ebp    = EBP_sig(sigcontext);
+    context->EFlags = EFL_sig(sigcontext);
+    context->Eip    = EIP_sig(sigcontext);
+    context->Esp    = ESP_sig(sigcontext);
+    context->SegCs  = LOWORD(CS_sig(sigcontext));
+    context->SegDs  = LOWORD(DS_sig(sigcontext));
+    context->SegEs  = LOWORD(ES_sig(sigcontext));
+    context->SegSs  = LOWORD(SS_sig(sigcontext));
+    /* %fs already handled in handler_init */
+#ifdef GS_sig
+    context->SegGs  = LOWORD(GS_sig(sigcontext));
+#else
+    GET_GS( context->SegGs );
+    context->SegGs &= 0xffff;
+#endif
+    if (ISV86(context)) V86BASE(context) = (DWORD)DOSMEM_MemoryBase(0);
+}
+
+
+/***********************************************************************
+ *           restore_context
+ *
+ * Build a sigcontext from the register values.
+ */
+static void restore_context( const CONTEXT *context, SIGCONTEXT *sigcontext )
+{
+    EAX_sig(sigcontext) = context->Eax;
+    EBX_sig(sigcontext) = context->Ebx;
+    ECX_sig(sigcontext) = context->Ecx;
+    EDX_sig(sigcontext) = context->Edx;
+    ESI_sig(sigcontext) = context->Esi;
+    EDI_sig(sigcontext) = context->Edi;
+    EBP_sig(sigcontext) = context->Ebp;
+    EFL_sig(sigcontext) = context->EFlags;
+    EIP_sig(sigcontext) = context->Eip;
+    ESP_sig(sigcontext) = context->Esp;
+    CS_sig(sigcontext)  = context->SegCs;
+    DS_sig(sigcontext)  = context->SegDs;
+    ES_sig(sigcontext)  = context->SegEs;
+    SS_sig(sigcontext)  = context->SegSs;
+#ifdef FS_sig
+    FS_sig(sigcontext)  = context->SegFs;
+#else
+    SET_FS( context->SegFs );
+#endif
+#ifdef GS_sig
+    GS_sig(sigcontext)  = context->SegGs;
+#else
+    SET_GS( context->SegGs );
+#endif
+}
+
+
+/***********************************************************************
+ *           save_fpu
+ *
+ * Set the FPU context from a sigcontext. 
+ */
+static void inline save_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext )
+{
+#ifdef FPU_sig
+    if (FPU_sig(sigcontext))
+    {
+        context->FloatSave = *FPU_sig(sigcontext);
+        return;
+    }
+#endif  /* FPU_sig */
+#ifdef __GNUC__
+    __asm__ __volatile__( "fnsave %0; fwait" : "=m" (context->FloatSave) );
+#endif  /* __GNUC__ */
+}
+
+
+/***********************************************************************
+ *           restore_fpu
+ *
+ * Restore the FPU context to a sigcontext. 
+ */
+static void inline restore_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext )
+{
+#ifdef FPU_sig
+    if (FPU_sig(sigcontext))
+    {
+        *FPU_sig(sigcontext) = context->FloatSave;
+        return;
+    }
+#endif  /* FPU_sig */
+#ifdef __GNUC__
+    /* avoid nested exceptions */
+    context->FloatSave.StatusWord &= context->FloatSave.ControlWord | 0xffffff80;
+    __asm__ __volatile__( "frstor %0; fwait" : : "m" (context->FloatSave) );
+#endif  /* __GNUC__ */
+}
+
+
+/**********************************************************************
+ *		get_fpu_code
+ *
+ * Get the FPU exception code from the FPU status.
+ */
+static inline DWORD get_fpu_code( const CONTEXT *context )
+{
+    DWORD status = context->FloatSave.StatusWord;
+
+    if (status & 0x01)  /* IE */
+    {
+        if (status & 0x40)  /* SF */
+            return EXCEPTION_FLT_STACK_CHECK;
+        else
+            return EXCEPTION_FLT_INVALID_OPERATION;
+    }
+    if (status & 0x02) return EXCEPTION_FLT_DENORMAL_OPERAND;  /* DE flag */
+    if (status & 0x04) return EXCEPTION_FLT_DIVIDE_BY_ZERO;    /* ZE flag */
+    if (status & 0x08) return EXCEPTION_FLT_OVERFLOW;          /* OE flag */
+    if (status & 0x10) return EXCEPTION_FLT_UNDERFLOW;         /* UE flag */
+    if (status & 0x20) return EXCEPTION_FLT_INEXACT_RESULT;    /* PE flag */
+    return EXCEPTION_FLT_INVALID_OPERATION;  /* generic error */
+}
+
+
+/**********************************************************************
+ *		segv_handler
+ *
+ * Handler for SIGSEGV and related errors.
+ */
+static HANDLER_DEF(segv_handler)
+{
+    EXCEPTION_RECORD rec;
+    CONTEXT context;
+
+    handler_init( &context, HANDLER_CONTEXT );
+
+#if defined(TRAP_sig) && defined(CR2_sig)
+    /* we want the page-fault case to be fast */
+    if (TRAP_sig(HANDLER_CONTEXT) == 14)
+        if (VIRTUAL_HandleFault( (LPVOID)CR2_sig(HANDLER_CONTEXT) )) return;
+#endif
+
+    save_context( &context, HANDLER_CONTEXT );
+    rec.ExceptionRecord  = NULL;
+    rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
+    rec.ExceptionAddress = (LPVOID)context.Eip;
+    rec.NumberParameters = 0;
+
+#ifdef TRAP_sig
+    switch(TRAP_sig(HANDLER_CONTEXT))
+    {
+    case 4:   /* Overflow exception */
+        rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
+        break;
+    case 5:   /* Bound range exception */
+        rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
+        break;
+    case 6:   /* Invalid opcode exception */
+        rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
+        break;
+    case 12:  /* Stack fault */
+        rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
+        break;
+    case 11:  /* Segment not present exception */
+    case 13:  /* General protection fault */
+        if (INSTR_EmulateInstruction( &context )) goto restore;
+        rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
+        break;
+    case 14:  /* Page fault */
+#ifdef CR2_sig
+        rec.NumberParameters = 2;
+#ifdef ERROR_sig
+        rec.ExceptionInformation[0] = (ERROR_sig(HANDLER_CONTEXT) & 2) != 0;
+#else
+        rec.ExceptionInformation[0] = 0;
+#endif /* ERROR_sig */
+        rec.ExceptionInformation[1] = CR2_sig(HANDLER_CONTEXT);
+#endif /* CR2_sig */
+        rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
+        break;
+    case 17:  /* Alignment check exception */
+        /* FIXME: pass through exception handler first? */
+    	if (context.EFlags & 0x00040000)
+        {
+            /* Disable AC flag, return */
+            context.EFlags &= ~0x00040000;
+            goto restore;
+ 	}
+        rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
+        break;
+    default:
+        ERR( "Got unexpected trap %ld\n", TRAP_sig(HANDLER_CONTEXT) );
+        /* fall through */
+    case 2:   /* NMI interrupt */
+    case 7:   /* Device not available exception */
+    case 8:   /* Double fault exception */
+    case 10:  /* Invalid TSS exception */
+    case 15:  /* Unknown exception */
+    case 18:  /* Machine check exception */
+    case 19:  /* Cache flush exception */
+        rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
+        break;
+    }
+#else  /* TRAP_sig */
+    if (INSTR_EmulateInstruction( &context )) return;
+    rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;  /* generic error */
+#endif  /* TRAP_sig */
+
+    REGS_FUNC(RtlRaiseException)( &rec, &context );
+ restore:
+    restore_context( &context, HANDLER_CONTEXT );
+}
+
+
+/**********************************************************************
+ *		trap_handler
+ *
+ * Handler for SIGTRAP.
+ */
+static HANDLER_DEF(trap_handler)
+{
+    EXCEPTION_RECORD rec;
+    CONTEXT context;
+
+    handler_init( &context, HANDLER_CONTEXT );
+
+#ifdef TRAP_sig
+    rec.ExceptionCode = (TRAP_sig(HANDLER_CONTEXT) == 1) ?
+                            EXCEPTION_SINGLE_STEP : EXCEPTION_BREAKPOINT;
+#else
+    rec.ExceptionCode = EXCEPTION_BREAKPOINT;
+#endif  /* TRAP_sig */
+
+    save_context( &context, HANDLER_CONTEXT );
+    rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
+    rec.ExceptionRecord  = NULL;
+    rec.ExceptionAddress = (LPVOID)context.Eip;
+    rec.NumberParameters = 0;
+    REGS_FUNC(RtlRaiseException)( &rec, &context );
+    restore_context( &context, HANDLER_CONTEXT );
+}
+
+
+/**********************************************************************
+ *		fpe_handler
+ *
+ * Handler for SIGFPE.
+ */
+static HANDLER_DEF(fpe_handler)
+{
+    EXCEPTION_RECORD rec;
+    CONTEXT context;
+
+    handler_init( &context, HANDLER_CONTEXT );
+
+    save_fpu( &context, HANDLER_CONTEXT );
+
+#ifdef TRAP_sig
+    switch(TRAP_sig(HANDLER_CONTEXT))
+    {
+    case 0:   /* Division by zero exception */
+        rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
+        break;
+    case 9:   /* Coprocessor segment overrun */
+        rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
+        break;
+    case 16:  /* Floating point exception */
+        rec.ExceptionCode = get_fpu_code( &context );
+        break;
+    default:
+        ERR( "Got unexpected trap %ld\n", TRAP_sig(HANDLER_CONTEXT) );
+        rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
+        break;
+    }
+#else  /* TRAP_sig */
+    rec.ExceptionCode = get_fpu_code( &context );
+#endif  /* TRAP_sig */
+
+    save_context( &context, HANDLER_CONTEXT );
+    rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
+    rec.ExceptionRecord  = NULL;
+    rec.ExceptionAddress = (LPVOID)context.Eip;
+    rec.NumberParameters = 0;
+    REGS_FUNC(RtlRaiseException)( &rec, &context );
+    restore_context( &context, HANDLER_CONTEXT );
+    restore_fpu( &context, HANDLER_CONTEXT );
+}
+
+
+/**********************************************************************
+ *		int_handler
+ *
+ * Handler for SIGINT.
+ */
+static HANDLER_DEF(int_handler)
+{
+    EXCEPTION_RECORD rec;
+    CONTEXT context;
+
+    handler_init( &context, HANDLER_CONTEXT );
+    save_context( &context, HANDLER_CONTEXT );
+    rec.ExceptionCode    = CONTROL_C_EXIT;
+    rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
+    rec.ExceptionRecord  = NULL;
+    rec.ExceptionAddress = (LPVOID)context.Eip;
+    rec.NumberParameters = 0;
+    REGS_FUNC(RtlRaiseException)( &rec, &context );
+    restore_context( &context, HANDLER_CONTEXT );
+}
+
+
+/***********************************************************************
+ *           set_handler
+ *
+ * Set a signal handler
+ */
+static int set_handler( int sig, void (*func)() )
+{
+#ifdef linux
+    struct kernel_sigaction sig_act;
+    sig_act.sa_handler = func;
+    sig_act.sa_flags   = SA_RESTART | SA_NOMASK;
+    sig_act.sa_mask    = 0;
+    /* point to the top of the stack */
+    sig_act.sa_restorer = (char *)NtCurrentTeb()->signal_stack + SIGNAL_STACK_SIZE;
+    return wine_sigaction( sig, &sig_act, NULL );
+#else  /* linux */
+    struct sigaction sig_act;
+    sig_act.sa_handler = func;
+    sigemptyset( &sig_act.sa_mask );
+
+# if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+    sig_act.sa_flags = SA_ONSTACK;
+# elif defined (__svr4__) || defined(_SCO_DS)
+    sig_act.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART;
+# elif defined(__EMX__)
+    sig_act.sa_flags = 0; /* FIXME: EMX has only SA_ACK and SA_SYSV */
+# else
+    sig_act.sa_flags = 0;
+# endif
+    return sigaction( sig, &sig_act, NULL );
+#endif  /* linux */
+}
+
+
+/**********************************************************************
+ *		SIGNAL_Init
+ */
+BOOL SIGNAL_Init(void)
+{
+#ifdef HAVE_WORKING_SIGALTSTACK
+    struct sigaltstack ss;
+    if ((ss.ss_sp = NtCurrentTeb()->signal_stack))
+    {
+        ss.ss_size  = SIGNAL_STACK_SIZE;
+        ss.ss_flags = 0;
+        if (sigaltstack(&ss, NULL) < 0)
+        {
+            perror("sigaltstack");
+            /* fall through on error and try it differently */
+        }
+    }
+#endif  /* HAVE_SIGALTSTACK */
+    
+    /* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead  */
+    signal( SIGPIPE, SIG_IGN );
+    /* automatic child reaping to avoid zombies */
+    signal( SIGCHLD, SIG_IGN );
+
+    if (set_handler( SIGINT,  (void (*)())int_handler ) == -1) goto error;
+    if (set_handler( SIGFPE,  (void (*)())fpe_handler ) == -1) goto error;
+    if (set_handler( SIGSEGV, (void (*)())segv_handler ) == -1) goto error;
+    if (set_handler( SIGILL,  (void (*)())segv_handler ) == -1) goto error;
+#ifdef SIGBUS
+    if (set_handler( SIGBUS,  (void (*)())segv_handler ) == -1) goto error;
+#endif
+#ifdef SIGTRAP
+    if (set_handler( SIGTRAP, (void (*)())trap_handler ) == -1) goto error;
+#endif
+    return TRUE;
+
+ error:
+    perror("sigaction");
+    return FALSE;
+}
+
+#endif  /* __i386__ */
diff --git a/graphics/ddraw.c b/graphics/ddraw.c
index 45a4534..853bef0 100644
--- a/graphics/ddraw.c
+++ b/graphics/ddraw.c
@@ -3516,7 +3516,7 @@
 	TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
 
 #ifdef RESTORE_SIGNALS
-	EXC_InitHandlers();
+	SIGNAL_Init();
 #endif
 	return DD_OK;
 }
@@ -3918,7 +3918,7 @@
 	Sleep(1000);
 	TSXF86DGADirectVideo(display,DefaultScreen(display),0);
 #ifdef RESTORE_SIGNALS
-	EXC_InitHandlers();
+	SIGNAL_Init();
 #endif
 	return DD_OK;
 }
@@ -3969,7 +3969,7 @@
 #endif
 		
 #ifdef RESTORE_SIGNALS
-		EXC_InitHandlers();
+		SIGNAL_Init();
 #endif
 		HeapFree(GetProcessHeap(),0,This);
 		return 0;
@@ -4958,7 +4958,7 @@
 	depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
 	_common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
 #ifdef RESTORE_SIGNALS
-	EXC_InitHandlers();
+	SIGNAL_Init();
 #endif
 
 	return DD_OK;
diff --git a/include/debugger.h b/include/debugger.h
index fd11fda..bcbded2 100644
--- a/include/debugger.h
+++ b/include/debugger.h
@@ -9,7 +9,6 @@
 
 #include <sys/types.h> /* u_long ... */
 #include "windef.h"
-#include "sig_context.h"
 #include "miscemu.h"
 
 #define STEP_FLAG 0x100 /* single step flag */
diff --git a/include/dosexe.h b/include/dosexe.h
index 9c27003..f8e365f 100644
--- a/include/dosexe.h
+++ b/include/dosexe.h
@@ -10,7 +10,6 @@
 #include <sys/types.h> /* pid_t */
 #include "winbase.h"   /* for LPSTARTUPINFO32A */
 #include "winnt.h"     /* for PCONTEXT */
-#include "sig_context.h"
 
 typedef struct _DOSSYSTEM {
   int id;
diff --git a/include/miscemu.h b/include/miscemu.h
index d6648a6..c91bb59 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -184,10 +184,6 @@
 /* msdos/xms.c */
 extern void WINAPI XMS_Handler(CONTEXT86*);
 
-/* loader/signal.c */
-extern BOOL SIGNAL_Init(void);
-extern void SIGNAL_SetHandler( int sig, void (*func)() );
-
 /* misc/aspi.c */
 extern void ASPI_DOS_HandleInt(CONTEXT86 *context);
 
diff --git a/include/sig_context.h b/include/sig_context.h
deleted file mode 100644
index 393e0c2..0000000
--- a/include/sig_context.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Signal context definitions
- *
- * Copyright 1995 Alexandre Julliard
- */
-
-#ifndef __WINE_SIG_CONTEXT_H
-#define __WINE_SIG_CONTEXT_H
-
-#ifdef __i386__
-
-#ifdef linux
-typedef struct
-{
-    unsigned short sc_gs, __gsh;
-    unsigned short sc_fs, __fsh;
-    unsigned short sc_es, __esh;
-    unsigned short sc_ds, __dsh;
-    unsigned long sc_edi;
-    unsigned long sc_esi;
-    unsigned long sc_ebp;
-    unsigned long sc_esp;
-    unsigned long sc_ebx;
-    unsigned long sc_edx;
-    unsigned long sc_ecx;
-    unsigned long sc_eax;
-    unsigned long sc_trapno;
-    unsigned long sc_err;
-    unsigned long sc_eip;
-    unsigned short sc_cs, __csh;
-    unsigned long sc_eflags;
-    unsigned long esp_at_signal;
-    unsigned short sc_ss, __ssh;
-    unsigned long i387;
-    unsigned long oldmask;
-    unsigned long cr2;
-} SIGCONTEXT;
-#define __HAVE_SIGCONTEXT
-
-#define HANDLER_DEF(name) void name (int signal, SIGCONTEXT __context)
-#define HANDLER_CONTEXT (&__context)
-
-#endif  /* linux */
-
-#ifdef BSDI
-
-#define EAX_sig(context)     ((context)->tf_eax)
-#define EBX_sig(context)     ((context)->tf_ebx)
-#define ECX_sig(context)     ((context)->tf_ecx)
-#define EDX_sig(context)     ((context)->tf_edx)
-#define ESI_sig(context)     ((context)->tf_esi)
-#define EDI_sig(context)     ((context)->tf_edi)
-#define EBP_sig(context)     ((context)->tf_ebp)
-                            
-#define CS_sig(context)      ((context)->tf_cs)
-#define DS_sig(context)      ((context)->tf_ds)
-#define ES_sig(context)      ((context)->tf_es)
-#define SS_sig(context)      ((context)->tf_ss)
-
-#include <machine/frame.h>
-typedef struct trapframe SIGCONTEXT;
-#define __HAVE_SIGCONTEXT
-
-#define HANDLER_DEF(name) void name(int signal, int code, SIGCONTEXT *__context)
-#define HANDLER_CONTEXT __context
-
-#define EFL_sig(context)     ((context)->tf_eflags)
-
-#define EIP_sig(context)     (*((unsigned long*)&(context)->tf_eip))
-#define ESP_sig(context)     (*((unsigned long*)&(context)->tf_esp))
-
-#endif /* bsdi */
-
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
-
-#include <signal.h>
-typedef struct sigcontext SIGCONTEXT;
-#define __HAVE_SIGCONTEXT
-
-#define HANDLER_DEF(name) void name(int signal, int code, SIGCONTEXT *__context)
-#define HANDLER_CONTEXT __context
-
-#endif  /* FreeBSD */
-
-#if defined(__svr4__) || defined(_SCO_DS) || defined(__sun)
-
-#include <signal.h>
-#ifdef _SCO_DS
-#include <sys/regset.h>
-#endif
-/* Solaris kludge */
-#undef ERR
-#include <sys/ucontext.h>
-#undef ERR
-typedef struct ucontext SIGCONTEXT;
-#define __HAVE_SIGCONTEXT
-
-#define HANDLER_DEF(name) void name(int signal, void *siginfo, SIGCONTEXT *__context)
-#define HANDLER_CONTEXT __context
-
-#endif  /* svr4 || SCO_DS */
-
-#ifdef __EMX__
-typedef struct _fpreg		/* Note 1 */
-{
-  ULONG	 losig;
-  ULONG	 hisig;
-  USHORT signexp;
-} FPREG;
-typedef FPREG *PFPREG;
-
-typedef struct _CONTEXT		/* Note 1 */
-{
-  ULONG ContextFlags;
-  ULONG ctx_env[7];
-  FPREG ctx_stack[8];
-  ULONG ctx_SegGs;
-  ULONG ctx_SegFs;
-  ULONG ctx_SegEs;
-  ULONG ctx_SegDs;
-  ULONG ctx_RegEdi;
-  ULONG ctx_RegEsi;
-  ULONG ctx_RegEax;
-  ULONG ctx_RegEbx;
-  ULONG ctx_RegEcx;
-  ULONG ctx_RegEdx;
-  ULONG ctx_RegEbp;
-  ULONG ctx_RegEip;
-  ULONG ctx_SegCs;
-  ULONG ctx_EFlags;
-  ULONG ctx_RegEsp;
-  ULONG ctx_SegSs;
-} SIGCONTEXT;
-#define __HAVE_SIGCONTEXT
-/*typedef CONTEXTRECORD *PCONTEXTRECORD;*/
-
-#endif  /* __EMX__ */
-
-
-#if defined(linux) || defined(__NetBSD__) || defined(__FreeBSD__) \
- || defined(__OpenBSD__)
-
-#define EAX_sig(context)     ((context)->sc_eax)
-#define EBX_sig(context)     ((context)->sc_ebx)
-#define ECX_sig(context)     ((context)->sc_ecx)
-#define EDX_sig(context)     ((context)->sc_edx)
-#define ESI_sig(context)     ((context)->sc_esi)
-#define EDI_sig(context)     ((context)->sc_edi)
-#define EBP_sig(context)     ((context)->sc_ebp)
-                            
-#define CS_sig(context)      ((context)->sc_cs)
-#define DS_sig(context)      ((context)->sc_ds)
-#define ES_sig(context)      ((context)->sc_es)
-#define SS_sig(context)      ((context)->sc_ss)
-                            
-#ifdef linux
-/* FS and GS are now in the sigcontext struct of FreeBSD, but not 
- * saved by the exception handling. duh.
- */
-#define FS_sig(context)      ((context)->sc_fs)
-#define GS_sig(context)      ((context)->sc_gs)
-#define CR2_sig(context)     ((context)->cr2)
-#define TRAP_sig(context)    ((context)->sc_trapno)
-#define ERROR_sig(context)   ((context)->sc_err)
-#define FPU_sig(context)     ((FLOATING_SAVE_AREA*)((context)->i387))
-#endif
-
-#ifndef __FreeBSD__
-#define EFL_sig(context)     ((context)->sc_eflags)
-#else                       
-#define EFL_sig(context)     ((context)->sc_efl)
-/* FreeBSD, see i386/i386/traps.c::trap_pfault va->err kludge  */
-#define CR2_sig(context)     ((context)->sc_err)
-#endif                      
-
-
-#define EIP_sig(context)     (*((unsigned long*)&(context)->sc_eip))
-#define ESP_sig(context)     (*((unsigned long*)&(context)->sc_esp))
-
-#endif  /* linux || __NetBSD__ || __FreeBSD__ || __OpenBSD__ */
-
-#if defined(__svr4__) || defined(_SCO_DS) || defined(__sun)
-
-#ifdef _SCO_DS
-#define gregs regs
-#endif
-
-#define EAX_sig(context)     ((context)->uc_mcontext.gregs[EAX])
-#define EBX_sig(context)     ((context)->uc_mcontext.gregs[EBX])
-#define ECX_sig(context)     ((context)->uc_mcontext.gregs[ECX])
-#define EDX_sig(context)     ((context)->uc_mcontext.gregs[EDX])
-#define ESI_sig(context)     ((context)->uc_mcontext.gregs[ESI])
-#define EDI_sig(context)     ((context)->uc_mcontext.gregs[EDI])
-#define EBP_sig(context)     ((context)->uc_mcontext.gregs[EBP])
-                            
-#define CS_sig(context)      ((context)->uc_mcontext.gregs[CS])
-#define DS_sig(context)      ((context)->uc_mcontext.gregs[DS])
-#define ES_sig(context)      ((context)->uc_mcontext.gregs[ES])
-#define SS_sig(context)      ((context)->uc_mcontext.gregs[SS])
-                            
-#define FS_sig(context)      ((context)->uc_mcontext.gregs[FS])
-#define GS_sig(context)      ((context)->uc_mcontext.gregs[GS])
-
-#define EFL_sig(context)     ((context)->uc_mcontext.gregs[EFL])
-                            
-#define EIP_sig(context)     ((context)->uc_mcontext.gregs[EIP])
-#ifdef R_ESP
-#define ESP_sig(context)     ((context)->uc_mcontext.gregs[R_ESP])
-#else
-#define ESP_sig(context)     ((context)->uc_mcontext.gregs[ESP])
-#endif
-#ifdef TRAPNO
-#define TRAP_sig(context)     ((context)->uc_mcontext.gregs[TRAPNO])
-#endif
-
-#endif  /* svr4 || SCO_DS */
-                            
-#ifdef __EMX__
-
-#define EAX_sig(context)     ((context)->ctx_RegEax)
-#define EBX_sig(context)     ((context)->ctx_RegEbx)
-#define ECX_sig(context)     ((context)->ctx_RegEcx)
-#define EDX_sig(context)     ((context)->ctx_RegEdx)
-#define ESI_sig(context)     ((context)->ctx_RegEsi)
-#define EDI_sig(context)     ((context)->ctx_RegEdi)
-#define EBP_sig(context)     ((context)->ctx_RegEbp)
-#define ESP_sig(context)     ((context)->ctx_RegEsp)
-#define CS_sig(context)      ((context)->ctx_SegCs)
-#define DS_sig(context)      ((context)->ctx_SegDs)
-#define ES_sig(context)      ((context)->ctx_SegEs)
-#define SS_sig(context)      ((context)->ctx_SegSs)
-#define FS_sig(context)      ((context)->ctx_SegFs)
-#define GS_sig(context)      ((context)->ctx_SegGs)
-#define EFL_sig(context)     ((context)->ctx_EFlags)
-#define EIP_sig(context)     ((context)->ctx_RegEip)
-
-#endif  /* __EMX__ */
-
-#ifdef FS_sig
-#include "syslevel.h"
-#define HANDLER_INIT() \
-    do { int fs = IS_SELECTOR_SYSTEM(CS_sig(HANDLER_CONTEXT)) ?       \
-                  FS_sig(HANDLER_CONTEXT) : SYSLEVEL_Win16CurrentTeb; \
-         if (!fs) fs = SYSLEVEL_EmergencyTeb;                         \
-         SET_FS(fs);                           } while (0)
-#else
-#define HANDLER_INIT() \
-    do { int fs; GET_FS(fs); fs &= 0xffff;                      \
-         if (!IS_SELECTOR_SYSTEM(CS_sig(HANDLER_CONTEXT)))      \
-             fs = SYSLEVEL_Win16CurrentTeb;                     \
-         if (!fs) fs = SYSLEVEL_EmergencyTeb;                   \
-         SET_FS(fs);                          } while (0)
-#endif
-
-#else /* __i386__ */
-
-#define HANDLER_DEF(name) void name (int signal)
-#define HANDLER_INIT() /* nothing */
-
-#endif /* __i386__ */
-
-#ifndef __HAVE_SIGCONTEXT
-/* empty entry for non x86 architectures mostly. */
-typedef DWORD SIGCONTEXT;
-#define HANDLER_CONTEXT 0
-#endif
-
-#endif /* __WINE_SIG_CONTEXT_H */
diff --git a/include/wine/exception.h b/include/wine/exception.h
index caa20b8..79c437a 100644
--- a/include/wine/exception.h
+++ b/include/wine/exception.h
@@ -169,7 +169,7 @@
 typedef DWORD (*DEBUGHOOK)( EXCEPTION_RECORD *, CONTEXT *, BOOL );
 extern void EXC_SetDebugEventHook( DEBUGHOOK hook );
 extern DEBUGHOOK EXC_GetDebugEventHook(void);
-extern void EXC_InitHandlers(void);
+extern BOOL SIGNAL_Init(void);
 #endif
 
 #endif  /* __WINE_WINE_EXCEPTION_H */
diff --git a/loader/Makefile.in b/loader/Makefile.in
index 448f984..67d1bd8 100644
--- a/loader/Makefile.in
+++ b/loader/Makefile.in
@@ -15,7 +15,6 @@
 	pe_image.c \
 	pe_resource.c \
 	resource.c \
-	signal.c \
 	task.c
 
 GLUE = task.c
diff --git a/loader/main.c b/loader/main.c
index dea1b95..a4a6815 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -65,9 +65,6 @@
     /* Initialize syslevel handling */
     SYSLEVEL_Init();
 
-    /* Initialize signal handling */
-    if (!SIGNAL_Init()) return FALSE;
-
     /* Load the configuration file */
     if (!PROFILE_LoadWineIni()) return FALSE;
 
diff --git a/loader/signal.c b/loader/signal.c
deleted file mode 100644
index ab67c24..0000000
--- a/loader/signal.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Wine signal handling
- *
- * Copyright 1995 Alexandre Julliard
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <errno.h>
-#include <time.h>
-#include <setjmp.h>
-
-#include <sys/time.h>
-#include <sys/timeb.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-#ifdef HAVE_SYSCALL_H
-# include <syscall.h>
-#else
-# ifdef HAVE_SYS_SYSCALL_H
-#  include <sys/syscall.h>
-# endif
-#endif
-
-#include "winsock.h"
-#include "global.h"
-#include "options.h"
-#include "miscemu.h"
-#include "dosexe.h"
-#include "thread.h"
-#include "wine/exception.h"
-#include "debugtools.h"
-
-
-/* Linux sigaction function */
-
-#if defined(linux) && defined(__i386__)
-/* This is the sigaction structure from the Linux 2.1.20 kernel.  */
-
-#undef sa_handler
-struct kernel_sigaction
-{
-    void (*sa_handler)();
-    unsigned long sa_mask;
-    unsigned long sa_flags;
-    void (*sa_restorer)();
-};
-
-/* Similar to the sigaction function in libc, except it leaves alone the
-   restorer field, which is used to specify the signal stack address */
-static inline int wine_sigaction( int sig, struct kernel_sigaction *new,
-                                      struct kernel_sigaction *old )
-{
-#ifdef __PIC__
-    __asm__ __volatile__( "pushl %%ebx\n\t"
-                          "movl %2,%%ebx\n\t"
-                          "int $0x80\n\t"
-                          "popl %%ebx"
-                          : "=a" (sig)
-                          : "0" (SYS_sigaction),
-                            "r" (sig),
-                            "c" (new),
-                            "d" (old) );
-#else
-    __asm__ __volatile__( "int $0x80"
-                          : "=a" (sig)
-                          : "0" (SYS_sigaction),
-                            "b" (sig),
-                            "c" (new),
-                            "d" (old) );
-#endif  /* __PIC__ */
-    if (sig>=0)
-        return 0;
-    errno = -sig;
-    return -1;
-}
-#endif /* linux && __i386__ */
-
-/* Signal stack */
-
-static char SIGNAL_Stack[16384];
-
-
-/**********************************************************************
- *		SIGNAL_SetHandler
- */
-void SIGNAL_SetHandler( int sig, void (*func)() )
-{
-    int ret;
-
-#if defined(linux) && defined(__i386__)
-
-    struct kernel_sigaction sig_act;
-    sig_act.sa_handler = func;
-    sig_act.sa_flags   = SA_RESTART | SA_NOMASK;
-    sig_act.sa_mask    = 0;
-    /* Point to the top of the stack, minus 4 just in case, and make
-       it aligned  */
-    sig_act.sa_restorer = 
-        (void (*)())((int)(SIGNAL_Stack + sizeof(SIGNAL_Stack) - 4) & ~3);
-    ret = wine_sigaction( sig, &sig_act, NULL );
-
-#else  /* linux && __i386__ */
-
-    struct sigaction sig_act;
-    sig_act.sa_handler = func;
-    sigemptyset( &sig_act.sa_mask );
-
-# if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
-    sig_act.sa_flags = SA_ONSTACK;
-# elif defined (__svr4__) || defined(_SCO_DS)
-    sig_act.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART;
-# elif defined(__EMX__)
-    sig_act.sa_flags = 0; /* FIXME: EMX has only SA_ACK and SA_SYSV */
-# else
-    sig_act.sa_flags = 0;
-# endif
-    ret = sigaction( sig, &sig_act, NULL );
-
-#endif  /* linux && __i386__ */
-
-    if (ret < 0)
-    {
-        perror( "sigaction" );
-        exit(1);
-    }
-}
-
-
-/**********************************************************************
- *		SIGNAL_Init
- */
-BOOL SIGNAL_Init(void)
-{
-#ifdef HAVE_WORKING_SIGALTSTACK
-    struct sigaltstack ss;
-    ss.ss_sp    = SIGNAL_Stack;
-    ss.ss_size  = sizeof(SIGNAL_Stack);
-    ss.ss_flags = 0;
-    if (sigaltstack(&ss, NULL) < 0)
-    {
-        perror("sigaltstack");
-	/* fall through on error and try it differently */
-    }
-#endif  /* HAVE_SIGALTSTACK */
-    
-    /* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead  */
-    signal (SIGPIPE, SIG_IGN);
-    /* automatic child reaping to avoid zombies */
-    signal (SIGCHLD, SIG_IGN);
-    EXC_InitHandlers();
-    return TRUE;
-}
diff --git a/scheduler/process.c b/scheduler/process.c
index db423d9..1e0bb8a 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -362,6 +362,9 @@
     if (!(SystemHeap = HeapCreate( HEAP_GROWABLE, 0x10000, 0 ))) return FALSE;
     initial_pdb.system_heap = initial_pdb.heap = SystemHeap;
 
+    /* Initialize signal handling */
+    if (!SIGNAL_Init()) return FALSE;
+
     /* Create the environment DB of the first process */
     if (!PROCESS_CreateEnvDB()) return FALSE;
 
diff --git a/scheduler/sysdeps.c b/scheduler/sysdeps.c
index 6086a38..c9ea1b0 100644
--- a/scheduler/sysdeps.c
+++ b/scheduler/sysdeps.c
@@ -28,6 +28,7 @@
 #include "thread.h"
 #include "server.h"
 #include "winbase.h"
+#include "wine/exception.h"
 #include "debugtools.h"
 
 DEFAULT_DEBUG_CHANNEL(thread)
@@ -130,7 +131,16 @@
 {
     SYSDEPS_SetCurThread( teb );
     CLIENT_InitThread();
-    teb->startup();
+    SIGNAL_Init();
+    __TRY
+    {
+        teb->startup();
+    }
+    __EXCEPT(UnhandledExceptionFilter)
+    {
+        TerminateThread( GetCurrentThread(), GetExceptionCode() );
+    }
+    __ENDTRY
     SYSDEPS_ExitThread();  /* should never get here */
 }