Mercurial > octave
diff src/sighandlers.cc @ 5451:ed08548b9054
[project @ 2005-09-15 19:52:50 by jwe]
author | jwe |
---|---|
date | Thu, 15 Sep 2005 19:52:50 +0000 |
parents | ac8d64b9e76a |
children | 89f5979e8552 |
line wrap: on
line diff
--- a/src/sighandlers.cc Thu Sep 15 15:36:26 2005 +0000 +++ b/src/sighandlers.cc Thu Sep 15 19:52:50 2005 +0000 @@ -114,17 +114,21 @@ switch (i) { +#ifdef SIGCHLD case SIGCHLD: octave_child_list::reap (); break; +#endif case SIGFPE: std::cerr << "warning: floating point exception -- trying to return to prompt" << std::endl; break; +#ifdef SIGPIPE case SIGPIPE: std::cerr << "warning: broken pipe -- some output may be lost" << std::endl; break; +#endif } } } @@ -143,6 +147,9 @@ #endif std::cerr << "panic: attempted clean up apparently failed -- aborting...\n"; + + MINGW_SIGNAL_CLEANUP (); + abort (); } else @@ -155,7 +162,11 @@ dump_octave_core (); if (sig_number < 0) - exit (1); + { + MINGW_SIGNAL_CLEANUP (); + + exit (1); + } else { octave_set_signal_handler (sig_number, SIG_DFL); @@ -343,13 +354,9 @@ // use the value of sig, instead of just assuming that it is called // for SIGINT only. -static RETSIGTYPE -sigint_handler (int sig) +static +void user_abort(const char *sig_name, int sig_number) { - MAYBE_ACK_SIGNAL (sig); - - MAYBE_REINSTALL_SIGHANDLER (sig, sigint_handler); - if (! octave_initialized) exit (1); @@ -361,7 +368,7 @@ { octave_debug_on_interrupt_state = true; - SIGHANDLER_RETURN (0); + return; } else // Clear the flag and do normal interrupt stuff. @@ -386,10 +393,28 @@ std::cerr << "Press Control-C again to abort." << std::endl; if (octave_interrupt_state >= 3) - my_friendly_exit (sys_siglist[sig], sig, true); + my_friendly_exit (sig_name, sig_number, true); } } +} + +static RETSIGTYPE +sigint_handler (int sig) +{ + MAYBE_ACK_SIGNAL (sig); + + MAYBE_REINSTALL_SIGHANDLER (sig, sigint_handler); + +#ifdef USE_W32_SIGINT + if (w32_in_main_thread ()) + user_abort (sys_siglist[sig], sig); + else + w32_raise (sig); +#else + user_abort (sys_siglist[sig], sig); +#endif + SIGHANDLER_RETURN (0); } @@ -414,6 +439,60 @@ } #endif /* defined(SIGPIPE) */ +#ifdef USE_W32_SIGINT +static BOOL CALLBACK +w32_sigint_handler (DWORD sig) +{ + const char *sig_name; + + switch(sig) + { + case CTRL_BREAK_EVENT: + sig_name = "Ctrl-Break"; + break; + case CTRL_C_EVENT: + sig_name = "Ctrl-C"; + break; + case CTRL_CLOSE_EVENT: + sig_name = "close console"; + break; + case CTRL_LOGOFF_EVENT: + sig_name = "logoff"; + break; + case CTRL_SHUTDOWN_EVENT: + sig_name = "shutdown"; + break; + default: + sig_name = "unknown console event"; + break; + } + + switch(sig) + { + case CTRL_BREAK_EVENT: + case CTRL_C_EVENT: + w32_raise (SIGINT); + break; + + case CTRL_CLOSE_EVENT: + case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: + default: + // We should do the following: + // clean_up_and_exit (0); + // We can't because we aren't running in the normal Octave thread. + user_abort(sig_name, sig); + break; + } + + // Return TRUE if the event was handled, or FALSE if another handler + // should be called. + // XXX FIXME XXX check that windows terminates the thread. + return TRUE; +} +#endif /* w32_sigint_handler */ + + octave_interrupt_handler octave_catch_interrupts (void) { @@ -427,6 +506,22 @@ retval.brk_handler = octave_set_signal_handler (SIGBREAK, sigint_handler); #endif +#ifdef USE_W32_SIGINT + + // Intercept windows console control events. + // Note that the windows console signal handlers chain, so if + // install_signal_handlers is called more than once in the same program, + // then first call the following to avoid duplicates: + // + // SetConsoleCtrlHandler (w32_sigint_handler, FALSE); + + if (! SetConsoleCtrlHandler (w32_sigint_handler, TRUE)) + error ("SetConsoleCtrlHandler failed with %ld\n", GetLastError ()); + + w32_set_quiet_shutdown (); + +#endif + return retval; } @@ -592,6 +687,7 @@ #ifdef SIGXFSZ octave_set_signal_handler (SIGXFSZ, generic_sig_handler); #endif + } static Octave_map