From 3d4d7e0153cc82043d079fe2b102696dba2c27ec Mon Sep 17 00:00:00 2001
From: Eric Pouech <eric.pouech@wanadoo.fr>
Date: Wed, 31 Jul 2002 18:46:09 +0000
Subject: [PATCH] Added a generic mechanism to set up hooks for dispatching
 signal handlers outside ntdll.

---
 dlls/kernel/kernel_main.c |  6 ++++++
 dlls/ntdll/ntdll.spec     |  3 +++
 dlls/ntdll/signal_i386.c  | 29 +++++++++++++++++++++++++++--
 dlls/ntdll/signal_sparc.c | 30 ++++++++++++++++++++++++++++--
 4 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/dlls/kernel/kernel_main.c b/dlls/kernel/kernel_main.c
index 00b8693f05f..a69380ed246 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 @@ static BOOL process_attach(void)
     /* 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 864afad052d..81b01ab3b6c 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 10c72022704..8e01db86028 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -380,9 +380,23 @@ typedef struct
 
 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
  *
@@ -974,8 +988,7 @@ static HANDLER_DEF(fpe_handler)
  */
 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 @@ static int set_handler( int sig, int have_sigaltstack, void (*func)() )
 }
 
 
+/***********************************************************************
+ *           __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 e5eaec7fcb8..257c14db1fd 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 fpe_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
  */
 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;
@@ -346,6 +360,18 @@ static int set_handler( int sig, void (*func)() )
 }
 
 
+/***********************************************************************
+ *           __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
  *
-- 
GitLab