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 #include #include +#include #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 *