714 lines
53 KiB
HTML
714 lines
53 KiB
HTML
|
|
|||
|
<!DOCTYPE html>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<html lang="en">
|
|||
|
<head>
|
|||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|||
|
|
|||
|
<title>2.7. Events and Signals — Computer Systems Fundamentals</title>
|
|||
|
|
|||
|
<link rel="stylesheet" href="_static/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous" />
|
|||
|
<link rel="stylesheet" href="_static/css/pygments.css" type="text/css" />
|
|||
|
<link rel="stylesheet" href="_static/css/normalize.css" type="text/css" />
|
|||
|
<link rel="stylesheet" href="../../../JSAV/css/JSAV.css" type="text/css" />
|
|||
|
<link rel="stylesheet" href="../../../lib/odsaMOD-min.css" type="text/css" />
|
|||
|
<link rel="stylesheet" href="_static/css/jquery-1.11.4-smoothness-ui.css" type="text/css" />
|
|||
|
<link rel="stylesheet" href="../../../lib/odsaStyle-min.css" type="text/css" />
|
|||
|
<link rel="stylesheet" href="_static/css/csf.css" type="text/css" />
|
|||
|
|
|||
|
<style>
|
|||
|
.underline { text-decoration: underline; }
|
|||
|
</style>
|
|||
|
|
|||
|
<script type="text/javascript">
|
|||
|
var DOCUMENTATION_OPTIONS = {
|
|||
|
URL_ROOT: './',
|
|||
|
VERSION: '0.4.1',
|
|||
|
COLLAPSE_INDEX: false,
|
|||
|
FILE_SUFFIX: '.html',
|
|||
|
HAS_SOURCE: true
|
|||
|
};
|
|||
|
</script>
|
|||
|
|
|||
|
<script type="text/x-mathjax-config">
|
|||
|
MathJax.Hub.Config({
|
|||
|
tex2jax: {
|
|||
|
inlineMath: [['$','$'], ['\\(','\\)']],
|
|||
|
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
|
|||
|
processEscapes: true
|
|||
|
},
|
|||
|
"HTML-CSS": {
|
|||
|
scale: "80"
|
|||
|
}
|
|||
|
});
|
|||
|
</script>
|
|||
|
<link rel="shortcut icon" href="_static/favicon.ico"/>
|
|||
|
<link rel="index" title="Index" href="genindex.html" />
|
|||
|
<link rel="search" title="Search" href="search.html" />
|
|||
|
<link rel="index" title="Computer Systems Fundamentals" href="index.html" />
|
|||
|
<link rel="next" title="8. Extended Example: Listing Files with Processes" href="Extended2Processes.html" />
|
|||
|
<link rel="prev" title="6. The UNIX File Abstraction" href="UnixFile.html" />
|
|||
|
|
|||
|
</head><body>
|
|||
|
|
|||
|
<nav class="navbar navbar-expand-md navbar-dark navbar-custom fixed-top">
|
|||
|
|
|||
|
<a class="navbar-brand py-0" href="index.html"><img src="_static/CSF-Logo-Square-Text.png" alt="OpenCSF Logo" height="40em" class="py-1 px-2 mb-0 align-center rounded-lg bg-white" /></a>
|
|||
|
<!-- Show a navbar toggler on mobile -->
|
|||
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#defaultNavbars" aria-controls="defaultNavbars" aria-expanded="false" aria-label="Toggle navigation">
|
|||
|
<span class="navbar-toggler-icon"></span>
|
|||
|
</button>
|
|||
|
<div class="collapse navbar-collapse" id="defaultNavbars">
|
|||
|
<ul class="navbar-nav mr-auto">
|
|||
|
<li class="nav-item dropdown">
|
|||
|
<a class="nav-link dropdown-toggle jmu-gold rounded" href="EventsSignals.html#" id="navbarDropdownChapters" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Contents</a>
|
|||
|
<div class="dropdown-menu scrollable-menu" role="menu" aria-labelledby="navbarDropdownChapters">
|
|||
|
<a class="dropdown-item" tabindex="-1" href="EventsSignals.html#"><b>Chapter 1</b></a>
|
|||
|
<a class="dropdown-item" href="IntroConcSysOverview.html"> 1.1. Introduction to Concurrent Systems</a>
|
|||
|
<a class="dropdown-item" href="SysAndModels.html"> 1.2. Systems and Models</a>
|
|||
|
<a class="dropdown-item" href="Themes.html"> 1.3. Themes and Guiding Principles</a>
|
|||
|
<a class="dropdown-item" href="Architectures.html"> 1.4. System Architectures</a>
|
|||
|
<a class="dropdown-item" href="StateModels.html"> 1.5. State Models in UML</a>
|
|||
|
<a class="dropdown-item" href="SequenceModels.html"> 1.6. Sequence Models in UML</a>
|
|||
|
<a class="dropdown-item" href="StateModelImplementation.html"> 1.7. Extended Example: State Model Implementation</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 2</b></a>
|
|||
|
<a class="dropdown-item" href="ProcessesOverview.html"> 2.1. Processes and OS Basics</a>
|
|||
|
<a class="dropdown-item" href="Multiprogramming.html"> 2.2. Processes and Multiprogramming</a>
|
|||
|
<a class="dropdown-item" href="KernelMechanics.html"> 2.3. Kernel Mechanics</a>
|
|||
|
<a class="dropdown-item" href="Syscall.html"> 2.4. System Call Interface</a>
|
|||
|
<a class="dropdown-item" href="ProcessCycle.html"> 2.5. Process Life Cycle</a>
|
|||
|
<a class="dropdown-item" href="UnixFile.html"> 2.6. The UNIX File Abstraction</a>
|
|||
|
<a class="dropdown-item" href="EventsSignals.html"> 2.7. Events and Signals</a>
|
|||
|
<a class="dropdown-item" href="Extended2Processes.html"> 2.8. Extended Example: Listing Files with Processes</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 3</b></a>
|
|||
|
<a class="dropdown-item" href="IPCOverview.html"> 3.1. Concurrency with IPC</a>
|
|||
|
<a class="dropdown-item" href="IPCModels.html"> 3.2. IPC Models</a>
|
|||
|
<a class="dropdown-item" href="Pipes.html"> 3.3. Pipes and FIFOs</a>
|
|||
|
<a class="dropdown-item" href="MMap.html"> 3.4. Shared Memory With Memory-mapped Files</a>
|
|||
|
<a class="dropdown-item" href="POSIXvSysV.html"> 3.5. POSIX vs. System V IPC</a>
|
|||
|
<a class="dropdown-item" href="MQueues.html"> 3.6. Message Passing With Message Queues</a>
|
|||
|
<a class="dropdown-item" href="ShMem.html"> 3.7. Shared Memory</a>
|
|||
|
<a class="dropdown-item" href="IPCSems.html"> 3.8. Semaphores</a>
|
|||
|
<a class="dropdown-item" href="Extended3Bash.html"> 3.9. Extended Example: Bash-lite: A Simple Command-line Shell</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 4</b></a>
|
|||
|
<a class="dropdown-item" href="SocketsOverview.html"> 4.1. Networked Concurrency</a>
|
|||
|
<a class="dropdown-item" href="FiveLayer.html"> 4.2. The TCP/IP Internet Model</a>
|
|||
|
<a class="dropdown-item" href="NetApps.html"> 4.3. Network Applications and Protocols</a>
|
|||
|
<a class="dropdown-item" href="Sockets.html"> 4.4. The Socket Interface</a>
|
|||
|
<a class="dropdown-item" href="TCPSockets.html"> 4.5. TCP Socket Programming: HTTP</a>
|
|||
|
<a class="dropdown-item" href="UDPSockets.html"> 4.6. UDP Socket Programming: DNS</a>
|
|||
|
<a class="dropdown-item" href="AppBroadcast.html"> 4.7. Application-Layer Broadcasting: DHCP</a>
|
|||
|
<a class="dropdown-item" href="Extended4CGI.html"> 4.8. Extended Example: CGI Web Server</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 5</b></a>
|
|||
|
<a class="dropdown-item" href="InternetOverview.html"> 5.1. The Internet and Connectivity</a>
|
|||
|
<a class="dropdown-item" href="AppLayer.html"> 5.2. Application Layer: Overlay Networks</a>
|
|||
|
<a class="dropdown-item" href="TransLayer.html"> 5.3. Transport Layer</a>
|
|||
|
<a class="dropdown-item" href="NetSec.html"> 5.4. Network Security Fundamentals</a>
|
|||
|
<a class="dropdown-item" href="NetLayer.html"> 5.5. Network Layer: IP</a>
|
|||
|
<a class="dropdown-item" href="LinkLayer.html"> 5.6. Link Layer</a>
|
|||
|
<a class="dropdown-item" href="Wireless.html"> 5.7. Wireless Connectivity: Wi-Fi, Bluetooth, and Zigbee</a>
|
|||
|
<a class="dropdown-item" href="Extended5DNS.html"> 5.8. Extended Example: DNS client</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 6</b></a>
|
|||
|
<a class="dropdown-item" href="ThreadsOverview.html"> 6.1. Concurrency with Multithreading</a>
|
|||
|
<a class="dropdown-item" href="ProcVThreads.html"> 6.2. Processes vs. Threads</a>
|
|||
|
<a class="dropdown-item" href="RaceConditions.html"> 6.3. Race Conditions and Critical Sections</a>
|
|||
|
<a class="dropdown-item" href="POSIXThreads.html"> 6.4. POSIX Thread Library</a>
|
|||
|
<a class="dropdown-item" href="ThreadArgs.html"> 6.5. Thread Arguments and Return Values</a>
|
|||
|
<a class="dropdown-item" href="ImplicitThreads.html"> 6.6. Implicit Threading and Language-based Threads</a>
|
|||
|
<a class="dropdown-item" href="Extended6Input.html"> 6.7. Extended Example: Keyboard Input Listener</a>
|
|||
|
<a class="dropdown-item" href="Extended6Primes.html"> 6.8. Extended Example: Concurrent Prime Number Search</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 7</b></a>
|
|||
|
<a class="dropdown-item" href="SynchOverview.html"> 7.1. Synchronization Primitives</a>
|
|||
|
<a class="dropdown-item" href="CritSect.html"> 7.2. Critical Sections and Peterson's Solution</a>
|
|||
|
<a class="dropdown-item" href="Locks.html"> 7.3. Locks</a>
|
|||
|
<a class="dropdown-item" href="Semaphores.html"> 7.4. Semaphores</a>
|
|||
|
<a class="dropdown-item" href="Barriers.html"> 7.5. Barriers</a>
|
|||
|
<a class="dropdown-item" href="Condvars.html"> 7.6. Condition Variables</a>
|
|||
|
<a class="dropdown-item" href="Deadlock.html"> 7.7. Deadlock</a>
|
|||
|
<a class="dropdown-item" href="Extended7Events.html"> 7.8. Extended Example: Event Log File</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 8</b></a>
|
|||
|
<a class="dropdown-item" href="SynchProblemsOverview.html"> 8.1. Synchronization Patterns and Problems</a>
|
|||
|
<a class="dropdown-item" href="SynchDesign.html"> 8.2. Basic Synchronization Design Patterns</a>
|
|||
|
<a class="dropdown-item" href="ProdCons.html"> 8.3. Producer-Consumer Problem</a>
|
|||
|
<a class="dropdown-item" href="ReadWrite.html"> 8.4. Readers-Writers Problem</a>
|
|||
|
<a class="dropdown-item" href="DiningPhil.html"> 8.5. Dining Philosophers Problem and Deadlock</a>
|
|||
|
<a class="dropdown-item" href="CigSmokers.html"> 8.6. Cigarette Smokers Problem and the Limits of Semaphores and Locks</a>
|
|||
|
<a class="dropdown-item" href="Extended8ModExp.html"> 8.7. Extended Example: Parallel Modular Exponentiation</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 9</b></a>
|
|||
|
<a class="dropdown-item" href="ParallelDistributedOverview.html"> 9.1. Parallel and Distributed Systems</a>
|
|||
|
<a class="dropdown-item" href="ParVConc.html"> 9.2. Parallelism vs. Concurrency</a>
|
|||
|
<a class="dropdown-item" href="ParallelDesign.html"> 9.3. Parallel Design Patterns</a>
|
|||
|
<a class="dropdown-item" href="Scaling.html"> 9.4. Limits of Parallelism and Scaling</a>
|
|||
|
<a class="dropdown-item" href="DistTiming.html"> 9.5. Timing in Distributed Environments</a>
|
|||
|
<a class="dropdown-item" href="DistDataStorage.html"> 9.6. Reliable Data Storage and Location</a>
|
|||
|
<a class="dropdown-item" href="DistConsensus.html"> 9.7. Consensus in Distributed Systems</a>
|
|||
|
<a class="dropdown-item" href="Extended9Blockchain.html"> 9.8. Extended Example: Blockchain Proof-of-Work</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Appendix A</b></a>
|
|||
|
<a class="dropdown-item" href="CLangOverview.html"> A.1. C Language Reintroduction</a>
|
|||
|
<a class="dropdown-item" href="Debugging.html"> A.2. Documentation and Debugging</a>
|
|||
|
<a class="dropdown-item" href="BasicTypes.html"> A.3. Basic Types and Pointers</a>
|
|||
|
<a class="dropdown-item" href="Arrays.html"> A.4. Arrays, Structs, Enums, and Type Definitions</a>
|
|||
|
<a class="dropdown-item" href="Functions.html"> A.5. Functions and Scope</a>
|
|||
|
<a class="dropdown-item" href="Pointers.html"> A.6. Pointers and Dynamic Allocation</a>
|
|||
|
<a class="dropdown-item" href="Strings.html"> A.7. Strings</a>
|
|||
|
<a class="dropdown-item" href="FunctionPointers.html"> A.8. Function Pointers</a>
|
|||
|
<a class="dropdown-item" href="Files.html"> A.9. Files</a>
|
|||
|
</div>
|
|||
|
</li>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
</ul>
|
|||
|
</div>
|
|||
|
|
|||
|
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
|||
|
<li class="nav-item"><a class="nav-link jmu-gold" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/source/EventsSignals.rst"
|
|||
|
target="_blank" rel="nofollow">Show Source</a></li>
|
|||
|
|
|||
|
</ul>
|
|||
|
</nav>
|
|||
|
|
|||
|
|
|||
|
<div class="container center">
|
|||
|
«  <a id="prevmod" href="UnixFile.html">2.6. The UNIX File Abstraction</a>
|
|||
|
  ::  
