# HG changeset patch # User John W. Eaton # Date 1466175611 14400 # Node ID 1d23b75cbcd16f5bb3d339755c7e960c9d68be46 # Parent 70824a0dd009f4a3549f4bf5f4df2179f43cf055 hide signal.h from C++ sources * signal-wrappers.c, signal-wrappers.h (octave_sig_handler): New typedef. (octave_block_child, octave_block_interrupt_signal, octave_get_sig_number, octave_num_signals, octave_raise_wrapper, octave_restore_signal_mask, octave_save_signal_mask, octave_set_signal_handler_by_name, octave_set_signal_handler_internal, octave_unblock_child, octave_unblock_interrupt_signal): New functions. * sighandlers.cc, sighandlers.h (BADSIG, BLOCK_SIGNAL, BLOCK_CHILD, UNBLOCK_CHILD): Delete macros. Use new signal wrapper functions. * cquit.c, quit.h (octave_signal_mask, octave_save_signal_mask, octave_restore_signal_mask): Move to signal-wrappers.c. * main.in.cc: Use new signal wrapper functions. * octave-gui.cc: Don't include sighandlers.cc. * thread-manager.cc: Use signal wrapper functions. (block_or_unblock_signal): Move to signal-wrappers.c. (octave_thread_manager::block_interrupt_signal): Call octave_block_interrupt_signal. (octave_thread_manager::unblock_interrupt_signal): Call Call octave_ublock_interrupt_signal. * libgui/src/module.mk (libgui_src_libgui_src_la_CPPFLAGS): Include liboctave/wrappers directory in the list. diff -r 70824a0dd009 -r 1d23b75cbcd1 libgui/src/module.mk --- a/libgui/src/module.mk Fri Jun 17 06:51:43 2016 -0400 +++ b/libgui/src/module.mk Fri Jun 17 11:00:11 2016 -0400 @@ -214,7 +214,8 @@ -Ilibinterp/parse-tree -I$(srcdir)/libinterp/parse-tree \ -Ilibinterp/corefcn -I$(srcdir)/libinterp/corefcn \ -I$(srcdir)/libinterp/octave-value \ - -Ilibgnu -I$(srcdir)/libgnu + -Ilibgnu -I$(srcdir)/libgnu \ + -I$(srcdir)/liboctave/wrappers libgui_src_libgui_src_la_CFLAGS = $(AM_CFLAGS) $(WARN_CFLAGS) diff -r 70824a0dd009 -r 1d23b75cbcd1 libgui/src/octave-gui.cc --- a/libgui/src/octave-gui.cc Fri Jun 17 06:51:43 2016 -0400 +++ b/libgui/src/octave-gui.cc Fri Jun 17 11:00:11 2016 -0400 @@ -40,7 +40,6 @@ #include "oct-syscalls.h" #include "octave.h" -#include "sighandlers.h" #include "welcome-wizard.h" #include "resource-manager.h" diff -r 70824a0dd009 -r 1d23b75cbcd1 libgui/src/thread-manager.cc --- a/libgui/src/thread-manager.cc Fri Jun 17 06:51:43 2016 -0400 +++ b/libgui/src/thread-manager.cc Fri Jun 17 11:00:11 2016 -0400 @@ -30,10 +30,8 @@ # include #endif -#include -#include +#include "signal-wrappers.h" -#include "sighandlers.h" #include "thread-manager.h" #if defined (__WIN32__) && ! defined (__CYGWIN__) @@ -82,7 +80,10 @@ // all be executed in the wrong thread? If so, is there any way to // prevent that from happening? - kill (0, SIGINT); + int sigint; + octave_get_sig_number ("SIGINT", &sigint); + + octave_kill_wrapper (0, sigint); } } @@ -99,37 +100,16 @@ : rep (octave_thread_manager::create_rep ()) { } -static void -block_or_unblock_signal (int how, int sig) -{ -#if ! defined (__WIN32__) || defined (__CYGWIN__) - // Blocking/unblocking signals at thread level is only supported - // on platform with fully compliant POSIX threads. This is not - // supported on Win32. Moreover, we have to make sure that SIGINT - // handler is not installed before calling AllocConsole: installing - // a SIGINT handler internally calls SetConsoleCtrlHandler, which - // must be called after AllocConsole to be effective. - - sigset_t signal_mask; - - gnulib::sigemptyset (&signal_mask); - - gnulib::sigaddset (&signal_mask, sig); - - pthread_sigmask (how, &signal_mask, 0); -#endif -} - void octave_thread_manager::block_interrupt_signal (void) { - block_or_unblock_signal (SIG_BLOCK, SIGINT); + octave_block_interrupt_signal (); } void octave_thread_manager::unblock_interrupt_signal (void) { - block_or_unblock_signal (SIG_UNBLOCK, SIGINT); + octave_unblock_interrupt_signal (); } octave_base_thread_manager * diff -r 70824a0dd009 -r 1d23b75cbcd1 libinterp/corefcn/sighandlers.cc --- a/libinterp/corefcn/sighandlers.cc Fri Jun 17 06:51:43 2016 -0400 +++ b/libinterp/corefcn/sighandlers.cc Fri Jun 17 11:00:11 2016 -0400 @@ -24,6 +24,7 @@ # include "config.h" #endif +#include #include #include @@ -69,7 +70,7 @@ static bool Vsigterm_dumps_octave_core = true; // List of signals we have caught since last call to octave_signal_handler. -static bool octave_signals_caught[NSIG]; +static bool *octave_signals_caught = 0; // Forward declaration. static void user_abort (const char *sig_name, int sig_number); @@ -173,11 +174,11 @@ bool is_interrupt_thread = (GetCurrentThreadId () == thread_id); if (is_interrupt_thread) - ::raise (SIGINT); + octave_raise_wrapper (SIGINT); else { SuspendThread (thread); - ::raise (SIGINT); + octave_raise_wrapper (SIGINT); ResumeThread (thread); } } @@ -221,28 +222,6 @@ #endif -// Signal handler return type. -#if ! defined (BADSIG) -# define BADSIG (void (*)(int))-1 -#endif - -#define BLOCK_SIGNAL(sig, nvar, ovar) \ - do \ - { \ - gnulib::sigemptyset (&nvar); \ - gnulib::sigaddset (&nvar, sig); \ - gnulib::sigemptyset (&ovar); \ - gnulib::sigprocmask (SIG_BLOCK, &nvar, &ovar); \ - } \ - while (0) - -#if ! defined (SIGCHLD) && defined (SIGCLD) -# define SIGCHLD SIGCLD -#endif - -#define BLOCK_CHILD(nvar, ovar) BLOCK_SIGNAL (SIGCHLD, nvar, ovar) -#define UNBLOCK_CHILD(ovar) gnulib::sigprocmask (SIG_SETMASK, &ovar, 0) - // Called from octave_quit () to actually do something about the signals // we have caught. @@ -252,45 +231,39 @@ // The list of signals is relatively short, so we will just go // linearly through the list. - for (int i = 0; i < NSIG; i++) + 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++) { if (octave_signals_caught[i]) { octave_signals_caught[i] = false; - switch (i) + if (have_sigchld && i == sigchld) { -#if defined (SIGCHLD) - case SIGCHLD: - { - volatile octave_interrupt_handler saved_interrupt_handler - = octave_ignore_interrupts (); + volatile octave_interrupt_handler saved_interrupt_handler + = octave_ignore_interrupts (); - sigset_t set, oset; - - BLOCK_CHILD (set, oset); + void *context = octave_block_child (); - octave_child_list::wait (); - - octave_set_interrupt_handler (saved_interrupt_handler); + octave_child_list::wait (); - UNBLOCK_CHILD (oset); + octave_set_interrupt_handler (saved_interrupt_handler); - octave_child_list::reap (); - } - break; -#endif + octave_unblock_child (context); - case SIGFPE: - std::cerr << "warning: floating point exception" << std::endl; - break; - -#if defined (SIGPIPE) - case SIGPIPE: - std::cerr << "warning: broken pipe" << std::endl; - break; -#endif + 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; } } } @@ -303,9 +276,7 @@ if (been_there_done_that) { -#if defined (SIGABRT) - octave_set_signal_handler (SIGABRT, SIG_DFL); -#endif + octave_set_signal_handler ("SIGABRT", SIG_DFL); std::cerr << "panic: attempted clean up apparently failed -- aborting...\n"; @@ -332,43 +303,24 @@ { octave_set_signal_handler (sig_number, SIG_DFL); - gnulib::raise (sig_number); + octave_raise_wrapper (sig_number); } } } -sig_handler * -octave_set_signal_handler (int sig, sig_handler *handler, +octave_sig_handler * +octave_set_signal_handler (int sig, octave_sig_handler *handler, bool restart_syscalls) { - struct sigaction act, oact; - - act.sa_handler = handler; - act.sa_flags = 0; + return octave_set_signal_handler_internal (sig, handler, restart_syscalls); +} -#if defined (SIGALRM) - if (sig == SIGALRM) - { -# if defined (SA_INTERRUPT) - act.sa_flags |= SA_INTERRUPT; -# endif - } -#endif -#if defined (SA_RESTART) -# if defined (SIGALRM) - else -# endif - // FIXME: Do we also need to explicitly disable SA_RESTART? - if (restart_syscalls) - act.sa_flags |= SA_RESTART; -#endif - - gnulib::sigemptyset (&act.sa_mask); - gnulib::sigemptyset (&oact.sa_mask); - - gnulib::sigaction (sig, &act, &oact); - - return oact.sa_handler; +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); } static void @@ -379,72 +331,54 @@ // Handle SIGCHLD. -#if defined (SIGCHLD) static void -sigchld_handler (int /* sig */) +sigchld_handler (int sig) { octave_signal_caught = 1; - octave_signals_caught[SIGCHLD] = true; + octave_signals_caught[sig] = true; } -#endif -#if defined (SIGFPE) && defined (__alpha__) +#if defined (__alpha__) static void -sigfpe_handler (int /* sig */) +sigfpe_handler (int sig) { if (can_interrupt && octave_interrupt_state >= 0) { octave_signal_caught = 1; - octave_signals_caught[SIGFPE] = true; + octave_signals_caught[sig] = true; octave_interrupt_state++; } } #endif -#if defined (SIGHUP) || defined (SIGTERM) static void -sig_hup_or_term_handler (int sig) +sig_hup_handler (int /* sig */) { - switch (sig) - { -#if defined (SIGHUP) - case SIGHUP: - { - if (Vsighup_dumps_octave_core) - dump_octave_core (); - } - break; -#endif - -#if defined (SIGTERM) - case SIGTERM: - { - if (Vsigterm_dumps_octave_core) - dump_octave_core (); - } - break; -#endif - - default: - break; - } + if (Vsighup_dumps_octave_core) + dump_octave_core (); clean_up_and_exit (0); } -#endif + +static void +sig_term_handler (int /* sig */) +{ + if (Vsigterm_dumps_octave_core) + dump_octave_core (); + + clean_up_and_exit (0); +} #if 0 -# if defined (SIGWINCH) static void sigwinch_handler (int /* sig */) { octave::command_editor::resize_terminal (); } #endif -#endif // Handle SIGINT by restarting the parser (see octave.cc). // @@ -523,20 +457,18 @@ #endif } -#if defined (SIGPIPE) static void -sigpipe_handler (int /* sig */) +sigpipe_handler (int sig) { octave_signal_caught = 1; - octave_signals_caught[SIGPIPE] = true; + 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++; } -#endif octave_interrupt_handler octave_catch_interrupts (void) @@ -547,13 +479,8 @@ w32_interrupt_manager::init (); #endif -#if defined (SIGINT) - retval.int_handler = octave_set_signal_handler (SIGINT, sigint_handler); -#endif - -#if defined (SIGBREAK) - retval.brk_handler = octave_set_signal_handler (SIGBREAK, sigint_handler); -#endif + retval.int_handler = octave_set_signal_handler ("SIGINT", sigint_handler); + retval.brk_handler = octave_set_signal_handler ("SIGBREAK", sigint_handler); return retval; } @@ -567,13 +494,8 @@ w32_interrupt_manager::init (); #endif -#if defined (SIGINT) - retval.int_handler = octave_set_signal_handler (SIGINT, SIG_IGN); -#endif - -#if defined (SIGBREAK) - retval.brk_handler = octave_set_signal_handler (SIGBREAK, SIG_IGN); -#endif + retval.int_handler = octave_set_signal_handler ("SIGINT", SIG_IGN); + retval.brk_handler = octave_set_signal_handler ("SIGBREAK", SIG_IGN); return retval; } @@ -588,15 +510,11 @@ w32_interrupt_manager::init (); #endif -#if defined (SIGINT) - retval.int_handler = octave_set_signal_handler (SIGINT, h.int_handler, + retval.int_handler = octave_set_signal_handler ("SIGINT", h.int_handler, restart_syscalls); -#endif -#if defined (SIGBREAK) - retval.brk_handler = octave_set_signal_handler (SIGBREAK, h.brk_handler, + retval.brk_handler = octave_set_signal_handler ("SIGBREAK", h.brk_handler, restart_syscalls); -#endif return retval; } @@ -606,287 +524,125 @@ void install_signal_handlers (void) { - for (int i = 0; i < NSIG; i++) + 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 (); -#if defined (SIGABRT) - octave_set_signal_handler (SIGABRT, generic_sig_handler); -#endif - -#if defined (SIGALRM) - octave_set_signal_handler (SIGALRM, generic_sig_handler); -#endif - -#if defined (SIGBUS) - octave_set_signal_handler (SIGBUS, generic_sig_handler); -#endif - -#if defined (SIGCHLD) - octave_set_signal_handler (SIGCHLD, sigchld_handler); -#endif + 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 -#if defined (SIGEMT) - octave_set_signal_handler (SIGEMT, generic_sig_handler); + octave_set_signal_handler ("SIGEMT", generic_sig_handler); + +#if defined (__alpha__) + octave_set_signal_handler ("SIGFPE", sigfpe_handler); +#else + octave_set_signal_handler ("SIGFPE", generic_sig_handler); #endif -#if defined (SIGFPE) -# if defined (__alpha__) - octave_set_signal_handler (SIGFPE, sigfpe_handler); -# else - octave_set_signal_handler (SIGFPE, generic_sig_handler); -# endif -#endif - -#if defined (SIGHUP) - octave_set_signal_handler (SIGHUP, sig_hup_or_term_handler); -#endif - -#if defined (SIGILL) - octave_set_signal_handler (SIGILL, generic_sig_handler); -#endif + octave_set_signal_handler ("SIGHUP", sig_hup_handler); + octave_set_signal_handler ("SIGILL", generic_sig_handler); // SIGINFO // SIGINT -#if defined (SIGIOT) - octave_set_signal_handler (SIGIOT, generic_sig_handler); -#endif - -#if defined (SIGLOST) - octave_set_signal_handler (SIGLOST, generic_sig_handler); -#endif - -#if defined (SIGPIPE) - octave_set_signal_handler (SIGPIPE, sigpipe_handler); -#endif - -#if defined (SIGPOLL) - octave_set_signal_handler (SIGPOLL, SIG_IGN); -#endif + 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); // SIGPROF // SIGPWR -#if defined (SIGQUIT) - octave_set_signal_handler (SIGQUIT, generic_sig_handler); -#endif - -#if defined (SIGSEGV) - octave_set_signal_handler (SIGSEGV, generic_sig_handler); -#endif + octave_set_signal_handler ("SIGQUIT", generic_sig_handler); + octave_set_signal_handler ("SIGSEGV", generic_sig_handler); // SIGSTOP -#if defined (SIGSYS) - octave_set_signal_handler (SIGSYS, generic_sig_handler); -#endif - -#if defined (SIGTERM) - octave_set_signal_handler (SIGTERM, sig_hup_or_term_handler); -#endif - -#if defined (SIGTRAP) - octave_set_signal_handler (SIGTRAP, generic_sig_handler); -#endif + 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 -#if defined (SIGUSR1) - octave_set_signal_handler (SIGUSR1, generic_sig_handler); -#endif + 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 defined (SIGUSR2) - octave_set_signal_handler (SIGUSR2, generic_sig_handler); -#endif - -#if defined (SIGVTALRM) - octave_set_signal_handler (SIGVTALRM, generic_sig_handler); -#endif - -#if defined (SIGIO) - octave_set_signal_handler (SIGIO, SIG_IGN); +#if 0 + octave_set_signal_handler ("SIGWINCH", sigwinch_handler); #endif -#if 0 -# if defined (SIGWINCH) - octave_set_signal_handler (SIGWINCH, sigwinch_handler); -#endif -#endif - -#if defined (SIGXCPU) - octave_set_signal_handler (SIGXCPU, generic_sig_handler); -#endif - -#if defined (SIGXFSZ) - octave_set_signal_handler (SIGXFSZ, generic_sig_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; -#if defined (SIGABRT) - m.assign ("ABRT", SIGABRT); -#endif - -#if defined (SIGALRM) - m.assign ("ALRM", SIGALRM); -#endif - -#if defined (SIGBUS) - m.assign ("BUS", SIGBUS); -#endif - -#if defined (SIGCHLD) - m.assign ("CHLD", SIGCHLD); -#endif - -#if defined (SIGCLD) - m.assign ("CLD", SIGCLD); -#endif - -#if defined (SIGCONT) - m.assign ("CONT", SIGCONT); -#endif - -#if defined (SIGEMT) - m.assign ("EMT", SIGEMT); -#endif - -#if defined (SIGFPE) - m.assign ("FPE", SIGFPE); -#endif - -#if defined (SIGHUP) - m.assign ("HUP", SIGHUP); -#endif - -#if defined (SIGILL) - m.assign ("ILL", SIGILL); -#endif - -#if defined (SIGINFO) - m.assign ("INFO", SIGINFO); -#endif - -#if defined (SIGINT) - m.assign ("INT", SIGINT); -#endif - -#if defined (SIGIO) - m.assign ("IO", SIGIO); -#endif - -#if defined (SIGIOT) - m.assign ("IOT", SIGIOT); -#endif - -#if defined (SIGKILL) - m.assign ("KILL", SIGKILL); -#endif - -#if defined (SIGLOST) - m.assign ("LOST", SIGLOST); -#endif - -#if defined (SIGPIPE) - m.assign ("PIPE", SIGPIPE); -#endif - -#if defined (SIGPOLL) - m.assign ("POLL", SIGPOLL); -#endif - -#if defined (SIGPROF) - m.assign ("PROF", SIGPROF); -#endif - -#if defined (SIGPWR) - m.assign ("PWR", SIGPWR); -#endif - -#if defined (SIGQUIT) - m.assign ("QUIT", SIGQUIT); -#endif - -#if defined (SIGSEGV) - m.assign ("SEGV", SIGSEGV); -#endif - -#if defined (SIGSTKFLT) - m.assign ("STKFLT", SIGSTKFLT); -#endif - -#if defined (SIGSTOP) - m.assign ("STOP", SIGSTOP); -#endif - -#if defined (SIGSYS) - m.assign ("SYS", SIGSYS); -#endif - -#if defined (SIGTERM) - m.assign ("TERM", SIGTERM); -#endif - -#if defined (SIGTRAP) - m.assign ("TRAP", SIGTRAP); -#endif - -#if defined (SIGTSTP) - m.assign ("TSTP", SIGTSTP); -#endif - -#if defined (SIGTTIN) - m.assign ("TTIN", SIGTTIN); -#endif - -#if defined (SIGTTOU) - m.assign ("TTOU", SIGTTOU); -#endif - -#if defined (SIGUNUSED) - m.assign ("UNUSED", SIGUNUSED); -#endif - -#if defined (SIGURG) - m.assign ("URG", SIGURG); -#endif - -#if defined (SIGUSR1) - m.assign ("USR1", SIGUSR1); -#endif - -#if defined (SIGUSR2) - m.assign ("USR2", SIGUSR2); -#endif - -#if defined (SIGVTALRM) - m.assign ("VTALRM", SIGVTALRM); -#endif - -#if defined (SIGWINCH) - m.assign ("WINCH", SIGWINCH); -#endif - -#if defined (SIGXCPU) - m.assign ("XCPU", SIGXCPU); -#endif - -#if defined (SIGXFSZ) - m.assign ("XFSZ", SIGXFSZ); -#endif + 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; } diff -r 70824a0dd009 -r 1d23b75cbcd1 libinterp/corefcn/sighandlers.h --- a/libinterp/corefcn/sighandlers.h Fri Jun 17 06:51:43 2016 -0400 +++ b/libinterp/corefcn/sighandlers.h Fri Jun 17 11:00:11 2016 -0400 @@ -35,28 +35,17 @@ #include "octave-config.h" -// Include signal.h, not csignal since the latter might only define -// the ANSI standard C signal interface. - -#include -#include +#include "signal-wrappers.h" #include "base-list.h" -typedef void sig_handler (int); - // FIXME: the data should probably be private... struct octave_interrupt_handler { -#if defined (SIGINT) - sig_handler *int_handler; -#endif - -#if defined (SIGBREAK) - sig_handler *brk_handler; -#endif + octave_sig_handler *int_handler; + octave_sig_handler *brk_handler; }; // Nonzero means we have already printed a message for this series of @@ -66,9 +55,13 @@ // TRUE means we can be interrupted. extern OCTINTERP_API bool can_interrupt; -extern OCTINTERP_API -sig_handler *octave_set_signal_handler (int, sig_handler *, - bool restart_syscalls = true); +extern OCTINTERP_API octave_sig_handler * +octave_set_signal_handler (int sig, octave_sig_handler *, + bool restart_syscalls = true); + +extern OCTINTERP_API octave_sig_handler * +octave_set_signal_handler (const char *signame, octave_sig_handler *, + bool restart_syscalls = true); extern OCTINTERP_API void install_signal_handlers (void); diff -r 70824a0dd009 -r 1d23b75cbcd1 liboctave/cruft/misc/cquit.c --- a/liboctave/cruft/misc/cquit.c Fri Jun 17 06:51:43 2016 -0400 +++ b/liboctave/cruft/misc/cquit.c Fri Jun 17 11:00:11 2016 -0400 @@ -53,28 +53,6 @@ #endif } -/* Allow us to save the signal mask and then restore it to the most - recently saved value. This is necessary when using the POSIX - signal handling interface on some systems calling longjmp out of - the signal handler to get to the top level on an interrupt doesn't - restore the original signal mask. Alternatively, we could use - sigsetjmp/siglongjmp, but saving and restoring the signal mask - ourselves works ok and seems simpler just now. */ - -static sigset_t octave_signal_mask; - -void -octave_save_signal_mask (void) -{ - sigprocmask (0, 0, &octave_signal_mask); -} - -void -octave_restore_signal_mask (void) -{ - sigprocmask (SIG_SETMASK, &octave_signal_mask, 0); -} - sig_atomic_t octave_interrupt_immediately = 0; sig_atomic_t octave_interrupt_state = 0; diff -r 70824a0dd009 -r 1d23b75cbcd1 liboctave/cruft/misc/quit.h --- a/liboctave/cruft/misc/quit.h Fri Jun 17 06:51:43 2016 -0400 +++ b/liboctave/cruft/misc/quit.h Fri Jun 17 11:00:11 2016 -0400 @@ -25,12 +25,15 @@ #include "octave-config.h" -#include #include +/* The signal header is just needed for the sig_atomic_t type. */ #if defined (__cplusplus) +# include # include extern "C" { +#else +# include #endif #if defined (__WIN32__) && ! defined (_POSIX_VERSION) @@ -67,10 +70,6 @@ OCTAVE_NORETURN OCTAVE_API extern void octave_jump_to_enclosing_context (void); -OCTAVE_API extern void octave_save_signal_mask (void); - -OCTAVE_API extern void octave_restore_signal_mask (void); - #if defined (__cplusplus) class octave_execution_exception diff -r 70824a0dd009 -r 1d23b75cbcd1 liboctave/wrappers/signal-wrappers.c --- a/liboctave/wrappers/signal-wrappers.c Fri Jun 17 06:51:43 2016 -0400 +++ b/liboctave/wrappers/signal-wrappers.c Fri Jun 17 11:00:11 2016 -0400 @@ -31,8 +31,15 @@ #include #include +#include #include +#if defined (__WIN32__) && ! defined (__CYGWIN__) +# include +#else +# include +#endif + #include "signal-wrappers.h" int @@ -56,3 +63,430 @@ return false; #endif } + +bool +octave_get_sig_number (const char *signame, int *signum) +{ + *signum = -1; + + // FIXME: this should probably use a perfect hash function. + + if (! strcmp (signame, "SIGINT")) + { +#if defined (SIGINT) + *signum = SIGINT; + return true; +#endif + } + else if (! strcmp (signame, "SIGBREAK")) + { +#if defined (SIGBREAK) + *signum = SIGBREAK; + return true; +#endif + } + else if (! strcmp (signame, "SIGABRT")) + { +#if defined (SIGABRT) + *signum = SIGABRT; + return true; +#endif + } + else if (! strcmp (signame, "SIGALRM")) + { +#if defined (SIGALRM) + *signum = SIGALRM; + return true; +#endif + } + else if (! strcmp (signame, "SIGBUS")) + { +#if defined (SIGBUS) + *signum = SIGBUS; + return true; +#endif + } + else if (! strcmp (signame, "SIGCHLD")) + { +#if defined (SIGCHLD) + *signum = SIGCHLD; + return true; +#endif + } + else if (! strcmp (signame, "SIGCLD")) + { +#if defined (SIGCLD) + *signum = SIGCLD; + return true; +#endif + } + else if (! strcmp (signame, "SIGCONT")) + { +#if defined (SIGCONT) + *signum = SIGCONT; + return true; +#endif + } + else if (! strcmp (signame, "SIGEMT")) + { +#if defined (SIGEMT) + *signum = SIGEMT; + return true; +#endif + } + else if (! strcmp (signame, "SIGFPE")) + { +#if defined (SIGFPE) + *signum = SIGFPE; + return true; +#endif + } + else if (! strcmp (signame, "SIGHUP")) + { +#if defined (SIGHUP) + *signum = SIGHUP; + return true; +#endif + } + else if (! strcmp (signame, "SIGILL")) + { +#if defined (SIGILL) + *signum = SIGILL; + return true; +#endif + } + else if (! strcmp (signame, "SIGINFO")) + { +#if defined (SIGINFO) + *signum = SIGINFO; + return true; +#endif + } + else if (! strcmp (signame, "SIGINT")) + { +#if defined (SIGINT) + *signum = SIGINT; + return true; +#endif + } + else if (! strcmp (signame, "SIGIOT")) + { +#if defined (SIGIOT) + *signum = SIGIOT; + return true; +#endif + } + else if (! strcmp (signame, "SIGLOST")) + { +#if defined (SIGLOST) + *signum = SIGLOST; + return true; +#endif + } + else if (! strcmp (signame, "SIGPIPE")) + { +#if defined (SIGPIPE) + *signum = SIGPIPE; + return true; +#endif + } + else if (! strcmp (signame, "SIGPOLL")) + { +#if defined (SIGPOLL) + *signum = SIGPOLL; + return true; +#endif + } + else if (! strcmp (signame, "SIGPROF")) + { +#if defined (SIGPROF) + *signum = SIGPROF; + return true; +#endif + } + else if (! strcmp (signame, "SIGPWR")) + { +#if defined (SIGPWR) + *signum = SIGPWR; + return true; +#endif + } + else if (! strcmp (signame, "SIGQUIT")) + { +#if defined (SIGQUIT) + *signum = SIGQUIT; + return true; +#endif + } + else if (! strcmp (signame, "SIGSEGV")) + { +#if defined (SIGSEGV) + *signum = SIGSEGV; + return true; +#endif + } + else if (! strcmp (signame, "SIGSTOP")) + { +#if defined (SIGSTOP) + *signum = SIGSTOP; + return true; +#endif + } + else if (! strcmp (signame, "SIGSYS")) + { +#if defined (SIGSYS) + *signum = SIGSYS; + return true; +#endif + } + else if (! strcmp (signame, "SIGTERM")) + { +#if defined (SIGTERM) + *signum = SIGTERM; + return true; +#endif + } + else if (! strcmp (signame, "SIGTRAP")) + { +#if defined (SIGTRAP) + *signum = SIGTRAP; + return true; +#endif + } + else if (! strcmp (signame, "SIGTSTP")) + { +#if defined (SIGTSTP) + *signum = SIGTSTP; + return true; +#endif + } + else if (! strcmp (signame, "SIGTTIN")) + { +#if defined (SIGTTIN) + *signum = SIGTTIN; + return true; +#endif + } + else if (! strcmp (signame, "SIGTTOU")) + { +#if defined (SIGTTOU) + *signum = SIGTTOU; + return true; +#endif + } + else if (! strcmp (signame, "SIGURG")) + { +#if defined (SIGURG) + *signum = SIGURG; + return true; +#endif + } + else if (! strcmp (signame, "SIGUSR1")) + { +#if defined (SIGUSR1) + *signum = SIGUSR1; + return true; +#endif + } + else if (! strcmp (signame, "SIGUSR2")) + { +#if defined (SIGUSR2) + *signum = SIGUSR2; + return true; +#endif + } + else if (! strcmp (signame, "SIGVTALRM")) + { +#if defined (SIGVTALRM) + *signum = SIGVTALRM; + return true; +#endif + } + else if (! strcmp (signame, "SIGIO")) + { +#if defined (SIGIO) + *signum = SIGIO; + return true; +#endif + } + else if (! strcmp (signame, "SIGWINCH")) + { +#if defined (SIGWINCH) + *signum = SIGWINCH; + return true; +#endif + } + else if (! strcmp (signame, "SIGXCPU")) + { +#if defined (SIGXCPU) + *signum = SIGXCPU; + return true; +#endif + } + else if (! strcmp (signame, "SIGXFSZ")) + { +#if defined (SIGXFSZ) + *signum = SIGXFSZ; + return true; +#endif + } + + return false; +} + +octave_sig_handler * +octave_set_signal_handler_internal (int sig, octave_sig_handler *handler, + bool restart_syscalls) +{ + struct sigaction act, oact; + + act.sa_handler = handler; + act.sa_flags = 0; + +#if defined (SIGALRM) + if (sig == SIGALRM) + { +# if defined (SA_INTERRUPT) + act.sa_flags |= SA_INTERRUPT; +# endif + } +#endif +#if defined (SA_RESTART) +# if defined (SIGALRM) + else +# endif + // FIXME: Do we also need to explicitly disable SA_RESTART? + if (restart_syscalls) + act.sa_flags |= SA_RESTART; +#endif + + sigemptyset (&act.sa_mask); + sigemptyset (&oact.sa_mask); + + sigaction (sig, &act, &oact); + + return oact.sa_handler; +} + +octave_sig_handler * +octave_set_signal_handler_by_name (const char *signame, + octave_sig_handler *handler, + bool restart_syscalls) +{ + int sig; + + return (octave_get_sig_number (signame, &sig) + ? octave_set_signal_handler_internal (sig, handler, restart_syscalls) + : 0); +} + +int +octave_num_signals (void) +{ + return NSIG; +} + +typedef struct +{ + sigset_t nvar; + sigset_t ovar; +} sigset_info; + +void * +octave_block_child (void) +{ +#if defined (SIGCHLD) + + sigset_info *context = (sigset_info *) malloc (sizeof (sigset_info)); + + if (context) + { + sigemptyset (&(context->nvar)); + sigaddset (&(context->nvar), SIGCHLD); + sigemptyset (&(context->ovar)); + sigprocmask (SIG_BLOCK, &(context->nvar), &(context->ovar)); + } + + return context; + +#else + + return 0; + +#endif +} + +void +octave_unblock_child (void *context_arg) +{ + if (context_arg) + { + sigset_info *context = (sigset_info *) context_arg; + + sigprocmask (SIG_SETMASK, &(context->ovar), 0); + + free (context); + } +} + +static void +block_or_unblock_signal (int how, int sig) +{ +#if ! defined (__WIN32__) || defined (__CYGWIN__) + // Blocking/unblocking signals at thread level is only supported + // on platform with fully compliant POSIX threads. This is not + // supported on Win32. Moreover, we have to make sure that SIGINT + // handler is not installed before calling AllocConsole: installing + // a SIGINT handler internally calls SetConsoleCtrlHandler, which + // must be called after AllocConsole to be effective. + + sigset_t signal_mask; + + sigemptyset (&signal_mask); + + sigaddset (&signal_mask, sig); + + pthread_sigmask (how, &signal_mask, 0); +#endif +} + +void +octave_block_interrupt_signal (void) +{ + block_or_unblock_signal (SIG_BLOCK, SIGINT); +} + +void +octave_unblock_interrupt_signal (void) +{ + block_or_unblock_signal (SIG_UNBLOCK, SIGINT); +} + + +/* Allow us to save the signal mask and then restore it to the most + recently saved value. This is necessary when using the POSIX signal + handling interface on some systems calling longjmp out of the signal + handler to get to the top level on an interrupt doesn't restore the + original signal mask. Alternatively, we could use + sigsetjmp/siglongjmp, but saving and restoring the signal mask + ourselves works ok and seems simpler just now. */ + +static sigset_t octave_signal_mask; + +void +octave_save_signal_mask (void) +{ + sigprocmask (0, 0, &octave_signal_mask); +} + +void +octave_restore_signal_mask (void) +{ + sigprocmask (SIG_SETMASK, &octave_signal_mask, 0); +} + +int +octave_raise_wrapper (int signum) +{ + return raise (signum); +} diff -r 70824a0dd009 -r 1d23b75cbcd1 liboctave/wrappers/signal-wrappers.h --- a/liboctave/wrappers/signal-wrappers.h Fri Jun 17 06:51:43 2016 -0400 +++ b/liboctave/wrappers/signal-wrappers.h Fri Jun 17 11:00:11 2016 -0400 @@ -33,12 +33,41 @@ extern "C" { #endif +typedef void octave_sig_handler (int); + extern int octave_kill_wrapper (pid_t pid, int signum); extern char *octave_strsignal_wrapper (int signum); extern bool octave_have_kill (void); +extern bool octave_get_sig_number (const char *signame, int *signum); + +extern octave_sig_handler * +octave_set_signal_handler_by_name (const char *signame, + octave_sig_handler *handler, + bool restart_syscalls); + +octave_sig_handler * +octave_set_signal_handler_internal (int sig, octave_sig_handler *handler, + bool restart_syscalls); + +extern int octave_num_signals (void); + +extern void *octave_block_child (void); + +extern void octave_unblock_child (void *context); + +extern void octave_block_interrupt_signal (void); + +extern void octave_unblock_interrupt_signal (void); + +extern void octave_save_signal_mask (void); + +extern void octave_restore_signal_mask (void); + +extern int octave_raise_wrapper (int signum); + #if defined __cplusplus } #endif diff -r 70824a0dd009 -r 1d23b75cbcd1 src/main.in.cc --- a/src/main.in.cc Fri Jun 17 06:51:43 2016 -0400 +++ b/src/main.in.cc Fri Jun 17 11:00:11 2016 -0400 @@ -40,6 +40,7 @@ #include #include "fcntl-wrappers.h" +#include "signal-wrappers.h" #include "unistd-wrappers.h" #include "wait-wrappers.h" @@ -65,10 +66,6 @@ #if (defined (HAVE_OCTAVE_QT_GUI) \ && ! defined (__WIN32__) || defined (__CYGWIN__)) -#include - -typedef void sig_handler (int); - // Forward signals to the GUI process. static pid_t gui_pid = 0; @@ -82,141 +79,65 @@ caught_signal = sig; } -static sig_handler * -octave_set_signal_handler (int sig, sig_handler *handler) +static void +gui_driver_set_signal_handler (const char *signame, + octave_sig_handler *handler) { - struct sigaction act, oact; - - act.sa_handler = handler; - act.sa_flags = 0; - - gnulib::sigemptyset (&act.sa_mask); - gnulib::sigemptyset (&oact.sa_mask); - - gnulib::sigaction (sig, &act, &oact); - - return oact.sa_handler; + octave_set_signal_handler_by_name (signame, handler, false); } static void install_signal_handlers (void) { - -#if defined (SIGINT) - octave_set_signal_handler (SIGINT, gui_driver_sig_handler); -#endif - -#if defined (SIGBREAK) - octave_set_signal_handler (SIGBREAK, gui_driver_sig_handler); -#endif - -#if defined (SIGABRT) - octave_set_signal_handler (SIGABRT, gui_driver_sig_handler); -#endif - -#if defined (SIGALRM) - octave_set_signal_handler (SIGALRM, gui_driver_sig_handler); -#endif - -#if defined (SIGBUS) - octave_set_signal_handler (SIGBUS, gui_driver_sig_handler); -#endif + gui_driver_set_signal_handler ("SIGINT", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGBREAK", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGABRT", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGALRM", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGBUS", gui_driver_sig_handler); // SIGCHLD // SIGCLD // SIGCONT -#if defined (SIGEMT) - octave_set_signal_handler (SIGEMT, gui_driver_sig_handler); -#endif - -#if defined (SIGFPE) - octave_set_signal_handler (SIGFPE, gui_driver_sig_handler); -#endif - -#if defined (SIGHUP) - octave_set_signal_handler (SIGHUP, gui_driver_sig_handler); -#endif - -#if defined (SIGILL) - octave_set_signal_handler (SIGILL, gui_driver_sig_handler); -#endif + gui_driver_set_signal_handler ("SIGEMT", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGFPE", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGHUP", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGILL", gui_driver_sig_handler); // SIGINFO // SIGINT -#if defined (SIGIOT) - octave_set_signal_handler (SIGIOT, gui_driver_sig_handler); -#endif - -#if defined (SIGLOST) - octave_set_signal_handler (SIGLOST, gui_driver_sig_handler); -#endif - -#if defined (SIGPIPE) - octave_set_signal_handler (SIGPIPE, gui_driver_sig_handler); -#endif - -#if defined (SIGPOLL) - octave_set_signal_handler (SIGPOLL, gui_driver_sig_handler); -#endif + gui_driver_set_signal_handler ("SIGIOT", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGLOST", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGPIPE", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGPOLL", gui_driver_sig_handler); // SIGPROF // SIGPWR -#if defined (SIGQUIT) - octave_set_signal_handler (SIGQUIT, gui_driver_sig_handler); -#endif - -#if defined (SIGSEGV) - octave_set_signal_handler (SIGSEGV, gui_driver_sig_handler); -#endif + gui_driver_set_signal_handler ("SIGQUIT", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGSEGV", gui_driver_sig_handler); // SIGSTOP -#if defined (SIGSYS) - octave_set_signal_handler (SIGSYS, gui_driver_sig_handler); -#endif - -#if defined (SIGTERM) - octave_set_signal_handler (SIGTERM, gui_driver_sig_handler); -#endif - -#if defined (SIGTRAP) - octave_set_signal_handler (SIGTRAP, gui_driver_sig_handler); -#endif + gui_driver_set_signal_handler ("SIGSYS", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGTERM", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGTRAP", gui_driver_sig_handler); // SIGTSTP // SIGTTIN // SIGTTOU // SIGURG -#if defined (SIGUSR1) - octave_set_signal_handler (SIGUSR1, gui_driver_sig_handler); -#endif - -#if defined (SIGUSR2) - octave_set_signal_handler (SIGUSR2, gui_driver_sig_handler); -#endif - -#if defined (SIGVTALRM) - octave_set_signal_handler (SIGVTALRM, gui_driver_sig_handler); -#endif - -#if defined (SIGIO) - octave_set_signal_handler (SIGIO, gui_driver_sig_handler); -#endif + gui_driver_set_signal_handler ("SIGUSR1", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGUSR2", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGVTALRM", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGIO", gui_driver_sig_handler); // SIGWINCH -#if defined (SIGXCPU) - octave_set_signal_handler (SIGXCPU, gui_driver_sig_handler); -#endif - -#if defined (SIGXFSZ) - octave_set_signal_handler (SIGXFSZ, gui_driver_sig_handler); -#endif - + gui_driver_set_signal_handler ("SIGXCPU", gui_driver_sig_handler); + gui_driver_set_signal_handler ("SIGXFSZ", gui_driver_sig_handler); } static bool @@ -569,7 +490,7 @@ caught_signal = -1; - kill (gui_pid, sig); + octave_kill_wrapper (gui_pid, sig); } else if (octave_wifexited_wrapper (status)) {