changelog shortlog tags changeset files revisions annotate raw

src/sighandlers.cc

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