Mercurial > octave
view libinterp/corefcn/sighandlers.cc @ 21966:112b20240c87
move docstrings in C++ files out of C strings and into comments
* __contourc__.cc, __dispatch__.cc, __dsearchn__.cc, __ichol__.cc,
__ilu__.cc, __lin_interpn__.cc, __luinc__.cc, __magick_read__.cc,
__pchip_deriv__.cc, __qp__.cc, balance.cc, besselj.cc, betainc.cc,
bitfcns.cc, bsxfun.cc, cellfun.cc, colloc.cc, conv2.cc, daspk.cc,
dasrt.cc, dassl.cc, data.cc, debug.cc, defaults.cc, det.cc, dirfns.cc,
dlmread.cc, dot.cc, eig.cc, ellipj.cc, error.cc, fft.cc, fft2.cc,
fftn.cc, file-io.cc, filter.cc, find.cc, gammainc.cc, gcd.cc,
getgrent.cc, getpwent.cc, getrusage.cc, givens.cc, graphics.cc,
hash.cc, help.cc, hess.cc, hex2num.cc, input.cc, inv.cc, kron.cc,
load-path.cc, load-save.cc, lookup.cc, ls-oct-text.cc, lsode.cc,
lu.cc, mappers.cc, matrix_type.cc, max.cc, mgorth.cc, nproc.cc,
oct-hist.cc, octave-link.cc, ordschur.cc, pager.cc, pinv.cc,
pr-output.cc, profiler.cc, psi.cc, pt-jit.cc, quad.cc, quadcc.cc,
qz.cc, rand.cc, rcond.cc, regexp.cc, schur.cc, sighandlers.cc,
sparse.cc, spparms.cc, sqrtm.cc, str2double.cc, strfind.cc, strfns.cc,
sub2ind.cc, svd.cc, sylvester.cc, symtab.cc, syscalls.cc, sysdep.cc,
time.cc, toplev.cc, tril.cc, tsearch.cc, typecast.cc, urlwrite.cc,
utils.cc, variables.cc, __delaunayn__.cc, __eigs__.cc,
__fltk_uigetfile__.cc, __glpk__.cc, __init_fltk__.cc,
__init_gnuplot__.cc, __osmesa_print__.cc, __voronoi__.cc, amd.cc,
audiodevinfo.cc, audioread.cc, ccolamd.cc, chol.cc, colamd.cc,
convhulln.cc, dmperm.cc, fftw.cc, qr.cc, symbfact.cc, symrcm.cc,
ov-base.cc, ov-bool-mat.cc, ov-cell.cc, ov-class.cc, ov-classdef.cc,
ov-fcn-handle.cc, ov-fcn-inline.cc, ov-flt-re-mat.cc, ov-int16.cc,
ov-int32.cc, ov-int64.cc, ov-int8.cc, ov-java.cc, ov-null-mat.cc,
ov-oncleanup.cc, ov-range.cc, ov-re-mat.cc, ov-struct.cc,
ov-typeinfo.cc, ov-uint16.cc, ov-uint32.cc, ov-uint64.cc, ov-uint8.cc,
ov-usr-fcn.cc, ov.cc, octave.cc, pt-arg-list.cc, pt-binop.cc,
pt-eval.cc, pt-mat.cc, lex.ll, oct-parse.in.yy:
Docstrings are now comments instead of C strings.
* build-aux/mk-opts.pl: Emit docstrings as comments instead of C
strings.
* DASPK-opts.in, LSODE-opts.in: Don't quote " in docstring fragments.
* builtins.h: Include builtin-defun-decls.h unconditionally.
* defun.h (DEFUN, DEFUNX, DEFCONSTFUN): Simply emit declaration.
(DEFALIAS): Always expand to nothing.
* defun-dld.h: No special macro expansions for MAKE_BUILTINS.
(DEFUN_DLD): Use FORWARD_DECLARE_FUN.
(DEFUNX_DLD): Use FORWARD_DECLARE_FUNX.
* defun-int.h: No special macro expansions for MAKE_BUILTINS.
(FORWARD_DECLARE_FUN, FORWARD_DECLARE_FUNX): New macros.
(DEFINE_FUN_INSTALLER_FUN): If compiling an Octave source file, pass
"external-doc" to DEFINE_FUNX_INSTALLER_FUN.
(DEFUN_INTERNAL, DEFCONSTFUN_INTERNAL, DEFUNX_INTERNAL,
DEFALIAS_INTERNAL): Delete.
* common.mk (move_if_change_rule): New macro.
(simple_move_if_change_rule): Define using move_if_change_rule.
* find-defun-files.sh (DEFUN_PATTERN): Update. Don't transform file
name extension to ".df".
* libinterp/mk-pkg-add, gendoc.pl: Operate directly on source files.
* mkbuiltins: New argument, SRCDIR. Operate directly on source files.
* mkdefs: Delete.
* libinterp/module.mk (BUILT_SOURCES): Update list to contain only
files included in other source files.
(GENERATED_MAKE_BUILTINS_INCS, DEF_FILES): Delete.
(LIBINTERP_BUILT_DISTFILES): Include $(OPT_HANDLERS) here.
(LIBINTERP_BUILT_NODISTFILES): Not here. Remove $(ALL_DEF_FILES from
the list.
(libinterp_EXTRA_DIST): Remove mkdefs from the list.
(FOUND_DEFUN_FILES): Rename from SRC_DEF_FILES.
(DLDFCN_DEFUN_FILES): Rename from DLDFCN_DEF_FILES.
(SRC_DEFUN_FILES): Rename from SRC_DEF_FILES.
(ALL_DEFUN_FILES): Rename from ALL_DEF_FILES.
(%.df: %.cc): Delete pattern rule.
(libinterp/build-env-features.cc, libinterp/builtins.cc,
libinterp/dldfcn/PKG_ADD): Use mv instead of move-if-change.
(libinterp/builtins.cc, libinterp/builtin-defun-decls.h):
Update mkbuiltins command.
($(srcdir)/libinterp/DOCSTRINGS): Update gendoc.pl command.
* liboctave/module.mk (BUILT_SOURCES): Don't include
liboctave-build-info.cc in the list.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 21 Jun 2016 16:07:51 -0400 |
parents | 1d23b75cbcd1 |
children | d04da18a407a |
line wrap: on
line source
/* Copyright (C) 1993-2015 John W. Eaton This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see <http://www.gnu.org/licenses/>. */ #if defined (HAVE_CONFIG_H) # include "config.h" #endif #include <csignal> #include <cstdlib> #include <iostream> #include <new> #include "cmd-edit.h" #include "oct-syscalls.h" #include "quit.h" #include "singleton-cleanup.h" #include "signal-wrappers.h" #include "debug.h" #include "defun.h" #include "error.h" #include "input.h" #include "load-save.h" #include "oct-map.h" #include "pager.h" #include "pt-bp.h" #include "pt-eval.h" #include "sighandlers.h" #include "sysdep.h" #include "toplev.h" #include "utils.h" #include "variables.h" // Nonzero means we have already printed a message for this series of // SIGPIPES. We assume that the writer will eventually give up. int pipe_handler_error_count = 0; // TRUE means we can be interrupted. bool can_interrupt = false; // TRUE means we should try to enter the debugger on SIGINT. bool Vdebug_on_interrupt = false; // Allow users to avoid writing octave-workspace for SIGHUP (sent by // closing gnome-terminal, for example). Note that this variable has // no effect if Vcrash_dumps_octave_core is FALSE. static bool Vsighup_dumps_octave_core = true; // Similar to Vsighup_dumps_octave_core, but for SIGTERM signal. static bool Vsigterm_dumps_octave_core = true; // List of signals we have caught since last call to octave_signal_handler. static bool *octave_signals_caught = 0; // Forward declaration. static void user_abort (const char *sig_name, int sig_number); #if defined (__WIN32__) && ! defined (__CYGWIN__) #define WIN32_LEAN_AND_MEAN #include <windows.h> class w32_interrupt_manager { public: ~w32_interrupt_manager (void) { if (thread) CloseHandle (thread); } static bool init (void) { return instance_ok (); } static void octave_jump_to_enclosing_context (void) { if (instance_ok ()) instance->do_octave_jump_to_enclosing_context (); } static void user_abort (const char *sig_name, int sig_number) { if (instance_ok ()) instance->do_user_abort (sig_name, sig_number); } static void raise_sigint (void) { if (instance_ok ()) instance->do_raise_sigint (); } private: w32_interrupt_manager (void) : thread (0), thread_id (0) { thread_id = GetCurrentThreadId (); DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), GetCurrentProcess (), &thread, 0, FALSE, DUPLICATE_SAME_ACCESS); } static void octave_jump_to_enclosing_context_sync (void) { #if defined (_MSC_VER) _fpreset (); #endif ::octave_jump_to_enclosing_context (); } void do_octave_jump_to_enclosing_context (void) { bool is_interrupt_thread = (GetCurrentThreadId () == thread_id); if (is_interrupt_thread) octave_jump_to_enclosing_context_sync (); else { // 64-bit Windows does not appear to have threadContext.Eip. // Something else must be done here to allow interrupts to // properly work across threads. #if ! (defined (__MINGW64__) || defined (_WIN64)) CONTEXT threadContext; SuspendThread (thread); threadContext.ContextFlags = CONTEXT_CONTROL; GetThreadContext (thread, &threadContext); threadContext.Eip = (DWORD) octave_jump_to_enclosing_context_sync; SetThreadContext (thread, &threadContext); ResumeThread (thread); #endif } } void do_user_abort (const char *sig_name, int sig_number) { bool is_interrupt_thread = (GetCurrentThreadId () == thread_id); if (is_interrupt_thread) ::user_abort (sig_name, sig_number); else { SuspendThread (thread); ::user_abort (sig_name, sig_number); ResumeThread (thread); } } void do_raise_sigint (void) { bool is_interrupt_thread = (GetCurrentThreadId () == thread_id); if (is_interrupt_thread) octave_raise_wrapper (SIGINT); else { SuspendThread (thread); octave_raise_wrapper (SIGINT); ResumeThread (thread); } } static bool instance_ok (void) { bool retval = true; if (! instance) { instance = new w32_interrupt_manager (); if (instance) singleton_cleanup_list::add (cleanup_instance); } if (! instance) error ("unable to create w32_interrupt_manager"); return retval; } static void cleanup_instance (void) { delete instance; instance = 0; } private: // A handle to the thread that is running the octave interpreter. HANDLE thread; // The ID of the thread that is running the octave interpreter. DWORD thread_id; static w32_interrupt_manager* instance; }; w32_interrupt_manager* w32_interrupt_manager::instance = 0; void w32_raise_sigint (void) { w32_interrupt_manager::raise_sigint (); } #endif // Called from octave_quit () to actually do something about the signals // we have caught. void octave_signal_handler (void) { // The list of signals is relatively short, so we will just go // linearly through the list. static int sigchld; static int sigfpe; static int sigpipe; static const bool have_sigchld = octave_get_sig_number ("SIGCHLD", &sigchld); static const bool have_sigfpe = octave_get_sig_number ("SIGFPE", &sigfpe); static const bool have_sigpipe = octave_get_sig_number ("SIGPIPE", &sigpipe); for (int i = 0; i < octave_num_signals (); i++) { if (octave_signals_caught[i]) { octave_signals_caught[i] = false; if (have_sigchld && i == sigchld) { volatile octave_interrupt_handler saved_interrupt_handler = octave_ignore_interrupts (); void *context = octave_block_child (); octave_child_list::wait (); octave_set_interrupt_handler (saved_interrupt_handler); octave_unblock_child (context); octave_child_list::reap (); } else if (have_sigfpe && i == sigfpe) std::cerr << "warning: floating point exception" << std::endl; else if (have_sigpipe && i == sigpipe) std::cerr << "warning: broken pipe" << std::endl; } } } static void my_friendly_exit (const char *sig_name, int sig_number, bool save_vars = true) { static bool been_there_done_that = false; if (been_there_done_that) { octave_set_signal_handler ("SIGABRT", SIG_DFL); std::cerr << "panic: attempted clean up apparently failed -- aborting...\n"; MINGW_SIGNAL_CLEANUP (); abort (); } else { been_there_done_that = true; std::cerr << "panic: " << sig_name << " -- stopping myself...\n"; if (save_vars) dump_octave_core (); if (sig_number < 0) { MINGW_SIGNAL_CLEANUP (); exit (1); } else { octave_set_signal_handler (sig_number, SIG_DFL); octave_raise_wrapper (sig_number); } } } octave_sig_handler * octave_set_signal_handler (int sig, octave_sig_handler *handler, bool restart_syscalls) { return octave_set_signal_handler_internal (sig, handler, restart_syscalls); } octave_sig_handler * octave_set_signal_handler (const char *signame, octave_sig_handler *handler, bool restart_syscalls) { return octave_set_signal_handler_by_name (signame, handler, restart_syscalls); } static void generic_sig_handler (int sig) { my_friendly_exit (octave_strsignal_wrapper (sig), sig); } // Handle SIGCHLD. static void sigchld_handler (int sig) { octave_signal_caught = 1; octave_signals_caught[sig] = true; } #if defined (__alpha__) static void sigfpe_handler (int sig) { if (can_interrupt && octave_interrupt_state >= 0) { octave_signal_caught = 1; octave_signals_caught[sig] = true; octave_interrupt_state++; } } #endif static void sig_hup_handler (int /* sig */) { if (Vsighup_dumps_octave_core) dump_octave_core (); clean_up_and_exit (0); } static void sig_term_handler (int /* sig */) { if (Vsigterm_dumps_octave_core) dump_octave_core (); clean_up_and_exit (0); } #if 0 static void sigwinch_handler (int /* sig */) { octave::command_editor::resize_terminal (); } #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 void user_abort (const char *sig_name, int sig_number) { if (! octave_initialized) exit (1); if (can_interrupt) { if (Vdebug_on_interrupt) { if (! octave_debug_on_interrupt_state) { tree_evaluator::debug_mode = true; octave_debug_on_interrupt_state = true; return; } else { // Clear the flag and do normal interrupt stuff. tree_evaluator::debug_mode = bp_table::have_breakpoints () || Vdebugging; octave_debug_on_interrupt_state = false; } } if (octave_interrupt_immediately) { if (octave_interrupt_state == 0) octave_interrupt_state = 1; #if defined (__WIN32__) && ! defined (__CYGWIN__) w32_interrupt_manager::octave_jump_to_enclosing_context (); #else octave_jump_to_enclosing_context (); #endif } else { // If we are already cleaning up from a previous interrupt, // take note of the fact that another interrupt signal has // arrived. if (octave_interrupt_state < 0) octave_interrupt_state = 0; octave_signal_caught = 1; octave_interrupt_state++; if (interactive && ! forced_interactive && octave_interrupt_state == 2) std::cerr << "Press Control-C again to abort." << std::endl; if (octave_interrupt_state >= 3) my_friendly_exit (sig_name, sig_number, true); } } } static void sigint_handler (int sig) { #if defined (__WIN32__) && ! defined (__CYGWIN__) w32_interrupt_manager::user_abort (octave_strsignal_wrapper (sig), sig); #else user_abort (octave_strsignal_wrapper (sig), sig); #endif } static void sigpipe_handler (int sig) { octave_signal_caught = 1; octave_signals_caught[sig] = true; // Don't loop forever on account of this. if (pipe_handler_error_count++ > 100 && octave_interrupt_state >= 0) octave_interrupt_state++; } octave_interrupt_handler octave_catch_interrupts (void) { octave_interrupt_handler retval; #if defined (__WIN32__) && ! defined (__CYGWIN__) w32_interrupt_manager::init (); #endif retval.int_handler = octave_set_signal_handler ("SIGINT", sigint_handler); retval.brk_handler = octave_set_signal_handler ("SIGBREAK", sigint_handler); return retval; } octave_interrupt_handler octave_ignore_interrupts (void) { octave_interrupt_handler retval; #if defined (__WIN32__) && ! defined (__CYGWIN__) w32_interrupt_manager::init (); #endif retval.int_handler = octave_set_signal_handler ("SIGINT", SIG_IGN); retval.brk_handler = octave_set_signal_handler ("SIGBREAK", SIG_IGN); return retval; } octave_interrupt_handler octave_set_interrupt_handler (const volatile octave_interrupt_handler& h, bool restart_syscalls) { octave_interrupt_handler retval; #if defined (__WIN32__) && ! defined (__CYGWIN__) w32_interrupt_manager::init (); #endif retval.int_handler = octave_set_signal_handler ("SIGINT", h.int_handler, restart_syscalls); retval.brk_handler = octave_set_signal_handler ("SIGBREAK", h.brk_handler, restart_syscalls); return retval; } // Install all the handlers for the signals we might care about. void install_signal_handlers (void) { if (! octave_signals_caught) octave_signals_caught = new bool [octave_num_signals ()]; for (int i = 0; i < octave_num_signals (); i++) octave_signals_caught[i] = false; octave_catch_interrupts (); octave_set_signal_handler ("SIGABRT", generic_sig_handler); octave_set_signal_handler ("SIGALRM", generic_sig_handler); octave_set_signal_handler ("SIGBUS", generic_sig_handler); octave_set_signal_handler ("SIGCHLD", sigchld_handler); // SIGCLD // SIGCONT octave_set_signal_handler ("SIGEMT", generic_sig_handler); #if defined (__alpha__) octave_set_signal_handler ("SIGFPE", sigfpe_handler); #else octave_set_signal_handler ("SIGFPE", generic_sig_handler); #endif octave_set_signal_handler ("SIGHUP", sig_hup_handler); octave_set_signal_handler ("SIGILL", generic_sig_handler); // SIGINFO // SIGINT octave_set_signal_handler ("SIGIOT", generic_sig_handler); octave_set_signal_handler ("SIGLOST", generic_sig_handler); octave_set_signal_handler ("SIGPIPE", sigpipe_handler); octave_set_signal_handler ("SIGPOLL", SIG_IGN); // SIGPROF // SIGPWR octave_set_signal_handler ("SIGQUIT", generic_sig_handler); octave_set_signal_handler ("SIGSEGV", generic_sig_handler); // SIGSTOP octave_set_signal_handler ("SIGSYS", generic_sig_handler); octave_set_signal_handler ("SIGTERM", sig_term_handler); octave_set_signal_handler ("SIGTRAP", generic_sig_handler); // SIGTSTP // SIGTTIN // SIGTTOU // SIGURG octave_set_signal_handler ("SIGUSR1", generic_sig_handler); octave_set_signal_handler ("SIGUSR2", generic_sig_handler); octave_set_signal_handler ("SIGVTALRM", generic_sig_handler); octave_set_signal_handler ("SIGIO", SIG_IGN); #if 0 octave_set_signal_handler ("SIGWINCH", sigwinch_handler); #endif octave_set_signal_handler ("SIGXCPU", generic_sig_handler); octave_set_signal_handler ("SIGXFSZ", generic_sig_handler); } static void set_sig_struct_field (octave_scalar_map& m, const char *signame) { int signum; // The names in the struct do not include the leading "SIG" prefix. if (octave_get_sig_number (signame, &signum)) m.assign (&signame[3], signum); } static octave_scalar_map make_sig_struct (void) { octave_scalar_map m; set_sig_struct_field (m, "SIGABRT"); set_sig_struct_field (m, "SIGALRM"); set_sig_struct_field (m, "SIGBUS"); set_sig_struct_field (m, "SIGCHLD"); set_sig_struct_field (m, "SIGCLD"); set_sig_struct_field (m, "SIGCONT"); set_sig_struct_field (m, "SIGEMT"); set_sig_struct_field (m, "SIGFPE"); set_sig_struct_field (m, "SIGHUP"); set_sig_struct_field (m, "SIGILL"); set_sig_struct_field (m, "SIGINFO"); set_sig_struct_field (m, "SIGINT"); set_sig_struct_field (m, "SIGIO"); set_sig_struct_field (m, "SIGIOT"); set_sig_struct_field (m, "SIGKILL"); set_sig_struct_field (m, "SIGLOST"); set_sig_struct_field (m, "SIGPIPE"); set_sig_struct_field (m, "SIGPOLL"); set_sig_struct_field (m, "SIGPROF"); set_sig_struct_field (m, "SIGPWR"); set_sig_struct_field (m, "SIGQUIT"); set_sig_struct_field (m, "SIGSEGV"); set_sig_struct_field (m, "SIGSTKFLT"); set_sig_struct_field (m, "SIGSTOP"); set_sig_struct_field (m, "SIGSYS"); set_sig_struct_field (m, "SIGTERM"); set_sig_struct_field (m, "SIGTRAP"); set_sig_struct_field (m, "SIGTSTP"); set_sig_struct_field (m, "SIGTTIN"); set_sig_struct_field (m, "SIGTTOU"); set_sig_struct_field (m, "SIGUNUSED"); set_sig_struct_field (m, "SIGURG"); set_sig_struct_field (m, "SIGUSR1"); set_sig_struct_field (m, "SIGUSR2"); set_sig_struct_field (m, "SIGVTALRM"); set_sig_struct_field (m, "SIGWINCH"); set_sig_struct_field (m, "SIGXCPU"); set_sig_struct_field (m, "SIGXFSZ"); return m; } octave_child_list::octave_child_list_rep *octave_child_list::instance = 0; bool octave_child_list::instance_ok (void) { bool retval = true; if (! instance) { instance = new octave_child_list_rep (); if (instance) singleton_cleanup_list::add (cleanup_instance); } if (! instance) error ("unable to create child list object!"); return retval; } void octave_child_list::insert (pid_t pid, octave_child::child_event_handler f) { if (instance_ok ()) instance->insert (pid, f); } void octave_child_list::reap (void) { if (instance_ok ()) instance->reap (); } bool octave_child_list::wait (void) { return (instance_ok ()) ? instance->wait () : false; } class pid_equal { public: pid_equal (pid_t v) : val (v) { } bool operator () (const octave_child& oc) const { return oc.pid == val; } private: pid_t val; }; void octave_child_list::remove (pid_t pid) { if (instance_ok ()) instance->remove_if (pid_equal (pid)); } #define OCL_REP octave_child_list::octave_child_list_rep void OCL_REP::insert (pid_t pid, octave_child::child_event_handler f) { append (octave_child (pid, f)); } void OCL_REP::reap (void) { // Mark the record for PID invalid. for (iterator p = begin (); p != end (); p++) { // The call to the octave_child::child_event_handler might // invalidate the iterator (for example, by calling // octave_child_list::remove), so we increment the iterator // here. octave_child& oc = *p; if (oc.have_status) { oc.have_status = 0; octave_child::child_event_handler f = oc.handler; if (f && f (oc.pid, oc.status)) oc.pid = -1; } } remove_if (pid_equal (-1)); } // Wait on our children and record any changes in their status. bool OCL_REP::wait (void) { bool retval = false; for (iterator p = begin (); p != end (); p++) { octave_child& oc = *p; pid_t pid = oc.pid; if (pid > 0) { int status; if (octave::sys::waitpid (pid, &status, octave::sys::wnohang ()) > 0) { oc.have_status = 1; oc.status = status; retval = true; break; } } } return retval; } DEFUN (SIG, args, , doc: /* -*- texinfo -*- @deftypefn {} {} SIG () Return a structure containing Unix signal names and their defined values. @end deftypefn */) { if (args.length () != 0) print_usage (); static octave_scalar_map m = make_sig_struct (); return ovl (m); } /* %!assert (isstruct (SIG ())) %!assert (! isempty (SIG ())) %!error SIG (1) */ DEFUN (debug_on_interrupt, args, nargout, doc: /* -*- texinfo -*- @deftypefn {} {@var{val} =} debug_on_interrupt () @deftypefnx {} {@var{old_val} =} debug_on_interrupt (@var{new_val}) @deftypefnx {} {} debug_on_interrupt (@var{new_val}, "local") Query or set the internal variable that controls whether Octave will try to enter debugging mode when it receives an interrupt signal (typically generated with @kbd{C-c}). If a second interrupt signal is received before reaching the debugging mode, a normal interrupt will occur. When called from inside a function with the @qcode{"local"} option, the variable is changed locally for the function and any subroutines it calls. The original variable value is restored when exiting the function. @seealso{debug_on_error, debug_on_warning} @end deftypefn */) { return SET_INTERNAL_VARIABLE (debug_on_interrupt); } /* %!test %! orig_val = debug_on_interrupt (); %! old_val = debug_on_interrupt (! orig_val); %! assert (orig_val, old_val); %! assert (debug_on_interrupt (), ! orig_val); %! debug_on_interrupt (orig_val); %! assert (debug_on_interrupt (), orig_val); %!error (debug_on_interrupt (1, 2)) */ DEFUN (sighup_dumps_octave_core, args, nargout, doc: /* -*- texinfo -*- @deftypefn {} {@var{val} =} sighup_dumps_octave_core () @deftypefnx {} {@var{old_val} =} sighup_dumps_octave_core (@var{new_val}) @deftypefnx {} {} sighup_dumps_octave_core (@var{new_val}, "local") Query or set the internal variable that controls whether Octave tries to save all current variables to the file @file{octave-workspace} if it receives a hangup signal. When called from inside a function with the @qcode{"local"} option, the variable is changed locally for the function and any subroutines it calls. The original variable value is restored when exiting the function. @end deftypefn */) { return SET_INTERNAL_VARIABLE (sighup_dumps_octave_core); } /* %!test %! orig_val = sighup_dumps_octave_core (); %! old_val = sighup_dumps_octave_core (! orig_val); %! assert (orig_val, old_val); %! assert (sighup_dumps_octave_core (), ! orig_val); %! sighup_dumps_octave_core (orig_val); %! assert (sighup_dumps_octave_core (), orig_val); %!error (sighup_dumps_octave_core (1, 2)) */ DEFUN (sigterm_dumps_octave_core, args, nargout, doc: /* -*- texinfo -*- @deftypefn {} {@var{val} =} sigterm_dumps_octave_core () @deftypefnx {} {@var{old_val} =} sigterm_dumps_octave_core (@var{new_val}) @deftypefnx {} {} sigterm_dumps_octave_core (@var{new_val}, "local") Query or set the internal variable that controls whether Octave tries to save all current variables to the file @file{octave-workspace} if it receives a terminate signal. When called from inside a function with the @qcode{"local"} option, the variable is changed locally for the function and any subroutines it calls. The original variable value is restored when exiting the function. @end deftypefn */) { return SET_INTERNAL_VARIABLE (sigterm_dumps_octave_core); } /* %!test %! orig_val = sigterm_dumps_octave_core (); %! old_val = sigterm_dumps_octave_core (! orig_val); %! assert (orig_val, old_val); %! assert (sigterm_dumps_octave_core (), ! orig_val); %! sigterm_dumps_octave_core (orig_val); %! assert (sigterm_dumps_octave_core (), orig_val); %!error (sigterm_dumps_octave_core (1, 2)) */