Added a generic mechanism to set up hooks for dispatching signal
handlers outside ntdll.
diff --git a/dlls/kernel/kernel_main.c b/dlls/kernel/kernel_main.c
index 00b8693..a69380e 100644
--- a/dlls/kernel/kernel_main.c
+++ b/dlls/kernel/kernel_main.c
@@ -24,6 +24,7 @@
#include <ctype.h>
#include <string.h>
#include <sys/stat.h>
+#include <signal.h>
#include "winbase.h"
@@ -38,6 +39,8 @@
extern void CODEPAGE_Init(void);
extern BOOL RELAY_Init(void);
+extern int __wine_set_signal_handler(unsigned, int (*)(unsigned));
+extern int CONSOLE_HandleCtrlC(unsigned);
/***********************************************************************
* KERNEL process initialisation routine
@@ -100,6 +103,9 @@
/* Create the shared heap for broken win95 native dlls */
HeapCreate( HEAP_SHARED, 0, 0 );
+ /* finish the process initialisation, if needed */
+ __wine_set_signal_handler(SIGINT, CONSOLE_HandleCtrlC);
+
return TRUE;
}
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 864afad..81b01ab 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1026,3 +1026,6 @@
# Codepages
@ cdecl __wine_init_codepages(ptr ptr) __wine_init_codepages
+
+# signal handling
+@ cdecl __wine_set_signal_handler(long ptr) __wine_set_signal_handler
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index 10c7202..8e01db8 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -380,10 +380,24 @@
WINE_DEFAULT_DEBUG_CHANNEL(seh);
+typedef int (*wine_signal_handler)(unsigned sig);
+
+static wine_signal_handler handlers[256];
+
static sigset_t all_sigs;
/***********************************************************************
+ * dispatch_signal
+ */
+inline static int dispatch_signal(unsigned sig)
+{
+ if (handlers[sig] == NULL) return 0;
+ return handlers[sig](sig);
+}
+
+
+/***********************************************************************
* get_trap_code
*
* Get the trap code for a signal.
@@ -974,8 +988,7 @@
*/
static HANDLER_DEF(int_handler)
{
- extern int CONSOLE_HandleCtrlC(void);
- if (!CONSOLE_HandleCtrlC())
+ if (!dispatch_signal(SIGINT))
{
EXCEPTION_RECORD rec;
CONTEXT context;
@@ -1034,6 +1047,18 @@
}
+/***********************************************************************
+ * __wine_set_signal_handler (NTDLL.@)
+ */
+int __wine_set_signal_handler(unsigned sig, wine_signal_handler wsh)
+{
+ if (sig > sizeof(handlers) / sizeof(handlers[0])) return -1;
+ if (handlers[sig] != NULL) return -2;
+ handlers[sig] = wsh;
+ return 0;
+}
+
+
/**********************************************************************
* SIGNAL_Init
*/
diff --git a/dlls/ntdll/signal_sparc.c b/dlls/ntdll/signal_sparc.c
index e5eaec7..257c14d 100644
--- a/dlls/ntdll/signal_sparc.c
+++ b/dlls/ntdll/signal_sparc.c
@@ -40,8 +40,23 @@
WINE_DEFAULT_DEBUG_CHANNEL(seh);
+typedef int (*wine_signal_handler)(unsigned sig);
+
+static wine_signal_handler handlers[256];
+
static sigset_t all_sigs;
+
+/***********************************************************************
+ * dispatch_signal
+ */
+inline static int dispatch_signal(unsigned sig)
+{
+ if (handlers[sig] == NULL) return 0;
+ return handlers[sig](sig);
+}
+
+
/*
* FIXME: All this works only on Solaris for now
*/
@@ -310,8 +325,7 @@
*/
static void int_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
{
- extern int CONSOLE_HandleCtrlC(void);
- if (!CONSOLE_HandleCtrlC())
+ if (!dispatch_signal(SIGINT))
{
EXCEPTION_RECORD rec;
CONTEXT context;
@@ -347,6 +361,18 @@
/***********************************************************************
+ * __wine_set_signal_handler (NTDLL.@)
+ */
+int __wine_set_signal_handler(unsigned sig, wine_signal_handler wsh)
+{
+ if (sig > sizeof(handlers) / sizeof(handlers[0])) return -1;
+ if (handlers[sig] != NULL) return -2;
+ handlers[sig] = wsh;
+ return 0;
+}
+
+
+/***********************************************************************
* SIGNAL_Unblock
*
* Unblock signals. Called from EXC_RtlRaiseException.