|
|||
|
<a class="uplink" href="index.html">Contents</a>
|
|||
|
  ::  
|
|||
|
<a id="nextmod" href="Extended2Processes.html">2.8. Extended Example: Listing Files with Processes</a>  »
|
|||
|
|
|||
|
</div>
|
|||
|
<br />
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<script type="text/javascript" src="_static/js/jquery-2.1.4.min.js"></script>
|
|||
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
|||
|
<script type="text/javascript" src="_static/js/jquery-1.11.4-ui.min.js"></script>
|
|||
|
<script type="text/javascript" src="_static/js/forge-0.7.0.min.js"></script>
|
|||
|
<script type="text/javascript" src="../../../JSAV/lib/jquery.transit.js"></script>
|
|||
|
<script type="text/javascript" src="../../../JSAV/lib/raphael.js"></script>
|
|||
|
<script type="text/javascript" src="../../../JSAV/build/JSAV-min.js"></script>
|
|||
|
<script type="text/javascript" src="_static/js/config.js"></script>
|
|||
|
<script type="text/javascript" src="../../../lib/odsaUtils-min.js"></script>
|
|||
|
<script type="text/javascript" src="../../../lib/odsaMOD-min.js"></script>
|
|||
|
<script type="text/javascript" src="_static/js/d3-4.13.0.min.js"></script>
|
|||
|
<script type="text/javascript" src="_static/js/d3-selection-multi.v1.min.js"></script>
|
|||
|
<script type="text/javascript" src="../../../lib/dataStructures.js"></script>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<div class="container">
|
|||
|
|
|||
|
<script>ODSA.SETTINGS.DISP_MOD_COMP = true;ODSA.SETTINGS.MODULE_NAME = "EventsSignals";ODSA.SETTINGS.MODULE_LONG_NAME = "Events and Signals";ODSA.SETTINGS.MODULE_CHAPTER = "Processes and OS Basics"; ODSA.SETTINGS.BUILD_DATE = "2021-10-29 12:02:09"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="events-and-signals">
|
|||
|
<h1>2.7. Events and Signals<a class="headerlink" href="EventsSignals.html#events-and-signals" title="Permalink to this headline">¶</a></h1>
|
|||
|
<p>In between the creation and destruction of the process, a number of other events can occur that may
|
|||
|
or may not be expected. For instance, the program may require user input from the keyboard, or it
|
|||
|
may try to read data from a file. When these requests are made, the process may be put into a
|
|||
|
<a class="reference internal" href="Glossary.html#term-blocked-state"><span class="xref std std-term">blocked state</span></a> until the requested input data is available. When that input data is provided,
|
|||
|
the process will then resume. Similarly, an external user or the kernel itself might force the
|
|||
|
process to enter a <a class="reference internal" href="Glossary.html#term-suspended-state"><span class="xref std std-term">suspended state</span></a> for an indefinite time period. For instance, maybe the
|
|||
|
machine is overloaded and slow, so a system administrator intervenes to pause some processes temporarily.</p>
|
|||
|
<p>Blocking, suspending, and resuming processes all correspond to the abstract notion of a process life
|
|||
|
cycle event. Other events can occur that do not necessarily cause a change in the process state
|
|||
|
(e.g., the process can ignore the event and continue running). Here, we’ll look at code for creating
|
|||
|
processes and handling these events using <a class="reference internal" href="Glossary.html#term-signal"><span class="xref std std-term">signals</span></a>.</p>
|
|||
|
<div class="section" id="sending-process-signals">
|
|||
|
<h2>2.7.1. Sending Process Signals<a class="headerlink" href="EventsSignals.html#sending-process-signals" title="Permalink to this headline">¶</a></h2>
|
|||
|
<p>If you have been working with the command line for a while, there is a good chance that you have
|
|||
|
used signals without realizing it. When a process gets stuck (e.g., in an infinite loop), you might
|
|||
|
have hit <code class="docutils literal notranslate"><span class="pre">Ctrl-c</span></code> to kill the process. Or if you knew the PID, you may have executed <code class="docutils literal notranslate"><span class="pre">kill</span> <span class="pre">-9</span></code>
|
|||
|
on the PID or even <code class="docutils literal notranslate"><span class="pre">killall</span></code> with the name of the program. In all of these cases, bash sent a
|
|||
|
signal to the killed process that caused the process to terminate.</p>
|
|||
|
<p>Signals can be identified by either their name or their number. From the command line, you can send
|
|||
|
a signal using the <code class="docutils literal notranslate"><span class="pre">kill</span></code> utility with either the signal name or the associated number. For
|
|||
|
instance, the following command would send <code class="docutils literal notranslate"><span class="pre">SIGKILL</span></code> to process number 12345:</p>
|
|||
|
<div class="highlight-none border border-dark rounded-lg bg-light px-2 mb-3 notranslate"><div class="highlight bg-light"><pre class="mb-0"><span></span>$ kill -KILL 12345
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>This command is identical to calling <code class="docutils literal notranslate"><span class="pre">kill</span> <span class="pre">-9</span> <span class="pre">12345</span></code>, because <code class="docutils literal notranslate"><span class="pre">SIGKILL</span></code> is signal 9 in POSIX
|
|||
|
systems. One thing to note about using the <code class="docutils literal notranslate"><span class="pre">kill</span></code> utility is that the <code class="docutils literal notranslate"><span class="pre">"SIG"</span></code> part of the name
|
|||
|
is omitted. You can observe this in the previous example, where we used the <code class="docutils literal notranslate"><span class="pre">-KILL</span></code> argument to
|
|||
|
specify the <code class="docutils literal notranslate"><span class="pre">SIGKILL</span></code> signal. <a class="reference external" href="EventsSignals.html#tbl2-4">Table 2.4</a> describes some common signals. Note that the
|
|||
|
signal numbers shown are for x86 and ARM architectures (and most others). Some CPU architectures,
|
|||
|
such as Alpha and MIPS, use different numbers for some of these. Because of these variations, it
|
|||
|
is generally preferred to use the signal name rather than the number.</p>
|
|||
|
<center>
|
|||
|
<div class="col-10">
|
|||
|
<table class="table table-bordered">
|
|||
|
<thead class="jmu-dark-purple-bg text-light">
|
|||
|
<tr>
|
|||
|
<th class="py-0 center">Name</th>
|
|||
|
<th class="py-0 center">Number</th>
|
|||
|
<th class="py-0 center">Description</th>
|
|||
|
</tr>
|
|||
|
</thead>
|
|||
|
<tbody>
|
|||
|
<tr>
|
|||
|
<td class="py-0 center"><code>SIGINT</code></td>
|
|||
|
<td class="py-0 center">2</td>
|
|||
|
<td class="py-0">Interrupts the process, generally killing it. Typically sent with <code>Ctrl-c</code>.</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0 center"><code>SIGKILL</code></td>
|
|||
|
<td class="py-0 center">9</td>
|
|||
|
<td class="py-0">Kills the process. Cannot be ignored or overwritten.</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0 center"><code>SIGSEGV</code></td>
|
|||
|
<td class="py-0 center">11</td>
|
|||
|
<td class="py-0">Sent to a process when it experiences a segmentation fault.</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0 center"><code>SIGCHLD</code></td>
|
|||
|
<td class="py-0 center">17</td>
|
|||
|
<td class="py-0">Sent to a parent when a child process finishes. Used by <code>wait()</code>.</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0 center"><code>SIGSTOP</code></td>
|
|||
|
<td class="py-0 center">19</td>
|
|||
|
<td class="py-0">Suspends the process. Cannot be ignored or overwritten.</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0 center"><code>SIGTSTP</code></td>
|
|||
|
<td class="py-0 center">20</td>
|
|||
|
<td class="py-0">Suspends the process. Typically sent with <code>Ctrl-z</code>.</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0 center"><code>SIGCONT</code></td>
|
|||
|
<td class="py-0 center">18</td>
|
|||
|
<td class="py-0">Resumes a suspended process.</td>
|
|||
|
</tr>
|
|||
|
</tbody>
|
|||
|
</table>
|
|||
|
<p>Table 2.4: Common POSIX signals, their numbers (on x86 and ARM architectures), and their effects</p>
|
|||
|
</div>
|
|||
|
</center><p>As described in the table, <code class="docutils literal notranslate"><span class="pre">SIGINT</span></code> and <code class="docutils literal notranslate"><span class="pre">SIGKILL</span></code> serve essentially the same purpose, as do
|
|||
|
<code class="docutils literal notranslate"><span class="pre">SIGSTOP</span></code> and <code class="docutils literal notranslate"><span class="pre">SIGTSTP</span></code>. The difference is that programs can implement custom handlers for
|
|||
|
<code class="docutils literal notranslate"><span class="pre">SIGINT</span></code> and <code class="docutils literal notranslate"><span class="pre">SIGTSTP</span></code>, possibly even ignoring them. The reason for this is that the application
|
|||
|
may be in the middle of some critical task that cannot wait. For example, the process may be
|
|||
|
half-way completed with writing data to a file; a custom signal handler may allow the process to
|
|||
|
finish writing the file before exiting. <code class="docutils literal notranslate"><span class="pre">SIGKILL</span></code> and <code class="docutils literal notranslate"><span class="pre">SIGSTOP</span></code> cannot be overwritten, and these
|
|||
|
signals will kill or suspend the process immediately.</p>
|
|||
|
<p>The <code class="docutils literal notranslate"><span class="pre">SIGCONT</span></code> signal can be used to resume a process that has been suspended with either
|
|||
|
<code class="docutils literal notranslate"><span class="pre">SIGSTOP</span></code> or <code class="docutils literal notranslate"><span class="pre">SIGTSTP</span></code>. For instance, you may start a program on the command line, then wish to
|
|||
|
make it run in the background. You could use <code class="docutils literal notranslate"><span class="pre">Ctrl-z</span></code> to send <code class="docutils literal notranslate"><span class="pre">SIGTSTP</span></code>, suspending the process;
|
|||
|
then, use the <code class="docutils literal notranslate"><span class="pre">bg</span></code> command to send <code class="docutils literal notranslate"><span class="pre">SIGCONT</span></code>, resuming the process in the background. Similarly,
|
|||
|
<code class="docutils literal notranslate"><span class="pre">fg</span></code> would send <code class="docutils literal notranslate"><span class="pre">SIGCONT</span></code>, but resume the process in the foreground.</p>
|
|||
|
<p>The default behavior for C programs is to respond to <code class="docutils literal notranslate"><span class="pre">SIGSEGV</span></code> by printing a message that a
|
|||
|
segmentation fault occurred and then exit. A program can include a custom signal handler to respond
|
|||
|
to segmentation faults differently. As an example, this is how debuggers (e.g., <code class="docutils literal notranslate"><span class="pre">gdb</span></code>) detect
|
|||
|
segmentation faults. Instead of killing the process, the debugger pauses it, allowing the user to
|
|||
|
run the <code class="docutils literal notranslate"><span class="pre">backtrace</span></code> utility to determine what line of code caused the fault.</p>
|
|||
|
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
|||
|
<div class="figure align-left">
|
|||
|
<a class="reference internal image-reference" href="_images/CSF-Images-Library.png"><img alt="Decorative C library image" src="_images/CSF-Images-Library.png" style="width: 100%;" /></a>
|
|||
|
</div>
|
|||
|
<p class="topic-title first pt-2 mb-1">C library functions – <signal.h></p><hr class="mt-1" />
|
|||
|
<dl class="docutils">
|
|||
|
<dt><code class="docutils literal notranslate"><span class="pre">int kill(pid_t pid, int sig);</span></code></dt>
|
|||
|
<dd>Send a signal to another process.</dd>
|
|||
|
</dl>
|
|||
|
</div>
|
|||
|
<p>The <code class="docutils literal notranslate"><span class="pre">SIGCHLD</span></code> signal gets sent to a process whenever any of its children terminate. The
|
|||
|
<code class="docutils literal notranslate"><span class="pre">waitpid()</span></code> library function includes a custom signal handler that checks if the terminated
|
|||
|
process matches the one that the parent was waiting on. If not, the parent would suspend itself
|
|||
|
again. Similarly, <code class="docutils literal notranslate"><span class="pre">wait()</span></code> includes a signal handler to determine if all of the process’s children
|
|||
|
have completed.</p>
|
|||
|
<p><a class="reference external" href="EventsSignals.html#cl2-18">Code Listing 2.18</a> shows how to use <code class="docutils literal notranslate"><span class="pre">kill()</span></code> to send a signal from inside a program. Since
|
|||
|
<code class="docutils literal notranslate"><span class="pre">fork()</span></code> returns 0 to the child process, only the child will enter the infinite loop on line 15.
|
|||
|
The parent process would skip over this and execute the call to <code class="docutils literal notranslate"><span class="pre">kill()</span></code> on line 20. Note that the
|
|||
|
timing of the two processes does not matter here. Without the <code class="docutils literal notranslate"><span class="pre">sleep()</span></code> on line 18, the parent
|
|||
|
would kill the child before it had a chance to run; adding the <code class="docutils literal notranslate"><span class="pre">sleep()</span></code> gives both a chance to
|
|||
|
print the message on line 7. Since the child is killed while running on line 15, only the parent
|
|||
|
will print the message on line 21.</p>
|
|||
|
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl2-18"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11
|
|||
|
12
|
|||
|
13
|
|||
|
14
|
|||
|
15
|
|||
|
16
|
|||
|
17
|
|||
|
18
|
|||
|
19
|
|||
|
20
|
|||
|
21</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code listing 2.18:</span>
|
|||
|
<span class="cm"> Using the kill() function to terminate a child process in an infinite loop</span>
|
|||
|
<span class="cm"> */</span>
|
|||
|
|
|||
|
<span class="cm">/* Create a child process */</span>
|
|||
|
<span class="kt">pid_t</span> <span class="n">child_pid</span> <span class="o">=</span> <span class="n">fork</span> <span class="p">();</span>
|
|||
|
<span class="n">printf</span> <span class="p">(</span><span class="s">"Process %d is running</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">getpid</span> <span class="p">());</span>
|
|||
|
|
|||
|
<span class="cm">/* Exit if the fork fails to create a process */</span>
|
|||
|
<span class="k">if</span> <span class="p">(</span><span class="n">child_pid</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span>
|
|||
|
<span class="n">exit</span> <span class="p">(</span><span class="mi">1</span><span class="p">);</span>
|
|||
|
|
|||
|
<span class="cm">/* The child enters an infinite loop */</span>
|
|||
|
<span class="k">if</span> <span class="p">(</span><span class="n">child_pid</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
|
|||
|
<span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">;</span>
|
|||
|
|
|||
|
<span class="cm">/* Make the parent sleep so the child gets a chance to run */</span>
|
|||
|
<span class="n">sleep</span> <span class="p">(</span><span class="mi">1</span><span class="p">);</span>
|
|||
|
<span class="cm">/* The parent sends the SIGKILL signal to kill the child */</span>
|
|||
|
<span class="n">kill</span> <span class="p">(</span><span class="n">child_pid</span><span class="p">,</span> <span class="n">SIGKILL</span><span class="p">);</span>
|
|||
|
<span class="n">printf</span> <span class="p">(</span><span class="s">"Process %d is exiting</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">getpid</span> <span class="p">());</span>
|
|||
|
</pre></div>
|
|||
|
</td></tr></table></div>
|
|||
|
</div>
|
|||
|
<div class="section" id="custom-signal-handlers">
|
|||
|
<h2>2.7.2. Custom Signal Handlers<a class="headerlink" href="EventsSignals.html#custom-signal-handlers" title="Permalink to this headline">¶</a></h2>
|
|||
|
<p>To overwrite a signal handler, you start by defining a function with the desired new behavior. In
|
|||
|
the simplest form, this function must take exactly one <code class="docutils literal notranslate"><span class="pre">int</span></code> parameter and have a <code class="docutils literal notranslate"><span class="pre">void</span></code> return
|
|||
|
type. The parameter received by this function will be the specific signal that was passed. As such,
|
|||
|
it is possible to define one signal handling function and use it to respond to multiple signals.</p>
|
|||
|
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
|||
|
<div class="figure align-left">
|
|||
|
<a class="reference internal image-reference" href="_images/CSF-Images-Library.png"><img alt="Decorative C library image" src="_images/CSF-Images-Library.png" style="width: 100%;" /></a>
|
|||
|
</div>
|
|||
|
<p class="topic-title first pt-2 mb-1">C library functions – <signal.h></p><hr class="mt-1" />
|
|||
|
<dl class="docutils">
|
|||
|
<dt><code class="docutils literal notranslate"><span class="pre">int sigaction(int sig, const struct sigaction *restrict act, </span> <span class="pre">struct</span> <span class="pre">sigaction *restrict oact);</span></code></dt>
|
|||
|
<dd>Use a custom function to respond to a standard signal.</dd>
|
|||
|
</dl>
|
|||
|
</div>
|
|||
|
<p><a class="reference external" href="EventsSignals.html#cl2-19">Code Listing 2.19</a> shows how to use <code class="docutils literal notranslate"><span class="pre">sigaction()</span></code> to overwrite a signal handler. Lines 6 – 21
|
|||
|
define the behavior of the signal handler. On line 29, this function name (i.e., the address of the
|
|||
|
function) is copied into the <code class="docutils literal notranslate"><span class="pre">sa_handler</span></code> field of a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sigaction</span></code>. Line 32 successfully
|
|||
|
overwrites the <code class="docutils literal notranslate"><span class="pre">SIGINT</span></code> handler, so using <code class="docutils literal notranslate"><span class="pre">Ctrl-C</span></code> on the command line will invoke the custom
|
|||
|
<code class="docutils literal notranslate"><span class="pre">sigint_handler()</span></code> function. Line 36 will fail to overwrite the <code class="docutils literal notranslate"><span class="pre">SIGKILL</span></code> handler, as this
|
|||
|
action is not permitted. When this program is run, it can still be killed with the <code class="docutils literal notranslate"><span class="pre">kill</span> <span class="pre">-9</span></code> command.</p>
|
|||
|
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl2-19"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11
|
|||
|
12
|
|||
|
13
|
|||
|
14
|
|||
|
15
|
|||
|
16
|
|||
|
17
|
|||
|
18
|
|||
|
19
|
|||
|
20
|
|||
|
21
|
|||
|
22
|
|||
|
23
|
|||
|
24
|
|||
|
25
|
|||
|
26
|
|||
|
27
|
|||
|
28
|
|||
|
29
|
|||
|
30
|
|||
|
31
|
|||
|
32
|
|||
|
33
|
|||
|
34
|
|||
|
35
|
|||
|
36
|
|||
|
37
|
|||
|
38
|
|||
|
39
|
|||
|
40
|
|||
|
41
|
|||
|
42
|
|||
|
43</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 2.19:</span>
|
|||
|
<span class="cm"> Overwriting the SIGINT handler to overwrite Ctrl-C termination</span>
|
|||
|
<span class="cm"> */</span>
|
|||
|
|
|||
|
<span class="cm">/* Create the function for responding to signals */</span>
|
|||
|
<span class="k">static</span> <span class="kt">void</span>
|
|||
|
<span class="nf">sigint_handler</span> <span class="p">(</span><span class="kt">int</span> <span class="n">signum</span><span class="p">)</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="cm">/* Length is hard-coded at 19; write signum into spaces */</span>
|
|||
|
<span class="kt">char</span> <span class="n">buffer</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"Received signal </span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
|
|||
|
<span class="k">if</span> <span class="p">(</span><span class="n">signum</span> <span class="o"><</span> <span class="mi">10</span><span class="p">)</span>
|
|||
|
<span class="n">buffer</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="sc">'0'</span> <span class="o">+</span> <span class="n">signum</span><span class="p">;</span>
|
|||
|
<span class="k">else</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="n">buffer</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="sc">'0'</span> <span class="o">+</span> <span class="p">(</span><span class="n">signum</span> <span class="o">/</span> <span class="mi">10</span><span class="p">);</span>
|
|||
|
<span class="n">buffer</span><span class="p">[</span><span class="mi">17</span><span class="p">]</span> <span class="o">=</span> <span class="sc">'0'</span> <span class="o">+</span> <span class="p">(</span><span class="n">signum</span> <span class="o">%</span> <span class="mi">10</span><span class="p">);</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="cm">/* Must use write(), because it is asynchronous-safe */</span>
|
|||
|
<span class="n">write</span> <span class="p">(</span><span class="n">STDOUT_FILENO</span><span class="p">,</span> <span class="n">buffer</span><span class="p">,</span> <span class="mi">19</span><span class="p">);</span>
|
|||
|
<span class="n">exit</span> <span class="p">(</span><span class="mi">0</span><span class="p">);</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="kt">int</span>
|
|||
|
<span class="nf">main</span> <span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="cm">/* Create a sigaction and link it to the handler */</span>
|
|||
|
<span class="k">struct</span> <span class="n">sigaction</span> <span class="n">sa</span><span class="p">;</span>
|
|||
|
<span class="n">memset</span> <span class="p">(</span><span class="o">&</span><span class="n">sa</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">sa</span><span class="p">));</span>
|
|||
|
<span class="n">sa</span><span class="p">.</span><span class="n">sa_handler</span> <span class="o">=</span> <span class="n">sigint_handler</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="cm">/* Overwrite the SIGINT handler */</span>
|
|||
|
<span class="k">if</span> <span class="p">(</span><span class="n">sigaction</span> <span class="p">(</span><span class="n">SIGINT</span><span class="p">,</span> <span class="o">&</span><span class="n">sa</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">)</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
|
|||
|
<span class="n">printf</span> <span class="p">(</span><span class="s">"Failed to overwrite SIGINT.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
|
|||
|
|
|||
|
<span class="cm">/* Try (and fail) to overwrite SIGKILL */</span>
|
|||
|
<span class="k">if</span> <span class="p">(</span><span class="n">sigaction</span> <span class="p">(</span><span class="n">SIGKILL</span><span class="p">,</span> <span class="o">&</span><span class="n">sa</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">)</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
|
|||
|
<span class="n">printf</span> <span class="p">(</span><span class="s">"This should fail. SIGKILL cannot change.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
|
|||
|
|
|||
|
<span class="cm">/* Loop until SIGINT or SIGKILL is received */</span>
|
|||
|
<span class="n">printf</span> <span class="p">(</span><span class="s">"Entering loop</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
|
|||
|
<span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">;</span>
|
|||
|
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
</pre></div>
|
|||
|
</td></tr></table></div>
|
|||
|
<p>The call to <code class="docutils literal notranslate"><span class="pre">exit()</span></code> on line 20 is important for this example. Without this call, using <code class="docutils literal notranslate"><span class="pre">Ctrl-c</span></code>
|
|||
|
would no longer terminate the program. Each time that the <code class="docutils literal notranslate"><span class="pre">SIGINT</span></code> would be raised, the signal
|
|||
|
handler would print the message and the function would return back to what it was doing before. That
|
|||
|
is, the function would return back to the infinite loop on line 41. <strong>This is very dangerous and
|
|||
|
should not be done in regular practice</strong>. We can do so here only because our infinite loop is doing nothing.</p>
|
|||
|
<p>In more realistic code, the signal might interfere with the executing code. For instance, the
|
|||
|
interrupted code might have just set a number of registers to prepare for a function call. The
|
|||
|
signal handler might then change these values, leading to errors when the normal execution resumes.
|
|||
|
If the application must be able to return to normal execution after processing a signal, the
|
|||
|
solution is to create a non-local goto with <code class="docutils literal notranslate"><span class="pre">sigsetjmp()</span></code> and <code class="docutils literal notranslate"><span class="pre">siglongjmp()</span></code>.</p>
|
|||
|
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
|||
|
<div class="figure align-left">
|
|||
|
<a class="reference internal image-reference" href="_images/CSF-Images-Library.png"><img alt="Decorative C library image" src="_images/CSF-Images-Library.png" style="width: 100%;" /></a>
|
|||
|
</div>
|
|||
|
<p class="topic-title first pt-2 mb-1">C library functions – <sig/setjmp.h></p><hr class="mt-1" />
|
|||
|
<dl class="docutils">
|
|||
|
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">sigsetjmp(sigjmp_buf</span> <span class="pre">env,</span> <span class="pre">int</span> <span class="pre">savemask);</span></code></dt>
|
|||
|
<dd>Set jump point for a non-local goto.</dd>
|
|||
|
<dt><code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">siglongjmp(sigjmp_buf</span> <span class="pre">env,</span> <span class="pre">int</span> <span class="pre">val);</span></code></dt>
|
|||
|
<dd>Non-local goto with signal handling.</dd>
|
|||
|
</dl>
|
|||
|
</div>
|
|||
|
<p><a class="reference external" href="EventsSignals.html#cl2-20">Code Listing 2.20</a> illustrates the basic structure of non-local gotos. Assuming the signal handler is
|
|||
|
set up properly (as indicated by the comment on line 17), the call to <code class="docutils literal notranslate"><span class="pre">sigsetjmp()</span></code> on line 18
|
|||
|
creates a safe place to resume execution after handling the signal. When this function is called
|
|||
|
directly, the return value will be 0 (i.e., false); as such, the body of the if-statement will not
|
|||
|
be executed when the process first runs. The process will enter the infinite loop at line 21. Then,
|
|||
|
when the signal occurs, the <code class="docutils literal notranslate"><span class="pre">sig_handler()</span></code> will run. The call to <code class="docutils literal notranslate"><span class="pre">siglongjmp()</span></code> on line 11
|
|||
|
causes the flow of execution to return to line 18, where the target of the goto was set. However,
|
|||
|
critically, this call also changes the return value from <code class="docutils literal notranslate"><span class="pre">sigsetjmp()</span></code> to become the second value
|
|||
|
passed to <code class="docutils literal notranslate"><span class="pre">siglongjmp()</span></code>! As such, after the signal handler runs, the process will resume normal
|
|||
|
execution as if <code class="docutils literal notranslate"><span class="pre">sigsetjmp()</span></code> had returned 1 (true) and printing the message on line 19. At that
|
|||
|
point, the process would return to the infinite loop. Note that both <code class="docutils literal notranslate"><span class="pre">sigsetjmp()</span></code> and
|
|||
|
<code class="docutils literal notranslate"><span class="pre">siglongjmp()</span></code> require the same global <code class="docutils literal notranslate"><span class="pre">sigjmp_buf</span></code> variable to be connected.</p>
|
|||
|
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl2-20"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11
|
|||
|
12
|
|||
|
13
|
|||
|
14
|
|||
|
15
|
|||
|
16
|
|||
|
17
|
|||
|
18
|
|||
|
19
|
|||
|
20
|
|||
|
21
|
|||
|
22
|
|||
|
23</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 2.20:</span>
|
|||
|
<span class="cm"> Using non-local gotos with signal handling</span>
|
|||
|
<span class="cm"> */</span>
|
|||
|
|
|||
|
<span class="n">sigjmp_buf</span> <span class="n">context</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="kt">void</span>
|
|||
|
<span class="nf">sig_handler</span> <span class="p">(</span><span class="kt">int</span> <span class="n">signum</span><span class="p">)</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="cm">/* Code to process the signal is omitted */</span>
|
|||
|
<span class="n">siglongjmp</span> <span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="kt">int</span>
|
|||
|
<span class="nf">main</span> <span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="cm">/* Code to set up the signal handler is omitted */</span>
|
|||
|
<span class="k">if</span> <span class="p">(</span><span class="n">sigsetjmp</span> <span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
|
|||
|
<span class="n">printf</span> <span class="p">(</span><span class="s">"Resuming execution</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
|
|||
|
<span class="n">printf</span> <span class="p">(</span><span class="s">"Entering loop</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
|
|||
|
<span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">;</span>
|
|||
|
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
</pre></div>
|
|||
|
</td></tr></table></div>
|
|||
|
<p>The existing code has a problem, however. When a signal occurs, a bit gets set in the <em>signal
|
|||
|
mask</em> to indicate that this signal has been raised. If the signal occurs again, <strong>the signal handler
|
|||
|
will not get invoked again</strong>. Rather, signal handlers will only run when the bit in the signal mask
|
|||
|
first gets set. Consequently, if <a class="reference external" href="EventsSignals.html#cl2-20">Code Listing 2.20</a> was used to overwrite <code class="docutils literal notranslate"><span class="pre">SIGINT</span></code>, only the first
|
|||
|
<code class="docutils literal notranslate"><span class="pre">Ctrl-c</span></code> would invoke the signal handler. All additional <code class="docutils literal notranslate"><span class="pre">SIGINT</span></code>s would be ignored. The
|
|||
|
<code class="docutils literal notranslate"><span class="pre">sigprocmask()</span></code> function can fix this problem by lowering the bit in the signal mask.</p>
|
|||
|
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
|||
|
<div class="figure align-left">
|
|||
|
<a class="reference internal image-reference" href="_images/CSF-Images-Library.png"><img alt="Decorative C library image" src="_images/CSF-Images-Library.png" style="width: 100%;" /></a>
|
|||
|
</div>
|
|||
|
<p class="topic-title first pt-2 mb-1">C library functions – <setjmp.h></p><hr class="mt-1" />
|
|||
|
<dl class="docutils">
|
|||
|
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">sigaddset(sigset_t</span> <span class="pre">*set,</span> <span class="pre">int</span> <span class="pre">signo);</span></code></dt>
|
|||
|
<dd>Add a signal to a signal set.</dd>
|
|||
|
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">sigemptyset(sigset_t</span> <span class="pre">*set);</span></code></dt>
|
|||
|
<dd>Initialize an empty signal set.</dd>
|
|||
|
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">sigprocmask(int</span> <span class="pre">how,</span> <span class="pre">const</span> <span class="pre">sigset_t</span> <span class="pre">*set,</span> <span class="pre">sigset_t</span> <span class="pre">*oset);</span></code></dt>
|
|||
|
<dd>Examine and change blocked signals.</dd>
|
|||
|
</dl>
|
|||
|
</div>
|
|||
|
<p><a class="reference external" href="EventsSignals.html#cl2-21">Code Listing 2.21</a> fixes the signal handler from <a class="reference external" href="EventsSignals.html#cl2-20">Code Listing 2.20</a> by resetting the signal
|
|||
|
mask. Line 12 will clear the bit (<code class="docutils literal notranslate"><span class="pre">SIG_UNBLOCK</span></code>) in the signal mask for each signal in the set. Since lines 9
|
|||
|
– 11 create a set that contains only the signal that was being processed (i.e., because the current
|
|||
|
signal number gets passed as the <code class="docutils literal notranslate"><span class="pre">signum</span></code> argument), only the current signal will get reset. <a class="footnote-reference" href="EventsSignals.html#f16" id="id3">[1]</a>
|
|||
|
Consequently, when the normal execution would resume, the signal could be repeatedly raised.</p>
|
|||
|
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl2-21"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11
|
|||
|
12
|
|||
|
13
|
|||
|
14
|
|||
|
15</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 2.21:</span>
|
|||
|
<span class="cm"> Resetting a signal in the signal mask</span>
|
|||
|
<span class="cm"> */</span>
|
|||
|
|
|||
|
<span class="kt">void</span>
|
|||
|
<span class="nf">sig_handler</span> <span class="p">(</span><span class="kt">int</span> <span class="n">signum</span><span class="p">)</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="cm">/* Code to process the signal */</span>
|
|||
|
<span class="kt">sigset_t</span> <span class="n">set</span><span class="p">;</span>
|
|||
|
<span class="n">sigemptyset</span> <span class="p">(</span><span class="o">&</span><span class="n">set</span><span class="p">);</span>
|
|||
|
<span class="n">sigaddset</span> <span class="p">(</span><span class="o">&</span><span class="n">set</span><span class="p">,</span> <span class="n">signum</span><span class="p">);</span>
|
|||
|
<span class="n">sigprocmask</span> <span class="p">(</span><span class="n">SIG_UNBLOCK</span><span class="p">,</span> <span class="o">&</span><span class="n">set</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
|
|||
|
<span class="cm">/* Now that the signal has been cleared, do the goto */</span>
|
|||
|
<span class="n">siglongjmp</span> <span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
|
|||
|
<span class="p">}</span>
|
|||
|
</pre></div>
|
|||
|
</td></tr></table></div>
|
|||
|
<div class="topic border border-dark rounded-lg alert-danger px-2 mb-3">
|
|||
|
<div class="figure align-left">
|
|||
|
<a class="reference internal image-reference" href="_images/CSF-Images-BugWarning.png"><img alt="Decorative bug warning" src="_images/CSF-Images-BugWarning.png" style="width: 90%;" /></a>
|
|||
|
</div>
|
|||
|
<p class="topic-title first pt-2 mb-1">Bug Warning</p><hr class="mt-1" />
|
|||
|
<p>The number of functions that can be safely called from within a signal handler is very limited. For
|
|||
|
instance, you should never call <code class="docutils literal notranslate"><span class="pre">printf()</span></code> from within a signal handler. The problem is that most
|
|||
|
C functions in the standard library are not guaranteed to have well-defined behavior in an
|
|||
|
asynchronous context. To avoid bugs that arise from undefined execution timing, you should only
|
|||
|
call functions that are asynchronous-safe. The list of functions and more information can be found
|
|||
|
in CERT Secure Coding Rule SIG30-C.</p>
|
|||
|
</div>
|
|||
|
<p>There are other variations that can be used for custom signal handlers beyond what is shown here.
|
|||
|
For further information, consult the POSIX documentation for <code class="docutils literal notranslate"><span class="pre">sigaction()</span></code>. Also, note that there
|
|||
|
is an older <code class="docutils literal notranslate"><span class="pre">signal()</span></code> function that can also be used for overwriting signals. However, use of
|
|||
|
<code class="docutils literal notranslate"><span class="pre">signal()</span></code> is discouraged in the POSIX specification, and newer applications should use
|
|||
|
<code class="docutils literal notranslate"><span class="pre">sigaction()</span></code> instead.</p>
|
|||
|
<table class="docutils footnote" frame="void" id="f16" rules="none">
|
|||
|
<colgroup><col class="label" /><col /></colgroup>
|
|||
|
<tbody valign="top">
|
|||
|
<tr><td class="label"><a class="fn-backref" href="EventsSignals.html#id3">[1]</a></td><td>Note that other signals could be added to this set; if those other signals were currently
|
|||
|
waiting to be handled, the call to <code class="docutils literal notranslate"><span class="pre">sigprocmask()</span></code> would clear them and their handlers would not be invoked.</td></tr>
|
|||
|
</tbody>
|
|||
|
</table>
|
|||
|
<div
|
|||
|
id="ProcSigSumm"
|
|||
|
class="embedContainer"
|
|||
|
data-exer-name="ProcSigSumm"
|
|||
|
data-long-name="Signals questions"
|
|||
|
data-short-name="ProcSigSumm"
|
|||
|
data-frame-src="../../../Exercises/Processes/ProcSigSumm.html?selfLoggingEnabled=false&localMode=true&module=EventsSignals&JXOP-debug=true&JOP-lang=en&JXOP-code=java"
|
|||
|
data-frame-width="950"
|
|||
|
data-frame-height="550"
|
|||
|
data-external="false"
|
|||
|
data-points="1.0"
|
|||
|
data-required="True"
|
|||
|
data-showhide="show"
|
|||
|
data-threshold="3"
|
|||
|
data-type="ka"
|
|||
|
data-exer-id="">
|
|||
|
|
|||
|
<div class="center">
|
|||
|
<div id="ProcSigSumm_iframe"></div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<div class="container">
|
|||
|
|
|||
|
<div class="mt-4 container center">
|
|||
|
«  <a id="prevmod1" href="UnixFile.html">2.6. The UNIX File Abstraction</a>
|
|||
|
  ::  
|
|||
|
<a class="uplink" href="index.html">Contents</a>
|
|||
|
  ::  
|
|||
|
<a id="nextmod1" href="Extended2Processes.html">2.8. Extended Example: Listing Files with Processes</a>  »
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
</div>
|
|||
|
|
|||
|
<br />
|
|||
|
|
|||
|
<div class="row jmu-dark-purple-bg">
|
|||
|
<div class="col-md-12">
|
|||
|
<center>
|
|||
|
<a id="contact_us" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="mailto:webmaster@opencsf.org" role="button">Contact Us</a>
|
|||
|
<a id="license" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/lib/license.html" target="_blank">License</a>
|
|||
|
</center>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<script src="_static/js/popper.js-1.14.7-min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
|||
|
<script src="_static/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
|||
|
</body>
|
|||
|
</html>
|