Mercurial > hg > octave-lyh
diff src/sighandlers.cc @ 2554:f7e3d23f0a8f
[project @ 1996-11-21 01:41:57 by jwe]
author | jwe |
---|---|
date | Thu, 21 Nov 1996 01:43:06 +0000 |
parents | 1d63e820ee13 |
children | c454cd888ada |
line wrap: on
line diff
--- a/src/sighandlers.cc +++ b/src/sighandlers.cc @@ -71,6 +71,22 @@ #define SIGHANDLER_RETURN(status) return status #endif +#if defined (MUST_REINSTALL_SIGHANDLERS) +#define MAYBE_REINSTALL_SIGHANDLER(sig, handler) \ + octave_set_signal_handler (sig, handler) +#else +#define MAYBE_REINSTALL_SIGHANDLER(sig, handler) \ + do { } while (0) +#endif + +#if defined (__EMX__) +#define MAYBE_UNBLOCK_SIGNAL(sig) \ + octave_set_signal_handler (sig, SIG_ACK) +#else +#define MAYBE_UNBLOCK_SIGNAL(sig) \ + do { } while (0) +#endif + void octave_save_signal_mask (void) { @@ -87,6 +103,20 @@ #endif } +struct +octave_interrupt_handler +{ +#ifdef SIGINT + sig_handler *int_handler; +#endif + +#ifdef SIGBREAK + sig_handler *brk_handler; +#endif +}; + +static octave_interrupt_handler the_interrupt_handler; + static void my_friendly_exit (const char *sig_name, int sig_number) { @@ -94,7 +124,7 @@ if (been_there_done_that) { -#ifdef SIGABRT +#if defined (SIGABRT) octave_set_signal_handler (SIGABRT, SIG_DFL); #endif @@ -159,36 +189,57 @@ static RETSIGTYPE sigchld_handler (int /* sig */) { +#if defined (__EMX__) + volatile octave_interrupt_handler *saved_interrupt_handler + = octave_ignore_interrupts (); + + volatile sig_handler *saved_sigchld_handler + = octave_set_sighanlder (SIGCHLD, SIG_IGN); +#endif + int n = octave_child_list::length (); - for (int i = 0; i < n; i++) + if (n == 0) { - octave_child& elt = octave_child_list::elem (i); + waitpid (-1, 0, WNOHANG); + } + else + { + for (int i = 0; i < n; i++) + { + octave_child& elt = octave_child_list::elem (i); - pid_t pid = elt.pid; - - if (pid > 0) - { - int status; + pid_t pid = elt.pid; - if (waitpid (pid, &status, WNOHANG) > 0) + if (pid > 0) { - elt.pid = -1; + int status; + + if (waitpid (pid, &status, WNOHANG) > 0) + { + elt.pid = -1; - octave_child::dead_child_handler f = elt.handler; + octave_child::dead_child_handler f = elt.handler; - if (f) - f (pid, status); + if (f) + f (pid, status); - break; + break; + } } } } -#ifdef MUST_REINSTALL_SIGHANDLERS - octave_set_signal_handler (SIGCHLD, sigchld_handler); +#if defined (__EMX__) + octave_set_inerrupt_handler (saved_interrupt_handler); + + octave_set_signal_handler (SIGCHLD, saved_sigchld_handler); #endif + MAYBE_UNBLOCK_SIGNAL (SIGCHLD); + + MAYBE_REINSTALL_SIGHANDLER (SIGCHLD, sigchld_handler); + SIGHANDLER_RETURN (0); } @@ -196,9 +247,9 @@ static RETSIGTYPE sigfpe_handler (int /* sig */) { -#ifdef MUST_REINSTALL_SIGHANDLERS - octave_set_signal_handler (SIGFPE, sigfpe_handler); -#endif + MAYBE_UNBLOCK_SIGNAL (SIGFPE); + + MAYBE_REINSTALL_SIGHANDLER (SIGFPE, sigfpe_handler); error ("floating point exception -- trying to return to prompt"); @@ -213,13 +264,17 @@ #endif // Handle SIGINT by restarting the parser (see octave.cc). +// +// This also has to work for SIGBREAK (on systems that have it), so we +// use the value of sig, instead of just assuming that it is called +// for SIGINT only. static RETSIGTYPE -sigint_handler (int /* sig */) +sigint_handler (int sig) { -#ifdef MUST_REINSTALL_SIGHANDLERS - octave_set_signal_handler (SIGINT, sigint_handler); -#endif + MAYBE_UNBLOCK_SIGNAL (sig); + + MAYBE_REINSTALL_SIGHANDLER (sig, sigint_handler); if (can_interrupt) { @@ -233,9 +288,9 @@ static RETSIGTYPE sigpipe_handler (int /* sig */) { -#ifdef MUST_REINSTALL_SIGHANDLERS - octave_set_signal_handler (SIGPIPE, sigpipe_handler); -#endif + MAYBE_UNBLOCK_SIGNAL (SIGPIPE); + + MAYBE_REINSTALL_SIGHANDLER (SIGPIPE, sigpipe_handler); if (pipe_handler_error_count++ == 0) warning ("broken pipe"); @@ -249,9 +304,54 @@ } void -catch_interrupts (void) +octave_catch_interrupts (void) +{ +#ifdef SIGINT + octave_set_signal_handler (SIGINT, sigint_handler); + + the_interrupt_handler.int_handler = sigint_handler; +#endif + +#ifdef SIGBREAK + octave_set_signal_handler (SIGBREAK, sigint_handler); + + the_interrupt_handler.brk_handler = sigint_handler; +#endif +} + +octave_interrupt_handler * +octave_ignore_interrupts (void) { - octave_set_signal_handler (SIGINT, sigint_handler); +#ifdef SIGINT + the_interrupt_handler.int_handler + = octave_set_signal_handler (SIGINT, SIG_IGN); +#endif + +#ifdef SIGBREAK + the_interrupt_handler.int_handler + = octave_set_signal_handler (SIGBREAK, SIG_IGN); +#endif + + return &the_interrupt_handler; +} + +octave_interrupt_handler * +octave_set_interrupt_handler (const volatile octave_interrupt_handler *h) +{ + if (h) + { +#ifdef SIGINT + the_interrupt_handler.int_handler + = octave_set_signal_handler (SIGINT, h->int_handler); +#endif + +#ifdef SIGBREAK + the_interrupt_handler.int_handler + = octave_set_signal_handler (SIGBREAK, h->brk_handler); +#endif + } + + return &the_interrupt_handler; } // Install all the handlers for the signals we might care about. @@ -261,6 +361,8 @@ { set_new_handler (octave_new_handler); + octave_catch_interrupts (); + #ifdef SIGABRT octave_set_signal_handler (SIGABRT, generic_sig_handler); #endif @@ -297,10 +399,6 @@ octave_set_signal_handler (SIGILL, generic_sig_handler); #endif -#ifdef SIGINT - octave_set_signal_handler (SIGINT, sigint_handler); -#endif - #ifdef SIGIOT octave_set_signal_handler (SIGIOT, generic_sig_handler); #endif