summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2001-11-05 16:10:12 +0000
committerXavier Leroy <xavier.leroy@inria.fr>2001-11-05 16:10:12 +0000
commit2ba4aa94da88c98c589429062b58a32500cc51c1 (patch)
tree9069e09712f2c9624a20d4c3aca2a0a98955818f
parent429076f326cab7fb6d508943ca48de0800127374 (diff)
Faire marcher ctrl-C sous Win32
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@3983 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r--asmrun/signals.c6
-rw-r--r--byterun/signals.c6
-rw-r--r--byterun/win32.c47
3 files changed, 59 insertions, 0 deletions
diff --git a/asmrun/signals.c b/asmrun/signals.c
index 158558a88..1d855f343 100644
--- a/asmrun/signals.c
+++ b/asmrun/signals.c
@@ -31,6 +31,12 @@
#include <sys/resource.h>
#endif
+#ifdef _WIN32
+typedef void (*sighandler)(int sig);
+extern sighandler win32_signal(int sig, sighandler action);
+#define signal(sig,act) win32_signal(sig,act)
+#endif
+
#if defined(TARGET_power) && defined(SYS_rhapsody)
/* Confer machdep/ppc/unix_signal.c and mach/ppc/thread_status.h
in the Darwin sources */
diff --git a/byterun/signals.c b/byterun/signals.c
index e376237ab..25920a9ed 100644
--- a/byterun/signals.c
+++ b/byterun/signals.c
@@ -28,6 +28,12 @@
#include "rotatecursor.h"
#endif /* macintosh */
+#ifdef _WIN32
+typedef void (*sighandler)(int sig);
+extern sighandler win32_signal(int sig, sighandler action);
+#define signal(sig,act) win32_signal(sig,act)
+#endif
+
int volatile async_signal_mode = 0;
int volatile pending_signal = 0;
int volatile something_to_do = 0;
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