Mercurial > octave
changeset 22051:6db928d06b07
move signal functions into octave namespace
* sighandlers.h, sighandlers.cc: Move all functions and variables into
the octave namespace. Change all uses.
(base_interrupt_manager, posix_interrupt_manager, interrupt_manager):
New classes.
(w32_interrupt_manager): Derive from base_interrupt_manager. Limit
Windows-specific code to this class alone.
(interrupt_manager::create_instance): Create w32_interrupt_manager
instance on Windows systems.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 06 Jul 2016 18:31:40 -0400 |
parents | eb751495ba43 |
children | 3cbfbb920de3 |
files | libinterp/corefcn/debug.cc libinterp/corefcn/gl2ps-print.cc libinterp/corefcn/input.cc libinterp/corefcn/oct-hist.cc libinterp/corefcn/pt-jit.cc libinterp/corefcn/sighandlers.cc libinterp/corefcn/sighandlers.h libinterp/corefcn/sysdep.cc libinterp/corefcn/toplev.cc libinterp/octave.cc |
diffstat | 10 files changed, 721 insertions(+), 577 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/debug.cc Wed Jul 06 15:11:14 2016 -0500 +++ b/libinterp/corefcn/debug.cc Wed Jul 06 18:31:40 2016 -0400 @@ -375,7 +375,7 @@ } else if (condition == "interrupt") { - Vdebug_on_interrupt = on_off; + octave::Vdebug_on_interrupt = on_off; } else if (condition == "naninf") #if defined (DBSTOP_NANINF) @@ -416,7 +416,10 @@ id_list->clear (); *stop_flag = on_off; if (stop_flag == &Vdebug_on_error) - Vdebug_on_interrupt = on_off; // Matlabs stops on both + { + // Matlab stops on both. + octave::Vdebug_on_interrupt = on_off; + } } } @@ -469,10 +472,16 @@ void bp_table::dbclear_all_signals (void) { - Vdebug_on_error = false; bp_table::errors_that_stop.clear (); - Vdebug_on_caught = false; bp_table::caught_that_stop.clear (); - Vdebug_on_warning = false; bp_table::warnings_that_stop.clear (); - Vdebug_on_interrupt = false; + Vdebug_on_error = false; + bp_table::errors_that_stop.clear (); + + Vdebug_on_caught = false; + bp_table::caught_that_stop.clear (); + + Vdebug_on_warning = false; + bp_table::warnings_that_stop.clear (); + + octave::Vdebug_on_interrupt = false; } // Process the "warn", "errs", "caught" and "intr" fields for a call of @@ -560,7 +569,7 @@ // process interrupt if (mv.isfield ("intr")) - Vdebug_on_interrupt = 1; + octave::Vdebug_on_interrupt = 1; } // Insert a breakpoint in function fcn at line within file fname, @@ -1322,7 +1331,7 @@ } // print dbstop if interrupt information - if (Vdebug_on_interrupt) + if (octave::Vdebug_on_interrupt) { if (to_screen) octave_stdout << "stop if interrupt\n";
--- a/libinterp/corefcn/gl2ps-print.cc Wed Jul 06 15:11:14 2016 -0500 +++ b/libinterp/corefcn/gl2ps-print.cc Wed Jul 06 18:31:40 2016 -0400 @@ -281,7 +281,7 @@ nwrite = std::fwrite (str, 1, nread, fp); if (nwrite != nread) { - octave_signal_handler (); // Clear SIGPIPE signal + octave::signal_handler (); // Clear SIGPIPE signal error ("gl2ps_renderer::draw: internal pipe error"); } }
--- a/libinterp/corefcn/input.cc Wed Jul 06 15:11:14 2016 -0500 +++ b/libinterp/corefcn/input.cc Wed Jul 06 18:31:40 2016 -0400 @@ -256,7 +256,7 @@ std::string prompt = octave::command_editor::decode_prompt_string (ps); - pipe_handler_error_count = 0; + octave::pipe_handler_error_count = 0; flush_octave_stdout ();
--- a/libinterp/corefcn/oct-hist.cc Wed Jul 06 15:11:14 2016 -0500 +++ b/libinterp/corefcn/oct-hist.cc Wed Jul 06 18:31:40 2016 -0400 @@ -455,12 +455,12 @@ // Ignore interrupts while we are off editing commands. Should we // maybe avoid using system()? - volatile octave_interrupt_handler old_interrupt_handler - = octave_ignore_interrupts (); + volatile octave::interrupt_handler old_interrupt_handler + = octave::ignore_interrupts (); int status = system (cmd.c_str ()); - octave_set_interrupt_handler (old_interrupt_handler); + octave::set_interrupt_handler (old_interrupt_handler); // Check if text edition was successfull. Abort the operation // in case of failure.
--- a/libinterp/corefcn/pt-jit.cc Wed Jul 06 15:11:14 2016 -0500 +++ b/libinterp/corefcn/pt-jit.cc Wed Jul 06 18:31:40 2016 -0400 @@ -2159,8 +2159,8 @@ // Ideally, we should only disable JIT if there is a breakpoint in the code // we are about to run. However, we can't figure this out in O(1) time, so // we conservatively check for the existence of any breakpoints. - return Vjit_enable && ! bp_table::have_breakpoints () - && ! Vdebug_on_interrupt && ! Vdebug_on_error; + return (Vjit_enable && ! bp_table::have_breakpoints () + && ! octave::Vdebug_on_interrupt && ! Vdebug_on_error); } size_t
--- a/libinterp/corefcn/sighandlers.cc Wed Jul 06 15:11:14 2016 -0500 +++ b/libinterp/corefcn/sighandlers.cc Wed Jul 06 18:31:40 2016 -0400 @@ -30,6 +30,11 @@ #include <iostream> #include <new> +#if defined (OCTAVE_USE_WINDOWS_API) +# define WIN32_LEAN_AND_MEAN +# include <windows.h> +#endif + #include "cmd-edit.h" #include "oct-syscalls.h" #include "quit.h" @@ -51,597 +56,672 @@ #include "utils.h" #include "variables.h" -// Nonzero means we have already printed a message for this series of -// SIGPIPES. We assume that the writer will eventually give up. -int pipe_handler_error_count = 0; +namespace octave +{ + // Nonzero means we have already printed a message for this series of + // SIGPIPES. We assume that the writer will eventually give up. + int pipe_handler_error_count = 0; + + // TRUE means we can be interrupted. + bool can_interrupt = false; -// TRUE means we can be interrupted. -bool can_interrupt = false; + // TRUE means we should try to enter the debugger on SIGINT. + bool Vdebug_on_interrupt = false; -// TRUE means we should try to enter the debugger on SIGINT. -bool Vdebug_on_interrupt = false; + // Allow users to avoid writing octave-workspace for SIGHUP (sent by + // closing gnome-terminal, for example). Note that this variable has + // no effect if Vcrash_dumps_octave_core is FALSE. + static bool Vsighup_dumps_octave_core = true; + + // Similar to Vsighup_dumps_octave_core, but for SIGTERM signal. + static bool Vsigterm_dumps_octave_core = true; + + // List of signals we have caught since last call to octave::signal_handler. + static bool *signals_caught = 0; -// Allow users to avoid writing octave-workspace for SIGHUP (sent by -// closing gnome-terminal, for example). Note that this variable has -// no effect if Vcrash_dumps_octave_core is FALSE. -static bool Vsighup_dumps_octave_core = true; + // Forward declaration. + static void user_abort (const char *sig_name, int sig_number); + + class + base_interrupt_manager + { + public: + + base_interrupt_manager (void) { } + + virtual ~base_interrupt_manager (void) { } -// Similar to Vsighup_dumps_octave_core, but for SIGTERM signal. -static bool Vsigterm_dumps_octave_core = true; + virtual void do_jump_to_enclosing_context (void) = 0; + + virtual void do_user_abort (const char *sig_name, int sig_number) = 0; + + virtual void do_raise_sigint (void) = 0; -// List of signals we have caught since last call to octave_signal_handler. -static bool *octave_signals_caught = 0; + private: + + // No copying! -// Forward declaration. -static void user_abort (const char *sig_name, int sig_number); + base_interrupt_manager (const base_interrupt_manager&); + + base_interrupt_manager& operator = (const base_interrupt_manager&); + }; #if defined (OCTAVE_USE_WINDOWS_API) -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -class -w32_interrupt_manager -{ -public: - ~w32_interrupt_manager (void) - { - if (thread) - CloseHandle (thread); - } - - static bool init (void) { return instance_ok (); } - - static void octave_jump_to_enclosing_context (void) - { - if (instance_ok ()) - instance->do_octave_jump_to_enclosing_context (); - } - - static void user_abort (const char *sig_name, int sig_number) - { - if (instance_ok ()) - instance->do_user_abort (sig_name, sig_number); - } - - static void raise_sigint (void) + class + w32_interrupt_manager : public base_interrupt_manager { - if (instance_ok ()) - instance->do_raise_sigint (); - } + public: + + w32_interrupt_manager (void) + : thread (0), thread_id (0) + { + thread_id = GetCurrentThreadId (); -private: - w32_interrupt_manager (void) - : thread (0), thread_id (0) - { - thread_id = GetCurrentThreadId (); + DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), + GetCurrentProcess (), &thread, 0, FALSE, + DUPLICATE_SAME_ACCESS); + } - DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), - GetCurrentProcess (), &thread, 0, FALSE, - DUPLICATE_SAME_ACCESS); - } + ~w32_interrupt_manager (void) { } - static void octave_jump_to_enclosing_context_sync (void) - { + static void jump_to_enclosing_context_sync (void) + { #if defined (_MSC_VER) - _fpreset (); + _fpreset (); #endif - ::octave_jump_to_enclosing_context (); - } + ::octave_jump_to_enclosing_context (); + } - void do_octave_jump_to_enclosing_context (void) - { - bool is_interrupt_thread = (GetCurrentThreadId () == thread_id); + void do_jump_to_enclosing_context (void) + { + bool is_interrupt_thread = (GetCurrentThreadId () == thread_id); - if (is_interrupt_thread) - octave_jump_to_enclosing_context_sync (); - else - { - // 64-bit Windows does not appear to have threadContext.Eip. - // Something else must be done here to allow interrupts to - // properly work across threads. + if (is_interrupt_thread) + jump_to_enclosing_context_sync (); + else + { + // 64-bit Windows does not appear to have threadContext.Eip. + // Something else must be done here to allow interrupts to + // properly work across threads. #if ! (defined (__MINGW64__) || defined (_WIN64)) - CONTEXT threadContext; + CONTEXT threadContext; + + SuspendThread (thread); + threadContext.ContextFlags = CONTEXT_CONTROL; + GetThreadContext (thread, &threadContext); + threadContext.Eip = (DWORD) jump_to_enclosing_context_sync; + SetThreadContext (thread, &threadContext); + ResumeThread (thread); +#endif + } + } + + void do_user_abort (const char *sig_name, int sig_number) + { + bool is_interrupt_thread = (GetCurrentThreadId () == thread_id); + + if (is_interrupt_thread) + octave::user_abort (sig_name, sig_number); + else + { + SuspendThread (thread); + octave::user_abort (sig_name, sig_number); + ResumeThread (thread); + } + } + + void do_raise_sigint (void) + { + bool is_interrupt_thread = (GetCurrentThreadId () == thread_id); + + if (is_interrupt_thread) + octave_raise_wrapper (SIGINT); + else + { + SuspendThread (thread); + octave_raise_wrapper (SIGINT); + ResumeThread (thread); + } + } + + private: + + // A handle to the thread that is running the octave interpreter. + HANDLE thread; + + // The ID of the thread that is running the octave interpreter. + DWORD thread_id; + + private: - SuspendThread (thread); - threadContext.ContextFlags = CONTEXT_CONTROL; - GetThreadContext (thread, &threadContext); - threadContext.Eip = (DWORD) octave_jump_to_enclosing_context_sync; - SetThreadContext (thread, &threadContext); - ResumeThread (thread); + // No copying! + + w32_interrupt_manager (const w32_interrupt_manager&); + + w32_interrupt_manager& operator = (const w32_interrupt_manager&); + }; + #endif - } - } + + class + posix_interrupt_manager : public base_interrupt_manager + { + public: + + posix_interrupt_manager (void) + : base_interrupt_manager () + { } + + ~posix_interrupt_manager (void) { } + + void do_jump_to_enclosing_context (void) + { + ::octave_jump_to_enclosing_context (); + } + + void do_user_abort (const char *sig_name, int sig_number) + { + octave::user_abort (sig_name, sig_number); + } + + void do_raise_sigint (void) + { + octave_raise_wrapper (SIGINT); + } + + private: + + // No copying! + + posix_interrupt_manager (const posix_interrupt_manager&); + + posix_interrupt_manager& operator = (const posix_interrupt_manager&); + }; + + class + interrupt_manager + { + public: + + ~interrupt_manager (void) { } + + static bool init (void) { return instance_ok (); } - void do_user_abort (const char *sig_name, int sig_number) - { - bool is_interrupt_thread = (GetCurrentThreadId () == thread_id); + static void jump_to_enclosing_context (void) + { + if (instance_ok ()) + instance->do_jump_to_enclosing_context (); + } + + static void user_abort (const char *sig_name, int sig_number) + { + if (instance_ok ()) + instance->do_user_abort (sig_name, sig_number); + } + + static void raise_sigint (void) + { + if (instance_ok ()) + instance->do_raise_sigint (); + } + + private: + + interrupt_manager (void) { } + + // No copying! + + interrupt_manager (const interrupt_manager&); + + interrupt_manager& operator = (const interrupt_manager&); + + static bool instance_ok (void) + { + bool retval = true; + + if (! instance) + { + instance = create_instance (); + + if (instance) + singleton_cleanup_list::add (cleanup_instance); + } + + if (! instance) + error ("unable to create interrupt_manager"); + + return retval; + } - if (is_interrupt_thread) - ::user_abort (sig_name, sig_number); - else + static base_interrupt_manager *create_instance (void) + { +#if defined (OCTAVE_USE_WINDOWS_API) + return new w32_interrupt_manager (); +#else + return new posix_interrupt_manager (); +#endif + } + + static void cleanup_instance (void) { delete instance; instance = 0; } + + static base_interrupt_manager* instance; + }; + + base_interrupt_manager *interrupt_manager::instance = 0; + + // Called from octave_quit () to actually do something about the signals + // we have caught. + + void + signal_handler (void) + { + // The list of signals is relatively short, so we will just go + // linearly through the list. + + static int sigchld; + static int sigfpe; + static int sigpipe; + + static const bool have_sigchld = octave_get_sig_number ("SIGCHLD", &sigchld); + static const bool have_sigfpe = octave_get_sig_number ("SIGFPE", &sigfpe); + static const bool have_sigpipe = octave_get_sig_number ("SIGPIPE", &sigpipe); + + for (int i = 0; i < octave_num_signals (); i++) { - SuspendThread (thread); - ::user_abort (sig_name, sig_number); - ResumeThread (thread); + if (signals_caught[i]) + { + signals_caught[i] = false; + + if (have_sigchld && i == sigchld) + { + volatile interrupt_handler saved_interrupt_handler + = ignore_interrupts (); + + void *context = octave_block_child (); + + child_list::wait (); + + set_interrupt_handler (saved_interrupt_handler); + + octave_unblock_child (context); + + child_list::reap (); + } + else if (have_sigfpe && i == sigfpe) + std::cerr << "warning: floating point exception" << std::endl; + else if (have_sigpipe && i == sigpipe) + std::cerr << "warning: broken pipe" << std::endl; + } } } - void do_raise_sigint (void) + static void + my_friendly_exit (const char *sig_name, int sig_number, + bool save_vars = true) { - bool is_interrupt_thread = (GetCurrentThreadId () == thread_id); + static bool been_there_done_that = false; + + if (been_there_done_that) + { + set_signal_handler ("SIGABRT", SIG_DFL); - if (is_interrupt_thread) - octave_raise_wrapper (SIGINT); + std::cerr << "panic: attempted clean up failed -- aborting..." + << std::endl; + + sysdep_cleanup (); + + abort (); + } else { - SuspendThread (thread); - octave_raise_wrapper (SIGINT); - ResumeThread (thread); + been_there_done_that = true; + + std::cerr << "panic: " << sig_name << " -- stopping myself..." + << std::endl; + + if (save_vars) + dump_octave_core (); + + if (sig_number < 0) + { + sysdep_cleanup (); + + exit (1); + } + else + { + set_signal_handler (sig_number, SIG_DFL); + + octave_raise_wrapper (sig_number); + } } } - static bool instance_ok (void) + sig_handler * + set_signal_handler (int sig, sig_handler *handler, bool restart_syscalls) + { + return octave_set_signal_handler_internal (sig, handler, restart_syscalls); + } + + sig_handler * + set_signal_handler (const char *signame, sig_handler *handler, + bool restart_syscalls) + { + return octave_set_signal_handler_by_name (signame, handler, + restart_syscalls); + } + + static void + generic_sig_handler (int sig) { - bool retval = true; + my_friendly_exit (octave_strsignal_wrapper (sig), sig); + } + + // Handle SIGCHLD. - if (! instance) + static void + sigchld_handler (int sig) + { + octave_signal_caught = 1; + + signals_caught[sig] = true; + } + +#if defined (__alpha__) + static void + sigfpe_handler (int sig) + { + if (can_interrupt && octave_interrupt_state >= 0) { - instance = new w32_interrupt_manager (); + octave_signal_caught = 1; + + signals_caught[sig] = true; + + octave_interrupt_state++; + } + } +#endif + + static void + sig_hup_handler (int /* sig */) + { + if (Vsighup_dumps_octave_core) + dump_octave_core (); + + clean_up_and_exit (0); + } + + static void + sig_term_handler (int /* sig */) + { + if (Vsigterm_dumps_octave_core) + dump_octave_core (); + + clean_up_and_exit (0); + } + +#if 0 + static void + sigwinch_handler (int /* sig */) + { + command_editor::resize_terminal (); + } +#endif + + // Handle SIGINT by restarting the parser (see octave.cc). + // + // This also has to work for SIGBREAK (on systems that have it), so we + // use the value of sig, instead of just assuming that it is called + // for SIGINT only. + + static void + user_abort (const char *sig_name, int sig_number) + { + if (! octave_initialized) + exit (1); + + if (can_interrupt) + { + if (Vdebug_on_interrupt) + { + if (! octave_debug_on_interrupt_state) + { + tree_evaluator::debug_mode = true; + octave_debug_on_interrupt_state = true; + + return; + } + else + { + // Clear the flag and do normal interrupt stuff. - if (instance) - singleton_cleanup_list::add (cleanup_instance); + tree_evaluator::debug_mode + = bp_table::have_breakpoints () || Vdebugging; + octave_debug_on_interrupt_state = false; + } + } + + if (octave_interrupt_immediately) + { + if (octave_interrupt_state == 0) + octave_interrupt_state = 1; + + interrupt_manager::jump_to_enclosing_context (); + } + else + { + // If we are already cleaning up from a previous interrupt, + // take note of the fact that another interrupt signal has + // arrived. + + if (octave_interrupt_state < 0) + octave_interrupt_state = 0; + + octave_signal_caught = 1; + octave_interrupt_state++; + + if (interactive && ! forced_interactive + && octave_interrupt_state == 2) + std::cerr << "Press Control-C again to abort." << std::endl; + + if (octave_interrupt_state >= 3) + my_friendly_exit (sig_name, sig_number, true); + } } + } - if (! instance) - error ("unable to create w32_interrupt_manager"); + static void + sigint_handler (int sig) + { + interrupt_manager::user_abort (octave_strsignal_wrapper (sig), sig); + } + + static void + sigpipe_handler (int sig) + { + octave_signal_caught = 1; + + signals_caught[sig] = true; + + // Don't loop forever on account of this. + + if (pipe_handler_error_count++ > 100 && octave_interrupt_state >= 0) + octave_interrupt_state++; + } + + interrupt_handler + catch_interrupts (void) + { + interrupt_handler retval; + + interrupt_manager::init (); + + retval.int_handler = set_signal_handler ("SIGINT", sigint_handler); + retval.brk_handler = set_signal_handler ("SIGBREAK", sigint_handler); return retval; } - static void cleanup_instance (void) { delete instance; instance = 0; } - -private: - // A handle to the thread that is running the octave interpreter. - HANDLE thread; - - // The ID of the thread that is running the octave interpreter. - DWORD thread_id; - - static w32_interrupt_manager* instance; -}; - -w32_interrupt_manager* w32_interrupt_manager::instance = 0; + interrupt_handler + ignore_interrupts (void) + { + interrupt_handler retval; -#endif - -// Called from octave_quit () to actually do something about the signals -// we have caught. + interrupt_manager::init (); -void -octave_signal_handler (void) -{ - // The list of signals is relatively short, so we will just go - // linearly through the list. - - static int sigchld; - static int sigfpe; - static int sigpipe; + retval.int_handler = set_signal_handler ("SIGINT", SIG_IGN); + retval.brk_handler = set_signal_handler ("SIGBREAK", SIG_IGN); - static const bool have_sigchld = octave_get_sig_number ("SIGCHLD", &sigchld); - static const bool have_sigfpe = octave_get_sig_number ("SIGFPE", &sigfpe); - static const bool have_sigpipe = octave_get_sig_number ("SIGPIPE", &sigpipe); - - for (int i = 0; i < octave_num_signals (); i++) - { - if (octave_signals_caught[i]) - { - octave_signals_caught[i] = false; - - if (have_sigchld && i == sigchld) - { - volatile octave_interrupt_handler saved_interrupt_handler - = octave_ignore_interrupts (); + return retval; + } - void *context = octave_block_child (); - - octave::child_list::wait (); - - octave_set_interrupt_handler (saved_interrupt_handler); - - octave_unblock_child (context); + interrupt_handler + set_interrupt_handler (const volatile interrupt_handler& h, + bool restart_syscalls) + { + interrupt_handler retval; - octave::child_list::reap (); - } - else if (have_sigfpe && i == sigfpe) - std::cerr << "warning: floating point exception" << std::endl; - else if (have_sigpipe && i == sigpipe) - std::cerr << "warning: broken pipe" << std::endl; - } - } -} + interrupt_manager::init (); + + retval.int_handler = set_signal_handler ("SIGINT", h.int_handler, + restart_syscalls); -static void -my_friendly_exit (const char *sig_name, int sig_number, - bool save_vars = true) -{ - static bool been_there_done_that = false; + retval.brk_handler = set_signal_handler ("SIGBREAK", h.brk_handler, + restart_syscalls); - if (been_there_done_that) - { - octave_set_signal_handler ("SIGABRT", SIG_DFL); - - std::cerr << "panic: attempted clean up failed -- aborting..." - << std::endl; - - sysdep_cleanup (); + return retval; + } - abort (); - } - else - { - been_there_done_that = true; + // Install all the handlers for the signals we might care about. - std::cerr << "panic: " << sig_name << " -- stopping myself..." - << std::endl; - - if (save_vars) - dump_octave_core (); - - if (sig_number < 0) - { - sysdep_cleanup (); + void + install_signal_handlers (void) + { + if (! signals_caught) + signals_caught = new bool [octave_num_signals ()]; - exit (1); - } - else - { - octave_set_signal_handler (sig_number, SIG_DFL); + for (int i = 0; i < octave_num_signals (); i++) + signals_caught[i] = false; - octave_raise_wrapper (sig_number); - } - } -} - -octave_sig_handler * -octave_set_signal_handler (int sig, octave_sig_handler *handler, - bool restart_syscalls) -{ - return octave_set_signal_handler_internal (sig, handler, restart_syscalls); -} + catch_interrupts (); -octave_sig_handler * -octave_set_signal_handler (const char *signame, octave_sig_handler *handler, - bool restart_syscalls) -{ - return octave_set_signal_handler_by_name (signame, handler, - restart_syscalls); -} + set_signal_handler ("SIGABRT", generic_sig_handler); + set_signal_handler ("SIGALRM", generic_sig_handler); + set_signal_handler ("SIGBUS", generic_sig_handler); + set_signal_handler ("SIGCHLD", sigchld_handler); -static void -generic_sig_handler (int sig) -{ - my_friendly_exit (octave_strsignal_wrapper (sig), sig); -} - -// Handle SIGCHLD. + // SIGCLD + // SIGCONT -static void -sigchld_handler (int sig) -{ - octave_signal_caught = 1; - - octave_signals_caught[sig] = true; -} + set_signal_handler ("SIGEMT", generic_sig_handler); #if defined (__alpha__) -static void -sigfpe_handler (int sig) -{ - if (can_interrupt && octave_interrupt_state >= 0) - { - octave_signal_caught = 1; - - octave_signals_caught[sig] = true; - - octave_interrupt_state++; - } -} -#endif - -static void -sig_hup_handler (int /* sig */) -{ - if (Vsighup_dumps_octave_core) - dump_octave_core (); - - clean_up_and_exit (0); -} - -static void -sig_term_handler (int /* sig */) -{ - if (Vsigterm_dumps_octave_core) - dump_octave_core (); - - clean_up_and_exit (0); -} - -#if 0 -static void -sigwinch_handler (int /* sig */) -{ - octave::command_editor::resize_terminal (); -} + set_signal_handler ("SIGFPE", sigfpe_handler); +#else + set_signal_handler ("SIGFPE", generic_sig_handler); #endif -// Handle SIGINT by restarting the parser (see octave.cc). -// -// This also has to work for SIGBREAK (on systems that have it), so we -// use the value of sig, instead of just assuming that it is called -// for SIGINT only. - -static void -user_abort (const char *sig_name, int sig_number) -{ - if (! octave_initialized) - exit (1); + set_signal_handler ("SIGHUP", sig_hup_handler); + set_signal_handler ("SIGILL", generic_sig_handler); - if (can_interrupt) - { - if (Vdebug_on_interrupt) - { - if (! octave_debug_on_interrupt_state) - { - tree_evaluator::debug_mode = true; - octave_debug_on_interrupt_state = true; - - return; - } - else - { - // Clear the flag and do normal interrupt stuff. + // SIGINFO + // SIGINT - tree_evaluator::debug_mode - = bp_table::have_breakpoints () || Vdebugging; - octave_debug_on_interrupt_state = false; - } - } - - if (octave_interrupt_immediately) - { - if (octave_interrupt_state == 0) - octave_interrupt_state = 1; + set_signal_handler ("SIGIOT", generic_sig_handler); + set_signal_handler ("SIGLOST", generic_sig_handler); + set_signal_handler ("SIGPIPE", sigpipe_handler); + set_signal_handler ("SIGPOLL", SIG_IGN); -#if defined (OCTAVE_USE_WINDOWS_API) - w32_interrupt_manager::octave_jump_to_enclosing_context (); -#else - octave_jump_to_enclosing_context (); -#endif - } - else - { - // If we are already cleaning up from a previous interrupt, - // take note of the fact that another interrupt signal has - // arrived. + // SIGPROF + // SIGPWR - if (octave_interrupt_state < 0) - octave_interrupt_state = 0; - - octave_signal_caught = 1; - octave_interrupt_state++; - - if (interactive && ! forced_interactive - && octave_interrupt_state == 2) - std::cerr << "Press Control-C again to abort." << std::endl; + set_signal_handler ("SIGQUIT", generic_sig_handler); + set_signal_handler ("SIGSEGV", generic_sig_handler); - if (octave_interrupt_state >= 3) - my_friendly_exit (sig_name, sig_number, true); - } - } - -} + // SIGSTOP -static void -sigint_handler (int sig) -{ -#if defined (OCTAVE_USE_WINDOWS_API) - w32_interrupt_manager::user_abort (octave_strsignal_wrapper (sig), sig); -#else - user_abort (octave_strsignal_wrapper (sig), sig); -#endif -} - -static void -sigpipe_handler (int sig) -{ - octave_signal_caught = 1; - - octave_signals_caught[sig] = true; - - // Don't loop forever on account of this. - - if (pipe_handler_error_count++ > 100 && octave_interrupt_state >= 0) - octave_interrupt_state++; -} + set_signal_handler ("SIGSYS", generic_sig_handler); + set_signal_handler ("SIGTERM", sig_term_handler); + set_signal_handler ("SIGTRAP", generic_sig_handler); -octave_interrupt_handler -octave_catch_interrupts (void) -{ - octave_interrupt_handler retval; - -#if defined (OCTAVE_USE_WINDOWS_API) - w32_interrupt_manager::init (); -#endif - - retval.int_handler = octave_set_signal_handler ("SIGINT", sigint_handler); - retval.brk_handler = octave_set_signal_handler ("SIGBREAK", sigint_handler); - - return retval; -} + // SIGTSTP + // SIGTTIN + // SIGTTOU + // SIGURG -octave_interrupt_handler -octave_ignore_interrupts (void) -{ - octave_interrupt_handler retval; - -#if defined (OCTAVE_USE_WINDOWS_API) - w32_interrupt_manager::init (); -#endif - - retval.int_handler = octave_set_signal_handler ("SIGINT", SIG_IGN); - retval.brk_handler = octave_set_signal_handler ("SIGBREAK", SIG_IGN); + set_signal_handler ("SIGUSR1", generic_sig_handler); + set_signal_handler ("SIGUSR2", generic_sig_handler); + set_signal_handler ("SIGVTALRM", generic_sig_handler); + set_signal_handler ("SIGIO", SIG_IGN); - return retval; -} - -octave_interrupt_handler -octave_set_interrupt_handler (const volatile octave_interrupt_handler& h, - bool restart_syscalls) -{ - octave_interrupt_handler retval; - -#if defined (OCTAVE_USE_WINDOWS_API) - w32_interrupt_manager::init (); +#if 0 + set_signal_handler ("SIGWINCH", sigwinch_handler); #endif - retval.int_handler = octave_set_signal_handler ("SIGINT", h.int_handler, - restart_syscalls); - - retval.brk_handler = octave_set_signal_handler ("SIGBREAK", h.brk_handler, - restart_syscalls); - - return retval; -} - -// Install all the handlers for the signals we might care about. + set_signal_handler ("SIGXCPU", generic_sig_handler); + set_signal_handler ("SIGXFSZ", generic_sig_handler); + } -void -install_signal_handlers (void) -{ - if (! octave_signals_caught) - octave_signals_caught = new bool [octave_num_signals ()]; - - for (int i = 0; i < octave_num_signals (); i++) - octave_signals_caught[i] = false; - - octave_catch_interrupts (); - - octave_set_signal_handler ("SIGABRT", generic_sig_handler); - octave_set_signal_handler ("SIGALRM", generic_sig_handler); - octave_set_signal_handler ("SIGBUS", generic_sig_handler); - octave_set_signal_handler ("SIGCHLD", sigchld_handler); - - // SIGCLD - // SIGCONT - - octave_set_signal_handler ("SIGEMT", generic_sig_handler); + static void + set_sig_struct_field (octave_scalar_map& m, const char *signame) + { + int signum; -#if defined (__alpha__) - octave_set_signal_handler ("SIGFPE", sigfpe_handler); -#else - octave_set_signal_handler ("SIGFPE", generic_sig_handler); -#endif - - octave_set_signal_handler ("SIGHUP", sig_hup_handler); - octave_set_signal_handler ("SIGILL", generic_sig_handler); - - // SIGINFO - // SIGINT - - octave_set_signal_handler ("SIGIOT", generic_sig_handler); - octave_set_signal_handler ("SIGLOST", generic_sig_handler); - octave_set_signal_handler ("SIGPIPE", sigpipe_handler); - octave_set_signal_handler ("SIGPOLL", SIG_IGN); + // The names in the struct do not include the leading "SIG" prefix. - // SIGPROF - // SIGPWR - - octave_set_signal_handler ("SIGQUIT", generic_sig_handler); - octave_set_signal_handler ("SIGSEGV", generic_sig_handler); - - // SIGSTOP + if (octave_get_sig_number (signame, &signum)) + m.assign (&signame[3], signum); + } - octave_set_signal_handler ("SIGSYS", generic_sig_handler); - octave_set_signal_handler ("SIGTERM", sig_term_handler); - octave_set_signal_handler ("SIGTRAP", generic_sig_handler); - - // SIGTSTP - // SIGTTIN - // SIGTTOU - // SIGURG + static octave_scalar_map + make_sig_struct (void) + { + octave_scalar_map m; - octave_set_signal_handler ("SIGUSR1", generic_sig_handler); - octave_set_signal_handler ("SIGUSR2", generic_sig_handler); - octave_set_signal_handler ("SIGVTALRM", generic_sig_handler); - octave_set_signal_handler ("SIGIO", SIG_IGN); - -#if 0 - octave_set_signal_handler ("SIGWINCH", sigwinch_handler); -#endif - - octave_set_signal_handler ("SIGXCPU", generic_sig_handler); - octave_set_signal_handler ("SIGXFSZ", generic_sig_handler); -} - -static void -set_sig_struct_field (octave_scalar_map& m, const char *signame) -{ - int signum; - - // The names in the struct do not include the leading "SIG" prefix. - - if (octave_get_sig_number (signame, &signum)) - m.assign (&signame[3], signum); -} - -static octave_scalar_map -make_sig_struct (void) -{ - octave_scalar_map m; + set_sig_struct_field (m, "SIGABRT"); + set_sig_struct_field (m, "SIGALRM"); + set_sig_struct_field (m, "SIGBUS"); + set_sig_struct_field (m, "SIGCHLD"); + set_sig_struct_field (m, "SIGCLD"); + set_sig_struct_field (m, "SIGCONT"); + set_sig_struct_field (m, "SIGEMT"); + set_sig_struct_field (m, "SIGFPE"); + set_sig_struct_field (m, "SIGHUP"); + set_sig_struct_field (m, "SIGILL"); + set_sig_struct_field (m, "SIGINFO"); + set_sig_struct_field (m, "SIGINT"); + set_sig_struct_field (m, "SIGIO"); + set_sig_struct_field (m, "SIGIOT"); + set_sig_struct_field (m, "SIGKILL"); + set_sig_struct_field (m, "SIGLOST"); + set_sig_struct_field (m, "SIGPIPE"); + set_sig_struct_field (m, "SIGPOLL"); + set_sig_struct_field (m, "SIGPROF"); + set_sig_struct_field (m, "SIGPWR"); + set_sig_struct_field (m, "SIGQUIT"); + set_sig_struct_field (m, "SIGSEGV"); + set_sig_struct_field (m, "SIGSTKFLT"); + set_sig_struct_field (m, "SIGSTOP"); + set_sig_struct_field (m, "SIGSYS"); + set_sig_struct_field (m, "SIGTERM"); + set_sig_struct_field (m, "SIGTRAP"); + set_sig_struct_field (m, "SIGTSTP"); + set_sig_struct_field (m, "SIGTTIN"); + set_sig_struct_field (m, "SIGTTOU"); + set_sig_struct_field (m, "SIGUNUSED"); + set_sig_struct_field (m, "SIGURG"); + set_sig_struct_field (m, "SIGUSR1"); + set_sig_struct_field (m, "SIGUSR2"); + set_sig_struct_field (m, "SIGVTALRM"); + set_sig_struct_field (m, "SIGWINCH"); + set_sig_struct_field (m, "SIGXCPU"); + set_sig_struct_field (m, "SIGXFSZ"); - set_sig_struct_field (m, "SIGABRT"); - set_sig_struct_field (m, "SIGALRM"); - set_sig_struct_field (m, "SIGBUS"); - set_sig_struct_field (m, "SIGCHLD"); - set_sig_struct_field (m, "SIGCLD"); - set_sig_struct_field (m, "SIGCONT"); - set_sig_struct_field (m, "SIGEMT"); - set_sig_struct_field (m, "SIGFPE"); - set_sig_struct_field (m, "SIGHUP"); - set_sig_struct_field (m, "SIGILL"); - set_sig_struct_field (m, "SIGINFO"); - set_sig_struct_field (m, "SIGINT"); - set_sig_struct_field (m, "SIGIO"); - set_sig_struct_field (m, "SIGIOT"); - set_sig_struct_field (m, "SIGKILL"); - set_sig_struct_field (m, "SIGLOST"); - set_sig_struct_field (m, "SIGPIPE"); - set_sig_struct_field (m, "SIGPOLL"); - set_sig_struct_field (m, "SIGPROF"); - set_sig_struct_field (m, "SIGPWR"); - set_sig_struct_field (m, "SIGQUIT"); - set_sig_struct_field (m, "SIGSEGV"); - set_sig_struct_field (m, "SIGSTKFLT"); - set_sig_struct_field (m, "SIGSTOP"); - set_sig_struct_field (m, "SIGSYS"); - set_sig_struct_field (m, "SIGTERM"); - set_sig_struct_field (m, "SIGTRAP"); - set_sig_struct_field (m, "SIGTSTP"); - set_sig_struct_field (m, "SIGTTIN"); - set_sig_struct_field (m, "SIGTTOU"); - set_sig_struct_field (m, "SIGUNUSED"); - set_sig_struct_field (m, "SIGURG"); - set_sig_struct_field (m, "SIGUSR1"); - set_sig_struct_field (m, "SIGUSR2"); - set_sig_struct_field (m, "SIGVTALRM"); - set_sig_struct_field (m, "SIGWINCH"); - set_sig_struct_field (m, "SIGXCPU"); - set_sig_struct_field (m, "SIGXFSZ"); - - return m; + return m; + } } DEFUN (SIG, args, , @@ -653,7 +733,7 @@ if (args.length () != 0) print_usage (); - static octave_scalar_map m = make_sig_struct (); + static octave_scalar_map m = octave::make_sig_struct (); return ovl (m); } @@ -683,7 +763,8 @@ @seealso{debug_on_error, debug_on_warning} @end deftypefn */) { - return SET_INTERNAL_VARIABLE (debug_on_interrupt); + return set_internal_variable (octave::Vdebug_on_interrupt, args, nargout, + "debug_on_interrupt"); } /* @@ -712,7 +793,9 @@ The original variable value is restored when exiting the function. @end deftypefn */) { - return SET_INTERNAL_VARIABLE (sighup_dumps_octave_core); + return set_internal_variable (octave::Vsighup_dumps_octave_core, + args, nargout, + "sighup_dumps_octave_core"); } /* @@ -741,7 +824,9 @@ The original variable value is restored when exiting the function. @end deftypefn */) { - return SET_INTERNAL_VARIABLE (sigterm_dumps_octave_core); + return set_internal_variable (octave::Vsigterm_dumps_octave_core, + args, nargout, + "sigterm_dumps_octave_core"); } /*
--- a/libinterp/corefcn/sighandlers.h Wed Jul 06 15:11:14 2016 -0500 +++ b/libinterp/corefcn/sighandlers.h Wed Jul 06 18:31:40 2016 -0400 @@ -37,47 +37,97 @@ #include "child-list.h" -// FIXME: the data should probably be private... - -typedef void octave_sig_handler (int); - -struct -octave_interrupt_handler +namespace octave { - octave_sig_handler *int_handler; - octave_sig_handler *brk_handler; -}; + // This type must match the typedef in signal-wrappers.h. + typedef void sig_handler (int); + + struct + interrupt_handler + { + sig_handler *int_handler; + sig_handler *brk_handler; + }; + + // Nonzero means we have already printed a message for this series of + // SIGPIPES. We assume that the writer will eventually give up. + extern int pipe_handler_error_count; + + // TRUE means we can be interrupted. + extern OCTINTERP_API bool can_interrupt; + + extern OCTINTERP_API sig_handler * + set_signal_handler (int sig, sig_handler *h, + bool restart_syscalls = true); -// Nonzero means we have already printed a message for this series of -// SIGPIPES. We assume that the writer will eventually give up. -extern int pipe_handler_error_count; + extern OCTINTERP_API sig_handler * + set_signal_handler (const char *signame, sig_handler *h, + bool restart_syscalls = true); + + extern OCTINTERP_API void install_signal_handlers (void); + + extern OCTINTERP_API void signal_handler (void); + + extern OCTINTERP_API interrupt_handler catch_interrupts (void); -// TRUE means we can be interrupted. -extern OCTINTERP_API bool can_interrupt; + extern OCTINTERP_API interrupt_handler ignore_interrupts (void); + + extern OCTINTERP_API interrupt_handler + set_interrupt_handler (const volatile interrupt_handler& h, + bool restart_syscalls = true); + + // TRUE means we should try to enter the debugger on SIGINT. + extern OCTINTERP_API bool Vdebug_on_interrupt; +} + +#if defined (OCTAVE_USE_DEPRECATED_FUNCTIONS) -extern OCTINTERP_API octave_sig_handler * -octave_set_signal_handler (int sig, octave_sig_handler *, - bool restart_syscalls = true); +OCTAVE_DEPRECATED ("use 'octave::interrupt_handler' instead") +typedef octave::interrupt_handler octave_interrupt_handler; + +OCTAVE_DEPRECATED ("use 'octave::sig_handler' instead") +typedef octave::sig_handler octave_sig_handler; + +OCTAVE_DEPRECATED ("use 'octave::pipe_handler_error_count' instead") +static auto& pipe_handler_error_count = octave::pipe_handler_error_count; -extern OCTINTERP_API octave_sig_handler * -octave_set_signal_handler (const char *signame, octave_sig_handler *, - bool restart_syscalls = true); +OCTAVE_DEPRECATED ("use 'octave::can_interrupt' instead") +static auto& can_interrupt = octave::can_interrupt; -extern OCTINTERP_API void install_signal_handlers (void); - -extern OCTINTERP_API void octave_signal_handler (void); +OCTAVE_DEPRECATED ("use 'octave::set_signal_handler' instead") +inline octave::sig_handler * +octave_set_signal_handler (int sig, octave::sig_handler *handler, + bool restart_syscalls = true) +{ + return octave::set_signal_handler (sig, handler, restart_syscalls); +} -extern OCTINTERP_API octave_interrupt_handler octave_catch_interrupts (void); +OCTAVE_DEPRECATED ("use 'octave::set_signal_handler' instead") +inline octave::sig_handler * +octave_set_signal_handler (const char *signame, octave::sig_handler *handler, + bool restart_syscalls = true) +{ + return octave::set_signal_handler (signame, handler, restart_syscalls); +} -extern OCTINTERP_API octave_interrupt_handler octave_ignore_interrupts (void); +OCTAVE_DEPRECATED ("use 'octave::set_signal_handler' instead") +const auto install_signal_handlers = octave::install_signal_handlers; -extern OCTINTERP_API octave_interrupt_handler -octave_set_interrupt_handler (const volatile octave_interrupt_handler&, - bool restart_syscalls = true); +OCTAVE_DEPRECATED ("use 'octave::signal_handler' instead") +const auto octave_signal_handler = octave::signal_handler; + +OCTAVE_DEPRECATED ("use 'octave::interrupt_handler' instead") +const auto octave_catch_interrupts = octave::catch_interrupts; -// extern void ignore_sigchld (void); +OCTAVE_DEPRECATED ("use 'octave::ignore_interrupts' instead") +const auto octave_ignore_interrupts = octave::ignore_interrupts; -// TRUE means we should try to enter the debugger on SIGINT. -extern OCTINTERP_API bool Vdebug_on_interrupt; +OCTAVE_DEPRECATED ("use 'octave::set_interrupt_handler' instead") +const auto octave_set_interrupt_handler = octave::set_interrupt_handler; + +OCTAVE_DEPRECATED ("use 'octave::Vdebug_on_interrupt' instead") +static auto& Vdebug_on_interrupt = octave::Vdebug_on_interrupt; #endif + +#endif
--- a/libinterp/corefcn/sysdep.cc Wed Jul 06 15:11:14 2016 -0500 +++ b/libinterp/corefcn/sysdep.cc Wed Jul 06 18:31:40 2016 -0400 @@ -523,13 +523,13 @@ raw_mode (true, wait); // Get current handler. - octave_interrupt_handler saved_interrupt_handler - = octave_ignore_interrupts (); + octave::interrupt_handler saved_interrupt_handler + = octave::ignore_interrupts (); // Restore it, disabling system call restarts (if possible) so the // read can be interrupted. - octave_set_interrupt_handler (saved_interrupt_handler, false); + octave::set_interrupt_handler (saved_interrupt_handler, false); int c = std::cin.get (); @@ -537,7 +537,7 @@ std::cin.clear (); // Restore it, enabling system call restarts (if possible). - octave_set_interrupt_handler (saved_interrupt_handler, true); + octave::set_interrupt_handler (saved_interrupt_handler, true); raw_mode (false, true); #endif
--- a/libinterp/corefcn/toplev.cc Wed Jul 06 15:11:14 2016 -0500 +++ b/libinterp/corefcn/toplev.cc Wed Jul 06 18:31:40 2016 -0400 @@ -659,13 +659,13 @@ void recover_from_exception (void) { - can_interrupt = true; + octave::can_interrupt = true; octave_interrupt_immediately = 0; octave_interrupt_state = 0; octave_signal_caught = 0; octave_exception_state = octave_no_exception; octave_restore_signal_mask (); - octave_catch_interrupts (); + octave::catch_interrupts (); } int @@ -673,13 +673,13 @@ { octave_save_signal_mask (); - can_interrupt = true; + octave::can_interrupt = true; - octave_signal_hook = octave_signal_handler; + octave_signal_hook = octave::signal_handler; octave_interrupt_hook = 0; octave_bad_alloc_hook = 0; - octave_catch_interrupts (); + octave::catch_interrupts (); octave_initialized = true;
--- a/libinterp/octave.cc Wed Jul 06 15:11:14 2016 -0500 +++ b/libinterp/octave.cc Wed Jul 06 18:31:40 2016 -0400 @@ -424,13 +424,13 @@ octave_save_signal_mask (); - can_interrupt = true; + octave::can_interrupt = true; - octave_signal_hook = octave_signal_handler; + octave_signal_hook = octave::signal_handler; octave_interrupt_hook = 0; octave_bad_alloc_hook = 0; - octave_catch_interrupts (); + octave::catch_interrupts (); octave_initialized = true; @@ -469,13 +469,13 @@ octave_save_signal_mask (); - can_interrupt = true; + octave::can_interrupt = true; - octave_signal_hook = octave_signal_handler; + octave_signal_hook = octave::signal_handler; octave_interrupt_hook = 0; octave_bad_alloc_hook = 0; - octave_catch_interrupts (); + octave::catch_interrupts (); octave_initialized = true; @@ -816,7 +816,7 @@ initialize_error_handlers (); if (! embedded) - install_signal_handlers (); + octave::install_signal_handlers (); else quit_allowed = false;