Mercurial > octave-nkf
annotate src/sighandlers.cc @ 7961:a5d1e27ee1f4 ss-3-1-51
3.1.51 snapshot
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 22 Jul 2008 11:40:48 -0400 |
parents | 78f3811155f7 |
children | 73c4516fae10 |
rev | line source |
---|---|
1 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, |
4 2003, 2004, 2005, 2006, 2007 John W. Eaton | |
1 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
1 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
1 | 21 |
22 */ | |
23 | |
240 | 24 #ifdef HAVE_CONFIG_H |
1230 | 25 #include <config.h> |
1 | 26 #endif |
27 | |
2536 | 28 #include <cstdlib> |
29 | |
3503 | 30 #include <iostream> |
1344 | 31 #include <new> |
32 | |
1350 | 33 #ifdef HAVE_UNISTD_H |
2442 | 34 #ifdef HAVE_SYS_TYPES_H |
834 | 35 #include <sys/types.h> |
2442 | 36 #endif |
834 | 37 #include <unistd.h> |
38 #endif | |
1343 | 39 |
3281 | 40 #include "cmd-edit.h" |
5453 | 41 #include "oct-syscalls.h" |
4153 | 42 #include "quit.h" |
3281 | 43 |
4185 | 44 #include "defun.h" |
1352 | 45 #include "error.h" |
1373 | 46 #include "load-save.h" |
4294 | 47 #include "oct-map.h" |
2091 | 48 #include "pager.h" |
4185 | 49 #include "pt-bp.h" |
1 | 50 #include "sighandlers.h" |
4787 | 51 #include "sysdep.h" |
1352 | 52 #include "syswait.h" |
2091 | 53 #include "toplev.h" |
1 | 54 #include "utils.h" |
5794 | 55 #include "variables.h" |
1 | 56 |
57 // Nonzero means we have already printed a message for this series of | |
58 // SIGPIPES. We assume that the writer will eventually give up. | |
59 int pipe_handler_error_count = 0; | |
60 | |
3018 | 61 // TRUE means we can be interrupted. |
62 bool can_interrupt = false; | |
1 | 63 |
4185 | 64 // TRUE means we should try to enter the debugger on SIGINT. |
65 static bool Vdebug_on_interrupt = false; | |
66 | |
4449 | 67 // Allow users to avoid writing octave-core for SIGHUP (sent by |
68 // closing gnome-terminal, for example). Note that this variable has | |
69 // no effect if Vcrash_dumps_octave_core is FALSE. | |
5794 | 70 static bool Vsighup_dumps_octave_core = true; |
4449 | 71 |
72 // Similar to Vsighup_dumps_octave_core, but for SIGTERM signal. | |
5794 | 73 static bool Vsigterm_dumps_octave_core = true; |
4449 | 74 |
6098 | 75 #if defined (RETSIGTYPE_IS_VOID) |
2469 | 76 #define SIGHANDLER_RETURN(status) return |
77 #else | |
78 #define SIGHANDLER_RETURN(status) return status | |
79 #endif | |
80 | |
2554 | 81 #if defined (MUST_REINSTALL_SIGHANDLERS) |
82 #define MAYBE_REINSTALL_SIGHANDLER(sig, handler) \ | |
83 octave_set_signal_handler (sig, handler) | |
2931 | 84 #define REINSTALL_USES_SIG 1 |
2554 | 85 #else |
86 #define MAYBE_REINSTALL_SIGHANDLER(sig, handler) \ | |
87 do { } while (0) | |
88 #endif | |
89 | |
90 #if defined (__EMX__) | |
2626 | 91 #define MAYBE_ACK_SIGNAL(sig) \ |
2554 | 92 octave_set_signal_handler (sig, SIG_ACK) |
2931 | 93 #define ACK_USES_SIG 1 |
2554 | 94 #else |
2626 | 95 #define MAYBE_ACK_SIGNAL(sig) \ |
2554 | 96 do { } while (0) |
97 #endif | |
98 | |
5142 | 99 // List of signals we have caught since last call to octave_signal_handler. |
100 static bool octave_signals_caught[NSIG]; | |
101 | |
102 // Called from OCTAVE_QUIT to actually do something about the signals | |
103 // we have caught. | |
104 | |
105 void | |
106 octave_signal_handler (void) | |
107 { | |
108 // The list of signals is relatively short, so we will just go | |
109 // linearly through the list. | |
110 | |
111 for (int i = 0; i < NSIG; i++) | |
112 { | |
113 if (octave_signals_caught[i]) | |
114 { | |
115 octave_signals_caught[i] = false; | |
116 | |
117 switch (i) | |
118 { | |
5451 | 119 #ifdef SIGCHLD |
5142 | 120 case SIGCHLD: |
121 octave_child_list::reap (); | |
122 break; | |
5451 | 123 #endif |
5142 | 124 |
125 case SIGFPE: | |
126 std::cerr << "warning: floating point exception -- trying to return to prompt" << std::endl; | |
127 break; | |
128 | |
5451 | 129 #ifdef SIGPIPE |
5142 | 130 case SIGPIPE: |
131 std::cerr << "warning: broken pipe -- some output may be lost" << std::endl; | |
132 break; | |
5451 | 133 #endif |
5142 | 134 } |
135 } | |
136 } | |
137 } | |
138 | |
1 | 139 static void |
4787 | 140 my_friendly_exit (const char *sig_name, int sig_number, |
141 bool save_vars = true) | |
1 | 142 { |
2536 | 143 static bool been_there_done_that = false; |
144 | |
145 if (been_there_done_that) | |
146 { | |
2554 | 147 #if defined (SIGABRT) |
2536 | 148 octave_set_signal_handler (SIGABRT, SIG_DFL); |
149 #endif | |
150 | |
3644 | 151 std::cerr << "panic: attempted clean up apparently failed -- aborting...\n"; |
5451 | 152 |
153 MINGW_SIGNAL_CLEANUP (); | |
154 | |
2536 | 155 abort (); |
156 } | |
157 else | |
158 { | |
159 been_there_done_that = true; | |
1373 | 160 |
3644 | 161 std::cerr << "panic: " << sig_name << " -- stopping myself...\n"; |
2536 | 162 |
4787 | 163 if (save_vars) |
4791 | 164 dump_octave_core (); |
2536 | 165 |
3162 | 166 if (sig_number < 0) |
5451 | 167 { |
168 MINGW_SIGNAL_CLEANUP (); | |
169 | |
170 exit (1); | |
171 } | |
3162 | 172 else |
173 { | |
174 octave_set_signal_handler (sig_number, SIG_DFL); | |
175 | |
4092 | 176 #if defined (HAVE_RAISE) |
177 raise (sig_number); | |
178 #elif defined (HAVE_KILL) | |
3162 | 179 kill (getpid (), sig_number); |
4092 | 180 #else |
181 exit (1); | |
182 #endif | |
3162 | 183 } |
4092 | 184 |
2536 | 185 } |
1 | 186 } |
187 | |
1446 | 188 sig_handler * |
5770 | 189 octave_set_signal_handler (int sig, sig_handler *handler, |
190 bool restart_syscalls) | |
1446 | 191 { |
192 #if defined (HAVE_POSIX_SIGNALS) | |
193 struct sigaction act, oact; | |
5144 | 194 |
1446 | 195 act.sa_handler = handler; |
196 act.sa_flags = 0; | |
5144 | 197 |
198 if (sig == SIGALRM) | |
199 { | |
200 #if defined (SA_INTERRUPT) | |
201 act.sa_flags |= SA_INTERRUPT; | |
202 #endif | |
203 } | |
204 #if defined (SA_RESTART) | |
5775 | 205 // FIXME -- Do we also need to explicitly disable SA_RESTART? |
5770 | 206 else if (restart_syscalls) |
207 act.sa_flags |= SA_RESTART; | |
5144 | 208 #endif |
209 | |
1446 | 210 sigemptyset (&act.sa_mask); |
211 sigemptyset (&oact.sa_mask); | |
5144 | 212 |
1446 | 213 sigaction (sig, &act, &oact); |
5144 | 214 |
1446 | 215 return oact.sa_handler; |
216 #else | |
217 return signal (sig, handler); | |
218 #endif | |
219 } | |
220 | |
1 | 221 static RETSIGTYPE |
1446 | 222 generic_sig_handler (int sig) |
1 | 223 { |
5844 | 224 my_friendly_exit (strsignal (sig), sig); |
1 | 225 |
2469 | 226 SIGHANDLER_RETURN (0); |
1 | 227 } |
228 | |
2091 | 229 // Handle SIGCHLD. |
1230 | 230 |
4064 | 231 #ifdef SIGCHLD |
1230 | 232 static RETSIGTYPE |
2092 | 233 sigchld_handler (int /* sig */) |
1230 | 234 { |
2705 | 235 volatile octave_interrupt_handler saved_interrupt_handler |
2554 | 236 = octave_ignore_interrupts (); |
237 | |
2626 | 238 // I wonder if this is really right, or if SIGCHLD should just be |
239 // blocked on OS/2 systems the same as for systems with POSIX signal | |
240 // functions. | |
241 | |
242 #if defined (__EMX__) | |
2554 | 243 volatile sig_handler *saved_sigchld_handler |
2626 | 244 = octave_set_signal_handler (SIGCHLD, SIG_IGN); |
2554 | 245 #endif |
246 | |
2626 | 247 sigset_t set, oset; |
248 | |
249 BLOCK_CHILD (set, oset); | |
250 | |
5142 | 251 if (octave_child_list::wait ()) |
2554 | 252 { |
5142 | 253 // The status of some child changed. |
2209 | 254 |
5142 | 255 octave_signal_caught = 1; |
2197 | 256 |
5142 | 257 octave_signals_caught[SIGCHLD] = true; |
1230 | 258 } |
2469 | 259 |
2600 | 260 octave_set_interrupt_handler (saved_interrupt_handler); |
2554 | 261 |
2626 | 262 UNBLOCK_CHILD (oset); |
263 | |
264 #ifdef __EMX__ | |
2554 | 265 octave_set_signal_handler (SIGCHLD, saved_sigchld_handler); |
2475 | 266 #endif |
267 | |
2626 | 268 MAYBE_ACK_SIGNAL (SIGCHLD); |
2554 | 269 |
270 MAYBE_REINSTALL_SIGHANDLER (SIGCHLD, sigchld_handler); | |
271 | |
2469 | 272 SIGHANDLER_RETURN (0); |
1230 | 273 } |
4064 | 274 #endif /* defined(SIGCHLD) */ |
1230 | 275 |
4064 | 276 #ifdef SIGFPE |
1373 | 277 #if defined (__alpha__) |
278 static RETSIGTYPE | |
1488 | 279 sigfpe_handler (int /* sig */) |
1373 | 280 { |
2626 | 281 MAYBE_ACK_SIGNAL (SIGFPE); |
2554 | 282 |
283 MAYBE_REINSTALL_SIGHANDLER (SIGFPE, sigfpe_handler); | |
1373 | 284 |
5142 | 285 if (can_interrupt && octave_interrupt_state >= 0) |
286 { | |
287 octave_signal_caught = 1; | |
1373 | 288 |
5142 | 289 octave_signals_caught[SIGFPE] = true; |
4182 | 290 |
5142 | 291 octave_interrupt_state++; |
292 } | |
1373 | 293 |
2469 | 294 SIGHANDLER_RETURN (0); |
1373 | 295 } |
4064 | 296 #endif /* defined(__alpha__) */ |
297 #endif /* defined(SIGFPE) */ | |
1373 | 298 |
4449 | 299 #if defined (SIGHUP) || defined (SIGTERM) |
300 static RETSIGTYPE | |
301 sig_hup_or_term_handler (int sig) | |
302 { | |
303 MAYBE_ACK_SIGNAL (sig); | |
304 | |
305 MAYBE_REINSTALL_SIGHANDLER (sig, sig_hup_or_term_handler); | |
306 | |
307 switch (sig) | |
308 { | |
309 #if defined (SIGHUP) | |
310 case SIGHUP: | |
311 { | |
312 if (Vsighup_dumps_octave_core) | |
4791 | 313 dump_octave_core (); |
4449 | 314 } |
315 break; | |
316 #endif | |
317 | |
318 #if defined (SIGTERM) | |
319 case SIGTERM: | |
320 { | |
321 if (Vsigterm_dumps_octave_core) | |
4791 | 322 dump_octave_core (); |
4449 | 323 } |
324 break; | |
325 #endif | |
326 | |
327 default: | |
328 break; | |
329 } | |
330 | |
331 clean_up_and_exit (0); | |
332 | |
333 SIGHANDLER_RETURN (0); | |
334 } | |
335 #endif | |
336 | |
3343 | 337 #if 0 |
3281 | 338 #if defined (SIGWINCH) |
339 static RETSIGTYPE | |
340 sigwinch_handler (int /* sig */) | |
341 { | |
342 MAYBE_ACK_SIGNAL (SIGWINCH); | |
343 | |
344 MAYBE_REINSTALL_SIGHANDLER (SIGWINCH, sigwinch_handler); | |
345 | |
346 command_editor::resize_terminal (); | |
347 | |
348 SIGHANDLER_RETURN (0); | |
349 } | |
350 #endif | |
3343 | 351 #endif |
3281 | 352 |
635 | 353 // Handle SIGINT by restarting the parser (see octave.cc). |
2554 | 354 // |
355 // This also has to work for SIGBREAK (on systems that have it), so we | |
356 // use the value of sig, instead of just assuming that it is called | |
357 // for SIGINT only. | |
635 | 358 |
5451 | 359 static |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
360 void user_abort (const char *sig_name, int sig_number) |
1 | 361 { |
4172 | 362 if (! octave_initialized) |
363 exit (1); | |
364 | |
1 | 365 if (can_interrupt) |
366 { | |
4185 | 367 if (Vdebug_on_interrupt) |
368 { | |
369 if (! octave_debug_on_interrupt_state) | |
370 { | |
371 octave_debug_on_interrupt_state = true; | |
372 | |
5451 | 373 return; |
4185 | 374 } |
375 else | |
376 // Clear the flag and do normal interrupt stuff. | |
377 octave_debug_on_interrupt_state = false; | |
378 } | |
379 | |
4153 | 380 if (octave_interrupt_immediately) |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
381 { |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
382 if (octave_interrupt_state == 0) |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
383 octave_interrupt_state = 1; |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
384 |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
385 octave_jump_to_enclosing_context (); |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
386 } |
4429 | 387 else |
4787 | 388 { |
4793 | 389 // If we are already cleaning up from a previous interrupt, |
390 // take note of the fact that another interrupt signal has | |
391 // arrived. | |
392 | |
393 if (octave_interrupt_state < 0) | |
394 octave_interrupt_state = 0; | |
395 | |
5142 | 396 octave_signal_caught = 1; |
4787 | 397 octave_interrupt_state++; |
398 | |
4791 | 399 if (interactive && octave_interrupt_state == 2) |
400 std::cerr << "Press Control-C again to abort." << std::endl; | |
4787 | 401 |
4791 | 402 if (octave_interrupt_state >= 3) |
5451 | 403 my_friendly_exit (sig_name, sig_number, true); |
4787 | 404 } |
1 | 405 } |
406 | |
5451 | 407 } |
408 | |
409 static RETSIGTYPE | |
410 sigint_handler (int sig) | |
411 { | |
412 MAYBE_ACK_SIGNAL (sig); | |
413 | |
414 MAYBE_REINSTALL_SIGHANDLER (sig, sigint_handler); | |
415 | |
416 #ifdef USE_W32_SIGINT | |
417 if (w32_in_main_thread ()) | |
5844 | 418 user_abort (strsignal (sig), sig); |
5451 | 419 else |
420 w32_raise (sig); | |
421 #else | |
5844 | 422 user_abort (strsignal (sig), sig); |
5451 | 423 #endif |
424 | |
2469 | 425 SIGHANDLER_RETURN (0); |
1 | 426 } |
427 | |
4064 | 428 #ifdef SIGPIPE |
1 | 429 static RETSIGTYPE |
1488 | 430 sigpipe_handler (int /* sig */) |
1 | 431 { |
2626 | 432 MAYBE_ACK_SIGNAL (SIGPIPE); |
2554 | 433 |
434 MAYBE_REINSTALL_SIGHANDLER (SIGPIPE, sigpipe_handler); | |
834 | 435 |
5142 | 436 octave_signal_caught = 1; |
437 | |
438 octave_signals_caught[SIGPIPE] = true; | |
1 | 439 |
1358 | 440 // Don't loop forever on account of this. |
441 | |
5142 | 442 if (pipe_handler_error_count++ > 100 && octave_interrupt_state >= 0) |
4787 | 443 octave_interrupt_state++; |
1 | 444 |
2469 | 445 SIGHANDLER_RETURN (0); |
1 | 446 } |
4064 | 447 #endif /* defined(SIGPIPE) */ |
1 | 448 |
5451 | 449 #ifdef USE_W32_SIGINT |
450 static BOOL CALLBACK | |
451 w32_sigint_handler (DWORD sig) | |
452 { | |
453 const char *sig_name; | |
454 | |
455 switch(sig) | |
456 { | |
457 case CTRL_BREAK_EVENT: | |
458 sig_name = "Ctrl-Break"; | |
459 break; | |
460 case CTRL_C_EVENT: | |
461 sig_name = "Ctrl-C"; | |
462 break; | |
463 case CTRL_CLOSE_EVENT: | |
464 sig_name = "close console"; | |
465 break; | |
466 case CTRL_LOGOFF_EVENT: | |
467 sig_name = "logoff"; | |
468 break; | |
469 case CTRL_SHUTDOWN_EVENT: | |
470 sig_name = "shutdown"; | |
471 break; | |
472 default: | |
473 sig_name = "unknown console event"; | |
474 break; | |
475 } | |
476 | |
477 switch(sig) | |
478 { | |
479 case CTRL_BREAK_EVENT: | |
480 case CTRL_C_EVENT: | |
481 w32_raise (SIGINT); | |
482 break; | |
483 | |
484 case CTRL_CLOSE_EVENT: | |
485 case CTRL_LOGOFF_EVENT: | |
486 case CTRL_SHUTDOWN_EVENT: | |
487 default: | |
488 // We should do the following: | |
489 // clean_up_and_exit (0); | |
490 // We can't because we aren't running in the normal Octave thread. | |
491 user_abort(sig_name, sig); | |
492 break; | |
493 } | |
494 | |
495 // Return TRUE if the event was handled, or FALSE if another handler | |
496 // should be called. | |
5775 | 497 // FIXME check that windows terminates the thread. |
5451 | 498 return TRUE; |
499 } | |
500 #endif /* w32_sigint_handler */ | |
501 | |
502 | |
2705 | 503 octave_interrupt_handler |
2554 | 504 octave_catch_interrupts (void) |
505 { | |
2705 | 506 octave_interrupt_handler retval; |
2554 | 507 |
508 #ifdef SIGINT | |
2705 | 509 retval.int_handler = octave_set_signal_handler (SIGINT, sigint_handler); |
2554 | 510 #endif |
511 | |
512 #ifdef SIGBREAK | |
2705 | 513 retval.brk_handler = octave_set_signal_handler (SIGBREAK, sigint_handler); |
2554 | 514 #endif |
2705 | 515 |
5451 | 516 #ifdef USE_W32_SIGINT |
517 | |
518 // Intercept windows console control events. | |
519 // Note that the windows console signal handlers chain, so if | |
520 // install_signal_handlers is called more than once in the same program, | |
521 // then first call the following to avoid duplicates: | |
522 // | |
523 // SetConsoleCtrlHandler (w32_sigint_handler, FALSE); | |
524 | |
525 if (! SetConsoleCtrlHandler (w32_sigint_handler, TRUE)) | |
526 error ("SetConsoleCtrlHandler failed with %ld\n", GetLastError ()); | |
527 | |
528 w32_set_quiet_shutdown (); | |
529 | |
530 #endif | |
531 | |
2705 | 532 return retval; |
2554 | 533 } |
534 | |
2705 | 535 octave_interrupt_handler |
536 octave_ignore_interrupts (void) | |
2554 | 537 { |
2705 | 538 octave_interrupt_handler retval; |
539 | |
2554 | 540 #ifdef SIGINT |
2705 | 541 retval.int_handler = octave_set_signal_handler (SIGINT, SIG_IGN); |
2554 | 542 #endif |
543 | |
544 #ifdef SIGBREAK | |
2705 | 545 retval.brk_handler = octave_set_signal_handler (SIGBREAK, SIG_IGN); |
2554 | 546 #endif |
2705 | 547 |
548 return retval; | |
549 } | |
550 | |
551 octave_interrupt_handler | |
5770 | 552 octave_set_interrupt_handler (const volatile octave_interrupt_handler& h, |
553 bool restart_syscalls) | |
2705 | 554 { |
555 octave_interrupt_handler retval; | |
556 | |
557 #ifdef SIGINT | |
5770 | 558 retval.int_handler = octave_set_signal_handler (SIGINT, h.int_handler, |
559 restart_syscalls); | |
2705 | 560 #endif |
561 | |
562 #ifdef SIGBREAK | |
5770 | 563 retval.brk_handler = octave_set_signal_handler (SIGBREAK, h.brk_handler, |
564 restart_syscalls); | |
2705 | 565 #endif |
566 | |
567 return retval; | |
1651 | 568 } |
569 | |
635 | 570 // Install all the handlers for the signals we might care about. |
571 | |
1 | 572 void |
573 install_signal_handlers (void) | |
574 { | |
5142 | 575 for (int i = 0; i < NSIG; i++) |
576 octave_signals_caught[i] = false; | |
577 | |
2554 | 578 octave_catch_interrupts (); |
579 | |
1 | 580 #ifdef SIGABRT |
1446 | 581 octave_set_signal_handler (SIGABRT, generic_sig_handler); |
1 | 582 #endif |
583 | |
584 #ifdef SIGALRM | |
1446 | 585 octave_set_signal_handler (SIGALRM, generic_sig_handler); |
1 | 586 #endif |
587 | |
588 #ifdef SIGBUS | |
1446 | 589 octave_set_signal_handler (SIGBUS, generic_sig_handler); |
1 | 590 #endif |
591 | |
1230 | 592 #ifdef SIGCHLD |
1446 | 593 octave_set_signal_handler (SIGCHLD, sigchld_handler); |
1230 | 594 #endif |
595 | |
3174 | 596 // SIGCLD |
597 // SIGCONT | |
598 | |
1 | 599 #ifdef SIGEMT |
1446 | 600 octave_set_signal_handler (SIGEMT, generic_sig_handler); |
1 | 601 #endif |
602 | |
603 #ifdef SIGFPE | |
1373 | 604 #if defined (__alpha__) |
1446 | 605 octave_set_signal_handler (SIGFPE, sigfpe_handler); |
1373 | 606 #else |
1446 | 607 octave_set_signal_handler (SIGFPE, generic_sig_handler); |
1 | 608 #endif |
1373 | 609 #endif |
1 | 610 |
611 #ifdef SIGHUP | |
4449 | 612 octave_set_signal_handler (SIGHUP, sig_hup_or_term_handler); |
1 | 613 #endif |
614 | |
615 #ifdef SIGILL | |
1446 | 616 octave_set_signal_handler (SIGILL, generic_sig_handler); |
1 | 617 #endif |
618 | |
3174 | 619 // SIGINFO |
620 // SIGINT | |
621 | |
1 | 622 #ifdef SIGIOT |
1446 | 623 octave_set_signal_handler (SIGIOT, generic_sig_handler); |
1 | 624 #endif |
625 | |
626 #ifdef SIGLOST | |
1446 | 627 octave_set_signal_handler (SIGLOST, generic_sig_handler); |
1 | 628 #endif |
629 | |
630 #ifdef SIGPIPE | |
1446 | 631 octave_set_signal_handler (SIGPIPE, sigpipe_handler); |
1 | 632 #endif |
633 | |
634 #ifdef SIGPOLL | |
1446 | 635 octave_set_signal_handler (SIGPOLL, SIG_IGN); |
1 | 636 #endif |
637 | |
5866 | 638 // SIGPROF |
3174 | 639 // SIGPWR |
640 | |
1 | 641 #ifdef SIGQUIT |
1446 | 642 octave_set_signal_handler (SIGQUIT, generic_sig_handler); |
1 | 643 #endif |
644 | |
645 #ifdef SIGSEGV | |
1446 | 646 octave_set_signal_handler (SIGSEGV, generic_sig_handler); |
1 | 647 #endif |
648 | |
3174 | 649 // SIGSTOP |
650 | |
1 | 651 #ifdef SIGSYS |
1446 | 652 octave_set_signal_handler (SIGSYS, generic_sig_handler); |
1 | 653 #endif |
654 | |
655 #ifdef SIGTERM | |
4449 | 656 octave_set_signal_handler (SIGTERM, sig_hup_or_term_handler); |
1 | 657 #endif |
658 | |
659 #ifdef SIGTRAP | |
1446 | 660 octave_set_signal_handler (SIGTRAP, generic_sig_handler); |
1 | 661 #endif |
662 | |
3174 | 663 // SIGTSTP |
664 // SIGTTIN | |
665 // SIGTTOU | |
666 // SIGURG | |
667 | |
1 | 668 #ifdef SIGUSR1 |
1446 | 669 octave_set_signal_handler (SIGUSR1, generic_sig_handler); |
1 | 670 #endif |
671 | |
672 #ifdef SIGUSR2 | |
1446 | 673 octave_set_signal_handler (SIGUSR2, generic_sig_handler); |
1 | 674 #endif |
675 | |
676 #ifdef SIGVTALRM | |
1446 | 677 octave_set_signal_handler (SIGVTALRM, generic_sig_handler); |
1 | 678 #endif |
679 | |
895 | 680 #ifdef SIGIO |
1446 | 681 octave_set_signal_handler (SIGIO, SIG_IGN); |
895 | 682 #endif |
683 | |
3343 | 684 #if 0 |
3281 | 685 #ifdef SIGWINCH |
686 octave_set_signal_handler (SIGWINCH, sigwinch_handler); | |
687 #endif | |
3343 | 688 #endif |
3174 | 689 |
1 | 690 #ifdef SIGXCPU |
1446 | 691 octave_set_signal_handler (SIGXCPU, generic_sig_handler); |
1 | 692 #endif |
693 | |
694 #ifdef SIGXFSZ | |
1446 | 695 octave_set_signal_handler (SIGXFSZ, generic_sig_handler); |
1 | 696 #endif |
5451 | 697 |
1 | 698 } |
699 | |
4294 | 700 static Octave_map |
701 make_sig_struct (void) | |
702 { | |
703 Octave_map m; | |
704 | |
705 #ifdef SIGABRT | |
4675 | 706 m.assign ("ABRT", SIGABRT); |
4294 | 707 #endif |
708 | |
709 #ifdef SIGALRM | |
4675 | 710 m.assign ("ALRM", SIGALRM); |
4294 | 711 #endif |
712 | |
713 #ifdef SIGBUS | |
4675 | 714 m.assign ("BUS", SIGBUS); |
4294 | 715 #endif |
716 | |
717 #ifdef SIGCHLD | |
4675 | 718 m.assign ("CHLD", SIGCHLD); |
4294 | 719 #endif |
720 | |
721 #ifdef SIGCLD | |
4675 | 722 m.assign ("CLD", SIGCLD); |
4294 | 723 #endif |
724 | |
725 #ifdef SIGCONT | |
4675 | 726 m.assign ("CONT", SIGCONT); |
4294 | 727 #endif |
728 | |
729 #ifdef SIGEMT | |
4675 | 730 m.assign ("EMT", SIGEMT); |
4294 | 731 #endif |
732 | |
733 #ifdef SIGFPE | |
4675 | 734 m.assign ("FPE", SIGFPE); |
4294 | 735 #endif |
736 | |
737 #ifdef SIGHUP | |
4675 | 738 m.assign ("HUP", SIGHUP); |
4294 | 739 #endif |
740 | |
741 #ifdef SIGILL | |
4675 | 742 m.assign ("ILL", SIGILL); |
4294 | 743 #endif |
744 | |
745 #ifdef SIGINFO | |
4675 | 746 m.assign ("INFO", SIGINFO); |
4294 | 747 #endif |
748 | |
749 #ifdef SIGINT | |
4675 | 750 m.assign ("INT", SIGINT); |
4294 | 751 #endif |
752 | |
753 #ifdef SIGIOT | |
4675 | 754 m.assign ("IOT", SIGIOT); |
4294 | 755 #endif |
756 | |
757 #ifdef SIGLOST | |
4675 | 758 m.assign ("LOST", SIGLOST); |
4294 | 759 #endif |
760 | |
761 #ifdef SIGPIPE | |
4675 | 762 m.assign ("PIPE", SIGPIPE); |
4294 | 763 #endif |
764 | |
765 #ifdef SIGPOLL | |
4675 | 766 m.assign ("POLL", SIGPOLL); |
4294 | 767 #endif |
768 | |
769 #ifdef SIGPROF | |
4675 | 770 m.assign ("PROF", SIGPROF); |
4294 | 771 #endif |
772 | |
773 #ifdef SIGPWR | |
4675 | 774 m.assign ("PWR", SIGPWR); |
4294 | 775 #endif |
776 | |
777 #ifdef SIGQUIT | |
4675 | 778 m.assign ("QUIT", SIGQUIT); |
4294 | 779 #endif |
780 | |
781 #ifdef SIGSEGV | |
4675 | 782 m.assign ("SEGV", SIGSEGV); |
4294 | 783 #endif |
784 | |
785 #ifdef SIGSTOP | |
4675 | 786 m.assign ("STOP", SIGSTOP); |
4294 | 787 #endif |
788 | |
789 #ifdef SIGSYS | |
4675 | 790 m.assign ("SYS", SIGSYS); |
4294 | 791 #endif |
792 | |
793 #ifdef SIGTERM | |
4675 | 794 m.assign ("TERM", SIGTERM); |
4294 | 795 #endif |
796 | |
797 #ifdef SIGTRAP | |
4675 | 798 m.assign ("TRAP", SIGTRAP); |
4294 | 799 #endif |
800 | |
801 #ifdef SIGTSTP | |
4675 | 802 m.assign ("TSTP", SIGTSTP); |
4294 | 803 #endif |
804 | |
805 #ifdef SIGTTIN | |
4675 | 806 m.assign ("TTIN", SIGTTIN); |
4294 | 807 #endif |
808 | |
809 #ifdef SIGTTOU | |
4675 | 810 m.assign ("TTOU", SIGTTOU); |
4294 | 811 #endif |
812 | |
813 #ifdef SIGURG | |
4675 | 814 m.assign ("URG", SIGURG); |
4294 | 815 #endif |
816 | |
817 #ifdef SIGUSR1 | |
4675 | 818 m.assign ("USR1", SIGUSR1); |
4294 | 819 #endif |
820 | |
821 #ifdef SIGUSR2 | |
4675 | 822 m.assign ("USR2", SIGUSR2); |
4294 | 823 #endif |
824 | |
825 #ifdef SIGVTALRM | |
4675 | 826 m.assign ("VTALRM", SIGVTALRM); |
4294 | 827 #endif |
828 | |
829 #ifdef SIGIO | |
4675 | 830 m.assign ("IO", SIGIO); |
4294 | 831 #endif |
832 | |
833 #ifdef SIGWINCH | |
4675 | 834 m.assign ("WINCH", SIGWINCH); |
4294 | 835 #endif |
836 | |
837 #ifdef SIGXCPU | |
4675 | 838 m.assign ("XCPU", SIGXCPU); |
4294 | 839 #endif |
840 | |
841 #ifdef SIGXFSZ | |
4675 | 842 m.assign ("XFSZ", SIGXFSZ); |
4294 | 843 #endif |
844 | |
845 return m; | |
846 } | |
847 | |
5142 | 848 octave_child_list::octave_child_list_rep *octave_child_list::instance = 0; |
5128 | 849 |
2926 | 850 bool |
851 octave_child_list::instance_ok (void) | |
852 { | |
853 bool retval = true; | |
854 | |
855 if (! instance) | |
5142 | 856 instance = new octave_child_list_rep (); |
2926 | 857 |
858 if (! instance) | |
859 { | |
860 ::error ("unable to create child list object!"); | |
861 | |
862 retval = false; | |
863 } | |
864 | |
865 return retval; | |
866 } | |
867 | |
868 void | |
5142 | 869 octave_child_list::insert (pid_t pid, octave_child::child_event_handler f) |
870 { | |
871 if (instance_ok ()) | |
872 instance->insert (pid, f); | |
873 } | |
874 | |
875 void | |
876 octave_child_list::reap (void) | |
2926 | 877 { |
878 if (instance_ok ()) | |
5142 | 879 instance->reap (); |
880 } | |
881 | |
882 bool | |
883 octave_child_list::wait (void) | |
884 { | |
885 return (instance_ok ()) ? instance->wait () : false; | |
2926 | 886 } |
887 | |
5142 | 888 class pid_equal |
889 { | |
890 public: | |
891 | |
892 pid_equal (pid_t v) : val (v) { } | |
893 | |
894 bool operator () (const octave_child& oc) const { return oc.pid == val; } | |
895 | |
896 private: | |
897 | |
898 pid_t val; | |
899 }; | |
900 | |
2926 | 901 void |
902 octave_child_list::remove (pid_t pid) | |
903 { | |
904 if (instance_ok ()) | |
5142 | 905 instance->remove_if (pid_equal (pid)); |
2926 | 906 } |
907 | |
5142 | 908 #define OCL_REP octave_child_list::octave_child_list_rep |
2926 | 909 |
5142 | 910 void |
911 OCL_REP::insert (pid_t pid, octave_child::child_event_handler f) | |
2926 | 912 { |
5142 | 913 append (octave_child (pid, f)); |
2926 | 914 } |
915 | |
2209 | 916 void |
5142 | 917 OCL_REP::reap (void) |
2209 | 918 { |
5142 | 919 // Mark the record for PID invalid. |
2209 | 920 |
5142 | 921 for (iterator p = begin (); p != end (); p++) |
922 { | |
923 // The call to the octave_child::child_event_handler might | |
924 // invalidate the iterator (for example, by calling | |
925 // octave_child_list::remove), so we increment the iterator | |
926 // here. | |
2209 | 927 |
5142 | 928 octave_child& oc = *p; |
2209 | 929 |
5142 | 930 if (oc.have_status) |
2209 | 931 { |
5142 | 932 oc.have_status = 0; |
933 | |
934 octave_child::child_event_handler f = oc.handler; | |
935 | |
936 if (f && f (oc.pid, oc.status)) | |
937 oc.pid = -1; | |
2209 | 938 } |
939 } | |
940 | |
5142 | 941 remove_if (pid_equal (-1)); |
2209 | 942 } |
943 | |
5142 | 944 // Wait on our children and record any changes in their status. |
945 | |
946 bool | |
947 OCL_REP::wait (void) | |
2210 | 948 { |
5142 | 949 bool retval = false; |
2210 | 950 |
5142 | 951 for (iterator p = begin (); p != end (); p++) |
2210 | 952 { |
5142 | 953 octave_child& oc = *p; |
954 | |
955 pid_t pid = oc.pid; | |
956 | |
957 if (pid > 0) | |
958 { | |
959 int status; | |
2210 | 960 |
5453 | 961 if (octave_syscalls::waitpid (pid, &status, WNOHANG) > 0) |
5142 | 962 { |
963 oc.have_status = 1; | |
964 | |
965 oc.status = status; | |
966 | |
967 retval = true; | |
968 | |
969 break; | |
970 } | |
2210 | 971 } |
972 } | |
973 | |
5142 | 974 return retval; |
2210 | 975 } |
976 | |
5780 | 977 DEFUN (SIG, args, , |
978 "-*- texinfo -*-\n\ | |
979 @deftypefn {Built-in Function} {} SIG ()\n\ | |
980 Return a structure containing Unix signal names and their defined values.\n\ | |
981 @end deftypefn") | |
982 { | |
983 octave_value retval; | |
984 | |
985 if (args.length () == 0) | |
986 { | |
987 static Octave_map m = make_sig_struct (); | |
988 | |
989 retval = m; | |
990 } | |
991 else | |
5823 | 992 print_usage (); |
5780 | 993 |
994 return retval; | |
995 } | |
996 | |
5794 | 997 DEFUN (debug_on_interrupt, args, nargout, |
998 "-*- texinfo -*-\n\ | |
999 @deftypefn {Built-in Function} {@var{val} =} debug_on_interrupt ()\n\ | |
1000 @deftypefnx {Built-in Function} {@var{old_val} =} debug_on_interrupt (@var{new_val})\n\ | |
1001 Query or set the internal variable that controls whether Octave will try\n\ | |
1002 to enter debugging mode when it receives an interrupt signal (typically\n\ | |
1003 generated with @kbd{C-c}). If a second interrupt signal is received\n\ | |
1004 before reaching the debugging mode, a normal interrupt will occur.\n\ | |
1005 @end deftypefn") | |
4449 | 1006 { |
5794 | 1007 return SET_INTERNAL_VARIABLE (debug_on_interrupt); |
4449 | 1008 } |
1009 | |
5794 | 1010 DEFUN (sighup_dumps_octave_core, args, nargout, |
1011 "-*- texinfo -*-\n\ | |
1012 @deftypefn {Built-in Function} {@var{val} =} sighup_dumps_octave_core ()\n\ | |
1013 @deftypefnx {Built-in Function} {@var{old_val} =} sighup_dumps_octave_core (@var{new_val})\n\ | |
1014 Query or set the internal variable that controls whether Octave tries\n\ | |
6653 | 1015 to save all current variables to the file \"octave-core\" if it receives\n\ |
5794 | 1016 a hangup signal.\n\ |
1017 @end deftypefn") | |
4185 | 1018 { |
5794 | 1019 return SET_INTERNAL_VARIABLE (sighup_dumps_octave_core); |
1020 } | |
4294 | 1021 |
5794 | 1022 DEFUN (sigterm_dumps_octave_core, args, nargout, |
1023 "-*- texinfo -*-\n\ | |
1024 @deftypefn {Built-in Function} {@var{val} =} sigterm_dumps_octave_core ()\n\ | |
1025 @deftypefnx {Built-in Function} {@var{old_val} =} sigterm_dumps_octave_core (@var{new_val})\n\ | |
1026 Query or set the internal variable that controls whether Octave tries\n\ | |
6653 | 1027 to save all current variables to the file \"octave-core\" if it receives\n\ |
5794 | 1028 a terminate signal.\n\ |
1029 @end deftypefn") | |
1030 { | |
1031 return SET_INTERNAL_VARIABLE (sigterm_dumps_octave_core); | |
4185 | 1032 } |
1033 | |
1 | 1034 /* |
1035 ;;; Local Variables: *** | |
1036 ;;; mode: C++ *** | |
1037 ;;; End: *** | |
1038 */ |