1
0
Fork 0
cl-sites/ecl.common-lisp.dev/static/manual/Signals-and-Interrupts.html

426 lines
32 KiB
HTML
Raw Permalink Normal View History

2024-12-24 19:15:49 +01:00
<!DOCTYPE html>
<html>
<!-- Created by GNU Texinfo 7.0.3, https://www.gnu.org/software/texinfo/ -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Signals and Interrupts (ECL Manual)</title>
<meta name="description" content="Signals and Interrupts (ECL Manual)">
<meta name="keywords" content="Signals and Interrupts (ECL Manual)">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="index.html" rel="start" title="Top">
<link href="Indexes.html" rel="index" title="Indexes">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="Extensions.html" rel="up" title="Extensions">
<link href="Memory-Management.html#Memory-Management" rel="next" title="Memory Management">
<link href="Native-threads.html#Native-threads" rel="prev" title="Native threads">
<style type="text/css">
<!--
/* colors */
a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em}
div.example {margin-left: 3.2em}
kbd.kbd {font-style: oblique}
span.r {font-family: initial; font-weight: normal; font-style: normal}
span:hover a.copiable-link {visibility: visible}
strong.def-name {font-family: monospace; font-weight: bold; font-size: larger}
ul.mark-bullet {list-style-type: disc}
@media (prefers-color-scheme: dark) {
/* dark theme */
html { color: seashell;
background: #1A1A1A; }
body { background: #1A1A1A; }
th { border-bottom: 2px solid lightgray; }
h1, h2, h3, h4, h5 { background-image: linear-gradient(to left, #202020, #3A3A3A); }
code, var, code a { color: darkorange;
background: #2A2A2A; }
a { color: seashell; }
pre { background: #2A2A2A;
color: seashell;
/* mark longer code block with stripe on the left */
border-left: 5px solid darkorange;
padding-left: 10px; }
pre.screen { background: #2A2A2A;
border: 1px solid lightgray; }
pre.programlisting { background: #2A2A2A;
border-left: 1px solid lightgray;
border-top: 1px solid lightgray; }
/* we need a light background in order for the images to be readable */
img { background: white }
}
@media (prefers-color-scheme: light) {
/* light theme */
html { background: white }
body { background: white }
th { border-bottom: 2px solid gray; }
h1, h2, h3, h4, h5 { background: lightgray; }
code, var, code a { color: darkred;
background: whitesmoke; }
a { color: #000; }
pre { background: whitesmoke;
color: black;
/* mark longer code block with stripe on the left */
border-left: 5px solid darkred;
padding-left: 10px; }
pre.screen { background: #EEE;
border: 1px solid black; }
pre.programlisting { background: #EEEEEE;
border-left: 1px solid black;
border-top: 1px solid black; }
}
body {
margin: 1em 125px 0 10%;
line-height: 1.5em;
padding: 0 2em 1em 2em;
font: 13px Verdana,Arial, sans-serif
}
ul, dd, dl, dt { margin-top: 0; margin-bottom: 0; }
p, code, td, dl, dt {
line-height: 1.5em;
}
table {
font: inherit;
border-collapse: collapse;
}
th, td {
vertical-align: top;
}
h1, h2, h3 { padding-left: 15px; }
h4, h5 { padding-left: 5px; }
code, pre {
font-size: 1em;
font-family: monospace;
}
var {
font-size: 1em;
}
/* links inside code appear the same as the code itself */
code a {
font-weight: normal;
text-decoration: none;
}
/* but get an underline when hovering */
code a:hover {
text-decoration: underline;
}
/* ordinary links appear in bold */
a { font-weight: bold; }
pre.verbatim {
margin: 0 0 0 0;
}
pre {
overflow: auto;
}
pre.screen {
font-weight: bold;
padding: 0.5em;
}
pre.programlisting {
padding: 0.5em;
}
div p { padding: 0 2em }
li p { padding: 0; margin: 0 }
hr { display: none; }
div.funcsynopsis p {
text-indent: -2em;
}
div.variablelist {
padding: 0 2em;
}
.type, .funcsynopsis, .symbol {
font-family: monospace;
}
.type, .symbol, .replaceable {
white-space: nowrap;
}
-->
</style>
</head>
<body lang="en">
<div class="section-level-extent" id="Signals-and-Interrupts">
<div class="nav-panel">
<p>
Next: <a href="Memory-Management.html#Memory-Management" accesskey="n" rel="next">Memory Management</a>, Previous: <a href="Native-threads.html#Native-threads" accesskey="p" rel="prev">Native threads</a>, Up: <a href="Extensions.html" accesskey="u" rel="up">Extensions</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h3 class="section" id="Signals-and-Interrupts-1">3.5 Signals and Interrupts</h3>
<ul class="mini-toc">
<li><a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Problems-associated-to-signals" accesskey="1">Problems associated to signals</a></li>
<li><a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Kinds-of-signals" accesskey="2">Kinds of signals</a></li>
<li><a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Signals-and-interrupts-in-ECL" accesskey="3">Signals and interrupts in ECL</a></li>
<li><a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Considerations-when-embedding-ECL" accesskey="4">Considerations when embedding ECL</a></li>
<li><a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Signals-Reference" accesskey="5">Signals Reference</a></li>
</ul>
<hr>
<div class="subsection-level-extent" id="Signals-and-Interrupts-_002d-Problems-associated-to-signals">
<div class="nav-panel">
<p>
Next: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Kinds-of-signals" accesskey="n" rel="next">Kinds of signals</a>, Up: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts" accesskey="u" rel="up">Signals and Interrupts</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Problems-associated-to-signals">3.5.1 Problems associated to signals</h4>
<p>POSIX contemplates the notion of &quot;signals&quot;, which are events that cause a process or a thread to be interrupted. Windows uses the term &quot;exception&quot;, which includes also a more general kind of errors.
</p>
<p>In both cases the consequence is that a thread or process may be interrupted at any time, either by causes which are intrinsic to them (synchronous signals), such as floating point exceptions, or extrinsic (asynchronous signals), such as the process being aborted by the user.
</p>
<p>Of course, those interruptions are not always welcome. When the interrupt is delivered and a handler is invoked, the thread or even the whole program may be in an inconsistent state. For instance the thread may have acquired a lock, or it may be in the process of filling the fields of a structure. Furthermore, sometimes the signal that a process receives may not even be related to it, as in the case when a user presses <kbd class="kbd">Cltr-C</kbd> and a <code class="code">SIGINT</code> signal is delivered to an arbitrary thread, or when the process receives the Windows exception <code class="code">CTRL_CLOSE_EVENT</code> denoting that the terminal window is being closed.
</p>
<p>Understanding this, POSIX restricts severely what functions can be called from a signal handler, thereby limiting its usefulness. However, Common Lisp users expect to be able to handle floating point exceptions and to gracefully manage user interrupts, program exits, etc. In an attempt to solve this seemingly impossible problem, ECL has taken a pragmatic approach that works, it is rather safe, but involves some work on the ECL maintainers and also on users that want to embed ECL as a library.
</p>
<hr>
</div>
<div class="subsection-level-extent" id="Signals-and-Interrupts-_002d-Kinds-of-signals">
<div class="nav-panel">
<p>
Next: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Signals-and-interrupts-in-ECL" accesskey="n" rel="next">Signals and interrupts in ECL</a>, Previous: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Problems-associated-to-signals" accesskey="p" rel="prev">Problems associated to signals</a>, Up: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts" accesskey="u" rel="up">Signals and Interrupts</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Kinds-of-signals">3.5.2 Kinds of signals</h4>
<ul class="mini-toc">
<li><a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Synchronous-signals" accesskey="1">Synchronous signals</a></li>
<li><a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Asynchronous-signals" accesskey="2">Asynchronous signals</a></li>
</ul>
<hr>
<div class="subsubsection-level-extent" id="Signals-and-Interrupts-_002d-Synchronous-signals">
<div class="nav-panel">
<p>
Next: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Asynchronous-signals" accesskey="n" rel="next">Asynchronous signals</a>, Up: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Kinds-of-signals" accesskey="u" rel="up">Kinds of signals</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Synchronous-signals">3.5.2.1 Synchronous signals</h4>
<p>The name derives from POSIX and it denotes interrupts that occur due to the code that a particular thread executes. They are largely equivalent to C++ and Java exceptions, and in Windows they are called &quot;unchecked exceptions.&quot;
</p>
<p>Common Lisp programs may generate mostly three kinds of synchronous signals:
</p>
<ul class="itemize mark-bullet">
<li>Floating point exceptions, that result from overflows in computations, division by zero, and so on.
</li><li>Access violations, such as dereferencing NULL pointers, writing into regions of memory that are protected, etc.
</li><li>Process interrupts.
</li></ul>
<p>The first family of signals are generated by the floating point processing hardware in the computer, and they typically happen when code is compiled with low security settings, performing mathematical operations without checks.
</p>
<p>The second family of signals may seem rare, but unfortunately they still happen quite often. One scenario is wrong code that handles memory directly via FFI. Another one is undetected stack overflows, which typically result in access to protected memory regions. Finally, a very common cause of these kind of exceptions is invoking a function that has been compiled with very low security settings with arguments that are not of the expected type &ndash; for instance, passing a float when a structure is expected.
</p>
<p>The third family is related to the multiprocessing capabilities in Common Lisp systems and more precisely to the <code class="code"><a class="ref" href="Native-threads.html#mp_003ainterrupt_002dprocess">mp:interrupt-process</a></code> function which is used to kill, interrupt and inspect arbitrary threads. In POSIX systems ECL informs a given thread about the need to interrupt its execution by sending a particular signal from the set which is available to the user.
</p>
<p>Note that in neither of these cases we should let the signal pass unnoticed. Access violations and floating point exceptions may propagate through the program causing more harm than expected, and without process interrupts we will not be able to stop and cancel different threads. The only question that remains, though, is whether such signals can be handled by the thread in which they were generated and how.
</p>
<hr>
</div>
<div class="subsubsection-level-extent" id="Signals-and-Interrupts-_002d-Asynchronous-signals">
<div class="nav-panel">
<p>
Previous: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Synchronous-signals" accesskey="p" rel="prev">Synchronous signals</a>, Up: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Kinds-of-signals" accesskey="u" rel="up">Kinds of signals</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Asynchronous-signals">3.5.2.2 Asynchronous signals</h4>
<p>In addition to the set of synchronous signals or &quot;exceptions&quot;, we have a set of signals that denote &quot;events&quot;, things that happen while the program is being executed, and &quot;requests&quot;. Some typical examples are:
</p>
<ul class="itemize mark-bullet">
<li>Request for program termination (<code class="code">SIGKILL</code>, <code class="code">SIGTERM</code>).
</li><li>Indication that a child process has finished.
</li><li>Request for program interruption (<code class="code">SIGINT</code>), typically as a consequence of pressing a key combination, e.g. <kbd class="kbd">Ctrl-C</kbd>.
</li></ul>
<p>The important difference with synchronous signals is that we have no thread that causes the interrupt and thus there is no preferred way of handling them. Moreover, the operating system will typically dispatch these signals to an arbitrary thread, unless we set up mechanisms to prevent it. This can have nasty consequences if the incoming signal interrupt a system call, or leaves the interrupted thread in an inconsistent state.
</p>
<hr>
</div>
</div>
<div class="subsection-level-extent" id="Signals-and-Interrupts-_002d-Signals-and-interrupts-in-ECL">
<div class="nav-panel">
<p>
Next: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Considerations-when-embedding-ECL" accesskey="n" rel="next">Considerations when embedding ECL</a>, Previous: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Kinds-of-signals" accesskey="p" rel="prev">Kinds of signals</a>, Up: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts" accesskey="u" rel="up">Signals and Interrupts</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Signals-and-interrupts-in-ECL">3.5.3 Signals and interrupts in ECL</h4>
<p>The signal handling facilities in ECL are constrained by two needs. First of all, we can not ignore the synchronous signals mentioned in <a class="ref" href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Synchronous-signals">Synchronous signals</a>. Second, all other signals should cause the least harm to the running threads. Third, when a signal is handled synchronously using a signal handler, the handler should do almost nothing unless we are completely sure that we are in an interruptible region, that is outside system calls, in code that ECL knows and controls.
</p>
<p>The way in which this is solved is based on the existence of both synchronous and asynchronous signal handling code, as explained in the following two sections.
</p>
<ul class="mini-toc">
<li><a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Handling-of-asynchronous-signals" accesskey="1">Handling of asynchronous signals</a></li>
<li><a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Handling-of-synchronous-signals" accesskey="2">Handling of synchronous signals</a></li>
</ul>
<hr>
<div class="subsubsection-level-extent" id="Signals-and-Interrupts-_002d-Handling-of-asynchronous-signals">
<div class="nav-panel">
<p>
Next: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Handling-of-synchronous-signals" accesskey="n" rel="next">Handling of synchronous signals</a>, Up: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Signals-and-interrupts-in-ECL" accesskey="u" rel="up">Signals and interrupts in ECL</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Handling-of-asynchronous-signals">3.5.3.1 Handling of asynchronous signals</h4>
<p>In systems in which this is possible, ECL creates a signal handling thread to detect and process asynchronous signals (See <a class="xref" href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Asynchronous-signals">Asynchronous signals</a>). This thread is a trivial one and does not process the signals itself: it communicates with, or launches new signal handling threads to act accordingly to the denoted events.
</p>
<p>The use of a separate thread has some nice consequences. The first one is that those signals will not interrupt any sensitive code. The second one is that the signal handling thread will be able to execute arbitrary lisp or C code, since it is not being executed in a sensitive context. Most important, this style of signal handling is the recommended one by the POSIX standards, and it is the one that Windows uses.
</p>
<p>The installation of the signal handling thread is dictated by a boot time option, <code class="code">ECL_OPT_SIGNAL_HANDLING_THREAD</code> (see <a class="pxref" href="Embedding-ECL.html#tab_003aboot_002doptions">Table 1.1</a> for a summary of boot options), and it will only be possible in systems that support either POSIX or Windows threads.
</p>
<p>Systems which embed ECL as an extension language may wish to deactivate the signal handling thread using the previously mentioned option. If this is the case, then they should take appropriate measures to avoid interrupting the code in ECL when such signals are delivered.
</p>
<p>Systems which embed ECL and do not mind having a separate signal handling thread can control the set of asynchronous signals which is handled by this thread. This is done again using the appropriate boot options such as <code class="code">ECL_OPT_TRAP_SIGINT</code>, <code class="code">ECL_OPT_TRAP_SIGTERM</code>, etc. Note that in order to detect and handle those signals, ECL must block them from delivery to any other thread. This means changing the <code class="code">sigprocmask()</code> in POSIX systems or setting up a custom <code class="code">SetConsoleCtrlHandler()</code> in Windows.
</p>
<hr>
</div>
<div class="subsubsection-level-extent" id="Signals-and-Interrupts-_002d-Handling-of-synchronous-signals">
<div class="nav-panel">
<p>
Previous: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Handling-of-asynchronous-signals" accesskey="p" rel="prev">Handling of asynchronous signals</a>, Up: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Signals-and-interrupts-in-ECL" accesskey="u" rel="up">Signals and interrupts in ECL</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Handling-of-synchronous-signals">3.5.3.2 Handling of synchronous signals</h4>
<p>We have already mentioned that certain synchronous signals and exceptions can not be ignored and yet the corresponding signal handlers are not able to execute arbitrary code. To solve this seemingly impossible contradiction, ECL uses a simple solution, which is to mark the sections of code which are interruptible, and in which it is safe for the handler to run arbitrary code. All other regions would be considered &quot;unsafe&quot; and would be protected from signals and exceptions.
</p>
<p>In principle this &quot;marking&quot; of safe areas can be done using POSIX functions such as <code class="code">pthread_sigmask()</code> or <code class="code">sigprocmask()</code>. However in practice this is slow, as it involves at least a function call, resolving thread-local variables, etc, etc, and it will not work in Windows.
</p>
<p>Furthermore, sometimes we want signals to be detected but not to be immediately processed. For instance, when reading from the terminal we want to be able to interrupt the process, but we can not execute the code from the handler, since the C function which is used to read from the terminal, <code class="code">read()</code>, may have left the input stream in an inconsistent, or even locked state.
</p>
<p>The approach in ECL is more lightweight: we install our own signal handler and use a thread-local variable as a flag that determines whether the thread is executing interrupt safe code or not. More precisely, if the variable <code class="code">ecl_process_env()-&gt;disable_interrupts</code> is set, signals and exceptions will be postponed and then the information about the signal is queued. Otherwise the appropriate code is executed: for instance invoking the debugger, jumping to a condition handler, quitting, etc.
</p>
<p>Systems that embed ECL may wish to deactivate completely these signal handlers. This is done using the boot options, <code class="code">ECL_OPT_TRAP_SIGFPE</code>, <code class="code">ECL_OPT_TRAP_SIGSEGV</code>, <code class="code">ECL_OPT_TRAP_SIGBUS</code>, <code class="code">ECL_OPT_TRAP_INTERRUPT_SIGNAL</code>.
</p>
<p>Systems that embed ECL and want to allow handling of synchronous signals should take care to also trap the associated lisp conditions that may arise. This is automatically taken care of by functions such as <code class="code"><a class="ref" href="Manipulating-Lisp-objects.html#si_005fsafe_005feval">si_safe_eval</a></code>, and in all other cases it can be solved by enclosing the unsafe code in a <code class="code"><a class="ref" href="Embedding-ECL.html#ECL_005fCATCH_005fALL">ECL_CATCH_ALL</a></code> frame.
</p>
<hr>
</div>
</div>
<div class="subsection-level-extent" id="Signals-and-Interrupts-_002d-Considerations-when-embedding-ECL">
<div class="nav-panel">
<p>
Next: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Signals-Reference" accesskey="n" rel="next">Signals Reference</a>, Previous: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Signals-and-interrupts-in-ECL" accesskey="p" rel="prev">Signals and interrupts in ECL</a>, Up: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts" accesskey="u" rel="up">Signals and Interrupts</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Considerations-when-embedding-ECL">3.5.4 Considerations when embedding ECL</h4>
<p>There are several approaches when handling signals and interrupts in a program that uses ECL. One is to install your own signal handlers. This is perfectly fine, but you should respect the same restrictions as ECL. Namely, you may not execute arbitrary code from those signal handlers, and in particular it will not always be safe to execute Common Lisp code from there.
</p>
<p>If you want to use your own signal handlers then you should set the appropriate options before invoking <code class="code"><a class="ref" href="Embedding-ECL.html#cl_005fboot">cl_boot</a></code>, as explained in <code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fset_005foption">ecl_set_option</a></code>. Note that in this case ECL will not always be able to detect floating point exceptions.
</p>
<p>The other option is to let ECL handle signals itself. This would be safer when the dominant part of the code is Common Lisp, but you may need to protect the code that embeds ECL from being interrupted using either the macros <code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fdisable_005finterrupts">ecl_disable_interrupts</a></code> and <code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fenable_005finterrupts">ecl_enable_interrupts</a></code> or the POSIX functions <code class="code">pthread_sigmaks</code> and <code class="code">sigprocmask</code>.
</p>
<hr>
</div>
<div class="subsection-level-extent" id="Signals-and-Interrupts-_002d-Signals-Reference">
<div class="nav-panel">
<p>
Previous: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Considerations-when-embedding-ECL" accesskey="p" rel="prev">Considerations when embedding ECL</a>, Up: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts" accesskey="u" rel="up">Signals and Interrupts</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Signals-Reference">3.5.5 Signals Reference</h4>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-mp_003awith_002dinterrupts-1"><span class="category-def">Macro: </span><span><strong class="def-name">mp:with-interrupts</strong> <var class="def-var-arguments">&amp;body body</var><a class="copiable-link" href='Signals-and-Interrupts.html#index-mp_003awith_002dinterrupts-1'> &para;</a></span></dt>
<dt class="deffnx defmacx-alias-deffnx def-cmd-deffn" id="index-mp_003awithout_002dinterrupts-1"><span class="category-def">Macro: </span><span><strong class="def-name">mp:without-interrupts</strong> <var class="def-var-arguments">&amp;body body</var><a class="copiable-link" href='Signals-and-Interrupts.html#index-mp_003awithout_002dinterrupts-1'> &para;</a></span></dt>
<dd><p>Execute code with interrupts optionally enabled/disabled, See <a class="xref" href="Native-threads.html#Processes-dictionary">Processes dictionary</a>.
</p></dd></dl>
<a class="anchor" id="ext_003aunix_002dsignal_002dreceived"></a><a class="index-entry-id" id="index-ext_003aunix_002dsignal_002dreceived"></a>
<dl class="first-deftp">
<dt class="deftp" id="index-ext_003aunix_002dsignal_002dreceived-1"><span class="category-def">Condition: </span><span><strong class="def-name">ext:unix-signal-received</strong><a class="copiable-link" href='Signals-and-Interrupts.html#index-ext_003aunix_002dsignal_002dreceived-1'> &para;</a></span></dt>
<dd><p>Unix signal condition
</p>
<p><b class="b">Class Precedence List</b>
</p>
<p><code class="code">condition</code>, <code class="code">t</code>
</p>
<p><b class="b">Methods</b>
</p>
<a class="anchor" id="ext_003aunix_002dsignal_002dreceived_002dcode"></a><a class="index-entry-id" id="index-ext_003aunix_002dsignal_002dreceived_002dcode-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-ext_003aunix_002dsignal_002dreceived_002dcode"><span class="category-def">Function: </span><span><strong class="def-name">ext:unix-signal-received-code</strong> <var class="def-var-arguments">condition</var><a class="copiable-link" href='Signals-and-Interrupts.html#index-ext_003aunix_002dsignal_002dreceived_002dcode'> &para;</a></span></dt>
<dd><p>Returns the signal code of <var class="var">condition</var>
</p></dd></dl>
</dd></dl>
<a class="anchor" id="ext_003aget_002dsignal_002dhandler"></a><a class="index-entry-id" id="index-ext_003aget_002dsignal_002dhandler-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-ext_003aget_002dsignal_002dhandler"><span class="category-def">Function: </span><span><strong class="def-name">ext:get-signal-handler</strong> <var class="def-var-arguments">code</var><a class="copiable-link" href='Signals-and-Interrupts.html#index-ext_003aget_002dsignal_002dhandler'> &para;</a></span></dt>
<dd><p>Queries the currently active signal handler for <var class="var">code</var>.
</p></dd></dl>
<a class="anchor" id="ext_003aset_002dsignal_002dhandler"></a><a class="index-entry-id" id="index-ext_003aset_002dsignal_002dhandler-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-ext_003aset_002dsignal_002dhandler"><span class="category-def">Function: </span><span><strong class="def-name">ext:set-signal-handler</strong> <var class="def-var-arguments">code handler</var><a class="copiable-link" href='Signals-and-Interrupts.html#index-ext_003aset_002dsignal_002dhandler'> &para;</a></span></dt>
<dd><p>Arranges for the signal <var class="var">code</var> to be caught in all threads and
sets the signal handler for it. The value of <var class="var">handler</var> modifies
the signal handling behaviour as follows:
</p><dl class="table">
<dt><var class="var">handler</var> is a function designator</dt>
<dd><p>The function designated by <var class="var">handler</var> will be invoked with no
arguments
</p></dd>
<dt><var class="var">handler</var> is a symbol denoting a condition type</dt>
<dd><p>A continuable error of the given type will be signaled
</p></dd>
<dt><var class="var">handler</var> is equal to <var class="var">code</var></dt>
<dd><p>A condition of type <code class="code"><a class="ref" href="Signals-and-Interrupts.html#ext_003aunix_002dsignal_002dreceived">ext:unix-signal-received</a></code> with the
corresponding signal code will be signaled
</p></dd>
<dt><var class="var">handler</var> is <code class="code">nil</code></dt>
<dd><p>The signal will be caught but no handler will be called
</p></dd>
</dl>
</dd></dl>
<a class="anchor" id="ext_003acatch_002dsignal"></a><a class="index-entry-id" id="index-ext_003acatch_002dsignal-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-ext_003acatch_002dsignal"><span class="category-def">Function: </span><span><strong class="def-name">ext:catch-signal</strong> <var class="def-var-arguments">code flag &amp;key process</var><a class="copiable-link" href='Signals-and-Interrupts.html#index-ext_003acatch_002dsignal'> &para;</a></span></dt>
<dd><p>Changes the action taken on receiving the signal <var class="var">code</var>.
<var class="var">flag</var> can be one of the following:
</p><dl class="table">
<dt><code class="code">nil</code> or <code class="code">:ignore</code></dt>
<dd><p>Ignore the signal
</p></dd>
<dt><code class="code">:default</code></dt>
<dd><p>Use the default signal handling strategy of the operating system
</p></dd>
<dt><code class="code">t</code> or <code class="code">:catch</code></dt>
<dd><p>Catch the signal and invoke the signal handler as given by <code class="code"><a class="ref" href="Signals-and-Interrupts.html#ext_003aget_002dsignal_002dhandler">ext:get-signal-handler</a></code>
</p></dd>
<dt><code class="code">:mask</code>, <code class="code">:unmask</code></dt>
<dd><p>Change the signal mask of either a) the not yet enabled <var class="var">process</var>
or b) the current process, if <var class="var">process</var> is not supplied
</p></dd>
</dl>
<p>Returns <code class="code">t</code> on success and <code class="code">nil</code> on failure.
</p></dd></dl>
<a class="index-entry-id" id="index-Setting-a-signal-handler"></a>
<p>Example:
</p><div class="example lisp">
<pre class="lisp-preformatted">CL-USER&gt; (ext:catch-signal ext:+SIGPIPE+ :catch)
T
CL-USER&gt; (ext:get-signal-handler ext:+SIGPIPE+)
NIL
CL-USER&gt; (ext:set-signal-handler ext:+SIGPIPE+
#'(lambda ()
(format t &quot;SIGPIPE detected in process: ~a~%&quot; mp:*current-process*)))
#&lt;bytecompiled-function 0x25ffca8&gt;
</pre></div>
<p>Passing the SIGPIPE signal to the ECL program with <code class="code">killall -s
SIGPIPE ecl</code> results in the output:
</p><div class="example">
<pre class="verbatim">SIGPIPE detected in process: #&lt;process TOP-LEVEL 0x1ecdfc0&gt;
</pre></div>
</div>
</div>
<hr>
<div class="nav-panel">
<p>
Next: <a href="Memory-Management.html#Memory-Management" accesskey="n" rel="next">Memory Management</a>, Previous: <a href="Native-threads.html#Native-threads" accesskey="p" rel="prev">Native threads</a>, Up: <a href="Extensions.html" accesskey="u" rel="up">Extensions</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
</body>
</html>