blob: 6ab591afb56ac9feed59d68b6791d8d0d8e6c3a9 [file] [log] [blame]
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Library for easier and safe Unix signal handling"><meta name="keywords" content="rust, rustlang, rust-lang, signal_hook"><title>signal_hook - Rust</title><link rel="preload" as="font" type="font/woff2" crossorigin href="../SourceSerif4-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../FiraSans-Regular.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../FiraSans-Medium.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../SourceCodePro-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../SourceSerif4-Bold.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../SourceCodePro-Semibold.ttf.woff2"><link rel="stylesheet" href="../normalize.css"><link rel="stylesheet" href="../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../ayu.css" disabled><link rel="stylesheet" href="../dark.css" disabled><link rel="stylesheet" href="../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../storage.js"></script><script defer src="../crates.js"></script><script defer src="../main.js"></script><noscript><link rel="stylesheet" href="../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../favicon.svg"></head><body class="rustdoc mod crate"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle">&#9776;</button><a class="sidebar-logo" href="../signal_hook/index.html"><div class="logo-container"><img class="rust-logo" src="../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../signal_hook/index.html"><div class="logo-container"><img class="rust-logo" src="../rust-logo.svg" alt="logo"></div></a><h2 class="location"><a href="#">Crate signal_hook</a></h2><div class="sidebar-elems"><ul class="block"><li class="version">Version 0.1.17</li><li><a id="all-types" href="all.html">All Items</a></li></ul><section><ul class="block"><li><a href="#modules">Modules</a></li><li><a href="#structs">Structs</a></li><li><a href="#constants">Constants</a></li><li><a href="#functions">Functions</a></li></ul></section></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><div class="search-container"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../wheel.svg"></a></div></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Crate <a class="mod" href="#">signal_hook</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../src/signal_hook/lib.rs.html#1-190">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">&#x2212;</span>]</a></span></div><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Library for easier and safe Unix signal handling</p>
<p>Unix signals are inherently hard to handle correctly, for several reasons:</p>
<ul>
<li>They are a global resource. If a library wants to set its own signal handlers, it risks
disturbing some other library. It is possible to chain the previous signal handler, but then
it is impossible to remove the old signal handlers from the chains in any practical manner.</li>
<li>They can be called from whatever thread, requiring synchronization. Also, as they can
interrupt a thread at any time, making most handling race-prone.</li>
<li>According to the POSIX standard, the set of functions one may call inside a signal handler is
limited to very few of them. To highlight, mutexes (or other locking mechanisms) and memory
allocation and deallocation is <em>not</em> allowed.</li>
</ul>
<p>This library aims to solve some of the problems. It provides a global registry of actions
performed on arrival of signals. It is possible to register multiple actions for the same
signal and it is possible to remove the actions later on. If there was a previous signal
handler when the first action for a signal is registered, it is chained (but the original one
can’t be removed).</p>
<p>The main function of the library is <a href="fn.register.html"><code>register</code></a>.</p>
<p>It also offers several common actions one might want to register, implemented in the correct
way. They are scattered through submodules and have the same limitations and characteristics as
the <a href="fn.register.html"><code>register</code></a> function. Generally, they work to postpone the action taken
outside of the signal handler, where the full freedom and power of rust is available.</p>
<p>Unlike other Rust libraries for signal handling, this should be flexible enough to handle all
the common and useful patterns.</p>
<p>The library avoids all the newer fancy signal-handling routines. These generally have two
downsides:</p>
<ul>
<li>They are not fully portable, therefore the library would have to contain <em>both</em> the
implementation using the basic routines and the fancy ones. As signal handling is not on the
hot path of most programs, this would not bring any actual benefit.</li>
<li>The other routines require that the given signal is masked in all application’s threads. As
the signals are not masked by default and a new thread inherits the signal mask of its
parent, it is possible to guarantee such global mask by masking them before any threads
start. While this is possible for an application developer to do, it is not possible for a
a library.</li>
</ul>
<h2 id="warning"><a href="#warning">Warning</a></h2>
<p>Even with this library, you should thread with care. It does not eliminate all the problems
mentioned above.</p>
<p>Also, note that the OS may collate multiple instances of the same signal into just one call of
the signal handler. Furthermore, some abstractions implemented here also naturally collate
multiple instances of the same signal. The general guarantee is, if there was at least one
signal of the given number delivered, an action will be taken, but it is not specified how many
times ‒ signals work mostly as kind of „wake up now“ nudge, if the application is slow to wake
up, it may be nudged multiple times before it does so.</p>
<h2 id="signal-limitations"><a href="#signal-limitations">Signal limitations</a></h2>
<p>OS limits still apply ‒ it is not possible to redefine certain signals (eg. <code>SIGKILL</code> or
<code>SIGSTOP</code>) and it is probably a <em>very</em> stupid idea to touch certain other ones (<code>SIGSEGV</code>,
<code>SIGFPE</code>, <code>SIGILL</code>). Therefore, this library will panic if any attempt at manipulating these is
made. There are some use cases for redefining the latter ones, but these are not well served by
this library and you really <em>really</em> have to know what you’re doing and are generally on your
own doing that.</p>
<h2 id="signal-masks"><a href="#signal-masks">Signal masks</a></h2>
<p>As the library uses <code>sigaction</code> under the hood, signal masking works as expected (eg. with
<code>pthread_sigmask</code>). This means, signals will <em>not</em> be delivered if the signal is masked in all
program’s threads.</p>
<p>By the way, if you do want to modify the signal mask (or do other Unix-specific magic), the
<a href="https://crates.io/crates/nix">nix</a> crate offers safe interface to many low-level functions,
including
<a href="https://docs.rs/nix/0.11.0/nix/sys/signal/fn.pthread_sigmask.html"><code>pthread_sigmask</code></a>.</p>
<h2 id="portability"><a href="#portability">Portability</a></h2>
<p>It should work on any POSIX.1-2001 system, which are all the major big OSes with the notable
exception of Windows.</p>
<p>Non-standard signals are also supported. Pass the signal value directly from <code>libc</code> or use
the numeric value directly.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>std::sync::Arc;
<span class="kw">use </span>std::sync::atomic::{AtomicBool};
<span class="kw">let </span>term = Arc::new(AtomicBool::new(<span class="bool-val">false</span>));
<span class="kw">let _ </span>= signal_hook::flag::register(libc::SIGINT, Arc::clone(<span class="kw-2">&amp;</span>term));</code></pre></div>
<p>This crate includes a limited support for Windows, based on <code>signal</code>/<code>raise</code> in the CRT.
There are differences in both API and behavior:</p>
<ul>
<li><code>iterator</code> and <code>pipe</code> are not yet implemented.</li>
<li>We have only a few signals: <code>SIGABRT</code>, <code>SIGABRT_COMPAT</code>, <code>SIGBREAK</code>,
<code>SIGFPE</code>, <code>SIGILL</code>, <code>SIGINT</code>, <code>SIGSEGV</code> and <code>SIGTERM</code>.</li>
<li>Due to lack of signal blocking, there’s a race condition.
After the call to <code>signal</code>, there’s a moment where we miss a signal.
That means when you register a handler, there may be a signal which invokes
neither the default handler or the handler you register.</li>
<li>Handlers registered by <code>signal</code> in Windows are cleared on first signal.
To match behavior in other platforms, we re-register the handler each time the handler is
called, but there’s a moment where we miss a handler.
That means when you receive two signals in a row, there may be a signal which invokes
the default handler, nevertheless you certainly have registered the handler.</li>
</ul>
<p>Moreover, signals won’t work as you expected. <code>SIGTERM</code> isn’t actually used and
not all <code>Ctrl-C</code>s are turned into <code>SIGINT</code>.</p>
<p>Patches to improve Windows support in this library are welcome.</p>
<h2 id="examples"><a href="#examples">Examples</a></h2>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">extern crate </span>signal_hook;
<span class="kw">use </span>std::io::Error;
<span class="kw">use </span>std::sync::Arc;
<span class="kw">use </span>std::sync::atomic::{AtomicBool, Ordering};
<span class="kw">fn </span>main() -&gt; <span class="prelude-ty">Result</span>&lt;(), Error&gt; {
<span class="kw">let </span>term = Arc::new(AtomicBool::new(<span class="bool-val">false</span>));
signal_hook::flag::register(signal_hook::SIGTERM, Arc::clone(<span class="kw-2">&amp;</span>term))<span class="question-mark">?</span>;
<span class="kw">while </span>!term.load(Ordering::Relaxed) {
<span class="comment">// Do some time-limited stuff here
// (if this could block forever, then there&#39;s no guarantee the signal will have any
// effect).
</span>}
<span class="prelude-val">Ok</span>(())
}</code></pre></div>
<h2 id="features"><a href="#features">Features</a></h2>
<ul>
<li><code>mio-support</code>: The <a href="iterator/struct.Signals.html"><code>Signals</code> iterator</a> becomes pluggable into
mio 0.6.</li>
<li><code>mio-0_7-support</code>: The <a href="iterator/struct.Signals.html"><code>Signals</code> iterator</a> becomes pluggable into
mio 0.7.</li>
<li><code>tokio-support</code>: The <a href="iterator/struct.Signals.html"><code>Signals</code></a> can be turned into
<a href="iterator/struct.Async.html"><code>Async</code></a>, which provides a <code>Stream</code> interface for integration in
the asynchronous world.</li>
</ul>
</div></details><h2 id="modules" class="small-section-header"><a href="#modules">Modules</a></h2><div class="item-table"><div class="item-row"><div class="item-left module-item"><a class="mod" href="cleanup/index.html" title="signal_hook::cleanup mod">cleanup</a></div><div class="item-right docblock-short">Cleaning up signals.</div></div><div class="item-row"><div class="item-left module-item"><a class="mod" href="flag/index.html" title="signal_hook::flag mod">flag</a></div><div class="item-right docblock-short">Module for actions setting flags.</div></div><div class="item-row"><div class="item-left module-item"><a class="mod" href="iterator/index.html" title="signal_hook::iterator mod">iterator</a></div><div class="item-right docblock-short">An iterator over incoming signals.</div></div><div class="item-row"><div class="item-left module-item"><a class="mod" href="pipe/index.html" title="signal_hook::pipe mod">pipe</a></div><div class="item-right docblock-short">Module with the self-pipe pattern.</div></div></div><h2 id="structs" class="small-section-header"><a href="#structs">Structs</a></h2><div class="item-table"><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.SigId.html" title="signal_hook::SigId struct">SigId</a></div><div class="item-right docblock-short">An ID of registered action.</div></div></div><h2 id="constants" class="small-section-header"><a href="#constants">Constants</a></h2><div class="item-table"><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.FORBIDDEN.html" title="signal_hook::FORBIDDEN constant">FORBIDDEN</a></div><div class="item-right docblock-short">List of forbidden signals.</div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGABRT.html" title="signal_hook::SIGABRT constant">SIGABRT</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGALRM.html" title="signal_hook::SIGALRM constant">SIGALRM</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGBUS.html" title="signal_hook::SIGBUS constant">SIGBUS</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGCHLD.html" title="signal_hook::SIGCHLD constant">SIGCHLD</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGCONT.html" title="signal_hook::SIGCONT constant">SIGCONT</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGFPE.html" title="signal_hook::SIGFPE constant">SIGFPE</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGHUP.html" title="signal_hook::SIGHUP constant">SIGHUP</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGILL.html" title="signal_hook::SIGILL constant">SIGILL</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGINT.html" title="signal_hook::SIGINT constant">SIGINT</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGIO.html" title="signal_hook::SIGIO constant">SIGIO</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGKILL.html" title="signal_hook::SIGKILL constant">SIGKILL</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGPIPE.html" title="signal_hook::SIGPIPE constant">SIGPIPE</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGPROF.html" title="signal_hook::SIGPROF constant">SIGPROF</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGQUIT.html" title="signal_hook::SIGQUIT constant">SIGQUIT</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGSEGV.html" title="signal_hook::SIGSEGV constant">SIGSEGV</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGSTOP.html" title="signal_hook::SIGSTOP constant">SIGSTOP</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGSYS.html" title="signal_hook::SIGSYS constant">SIGSYS</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGTERM.html" title="signal_hook::SIGTERM constant">SIGTERM</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGTRAP.html" title="signal_hook::SIGTRAP constant">SIGTRAP</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGUSR1.html" title="signal_hook::SIGUSR1 constant">SIGUSR1</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGUSR2.html" title="signal_hook::SIGUSR2 constant">SIGUSR2</a></div></div><div class="item-row"><div class="item-left module-item"><a class="constant" href="constant.SIGWINCH.html" title="signal_hook::SIGWINCH constant">SIGWINCH</a></div></div></div><h2 id="functions" class="small-section-header"><a href="#functions">Functions</a></h2><div class="item-table"><div class="item-row"><div class="item-left module-item"><a class="fn" href="fn.register.html" title="signal_hook::register fn">register</a><sup title="unsafe function"></sup></div><div class="item-right docblock-short">Registers an arbitrary action for the given signal.</div></div><div class="item-row"><div class="item-left module-item"><a class="fn" href="fn.unregister.html" title="signal_hook::unregister fn">unregister</a></div><div class="item-right docblock-short">Removes a previously installed action.</div></div></div></section></div></main><div id="rustdoc-vars" data-root-path="../" data-current-crate="signal_hook" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0-nightly (5c8bff74b 2022-10-21)" ></div></body></html>