32 #include <sys/types.h>
78 static void user_abort (
const char *sig_name,
int sig_number);
80 #if defined (__WIN32__) && ! defined (__CYGWIN__)
82 #define WIN32_LEAN_AND_MEAN
89 ~w32_interrupt_manager (
void)
95 static bool init (
void) {
return instance_ok (); }
100 instance->do_octave_jump_to_enclosing_context ();
103 static void user_abort (
const char *sig_name,
int sig_number)
106 instance->do_user_abort (sig_name, sig_number);
109 static void raise_sigint (
void)
112 instance->do_raise_sigint ();
116 w32_interrupt_manager (
void)
117 : thread (0), thread_id (0)
119 thread_id = GetCurrentThreadId ();
121 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
122 GetCurrentProcess (), &thread, 0, FALSE,
123 DUPLICATE_SAME_ACCESS);
126 static void octave_jump_to_enclosing_context_sync (
void)
134 void do_octave_jump_to_enclosing_context (
void)
136 bool is_interrupt_thread = (GetCurrentThreadId () == thread_id);
138 if (is_interrupt_thread)
139 octave_jump_to_enclosing_context_sync ();
146 #if ! (defined (__MINGW64__) || defined (_WIN64))
148 CONTEXT threadContext;
150 SuspendThread (thread);
151 threadContext.ContextFlags = CONTEXT_CONTROL;
152 GetThreadContext (thread, &threadContext);
153 threadContext.Eip = (DWORD) octave_jump_to_enclosing_context_sync;
154 SetThreadContext (thread, &threadContext);
155 ResumeThread (thread);
160 void do_user_abort (
const char *sig_name,
int sig_number)
162 bool is_interrupt_thread = (GetCurrentThreadId () == thread_id);
164 if (is_interrupt_thread)
168 SuspendThread (thread);
170 ResumeThread (thread);
174 void do_raise_sigint (
void)
176 bool is_interrupt_thread = (GetCurrentThreadId () == thread_id);
178 if (is_interrupt_thread)
182 SuspendThread (thread);
184 ResumeThread (thread);
188 static bool instance_ok (
void)
194 instance =
new w32_interrupt_manager ();
202 ::error (
"unable to create w32_interrupt_manager");
210 static void cleanup_instance (
void) {
delete instance; instance = 0; }
219 static w32_interrupt_manager* instance;
222 w32_interrupt_manager* w32_interrupt_manager::instance = 0;
224 void w32_raise_sigint (
void)
226 w32_interrupt_manager::raise_sigint ();
233 #define BADSIG (void (*)(int))-1
238 #if defined (__GNUC__)
239 # if ! (__GNUC__ > 4 \
240 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 1 \
241 || (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ > 2))))
242 # undef GNULIB_NAMESPACE
243 # define GNULIB_NAMESPACE
244 # warning "disabling GNULIB_NAMESPACE for signal functions -- consider upgrading to a current version of GCC"
248 #define BLOCK_SIGNAL(sig, nvar, ovar) \
251 GNULIB_NAMESPACE::sigemptyset (&nvar); \
252 GNULIB_NAMESPACE::sigaddset (&nvar, sig); \
253 GNULIB_NAMESPACE::sigemptyset (&ovar); \
254 GNULIB_NAMESPACE::sigprocmask (SIG_BLOCK, &nvar, &ovar); \
258 #if !defined (SIGCHLD) && defined (SIGCLD)
259 #define SIGCHLD SIGCLD
262 #define BLOCK_CHILD(nvar, ovar) BLOCK_SIGNAL (SIGCHLD, nvar, ovar)
263 #define UNBLOCK_CHILD(ovar) GNULIB_NAMESPACE::sigprocmask (SIG_SETMASK, &ovar, 0)
274 for (
int i = 0; i < NSIG; i++)
304 std::cerr <<
"warning: floating point exception" << std::endl;
309 std::cerr <<
"warning: broken pipe" << std::endl;
321 static bool been_there_done_that =
false;
323 if (been_there_done_that)
325 #if defined (SIGABRT)
329 std::cerr <<
"panic: attempted clean up apparently failed -- aborting...\n";
337 been_there_done_that =
true;
339 std::cerr <<
"panic: " << sig_name <<
" -- stopping myself...\n";
354 GNULIB_NAMESPACE::raise (sig_number);
361 bool restart_syscalls)
363 struct sigaction act, oact;
365 act.sa_handler = handler;
368 #if defined (SIGALRM)
371 #if defined (SA_INTERRUPT)
372 act.sa_flags |= SA_INTERRUPT;
376 #if defined (SA_RESTART)
377 #if defined (SIGALRM)
381 if (restart_syscalls)
382 act.sa_flags |= SA_RESTART;
385 GNULIB_NAMESPACE::sigemptyset (&act.sa_mask);
386 GNULIB_NAMESPACE::sigemptyset (&oact.sa_mask);
388 GNULIB_NAMESPACE::sigaction (sig, &act, &oact);
390 return oact.sa_handler;
403 sigchld_handler (
int )
412 #if defined (__alpha__)
414 sigfpe_handler (
int )
428 #if defined (SIGHUP) || defined (SIGTERM)
430 sig_hup_or_term_handler (
int sig)
443 #if defined (SIGTERM)
461 #if defined (SIGWINCH)
463 sigwinch_handler (
int )
508 #if defined (__WIN32__) && ! defined (__CYGWIN__)
528 std::cerr <<
"Press Control-C again to abort." << std::endl;
540 #if defined (__WIN32__) && ! defined (__CYGWIN__)
549 sigpipe_handler (
int )
567 #if defined (__WIN32__) && ! defined (__CYGWIN__)
568 w32_interrupt_manager::init ();
587 #if defined (__WIN32__) && ! defined (__CYGWIN__)
588 w32_interrupt_manager::init ();
604 bool restart_syscalls)
608 #if defined (__WIN32__) && ! defined (__CYGWIN__)
609 w32_interrupt_manager::init ();
630 for (
int i = 0; i < NSIG; i++)
659 #if defined (__alpha__)
761 m.
assign (
"ABRT", SIGABRT);
765 m.
assign (
"ALRM", SIGALRM);
773 m.
assign (
"CHLD", SIGCHLD);
781 m.
assign (
"CONT", SIGCONT);
801 m.
assign (
"INFO", SIGINFO);
817 m.
assign (
"KILL", SIGKILL);
821 m.
assign (
"LOST", SIGLOST);
825 m.
assign (
"PIPE", SIGPIPE);
829 m.
assign (
"POLL", SIGPOLL);
833 m.
assign (
"PROF", SIGPROF);
841 m.
assign (
"QUIT", SIGQUIT);
845 m.
assign (
"SEGV", SIGSEGV);
849 m.
assign (
"STKFLT", SIGSTKFLT);
853 m.
assign (
"STOP", SIGSTOP);
861 m.
assign (
"TERM", SIGTERM);
865 m.
assign (
"TRAP", SIGTRAP);
869 m.
assign (
"TSTP", SIGTSTP);
873 m.
assign (
"TTIN", SIGTTIN);
877 m.
assign (
"TTOU", SIGTTOU);
881 m.
assign (
"UNUSED", SIGUNUSED);
889 m.
assign (
"USR1", SIGUSR1);
893 m.
assign (
"USR2", SIGUSR2);
897 m.
assign (
"VTALRM", SIGVTALRM);
901 m.
assign (
"WINCH", SIGWINCH);
905 m.
assign (
"XCPU", SIGXCPU);
909 m.
assign (
"XFSZ", SIGXFSZ);
932 ::error (
"unable to create child list object!");
980 #define OCL_REP octave_child_list::octave_child_list_rep
993 for (
iterator p = begin (); p != end (); p++)
1019 OCL_REP::wait (
void)
1021 bool retval =
false;
1023 for (
iterator p = begin (); p != end (); p++)
1051 @deftypefn {Built-in Function} {} SIG ()\n\
1052 Return a structure containing Unix signal names and their defined values.\n\
1057 if (args.length () == 0)
1076 DEFUN (debug_on_interrupt, args, nargout,
1078 @deftypefn {Built-in Function} {@var{val} =} debug_on_interrupt ()\n\
1079 @deftypefnx {Built-in Function} {@var{old_val} =} debug_on_interrupt (@var{new_val})\n\
1080 @deftypefnx {Built-in Function} {} debug_on_interrupt (@var{new_val}, \"local\")\n\
1081 Query or set the internal variable that controls whether Octave will try\n\
1082 to enter debugging mode when it receives an interrupt signal (typically\n\
1083 generated with @kbd{C-c}).\n\
1085 If a second interrupt signal is received before reaching the debugging mode,\n\
1086 a normal interrupt will occur.\n\
1088 When called from inside a function with the @qcode{\"local\"} option, the\n\
1089 variable is changed locally for the function and any subroutines it calls.\n\
1090 The original variable value is restored when exiting the function.\n\
1091 @seealso{debug_on_error, debug_on_warning}\n\
1109 DEFUN (sighup_dumps_octave_core, args, nargout,
1111 @deftypefn {Built-in Function} {@var{val} =} sighup_dumps_octave_core ()\n\
1112 @deftypefnx {Built-in Function} {@var{old_val} =} sighup_dumps_octave_core (@var{new_val})\n\
1113 @deftypefnx {Built-in Function} {} sighup_dumps_octave_core (@var{new_val}, \"local\")\n\
1114 Query or set the internal variable that controls whether Octave tries\n\
1115 to save all current variables to the file @file{octave-workspace} if it\n\
1116 receives a hangup signal.\n\
1118 When called from inside a function with the @qcode{\"local\"} option, the\n\
1119 variable is changed locally for the function and any subroutines it calls.\n\
1120 The original variable value is restored when exiting the function.\n\
1138 DEFUN (sigterm_dumps_octave_core, args, nargout,
1140 @deftypefn {Built-in Function} {@var{val} =} sigterm_dumps_octave_core ()\n\
1141 @deftypefnx {Built-in Function} {@var{old_val} =} sigterm_dumps_octave_core (@var{new_val})\n\
1142 @deftypefnx {Built-in Function} {} sigterm_dumps_octave_core (@var{new_val}, \"local\")\n\
1143 Query or set the internal variable that controls whether Octave tries\n\
1144 to save all current variables to the file @file{octave-workspace} if it\n\
1145 receives a terminate signal.\n\
1147 When called from inside a function with the @qcode{\"local\"} option, the\n\
1148 variable is changed locally for the function and any subroutines it calls.\n\
1149 The original variable value is restored when exiting the function.\n\
char * strsignal(int code)
volatile sig_atomic_t octave_signal_caught
static void cleanup_instance(void)
octave_interrupt_handler octave_set_interrupt_handler(const volatile octave_interrupt_handler &h, bool restart_syscalls)
OCTINTERP_API void print_usage(void)
static bool have_breakpoints(void)
static bool instance_ok(void)
#define DEFUN(name, args_name, nargout_name, doc)
void error(const char *fmt,...)
octave_interrupt_handler octave_catch_interrupts(void)
#define SET_INTERNAL_VARIABLE(NM)
#define UNBLOCK_CHILD(ovar)
static void sigint_handler(int sig)
void octave_jump_to_enclosing_context(void)
static octave_child_list_rep * instance
std::list< octave_child >::iterator iterator
void install_signal_handlers(void)
static pid_t waitpid(pid_t, int *status, int)
F77_RET_T const double const double * f
static void resize_terminal(void)
static bool octave_signals_caught[NSIG]
#define MINGW_SIGNAL_CLEANUP()
static void generic_sig_handler(int sig)
#define BLOCK_CHILD(nvar, ovar)
static bool Vsighup_dumps_octave_core
static void insert(pid_t pid, octave_child::child_event_handler f)
child_event_handler handler
void clean_up_and_exit(int status, bool safe_to_return)
sig_atomic_t octave_interrupt_state
static void remove(pid_t pid)
void insert(pid_t pid, octave_child::child_event_handler f)
sig_atomic_t octave_interrupt_immediately
int pipe_handler_error_count
void octave_signal_handler(void)
octave_interrupt_handler octave_ignore_interrupts(void)
static void user_abort(const char *sig_name, int sig_number)
static bool Vsigterm_dumps_octave_core
void assign(const std::string &k, const octave_value &val)
bool octave_debug_on_interrupt_state
static void my_friendly_exit(const char *sig_name, int sig_number, bool save_vars=true)
bool(* child_event_handler)(pid_t, int)
bool operator()(const octave_child &oc) const
sig_handler * octave_set_signal_handler(int sig, sig_handler *handler, bool restart_syscalls)
static octave_scalar_map make_sig_struct(void)
static size_t save_vars(std::ostream &os, const std::string &pattern, load_save_format fmt, bool save_as_floats)
static void dump_octave_core(std::ostream &os, const char *fname, load_save_format fmt, bool save_as_floats)