diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 2001-11-05 16:10:12 +0000 |
---|---|---|
committer | Xavier Leroy <xavier.leroy@inria.fr> | 2001-11-05 16:10:12 +0000 |
commit | 2ba4aa94da88c98c589429062b58a32500cc51c1 (patch) | |
tree | 9069e09712f2c9624a20d4c3aca2a0a98955818f /byterun/win32.c | |
parent | 429076f326cab7fb6d508943ca48de0800127374 (diff) |
Faire marcher ctrl-C sous Win32
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@3983 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'byterun/win32.c')
-rw-r--r-- | byterun/win32.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/byterun/win32.c b/byterun/win32.c index 44eb2bec8..bd82ca699 100644 --- a/byterun/win32.c +++ b/byterun/win32.c @@ -140,6 +140,53 @@ char * caml_dlerror(void) return dlerror_buffer; } +/* Proper emulation of signal(), including ctrl-C and ctrl-break */ + +typedef void (*sighandler)(int sig); +static int ctrl_handler_installed = 0; +static volatile sighandler ctrl_handler_action = SIG_DFL; + +static BOOL WINAPI ctrl_handler(DWORD event) +{ + int saved_mode; + sighandler action; + + /* Only ctrl-C and ctrl-Break are handled */ + if (event != CTRL_C_EVENT && event != CTRL_BREAK_EVENT) return FALSE; + /* Default behavior is to exit, which we get by not handling the event */ + if (ctrl_handler_action == SIG_DFL) return FALSE; + /* Ignore behavior is to do nothing, which we get by claiming that we + have handled the event */ + if (ctrl_handler_action == SIG_IGN) return TRUE; + /* Reset handler to default action for consistency with signal() */ + action = ctrl_handler_action; + ctrl_handler_action = SIG_DFL; + /* Call user-provided signal handler. Win32 doesn't like it when + we do a longjmp() at this point (it looks like we're running in + a different thread than the main program!). So, pretend we are not in + async signal mode, so that the handler simply records the signal. */ + saved_mode = async_signal_mode; + async_signal_mode = 0; + action(SIGINT); + async_signal_mode = saved_mode; + /* We have handled the event */ + return TRUE; +} + +sighandler win32_signal(int sig, sighandler action) +{ + sighandler oldaction; + + if (sig != SIGINT) return signal(sig, action); + if (! ctrl_handler_installed) { + SetConsoleCtrlHandler(ctrl_handler, TRUE); + ctrl_handler_installed = 1; + } + oldaction = ctrl_handler_action; + ctrl_handler_action = action; + return oldaction; +} + /* Expansion of @responsefile and *? file patterns in the command line */ #ifndef HAS_UI |