GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
sighandlers.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1993-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <atomic>
31 #include <csignal>
32 #include <cstdlib>
33 
34 #include <iostream>
35 #include <new>
36 
37 #if defined (OCTAVE_USE_WINDOWS_API)
38 # define WIN32_LEAN_AND_MEAN
39 # include <windows.h>
40 #endif
41 
42 #include "child-list.h"
43 #include "cmd-edit.h"
44 #include "oct-syscalls.h"
45 #include "quit.h"
46 #include "signal-wrappers.h"
47 
48 #include "defun.h"
49 #include "error.h"
50 #include "input.h"
51 #include "interpreter-private.h"
52 #include "interpreter.h"
53 #include "load-save.h"
54 #include "octave.h"
55 #include "oct-map.h"
56 #include "pager.h"
57 #include "sighandlers.h"
58 #include "sysdep.h"
59 #include "utils.h"
60 #include "variables.h"
61 
63 
64 // Nonzero means we have already printed a message for this series of
65 // SIGPIPES. We assume that the writer will eventually give up.
67 
68 // TRUE means we can be interrupted.
69 std::atomic<bool> can_interrupt{false};
70 
71 // TRUE means we should try to enter the debugger on SIGINT.
72 bool Vdebug_on_interrupt = false;
73 
74 // Allow users to avoid writing octave-workspace for SIGHUP (sent by
75 // closing gnome-terminal, for example). Note that this variable has
76 // no effect if Vcrash_dumps_octave_core is FALSE.
77 static bool Vsighup_dumps_octave_core = true;
78 
79 // Similar to Vsighup_dumps_octave_core, but for SIGQUIT signal.
80 static bool Vsigquit_dumps_octave_core = true;
81 
82 // Similar to Vsighup_dumps_octave_core, but for SIGTERM signal.
83 static bool Vsigterm_dumps_octave_core = true;
84 
85 // List of signals we have caught since last call to signal_handler.
86 static std::atomic<bool> *signals_caught = nullptr;
87 
88 static void
89 my_friendly_exit (int sig, bool save_vars = true)
90 {
91  std::cerr << "fatal: caught signal "
93  << " -- stopping myself..." << std::endl;
94 
95  if (save_vars)
96  {
97  load_save_system& load_save_sys = __get_load_save_system__ ();
98 
99  load_save_sys.dump_octave_core ();
100  }
101 
102  sysdep_cleanup ();
103 
104  throw exit_exception (1);
105 }
106 
107 // Called from octave_quit () to actually do something about the signals
108 // we have caught.
109 
110 void
112 {
113  // The list of signals is relatively short, so we will just go
114  // linearly through the list.
115 
116  // Interrupt signals are currently handled separately.
117 
118  static int sigint;
119  static const bool have_sigint
120  = octave_get_sig_number ("SIGINT", &sigint);
121 
122  static int sigbreak;
123  static const bool have_sigbreak
124  = octave_get_sig_number ("SIGBREAK", &sigbreak);
125 
126  // Termination signals.
127 
128  static int sighup;
129  static const bool have_sighup
130  = octave_get_sig_number ("SIGHUP", &sighup);
131 
132  static int sigquit;
133  static const bool have_sigquit
134  = octave_get_sig_number ("SIGQUIT", &sigquit);
135 
136  static int sigterm;
137  static const bool have_sigterm
138  = octave_get_sig_number ("SIGTERM", &sigterm);
139 
140  // Alarm signals.
141 
142  static int sigalrm;
143  static const bool have_sigalrm
144  = octave_get_sig_number ("SIGALRM", &sigalrm);
145 
146  static int sigvtalrm;
147  static const bool have_sigvtalrm
148  = octave_get_sig_number ("SIGVTALRM", &sigvtalrm);
149 
150  // I/O signals.
151 
152  static int sigio;
153  static const bool have_sigio
154  = octave_get_sig_number ("SIGIO", &sigio);
155 
156  static int siglost;
157  static const bool have_siglost
158  = octave_get_sig_number ("SIGLOST", &siglost);
159 
160  static int sigpipe;
161  static const bool have_sigpipe
162  = octave_get_sig_number ("SIGPIPE", &sigpipe);
163 
164  // Job control signals.
165 
166  static int sigchld;
167  static const bool have_sigchld
168  = octave_get_sig_number ("SIGCHLD", &sigchld);
169 
170  static int sigcld;
171  static const bool have_sigcld
172  = octave_get_sig_number ("SIGCLD", &sigcld);
173 
174  // Resource limit signals.
175 
176  static int sigxcpu;
177  static const bool have_sigxcpu
178  = octave_get_sig_number ("SIGXCPU", &sigxcpu);
179 
180  static int sigxfsz;
181  static const bool have_sigxfsz
182  = octave_get_sig_number ("SIGXFSZ", &sigxfsz);
183 
184  // User signals.
185 
186  static int sigusr1;
187  static const bool have_sigusr1
188  = octave_get_sig_number ("SIGUSR1", &sigusr1);
189 
190  static int sigusr2;
191  static const bool have_sigusr2
192  = octave_get_sig_number ("SIGUSR2", &sigusr2);
193 
194  child_list& kids = __get_child_list__ ();
195 
196  for (int sig = 0; sig < octave_num_signals (); sig++)
197  {
198  bool expected = true;
199 
200  if (signals_caught[sig].compare_exchange_strong (expected, false))
201  {
202  if ((have_sigchld && sig == sigchld)
203  || (have_sigcld && sig == sigcld))
204  {
205  // FIXME: should we block or ignore?
206  volatile interrupt_handler saved_interrupt_handler
207  = ignore_interrupts ();
208 
209  void *context = octave_block_child ();
210 
211  kids.wait ();
212 
213  set_interrupt_handler (saved_interrupt_handler);
214 
215  octave_unblock_child (context);
216 
217  kids.reap ();
218  }
219  else if (have_sigpipe && sig == sigpipe)
220  {
221  std::cerr << "warning: broken pipe" << std::endl;
222 
223  // Don't loop forever on account of this.
224  // FIXME: is this really needed? Does it do anything
225  // useful now?
226 
227  if (pipe_handler_error_count++ > 100
228  && octave_interrupt_state >= 0)
230  }
231  else if (have_sighup && sig == sighup)
232  my_friendly_exit (sighup, Vsighup_dumps_octave_core);
233  else if (have_sigquit && sig == sigquit)
234  my_friendly_exit (sigquit, Vsigquit_dumps_octave_core);
235  else if (have_sigterm && sig == sigterm)
236  my_friendly_exit (sigterm, Vsigterm_dumps_octave_core);
237  else if ((have_sigalrm && sig == sigalrm)
238  || (have_sigvtalrm && sig == sigvtalrm)
239  || (have_sigio && sig == sigio)
240  || (have_siglost && sig == siglost)
241  || (have_sigxcpu && sig == sigxcpu)
242  || (have_sigxfsz && sig == sigxfsz)
243  || (have_sigusr1 && sig == sigusr1)
244  || (have_sigusr2 && sig == sigusr2))
245  std::cerr << "warning: ignoring signal: "
246  << octave_strsignal_wrapper (sig)
247  << std::endl;
248  else if ((have_sigint && sig == sigint)
249  || (have_sigbreak && sig == sigbreak))
250  ; // Handled separately; do nothing.
251  else
252  std::cerr << "warning: ignoring unexpected signal: "
253  << octave_strsignal_wrapper (sig)
254  << std::endl;
255  }
256  }
257 }
258 
259 sig_handler *
260 set_signal_handler (int sig, sig_handler *handler, bool restart_syscalls)
261 {
262  return octave_set_signal_handler_internal (sig, handler, restart_syscalls);
263 }
264 
265 sig_handler *
266 set_signal_handler (const char *signame, sig_handler *handler,
267  bool restart_syscalls)
268 {
269  return octave_set_signal_handler_by_name (signame, handler,
270  restart_syscalls);
271 }
272 
273 static void
274 generic_sig_handler (int sig)
275 {
276  // FIXME: this function may execute in a separate signal handler or
277  // signal watcher thread so it should probably be more careful about
278  // how it accesses global objects.
279 
280  octave_signal_caught = true;
281 
282  signals_caught[sig] = true;
283 
284  static int sigint;
285  static const bool have_sigint
286  = octave_get_sig_number ("SIGINT", &sigint);
287 
288  static int sigbreak;
289  static const bool have_sigbreak
290  = octave_get_sig_number ("SIGBREAK", &sigbreak);
291 
292  if ((have_sigint && sig == sigint)
293  || (have_sigbreak && sig == sigbreak))
294  {
295  if (! octave_initialized)
296  exit (1);
297 
298  if (can_interrupt)
299  {
300  octave_signal_caught = true;
302  }
303  }
304 }
305 
306 static void
307 deadly_sig_handler (int sig)
308 {
309  std::cerr << "fatal: caught signal "
310  << octave_strsignal_wrapper (sig)
311  << " -- stopping myself..." << std::endl;
312 
314 
315  octave_raise_wrapper (sig);
316 }
317 
318 static void
319 fpe_sig_handler (int)
320 {
321  // FIXME: is there something better we can do?
322 
323  std::cerr << "warning: floating point exception" << std::endl;
324 }
325 
328 {
329  interrupt_handler retval;
330 
331  retval.int_handler = set_signal_handler ("SIGINT", generic_sig_handler);
332  retval.brk_handler = set_signal_handler ("SIGBREAK", generic_sig_handler);
333 
334  return retval;
335 }
336 
339 {
340  interrupt_handler retval;
341 
342  retval.int_handler = set_signal_handler ("SIGINT", SIG_IGN);
343  retval.brk_handler = set_signal_handler ("SIGBREAK", SIG_IGN);
344 
345  return retval;
346 }
347 
350  bool restart_syscalls)
351 {
352  interrupt_handler retval;
353 
354  retval.int_handler = set_signal_handler ("SIGINT", h.int_handler,
355  restart_syscalls);
356 
357  retval.brk_handler = set_signal_handler ("SIGBREAK", h.brk_handler,
358  restart_syscalls);
359 
360  return retval;
361 }
362 
363 // Install all the handlers for the signals we might care about.
364 
365 void
367 {
368  if (! signals_caught)
369  signals_caught = new std::atomic<bool> [octave_num_signals ()];
370 
371  for (int i = 0; i < octave_num_signals (); i++)
372  signals_caught[i] = false;
373 
374  // Interrupt signals.
375 
376  catch_interrupts ();
377 
378  // Program Error signals. These are most likely unrecoverable for
379  // us.
380 
381  set_signal_handler ("SIGABRT", deadly_sig_handler);
382  set_signal_handler ("SIGBUS", deadly_sig_handler);
383  set_signal_handler ("SIGEMT", deadly_sig_handler);
384  set_signal_handler ("SIGILL", deadly_sig_handler);
385  // SIGIOT is normally another name for SIGABRT.
386  set_signal_handler ("SIGIOT", deadly_sig_handler);
387  set_signal_handler ("SIGSEGV", deadly_sig_handler);
388  set_signal_handler ("SIGSYS", deadly_sig_handler);
389  set_signal_handler ("SIGTRAP", deadly_sig_handler);
390 
391  // Handle SIGFPE separately.
392 
393  set_signal_handler ("SIGFPE", fpe_sig_handler);
394 
395  // Handle other signals for which the default action is to terminate
396  // the program.
397 
398  // Termination signals.
399 
400  set_signal_handler ("SIGHUP", generic_sig_handler);
401  set_signal_handler ("SIGQUIT", generic_sig_handler);
402  set_signal_handler ("SIGTERM", generic_sig_handler);
403 
404  // Alarm signals.
405 
406  set_signal_handler ("SIGALRM", generic_sig_handler);
407  set_signal_handler ("SIGVTALRM", generic_sig_handler);
408 
409  // I/O signals.
410 
411  set_signal_handler ("SIGLOST", generic_sig_handler);
412  set_signal_handler ("SIGPIPE", generic_sig_handler);
413 
414  // Job control signals. We only recognize signals about child
415  // processes.
416 
417  set_signal_handler ("SIGCHLD", generic_sig_handler);
418  set_signal_handler ("SIGCLD", generic_sig_handler);
419 
420  // Resource limit signals.
421 
422  // FIXME: does it really make sense to try to handle the CPU limit
423  // signal?
424 
425  set_signal_handler ("SIGXCPU", generic_sig_handler);
426  set_signal_handler ("SIGXFSZ", generic_sig_handler);
427 
428  // User signals.
429 
430  set_signal_handler ("SIGUSR1", generic_sig_handler);
431  set_signal_handler ("SIGUSR2", generic_sig_handler);
432 
433  // This does nothing on Windows systems.
434  octave_create_interrupt_watcher_thread (generic_sig_handler);
435 }
436 
437 static void
438 set_sig_struct_field (octave_scalar_map& m, const char *signame)
439 {
440  int signum;
441 
442  // The names in the struct do not include the leading "SIG" prefix.
443 
444  if (octave_get_sig_number (signame, &signum))
445  m.assign (&signame[3], signum);
446 }
447 
448 static octave_scalar_map
449 make_sig_struct ()
450 {
452 
453  set_sig_struct_field (m, "SIGABRT");
454  set_sig_struct_field (m, "SIGALRM");
455  set_sig_struct_field (m, "SIGBUS");
456  set_sig_struct_field (m, "SIGCHLD");
457  set_sig_struct_field (m, "SIGCLD");
458  set_sig_struct_field (m, "SIGCONT");
459  set_sig_struct_field (m, "SIGEMT");
460  set_sig_struct_field (m, "SIGFPE");
461  set_sig_struct_field (m, "SIGHUP");
462  set_sig_struct_field (m, "SIGILL");
463  set_sig_struct_field (m, "SIGINFO");
464  set_sig_struct_field (m, "SIGINT");
465  set_sig_struct_field (m, "SIGIO");
466  set_sig_struct_field (m, "SIGIOT");
467  set_sig_struct_field (m, "SIGKILL");
468  set_sig_struct_field (m, "SIGLOST");
469  set_sig_struct_field (m, "SIGPIPE");
470  set_sig_struct_field (m, "SIGPOLL");
471  set_sig_struct_field (m, "SIGPROF");
472  set_sig_struct_field (m, "SIGPWR");
473  set_sig_struct_field (m, "SIGQUIT");
474  set_sig_struct_field (m, "SIGSEGV");
475  set_sig_struct_field (m, "SIGSTKFLT");
476  set_sig_struct_field (m, "SIGSTOP");
477  set_sig_struct_field (m, "SIGSYS");
478  set_sig_struct_field (m, "SIGTERM");
479  set_sig_struct_field (m, "SIGTRAP");
480  set_sig_struct_field (m, "SIGTSTP");
481  set_sig_struct_field (m, "SIGTTIN");
482  set_sig_struct_field (m, "SIGTTOU");
483  set_sig_struct_field (m, "SIGUNUSED");
484  set_sig_struct_field (m, "SIGURG");
485  set_sig_struct_field (m, "SIGUSR1");
486  set_sig_struct_field (m, "SIGUSR2");
487  set_sig_struct_field (m, "SIGVTALRM");
488  set_sig_struct_field (m, "SIGWINCH");
489  set_sig_struct_field (m, "SIGXCPU");
490  set_sig_struct_field (m, "SIGXFSZ");
491 
492  return m;
493 }
494 
495 DEFUN (SIG, args, ,
496  doc: /* -*- texinfo -*-
497 @deftypefn {} {@var{S} =} SIG ()
498 Return a structure containing Unix signal names and their defined values.
499 @end deftypefn */)
500 {
501  if (args.length () != 0)
502  print_usage ();
503 
504  static octave_scalar_map m = make_sig_struct ();
505 
506  return ovl (m);
507 }
508 
509 /*
510 %!assert (isstruct (SIG ()))
511 %!assert (! isempty (SIG ()))
512 
513 %!error SIG (1)
514 */
515 
516 DEFUN (debug_on_interrupt, args, nargout,
517  doc: /* -*- texinfo -*-
518 @deftypefn {} {@var{val} =} debug_on_interrupt ()
519 @deftypefnx {} {@var{old_val} =} debug_on_interrupt (@var{new_val})
520 @deftypefnx {} {@var{old_val} =} debug_on_interrupt (@var{new_val}, "local")
521 Query or set the internal variable that controls whether Octave will try
522 to enter debugging mode when it receives an interrupt signal (typically
523 generated with @kbd{C-c}).
524 
525 If a second interrupt signal is received before reaching the debugging mode,
526 a normal interrupt will occur.
527 
528 When called from inside a function with the @qcode{"local"} option, the
529 variable is changed locally for the function and any subroutines it calls.
530 The original variable value is restored when exiting the function.
531 @seealso{debug_on_error, debug_on_warning}
532 @end deftypefn */)
533 {
534  return set_internal_variable (Vdebug_on_interrupt, args, nargout,
535  "debug_on_interrupt");
536 }
537 
538 /*
539 %!test
540 %! orig_val = debug_on_interrupt ();
541 %! old_val = debug_on_interrupt (! orig_val);
542 %! assert (orig_val, old_val);
543 %! assert (debug_on_interrupt (), ! orig_val);
544 %! debug_on_interrupt (orig_val);
545 %! assert (debug_on_interrupt (), orig_val);
546 
547 %!error debug_on_interrupt (1, 2)
548 */
549 
550 DEFUN (sighup_dumps_octave_core, args, nargout,
551  doc: /* -*- texinfo -*-
552 @deftypefn {} {@var{val} =} sighup_dumps_octave_core ()
553 @deftypefnx {} {@var{old_val} =} sighup_dumps_octave_core (@var{new_val})
554 @deftypefnx {} {@var{old_val} =} sighup_dumps_octave_core (@var{new_val}, "local")
555 Query or set the internal variable that controls whether Octave tries
556 to save all current variables to the file @file{octave-workspace} if it
557 receives a hangup signal.
558 
559 When called from inside a function with the @qcode{"local"} option, the
560 variable is changed locally for the function and any subroutines it calls.
561 The original variable value is restored when exiting the function.
562 @end deftypefn */)
563 {
564  return set_internal_variable (Vsighup_dumps_octave_core,
565  args, nargout,
566  "sighup_dumps_octave_core");
567 }
568 
569 /*
570 %!test
571 %! orig_val = sighup_dumps_octave_core ();
572 %! old_val = sighup_dumps_octave_core (! orig_val);
573 %! assert (orig_val, old_val);
574 %! assert (sighup_dumps_octave_core (), ! orig_val);
575 %! sighup_dumps_octave_core (orig_val);
576 %! assert (sighup_dumps_octave_core (), orig_val);
577 
578 %!error sighup_dumps_octave_core (1, 2)
579 */
580 
581 DEFUN (sigquit_dumps_octave_core, args, nargout,
582  doc: /* -*- texinfo -*-
583 @deftypefn {} {@var{val} =} sigquit_dumps_octave_core ()
584 @deftypefnx {} {@var{old_val} =} sigquit_dumps_octave_core (@var{new_val})
585 @deftypefnx {} {@var{old_val} =} sigquit_dumps_octave_core (@var{new_val}, "local")
586 Query or set the internal variable that controls whether Octave tries
587 to save all current variables to the file @file{octave-workspace} if it
588 receives a quit signal.
589 
590 When called from inside a function with the @qcode{"local"} option, the
591 variable is changed locally for the function and any subroutines it calls.
592 The original variable value is restored when exiting the function.
593 @end deftypefn */)
594 {
595  return set_internal_variable (Vsigquit_dumps_octave_core,
596  args, nargout,
597  "sigquit_dumps_octave_core");
598 }
599 
600 /*
601 %!test
602 %! orig_val = sigquit_dumps_octave_core ();
603 %! old_val = sigquit_dumps_octave_core (! orig_val);
604 %! assert (orig_val, old_val);
605 %! assert (sigquit_dumps_octave_core (), ! orig_val);
606 %! sigquit_dumps_octave_core (orig_val);
607 %! assert (sigquit_dumps_octave_core (), orig_val);
608 
609 %!error sigquit_dumps_octave_core (1, 2)
610 */
611 
612 DEFUN (sigterm_dumps_octave_core, args, nargout,
613  doc: /* -*- texinfo -*-
614 @deftypefn {} {@var{val} =} sigterm_dumps_octave_core ()
615 @deftypefnx {} {@var{old_val} =} sigterm_dumps_octave_core (@var{new_val})
616 @deftypefnx {} {@var{old_val} =} sigterm_dumps_octave_core (@var{new_val}, "local")
617 Query or set the internal variable that controls whether Octave tries
618 to save all current variables to the file @file{octave-workspace} if it
619 receives a terminate signal.
620 
621 When called from inside a function with the @qcode{"local"} option, the
622 variable is changed locally for the function and any subroutines it calls.
623 The original variable value is restored when exiting the function.
624 @end deftypefn */)
625 {
626  return set_internal_variable (Vsigterm_dumps_octave_core,
627  args, nargout,
628  "sigterm_dumps_octave_core");
629 }
630 
631 /*
632 %!test
633 %! orig_val = sigterm_dumps_octave_core ();
634 %! old_val = sigterm_dumps_octave_core (! orig_val);
635 %! assert (orig_val, old_val);
636 %! assert (sigterm_dumps_octave_core (), ! orig_val);
637 %! sigterm_dumps_octave_core (orig_val);
638 %! assert (sigterm_dumps_octave_core (), orig_val);
639 
640 %!error sigterm_dumps_octave_core (1, 2)
641 */
642 
643 OCTAVE_END_NAMESPACE(octave)
bool wait()
Definition: child-list.cc:76
void reap()
Definition: child-list.cc:47
void dump_octave_core()
Definition: load-save.cc:734
void octave_create_interrupt_watcher_thread(octave_sig_handler *handler)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void print_usage(void)
Definition: defun-int.h:72
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
load_save_system & __get_load_save_system__()
child_list & __get_child_list__()
std::atomic< bool > octave_initialized
Definition: interpreter.cc:95
double signum(double x)
Definition: lo-mappers.h:229
T octave_idx_type m
Definition: mx-inlines.cc:781
octave_value set_internal_variable(bool &var, const octave_value_list &args, int nargout, const char *nm)
Definition: variables.cc:583
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:219
std::atomic< sig_atomic_t > octave_interrupt_state
Definition: quit.cc:39
volatile std::atomic< bool > octave_signal_caught
Definition: quit.cc:41
interrupt_handler ignore_interrupts()
Definition: sighandlers.cc:338
interrupt_handler set_interrupt_handler(const volatile interrupt_handler &h, bool restart_syscalls)
Definition: sighandlers.cc:349
void respond_to_pending_signals()
Definition: sighandlers.cc:111
bool Vdebug_on_interrupt
Definition: sighandlers.cc:72
int pipe_handler_error_count
Definition: sighandlers.cc:66
sig_handler * set_signal_handler(int sig, sig_handler *handler, bool restart_syscalls)
Definition: sighandlers.cc:260
std::atomic< bool > can_interrupt
Definition: sighandlers.cc:69
interrupt_handler catch_interrupts()
Definition: sighandlers.cc:327
void install_signal_handlers()
Definition: sighandlers.cc:366
void sig_handler(int)
Definition: sighandlers.h:48
octave_sig_handler * octave_set_default_signal_handler(int sig)
int octave_num_signals(void)
void * octave_block_child(void)
char * octave_strsignal_wrapper(int signum)
void octave_unblock_child(void *context_arg)
bool octave_get_sig_number(const char *signame, int *signum)
int octave_raise_wrapper(int signum)
octave_sig_handler * octave_set_signal_handler_by_name(const char *signame, octave_sig_handler *handler, bool restart_syscalls)
octave_sig_handler * octave_set_signal_handler_internal(int sig, octave_sig_handler *handler, bool restart_syscalls)
sig_handler * int_handler
Definition: sighandlers.h:52
sig_handler * brk_handler
Definition: sighandlers.h:53
void sysdep_cleanup()