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 ();
142 CONTEXT threadContext;
144 SuspendThread (thread);
145 threadContext.ContextFlags = CONTEXT_CONTROL;
146 GetThreadContext (thread, &threadContext);
147 threadContext.Eip = (DWORD) octave_jump_to_enclosing_context_sync;
148 SetThreadContext (thread, &threadContext);
149 ResumeThread (thread);
153 void do_user_abort (
const char *sig_name,
int sig_number)
155 bool is_interrupt_thread = (GetCurrentThreadId () == thread_id);
157 if (is_interrupt_thread)
161 SuspendThread (thread);
163 ResumeThread (thread);
167 void do_raise_sigint (
void)
169 bool is_interrupt_thread = (GetCurrentThreadId () == thread_id);
171 if (is_interrupt_thread)
175 SuspendThread (thread);
177 ResumeThread (thread);
181 static bool instance_ok (
void)
187 instance =
new w32_interrupt_manager ();
195 ::error (
"unable to create w32_interrupt_manager");
203 static void cleanup_instance (
void) {
delete instance; instance = 0; }
212 static w32_interrupt_manager* instance;
215 w32_interrupt_manager* w32_interrupt_manager::instance = 0;
217 void w32_raise_sigint (
void)
219 w32_interrupt_manager::raise_sigint ();
226 #define BADSIG (void (*)(int))-1
231 #if defined (__GNUC__)
232 # if ! (__GNUC__ > 4 \
233 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 1 \
234 || (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ > 2))))
235 # undef GNULIB_NAMESPACE
236 # define GNULIB_NAMESPACE
237 # warning "disabling GNULIB_NAMESPACE for signal functions -- consider upgrading to a current version of GCC"
241 #define BLOCK_SIGNAL(sig, nvar, ovar) \
244 GNULIB_NAMESPACE::sigemptyset (&nvar); \
245 GNULIB_NAMESPACE::sigaddset (&nvar, sig); \
246 GNULIB_NAMESPACE::sigemptyset (&ovar); \
247 GNULIB_NAMESPACE::sigprocmask (SIG_BLOCK, &nvar, &ovar); \
251 #if !defined (SIGCHLD) && defined (SIGCLD)
252 #define SIGCHLD SIGCLD
255 #define BLOCK_CHILD(nvar, ovar) BLOCK_SIGNAL (SIGCHLD, nvar, ovar)
256 #define UNBLOCK_CHILD(ovar) GNULIB_NAMESPACE::sigprocmask (SIG_SETMASK, &ovar, 0)
267 for (
int i = 0; i < NSIG; i++)
297 std::cerr <<
"warning: floating point exception" << std::endl;
302 std::cerr <<
"warning: broken pipe" << std::endl;
314 static bool been_there_done_that =
false;
316 if (been_there_done_that)
318 #if defined (SIGABRT)
322 std::cerr <<
"panic: attempted clean up apparently failed -- aborting...\n";
330 been_there_done_that =
true;
332 std::cerr <<
"panic: " << sig_name <<
" -- stopping myself...\n";
347 GNULIB_NAMESPACE::raise (sig_number);
354 bool restart_syscalls)
356 struct sigaction act, oact;
358 act.sa_handler = handler;
361 #if defined (SIGALRM)
364 #if defined (SA_INTERRUPT)
365 act.sa_flags |= SA_INTERRUPT;
369 #if defined (SA_RESTART)
370 #if defined (SIGALRM)
374 if (restart_syscalls)
375 act.sa_flags |= SA_RESTART;
378 GNULIB_NAMESPACE::sigemptyset (&act.sa_mask);
379 GNULIB_NAMESPACE::sigemptyset (&oact.sa_mask);
381 GNULIB_NAMESPACE::sigaction (sig, &act, &oact);
383 return oact.sa_handler;
396 sigchld_handler (
int )
405 #if defined (__alpha__)
407 sigfpe_handler (
int )
421 #if defined (SIGHUP) || defined (SIGTERM)
423 sig_hup_or_term_handler (
int sig)
436 #if defined (SIGTERM)
454 #if defined (SIGWINCH)
456 sigwinch_handler (
int )
501 #if defined (__WIN32__) && ! defined (__CYGWIN__)
520 std::cerr <<
"Press Control-C again to abort." << std::endl;
532 #if defined (__WIN32__) && ! defined (__CYGWIN__)
541 sigpipe_handler (
int )
559 #if defined (__WIN32__) && ! defined (__CYGWIN__)
560 w32_interrupt_manager::init ();
579 #if defined (__WIN32__) && ! defined (__CYGWIN__)
580 w32_interrupt_manager::init ();
596 bool restart_syscalls)
600 #if defined (__WIN32__) && ! defined (__CYGWIN__)
601 w32_interrupt_manager::init ();
622 for (
int i = 0; i < NSIG; i++)
651 #if defined (__alpha__)
753 m.
assign (
"ABRT", SIGABRT);
757 m.
assign (
"ALRM", SIGALRM);
765 m.
assign (
"CHLD", SIGCHLD);
773 m.
assign (
"CONT", SIGCONT);
793 m.
assign (
"INFO", SIGINFO);
809 m.
assign (
"KILL", SIGKILL);
813 m.
assign (
"LOST", SIGLOST);
817 m.
assign (
"PIPE", SIGPIPE);
821 m.
assign (
"POLL", SIGPOLL);
825 m.
assign (
"PROF", SIGPROF);
833 m.
assign (
"QUIT", SIGQUIT);
837 m.
assign (
"SEGV", SIGSEGV);
841 m.
assign (
"STKFLT", SIGSTKFLT);
845 m.
assign (
"STOP", SIGSTOP);
853 m.
assign (
"TERM", SIGTERM);
857 m.
assign (
"TRAP", SIGTRAP);
861 m.
assign (
"TSTP", SIGTSTP);
865 m.
assign (
"TTIN", SIGTTIN);
869 m.
assign (
"TTOU", SIGTTOU);
873 m.
assign (
"UNUSED", SIGUNUSED);
881 m.
assign (
"USR1", SIGUSR1);
885 m.
assign (
"USR2", SIGUSR2);
889 m.
assign (
"VTALRM", SIGVTALRM);
893 m.
assign (
"WINCH", SIGWINCH);
897 m.
assign (
"XCPU", SIGXCPU);
901 m.
assign (
"XFSZ", SIGXFSZ);
924 ::error (
"unable to create child list object!");
972 #define OCL_REP octave_child_list::octave_child_list_rep
985 for (
iterator p = begin (); p != end (); p++)
1011 OCL_REP::wait (
void)
1013 bool retval =
false;
1015 for (
iterator p = begin (); p != end (); p++)
1043 @deftypefn {Built-in Function} {} SIG ()\n\
1044 Return a structure containing Unix signal names and their defined values.\n\
1049 if (args.length () == 0)
1068 DEFUN (debug_on_interrupt, args, nargout,
1070 @deftypefn {Built-in Function} {@var{val} =} debug_on_interrupt ()\n\
1071 @deftypefnx {Built-in Function} {@var{old_val} =} debug_on_interrupt (@var{new_val})\n\
1072 @deftypefnx {Built-in Function} {} debug_on_interrupt (@var{new_val}, \"local\")\n\
1073 Query or set the internal variable that controls whether Octave will try\n\
1074 to enter debugging mode when it receives an interrupt signal (typically\n\
1075 generated with @kbd{C-c}). If a second interrupt signal is received\n\
1076 before reaching the debugging mode, a normal interrupt will occur.\n\
1078 When called from inside a function with the @qcode{\"local\"} option, the\n\
1079 variable is changed locally for the function and any subroutines it calls. \n\
1080 The original variable value is restored when exiting the function.\n\
1081 @seealso{debug_on_error, debug_on_warning}\n\
1099 DEFUN (sighup_dumps_octave_core, args, nargout,
1101 @deftypefn {Built-in Function} {@var{val} =} sighup_dumps_octave_core ()\n\
1102 @deftypefnx {Built-in Function} {@var{old_val} =} sighup_dumps_octave_core (@var{new_val})\n\
1103 @deftypefnx {Built-in Function} {} sighup_dumps_octave_core (@var{new_val}, \"local\")\n\
1104 Query or set the internal variable that controls whether Octave tries\n\
1105 to save all current variables to the file @file{octave-workspace} if it\n\
1106 receives a hangup signal.\n\
1108 When called from inside a function with the @qcode{\"local\"} option, the\n\
1109 variable is changed locally for the function and any subroutines it calls. \n\
1110 The original variable value is restored when exiting the function.\n\
1128 DEFUN (sigterm_dumps_octave_core, args, nargout,
1130 @deftypefn {Built-in Function} {@var{val} =} sigterm_dumps_octave_core ()\n\
1131 @deftypefnx {Built-in Function} {@var{old_val} =} sigterm_dumps_octave_core (@var{new_val})\n\
1132 @deftypefnx {Built-in Function} {} sigterm_dumps_octave_core (@var{new_val}, \"local\")\n\
1133 Query or set the internal variable that controls whether Octave tries\n\
1134 to save all current variables to the file @file{octave-workspace} if it\n\
1135 receives a terminate signal.\n\
1137 When called from inside a function with the @qcode{\"local\"} option, the\n\
1138 variable is changed locally for the function and any subroutines it calls. \n\
1139 The original variable value is restored when exiting the function.\n\