1
0
Fork 0
cl-sites/w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/html/Pipes.html
2025-01-28 10:11:14 +01:00

891 lines
No EOL
66 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>3.3. Pipes and FIFOs &mdash; 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="4. Shared Memory With Memory-mapped Files" href="MMap.html" />
<link rel="prev" title="2. IPC Models" href="IPCModels.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="Pipes.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="Pipes.html#"><b>Chapter 1</b></a>
<a class="dropdown-item" href="IntroConcSysOverview.html">&nbsp;&nbsp;&nbsp;1.1. Introduction to Concurrent Systems</a>
<a class="dropdown-item" href="SysAndModels.html">&nbsp;&nbsp;&nbsp;1.2. Systems and Models</a>
<a class="dropdown-item" href="Themes.html">&nbsp;&nbsp;&nbsp;1.3. Themes and Guiding Principles</a>
<a class="dropdown-item" href="Architectures.html">&nbsp;&nbsp;&nbsp;1.4. System Architectures</a>
<a class="dropdown-item" href="StateModels.html">&nbsp;&nbsp;&nbsp;1.5. State Models in UML</a>
<a class="dropdown-item" href="SequenceModels.html">&nbsp;&nbsp;&nbsp;1.6. Sequence Models in UML</a>
<a class="dropdown-item" href="StateModelImplementation.html">&nbsp;&nbsp;&nbsp;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">&nbsp;&nbsp;&nbsp;2.1. Processes and OS Basics</a>
<a class="dropdown-item" href="Multiprogramming.html">&nbsp;&nbsp;&nbsp;2.2. Processes and Multiprogramming</a>
<a class="dropdown-item" href="KernelMechanics.html">&nbsp;&nbsp;&nbsp;2.3. Kernel Mechanics</a>
<a class="dropdown-item" href="Syscall.html">&nbsp;&nbsp;&nbsp;2.4. System Call Interface</a>
<a class="dropdown-item" href="ProcessCycle.html">&nbsp;&nbsp;&nbsp;2.5. Process Life Cycle</a>
<a class="dropdown-item" href="UnixFile.html">&nbsp;&nbsp;&nbsp;2.6. The UNIX File Abstraction</a>
<a class="dropdown-item" href="EventsSignals.html">&nbsp;&nbsp;&nbsp;2.7. Events and Signals</a>
<a class="dropdown-item" href="Extended2Processes.html">&nbsp;&nbsp;&nbsp;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">&nbsp;&nbsp;&nbsp;3.1. Concurrency with IPC</a>
<a class="dropdown-item" href="IPCModels.html">&nbsp;&nbsp;&nbsp;3.2. IPC Models</a>
<a class="dropdown-item" href="Pipes.html">&nbsp;&nbsp;&nbsp;3.3. Pipes and FIFOs</a>
<a class="dropdown-item" href="MMap.html">&nbsp;&nbsp;&nbsp;3.4. Shared Memory With Memory-mapped Files</a>
<a class="dropdown-item" href="POSIXvSysV.html">&nbsp;&nbsp;&nbsp;3.5. POSIX vs. System V IPC</a>
<a class="dropdown-item" href="MQueues.html">&nbsp;&nbsp;&nbsp;3.6. Message Passing With Message Queues</a>
<a class="dropdown-item" href="ShMem.html">&nbsp;&nbsp;&nbsp;3.7. Shared Memory</a>
<a class="dropdown-item" href="IPCSems.html">&nbsp;&nbsp;&nbsp;3.8. Semaphores</a>
<a class="dropdown-item" href="Extended3Bash.html">&nbsp;&nbsp;&nbsp;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">&nbsp;&nbsp;&nbsp;4.1. Networked Concurrency</a>
<a class="dropdown-item" href="FiveLayer.html">&nbsp;&nbsp;&nbsp;4.2. The TCP/IP Internet Model</a>
<a class="dropdown-item" href="NetApps.html">&nbsp;&nbsp;&nbsp;4.3. Network Applications and Protocols</a>
<a class="dropdown-item" href="Sockets.html">&nbsp;&nbsp;&nbsp;4.4. The Socket Interface</a>
<a class="dropdown-item" href="TCPSockets.html">&nbsp;&nbsp;&nbsp;4.5. TCP Socket Programming: HTTP</a>
<a class="dropdown-item" href="UDPSockets.html">&nbsp;&nbsp;&nbsp;4.6. UDP Socket Programming: DNS</a>
<a class="dropdown-item" href="AppBroadcast.html">&nbsp;&nbsp;&nbsp;4.7. Application-Layer Broadcasting: DHCP</a>
<a class="dropdown-item" href="Extended4CGI.html">&nbsp;&nbsp;&nbsp;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">&nbsp;&nbsp;&nbsp;5.1. The Internet and Connectivity</a>
<a class="dropdown-item" href="AppLayer.html">&nbsp;&nbsp;&nbsp;5.2. Application Layer: Overlay Networks</a>
<a class="dropdown-item" href="TransLayer.html">&nbsp;&nbsp;&nbsp;5.3. Transport Layer</a>
<a class="dropdown-item" href="NetSec.html">&nbsp;&nbsp;&nbsp;5.4. Network Security Fundamentals</a>
<a class="dropdown-item" href="NetLayer.html">&nbsp;&nbsp;&nbsp;5.5. Network Layer: IP</a>
<a class="dropdown-item" href="LinkLayer.html">&nbsp;&nbsp;&nbsp;5.6. Link Layer</a>
<a class="dropdown-item" href="Wireless.html">&nbsp;&nbsp;&nbsp;5.7. Wireless Connectivity: Wi-Fi, Bluetooth, and Zigbee</a>
<a class="dropdown-item" href="Extended5DNS.html">&nbsp;&nbsp;&nbsp;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">&nbsp;&nbsp;&nbsp;6.1. Concurrency with Multithreading</a>
<a class="dropdown-item" href="ProcVThreads.html">&nbsp;&nbsp;&nbsp;6.2. Processes vs. Threads</a>
<a class="dropdown-item" href="RaceConditions.html">&nbsp;&nbsp;&nbsp;6.3. Race Conditions and Critical Sections</a>
<a class="dropdown-item" href="POSIXThreads.html">&nbsp;&nbsp;&nbsp;6.4. POSIX Thread Library</a>
<a class="dropdown-item" href="ThreadArgs.html">&nbsp;&nbsp;&nbsp;6.5. Thread Arguments and Return Values</a>
<a class="dropdown-item" href="ImplicitThreads.html">&nbsp;&nbsp;&nbsp;6.6. Implicit Threading and Language-based Threads</a>
<a class="dropdown-item" href="Extended6Input.html">&nbsp;&nbsp;&nbsp;6.7. Extended Example: Keyboard Input Listener</a>
<a class="dropdown-item" href="Extended6Primes.html">&nbsp;&nbsp;&nbsp;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">&nbsp;&nbsp;&nbsp;7.1. Synchronization Primitives</a>
<a class="dropdown-item" href="CritSect.html">&nbsp;&nbsp;&nbsp;7.2. Critical Sections and Peterson's Solution</a>
<a class="dropdown-item" href="Locks.html">&nbsp;&nbsp;&nbsp;7.3. Locks</a>
<a class="dropdown-item" href="Semaphores.html">&nbsp;&nbsp;&nbsp;7.4. Semaphores</a>
<a class="dropdown-item" href="Barriers.html">&nbsp;&nbsp;&nbsp;7.5. Barriers</a>
<a class="dropdown-item" href="Condvars.html">&nbsp;&nbsp;&nbsp;7.6. Condition Variables</a>
<a class="dropdown-item" href="Deadlock.html">&nbsp;&nbsp;&nbsp;7.7. Deadlock</a>
<a class="dropdown-item" href="Extended7Events.html">&nbsp;&nbsp;&nbsp;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">&nbsp;&nbsp;&nbsp;8.1. Synchronization Patterns and Problems</a>
<a class="dropdown-item" href="SynchDesign.html">&nbsp;&nbsp;&nbsp;8.2. Basic Synchronization Design Patterns</a>
<a class="dropdown-item" href="ProdCons.html">&nbsp;&nbsp;&nbsp;8.3. Producer-Consumer Problem</a>
<a class="dropdown-item" href="ReadWrite.html">&nbsp;&nbsp;&nbsp;8.4. Readers-Writers Problem</a>
<a class="dropdown-item" href="DiningPhil.html">&nbsp;&nbsp;&nbsp;8.5. Dining Philosophers Problem and Deadlock</a>
<a class="dropdown-item" href="CigSmokers.html">&nbsp;&nbsp;&nbsp;8.6. Cigarette Smokers Problem and the Limits of Semaphores and Locks</a>
<a class="dropdown-item" href="Extended8ModExp.html">&nbsp;&nbsp;&nbsp;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">&nbsp;&nbsp;&nbsp;9.1. Parallel and Distributed Systems</a>
<a class="dropdown-item" href="ParVConc.html">&nbsp;&nbsp;&nbsp;9.2. Parallelism vs. Concurrency</a>
<a class="dropdown-item" href="ParallelDesign.html">&nbsp;&nbsp;&nbsp;9.3. Parallel Design Patterns</a>
<a class="dropdown-item" href="Scaling.html">&nbsp;&nbsp;&nbsp;9.4. Limits of Parallelism and Scaling</a>
<a class="dropdown-item" href="DistTiming.html">&nbsp;&nbsp;&nbsp;9.5. Timing in Distributed Environments</a>
<a class="dropdown-item" href="DistDataStorage.html">&nbsp;&nbsp;&nbsp;9.6. Reliable Data Storage and Location</a>
<a class="dropdown-item" href="DistConsensus.html">&nbsp;&nbsp;&nbsp;9.7. Consensus in Distributed Systems</a>
<a class="dropdown-item" href="Extended9Blockchain.html">&nbsp;&nbsp;&nbsp;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">&nbsp;&nbsp;&nbsp;A.1. C Language Reintroduction</a>
<a class="dropdown-item" href="Debugging.html">&nbsp;&nbsp;&nbsp;A.2. Documentation and Debugging</a>
<a class="dropdown-item" href="BasicTypes.html">&nbsp;&nbsp;&nbsp;A.3. Basic Types and Pointers</a>
<a class="dropdown-item" href="Arrays.html">&nbsp;&nbsp;&nbsp;A.4. Arrays, Structs, Enums, and Type Definitions</a>
<a class="dropdown-item" href="Functions.html">&nbsp;&nbsp;&nbsp;A.5. Functions and Scope</a>
<a class="dropdown-item" href="Pointers.html">&nbsp;&nbsp;&nbsp;A.6. Pointers and Dynamic Allocation</a>
<a class="dropdown-item" href="Strings.html">&nbsp;&nbsp;&nbsp;A.7. Strings</a>
<a class="dropdown-item" href="FunctionPointers.html">&nbsp;&nbsp;&nbsp;A.8. Function Pointers</a>
<a class="dropdown-item" href="Files.html">&nbsp;&nbsp;&nbsp;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/Pipes.rst"
target="_blank" rel="nofollow">Show Source</a></li>
</ul>
</nav>
<div class="container center">
«&#160;&#160;<a id="prevmod" href="IPCModels.html">3.2. IPC Models</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod" href="MMap.html">3.4. Shared Memory With Memory-mapped Files</a>&#160;&#160;»
</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 = "Pipes";ODSA.SETTINGS.MODULE_LONG_NAME = "Pipes and FIFOs";ODSA.SETTINGS.MODULE_CHAPTER = "Concurrency with IPC"; ODSA.SETTINGS.BUILD_DATE = "2021-06-30 17:11:35"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="pipes-and-fifos">
<h1>3.3. Pipes and FIFOs<a class="headerlink" href="Pipes.html#pipes-and-fifos" title="Permalink to this headline"></a></h1>
<p><a class="reference internal" href="Glossary.html#term-pipe"><span class="xref std std-term">Pipes</span></a> allow processes to communicate using a unidirectional byte stream, with two
ends designated by distinct <a class="reference internal" href="Glossary.html#term-file-descriptor"><span class="xref std std-term">file descriptors</span></a>. A common visual analogy for
a pipe is a real-world water pipe; water that is poured into one end of the pipe comes out the other
end. In the case of IPC, the “water” is the sequence of bytes being sent between the processes; the
bytes are written into one end of the pipe and read from the other end. Pipes have several important
characteristics that shape their use:</p>
<blockquote>
<div><ul class="simple">
<li>Pipes are <em>unidirectional</em>; one end must be designated as the reading end and the other as
the writing end. Note that there is no restriction that different processes must read from and
write to the pipe; rather, if one process writes to a pipe then immediately reads from it, the
process will receive its own message. If two processes need to exchange messages back and forth,
they should use two pipes.</li>
<li>Pipes are <em>order preserving</em>; all data read from the receiving end of the pipe will match
the order in which it was written into the pipe. There is no way to designate some data as higher
priority to ensure it is read first.</li>
<li>Pipes have a <em>limited capacity</em> and they use <a class="reference internal" href="Glossary.html#term-blocking-i-o"><span class="xref std std-term">blocking I/O</span></a>; if a pipe is full, any
additional writes to the pipe will block the process until some of the data has been read. As such,
there is no concern that the messages will be dropped, but there may be performance delays, as the
writing process has no control over when the bytes will be removed from the pipe.</li>
<li>Pipes send data as unstructured <em>byte streams</em>. There are no pre-defined
characteristics to the data exchanged, such as a predictable message length. The processes using
the pipe must agree on a communication protocol and handle errors appropriately (such as if one of
the processes terminates the communication early).</li>
<li>Messages that are smaller than the size specified by <code class="docutils literal notranslate"><span class="pre">PIPE_BUF</span></code> are guaranteed to be sent
<a class="reference internal" href="Glossary.html#term-atomic"><span class="xref std std-term">atomically</span></a>. As such, if two processes write to a pipe at the same time, both
messages will be written correctly and they will not interfere with each other.</li>
</ul>
</div></blockquote>
<div class="section" id="basic-pipes">
<h2>3.3.1. Basic Pipes<a class="headerlink" href="Pipes.html#basic-pipes" title="Permalink to this headline"></a></h2>
<p>The simplest form of communication with pipes is to provide parent-child communication using the
<code class="docutils literal notranslate"><span class="pre">pipe()</span></code> library function. This function takes an int array of length 2. (Recall that arrays are
always passed by reference.) Assuming the kernel is able to create the pipe, the array will contain
the file descriptors for the two ends of the pipe. If the pipe creation, the function returns -1.</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 &lt;unistd.h&gt;</p><hr class="mt-1" />
<dl class="docutils">
<dt><code class="docutils literal notranslate"><span class="pre">int&nbsp;pipe&nbsp;(int&nbsp;pipefd[2]);</span></code></dt>
<dd>Opens a pipe and returns the file descriptors in the array.</dd>
</dl>
</div>
<p>Once the pipe is opened, we can use the standard <code class="docutils literal notranslate"><span class="pre">read()</span></code> and <code class="docutils literal notranslate"><span class="pre">write()</span></code> functions with the file
descriptors. <a class="reference external" href="Pipes.html#cl3-1">Code Listing 3.1</a> show the standard convention of using the array index 1 for writing
and 0 for reading. This practice aligns with the use of file descriptor 1 for <code class="docutils literal notranslate"><span class="pre">stdout</span></code> and 0 for <code class="docutils literal notranslate"><span class="pre">stdin</span></code>.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl3-1"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 3.1:</span>
<span class="cm"> Sending a simple message through a pipe to a child process</span>
<span class="cm"> */</span>
<span class="kt">int</span> <span class="n">pipefd</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
<span class="kt">char</span> <span class="n">buffer</span><span class="p">[</span><span class="mi">10</span><span class="p">];</span>
<span class="cm">/* Clear the buffer */</span>
<span class="n">memset</span> <span class="p">(</span><span class="n">buffer</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">buffer</span><span class="p">));</span>
<span class="cm">/* Open the pipe */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">pipe</span> <span class="p">(</span><span class="n">pipefd</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;ERROR: Failed to open pipe</span><span class="se">\n</span><span class="s">&quot;</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="p">}</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">assert</span> <span class="p">(</span><span class="n">child_pid</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">);</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="p">{</span>
<span class="cm">/* Child closes write-end, then reads from the pipe */</span>
<span class="n">close</span> <span class="p">(</span><span class="n">pipefd</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
<span class="kt">ssize_t</span> <span class="n">bytes_read</span> <span class="o">=</span> <span class="n">read</span> <span class="p">(</span><span class="n">pipefd</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">buffer</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">bytes_read</span> <span class="o">&lt;=</span> <span class="mi">0</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="n">printf</span> <span class="p">(</span><span class="s">&quot;Child received: &#39;%s&#39;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">buffer</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="cm">/* Parent closes the unused reading end */</span>
<span class="n">close</span> <span class="p">(</span><span class="n">pipefd</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="cm">/* Parent sends &#39;hello&#39; and waits */</span>
<span class="n">strncpy</span> <span class="p">(</span><span class="n">buffer</span><span class="p">,</span> <span class="s">&quot;hello&quot;</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">buffer</span><span class="p">));</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Parent is sending &#39;%s&#39;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">buffer</span><span class="p">);</span>
<span class="n">write</span> <span class="p">(</span><span class="n">pipefd</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">buffer</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">buffer</span><span class="p">));</span>
<span class="n">wait</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Child should have printed the message</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p>This code illustrates several conventions with using pipes. First, for the parent and child to
communicate, <code class="docutils literal notranslate"><span class="pre">pipe()</span></code> must be called before <code class="docutils literal notranslate"><span class="pre">fork()</span></code>. This ordering is required to give both
processes access to the pipe. Second, it is customary for each process to close one end of the pipe
immediately after the <code class="docutils literal notranslate"><span class="pre">fork()</span></code>. This practice helps to align the unidirectional nature of the pipe
with its intended use. That is, the convention is that a pipe is reserved for sending data from one
process to another; if the second process wants to respond, it should use a different pipe. Third,
the file descriptor at index 1 is used for writing, while index 0 is for reading.</p>
<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>It is very important to follow the convention of closing the unused end of the pipe
immediately after the <code class="docutils literal notranslate"><span class="pre">fork()</span></code>. Failure to do so can cause programs to freeze
unexpectedly. Consider the following example:</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="kt">int</span> <span class="n">pipefd</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
<span class="n">pipe</span> <span class="p">(</span><span class="n">pipefd</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">fork</span> <span class="p">()</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">0</span><span class="p">);</span> <span class="cm">/* child exits without writing */</span>
<span class="kt">char</span> <span class="n">buffer</span><span class="p">[</span><span class="mi">10</span><span class="p">];</span>
<span class="n">read</span> <span class="p">(</span><span class="n">pipefd</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">buffer</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">buffer</span><span class="p">));</span>
</pre></div>
</td></tr></table></div>
<p>On line 8, the parent process will try to read from the pipe. Instead of immediately
returning, the process will block until an <code class="docutils literal notranslate"><span class="pre">EOF</span></code> (end-of-file) is written into the pipe.
Since the child is the only other process that could write to the pipe and the child
exits without writing anything, the parent will block indefinitely. This problem can
be difficult to diagnose, such as when the child process is redirecting the standard
output of an external program using <code class="docutils literal notranslate"><span class="pre">dup2()</span></code> (which we illustrate below) and the
external program produces no output. To avoid this frustration, always close the
unused end of the pipe.</p>
</div>
<div class="figure mb-2 align-center" id="id1">
<span id="ipcpipe"></span><a class="reference internal image-reference" href="_images/CSF-Images.3.1.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="Pipes are unidirectional and should not be used to respond" src="_images/CSF-Images.3.1.png" style="width: 80%;" /></a>
<p class="caption align-center px-3"><span class="caption-text"> Figure 3.3.3: Pipes are unidirectional and should not be used to respond</span></p>
</div>
<p><a href="Pipes.html#ipcpipe">Figure 3.3.3</a> illustrates a key feature and common bug with pipes. Once a process
has used <code class="docutils literal notranslate"><span class="pre">pipefd[0]</span></code> in a call to <code class="docutils literal notranslate"><span class="pre">read()</span></code>, the same process cannot turn around and <code class="docutils literal notranslate"><span class="pre">write()</span></code>
to <code class="docutils literal notranslate"><span class="pre">pipefd[1]</span></code>; doing so will fail silently and no data will be sent. To allow for bidirectional
communication, use two pipes as in <a class="reference external" href="Pipes.html#cl3-2">Code Listing 3.2</a>. After performing the <code class="docutils literal notranslate"><span class="pre">fork()</span></code>, either pipe
can be designated to be used for parent-to-child or child-to-parent messages.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl3-2"><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
44
45
46
47
48
49
50
51</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 3.2:</span>
<span class="cm"> Using two pipes for bidirectional communication between parent and child</span>
<span class="cm"> */</span>
<span class="kt">int</span> <span class="n">p2cfd</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span> <span class="cm">/* parent-to-child */</span>
<span class="kt">int</span> <span class="n">c2pfd</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span> <span class="cm">/* child-to-parent */</span>
<span class="kt">char</span> <span class="n">buffer</span><span class="p">[</span><span class="mi">10</span><span class="p">];</span>
<span class="kt">ssize_t</span> <span class="n">bytes_read</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="cm">/* Clear the buffer and open the pipe */</span>
<span class="n">memset</span> <span class="p">(</span><span class="n">buffer</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">buffer</span><span class="p">));</span>
<span class="k">if</span> <span class="p">((</span><span class="n">pipe</span> <span class="p">(</span><span class="n">p2cfd</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="n">pipe</span> <span class="p">(</span><span class="n">c2pfd</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">))</span>
<span class="p">{</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;ERROR: Failed to open pipe</span><span class="se">\n</span><span class="s">&quot;</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="p">}</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">assert</span> <span class="p">(</span><span class="n">child_pid</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">);</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="p">{</span>
<span class="cm">/* Child closes write end of p2c, read of c2p */</span>
<span class="n">close</span> <span class="p">(</span><span class="n">p2cfd</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
<span class="n">close</span> <span class="p">(</span><span class="n">c2pfd</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="n">bytes_read</span> <span class="o">=</span> <span class="n">read</span> <span class="p">(</span><span class="n">p2cfd</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">buffer</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">bytes_read</span> <span class="o">&lt;=</span> <span class="mi">0</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="n">printf</span> <span class="p">(</span><span class="s">&quot;Child received: &#39;%s&#39;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">buffer</span><span class="p">);</span>
<span class="cm">/* Child sends response of &quot;goodbye&quot; */</span>
<span class="n">strncpy</span> <span class="p">(</span><span class="n">buffer</span><span class="p">,</span> <span class="s">&quot;goodbye&quot;</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">buffer</span><span class="p">));</span>
<span class="n">write</span> <span class="p">(</span><span class="n">c2pfd</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">buffer</span><span class="p">,</span> <span class="mi">10</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="cm">/* Parent closes read end of p2c, write of c2p */</span>
<span class="n">close</span> <span class="p">(</span><span class="n">p2cfd</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="n">close</span> <span class="p">(</span><span class="n">c2pfd</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
<span class="cm">/* Parent sends &#39;hello&#39; and waits */</span>
<span class="n">strncpy</span> <span class="p">(</span><span class="n">buffer</span><span class="p">,</span> <span class="s">&quot;hello&quot;</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">buffer</span><span class="p">));</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Parent is sending &#39;%s&#39;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">buffer</span><span class="p">);</span>
<span class="n">write</span> <span class="p">(</span><span class="n">p2cfd</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">buffer</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">buffer</span><span class="p">));</span>
<span class="cm">/* Parent reads response back from child */</span>
<span class="n">bytes_read</span> <span class="o">=</span> <span class="n">read</span> <span class="p">(</span><span class="n">c2pfd</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">buffer</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">bytes_read</span> <span class="o">&lt;=</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">/* should receive response */</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Parent received: &#39;%s&#39;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">buffer</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p><a href="Pipes.html#ipctwopipe">Figure 3.3.4</a> illustrates the circular structure of the two pipes used in Code
Listing 3.2. The parent uses <code class="docutils literal notranslate"><span class="pre">p2cfd</span></code> to send data to the child. Responses from the child use the
other pipe, identified by <code class="docutils literal notranslate"><span class="pre">c2pfd</span></code>. In both cases, the calls to <code class="docutils literal notranslate"><span class="pre">write()</span></code> use index 1 and the
<code class="docutils literal notranslate"><span class="pre">read()</span></code> calls use index 0.</p>
<div class="figure mb-2 align-center" id="id2">
<span id="ipctwopipe"></span><a class="reference internal image-reference" href="_images/CSF-Images.3.2.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="Structure of the two pipes used in Code Listing 3.2" src="_images/CSF-Images.3.2.png" style="width: 80%;" /></a>
<p class="caption align-center px-3"><span class="caption-text"> Figure 3.3.4: Structure of the two pipes used in Code Listing 3.2</span></p>
</div>
</div>
<div class="section" id="pipes-and-shell-commands">
<h2>3.3.2. Pipes and Shell Commands<a class="headerlink" href="Pipes.html#pipes-and-shell-commands" title="Permalink to this headline"></a></h2>
<p>One of the most common use of pipes is to link together multiple commands on the command line. For
instance, consider the following command line:</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>$ ls -l | sort -n -k 5 | tail -n 1 | awk &#39;{print $NF}&#39;
</pre></div>
</div>
<p>This command line creates four processes that are linked together. First, the <code class="docutils literal notranslate"><span class="pre">ls</span></code> command prints
out the list of files along with their details. This list is sent as input to <code class="docutils literal notranslate"><span class="pre">sort</span></code>, which sorts
numerically based on the 5th field (the file size). The <code class="docutils literal notranslate"><span class="pre">tail</span></code> process then grabs the last line,
which is the line for the largest file. Finally, <code class="docutils literal notranslate"><span class="pre">awk</span></code> will print the last field of that line,
which is the file name of whatever file is the largest.</p>
<div class="figure mb-2 align-center" id="id3">
<span id="ipcpipeline"></span><a class="reference internal image-reference" href="_images/CSF-Images.3.3.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="Chained logical structure of a sequence of bash commands connected with pipes" src="_images/CSF-Images.3.3.png" style="width: 80%;" /></a>
<p class="caption align-center px-3"><span class="caption-text"> Figure 3.3.5: Chained logical structure of a sequence of bash commands connected with pipes</span></p>
</div>
<p><a href="Pipes.html#ipcpipeline">Figure 3.3.5</a> illustrates the chained structure of these four processes. These
four processes are created by bash using both <code class="docutils literal notranslate"><span class="pre">fork()</span></code> and <code class="docutils literal notranslate"><span class="pre">exec()</span></code>. Once the processes are
created, <code class="docutils literal notranslate"><span class="pre">bash</span></code> links their standard input and output by setting up a pipe to connect each process
with the one after it. (This is the reason the vertical bar (<code class="docutils literal notranslate"><span class="pre">|</span></code>) is referred to as a pipe.)
However, there is an additional step: <code class="docutils literal notranslate"><span class="pre">bash</span></code> needs to link the pipe with each processs standard
input and output. The <code class="docutils literal notranslate"><span class="pre">dup2()</span></code> function accomplishes this task.</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 &lt;unistd.h&gt;</p><hr class="mt-1" />
<dl class="docutils">
<dt><code class="docutils literal notranslate"><span class="pre">int&nbsp;dup2&nbsp;(int&nbsp;oldfd,&nbsp;int&nbsp;newfd);</span></code></dt>
<dd>Closes&nbsp;newfd&nbsp;and replaces it with the file of&nbsp;oldfd</dd>
</dl>
</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 arguments for <code class="docutils literal notranslate"><span class="pre">dup2()</span></code> are easily confused because of the names given in the standard C
documentation. The <code class="docutils literal notranslate"><span class="pre">newfd</span></code> is the file descriptor that you want to use after the call to
<code class="docutils literal notranslate"><span class="pre">dup2()</span></code>. For instance, if you want to change your file descriptors so that subsequent calls to
<code class="docutils literal notranslate"><span class="pre">printf()</span></code> write to the pipe instead of the standard output screen, the <code class="docutils literal notranslate"><span class="pre">newfd</span></code> argument should
be <code class="docutils literal notranslate"><span class="pre">STDOUT_FILENO</span></code>. (The confusion seems to arise because the pipe was created after standard
output, so new programmers often think of the pipe file descriptor as “new,” which is incorrect.)</p>
</div>
<p><a class="reference external" href="Pipes.html#cl3-3">Code Listing 3.3</a> illustrates the basic functionality of how <code class="docutils literal notranslate"><span class="pre">bash</span></code> uses <code class="docutils literal notranslate"><span class="pre">dup2()</span></code> with pipes to
link commands together. Specifically, the command line would be <code class="docutils literal notranslate"><span class="pre">ls</span> <span class="pre">|</span> <span class="pre">sort</span></code>, so <code class="docutils literal notranslate"><span class="pre">bash</span></code> needs to
create and link two processes. The <code class="docutils literal notranslate"><span class="pre">sort</span></code> process closes the write end of the pipe and links the
read end to become its standard input.</p>
<p>Similarly, the <code class="docutils literal notranslate"><span class="pre">ls</span></code> process closes its read end of the pipe and links the write end to its
standard output. Anything that <code class="docutils literal notranslate"><span class="pre">ls</span></code> writes to its standard output (using <code class="docutils literal notranslate"><span class="pre">printf()</span></code>), <code class="docutils literal notranslate"><span class="pre">sort</span></code>
would read from its standard input; both processes are unaware that the pipe exists. In fact, even
if this code used <code class="docutils literal notranslate"><span class="pre">exec()</span></code> to load new program code within these child processes, the processes
would continue to use the pipe as <code class="docutils literal notranslate"><span class="pre">stdin</span></code> and <code class="docutils literal notranslate"><span class="pre">stdout</span></code> without any change to the programs source code.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl3-3"><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
44</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 3.3:</span>
<span class="cm"> Creating a bash-like linkage between two processes</span>
<span class="cm"> */</span>
<span class="cm">/* Parent is acting like &#39;bash&#39; interpreting the command line:</span>
<span class="cm"> $ ls | sort</span>
<span class="cm"> This example assumes the variable declaration and pipe creation</span>
<span class="cm"> as shown in Code Listing 3.1. */</span>
<span class="cm">/* &#39;sort&#39; child process */</span>
<span class="n">assert</span> <span class="p">((</span><span class="n">child_pid</span> <span class="o">=</span> <span class="n">fork</span> <span class="p">())</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">);</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="p">{</span>
<span class="cm">/* &#39;sort&#39; closes unused write end of the pipe */</span>
<span class="n">close</span> <span class="p">(</span><span class="n">pipefd</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
<span class="cm">/* ...and uses the read end as standard input */</span>
<span class="n">dup2</span> <span class="p">(</span><span class="n">pipefd</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">STDIN_FILENO</span><span class="p">);</span>
<span class="cm">/* Reading from &quot;stdin&quot; now reads from the pipe */</span>
<span class="kt">ssize_t</span> <span class="n">bytes_read</span> <span class="o">=</span> <span class="n">read</span> <span class="p">(</span><span class="n">STDIN_FILENO</span><span class="p">,</span> <span class="n">buffer</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">buffer</span><span class="p">));</span>
<span class="k">if</span> <span class="p">(</span><span class="n">bytes_read</span> <span class="o">&lt;=</span> <span class="mi">0</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="cm">/* Trim off the trailing newline character */</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">token</span> <span class="o">=</span> <span class="n">strtok</span> <span class="p">(</span><span class="n">buffer</span><span class="p">,</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;&#39;sort&#39; process received &#39;%s&#39;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">token</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="cm">/* &#39;ls&#39; child process */</span>
<span class="n">assert</span> <span class="p">((</span><span class="n">child_pid</span> <span class="o">=</span> <span class="n">fork</span> <span class="p">())</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">);</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="p">{</span>
<span class="cm">/* &#39;ls&#39; closes the read end of the pipe */</span>
<span class="n">close</span> <span class="p">(</span><span class="n">pipefd</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="cm">/* ...and uses the write end as standard output */</span>
<span class="n">dup2</span> <span class="p">(</span><span class="n">pipefd</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">STDOUT_FILENO</span><span class="p">);</span>
<span class="cm">/* printf() now writes to the pipe instead of the screen */</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;list of files</span><span class="se">\n</span><span class="s">&quot;</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="cm">/* &#39;bash&#39; parent closes both ends of the pipe within itself */</span>
<span class="n">close</span> <span class="p">(</span><span class="n">pipefd</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="n">close</span> <span class="p">(</span><span class="n">pipefd</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
<span class="n">wait</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p>This example also illustrates one subtle aspect of the closing of pipes. When a process closes one
end of the pipe, it is only closing <cite>its access</cite> to that end of the pipe. Other processes may still
use that end of the pipe. For instance, in the previous example, observe that the parent process
closes both <code class="docutils literal notranslate"><span class="pre">pipefd[0]</span></code> and <code class="docutils literal notranslate"><span class="pre">pipefd[1]</span></code>. This does not affect the pipe itself, and it does not
prevent the two child processes from communicating via the pipe. All these two lines of code do are
close the parents (<code class="docutils literal notranslate"><span class="pre">bash</span></code>s) access to the pipe, preventing it from reading or writing to the
pipe. The pipe will remain in existence until all processes with access either close both ends of
the pipe or exit (which closes all open file connections).</p>
</div>
<div class="section" id="fifos">
<h2>3.3.3. FIFOs<a class="headerlink" href="Pipes.html#fifos" title="Permalink to this headline"></a></h2>
<p>The pipes described above create a simple mechanism for parent and child processes to communicate,
but they cannot be used for unrelated processes. Specifically, notice that the call to <code class="docutils literal notranslate"><span class="pre">pipe()</span></code>
must happen within the same program that later calls <code class="docutils literal notranslate"><span class="pre">fork()</span></code>. That is, the pipe is first created
within a single process and is only shared with processes created as children (or children of
children, if the child also calls <code class="docutils literal notranslate"><span class="pre">fork()</span></code>). This approach will not work for two random processes
that need to create an ad hoc communication session. <a class="reference internal" href="Glossary.html#term-fifo"><span class="xref std std-term">FIFOs</span></a> (first-in, first-out)
are a variation on a pipe that creates a more flexible communication structure.</p>
<p>FIFOs work by attaching a filename to the pipe. For this reason, FIFOs are also called <a class="reference internal" href="Glossary.html#term-named-pipe"><span class="xref std std-term">named pipes</span></a>
as opposed to the anonymous pipes discussed previously. FIFOs are created by one process that
calls <code class="docutils literal notranslate"><span class="pre">mkfifo()</span></code>. Once created, any process (with correct access permissions) can access the FIFO
by calling <code class="docutils literal notranslate"><span class="pre">open()</span></code> on the associated filename. Once the processes have opened the file, they can
use the standard <code class="docutils literal notranslate"><span class="pre">read()</span></code> and <code class="docutils literal notranslate"><span class="pre">write()</span></code> functions to communicate.</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 &lt;sys/stat.h&gt;</p><hr class="mt-1" />
<dl class="docutils">
<dt><code class="docutils literal notranslate"><span class="pre">int&nbsp;mkfifo&nbsp;(const&nbsp;char&nbsp;*pathname,&nbsp;mode_t&nbsp;mode);</span></code></dt>
<dd>Creates a new file identified by the&nbsp;pathname&nbsp;to use as a FIFO</dd>
</dl>
</div>
<p>A common use for FIFOs is to create client/server applications on the same machine. For example,
consider an anti-virus server that runs in the background, scanning for corrupted files. When the
system administrator wants to get a report on potentially bad files, they run a client application
that uses a FIFO to initiate contact with the server. Both the server and the client application are
distinct processes that are running separate programs. That is, neither process was created by
either of them calling <code class="docutils literal notranslate"><span class="pre">fork()</span></code>. As such, an anonymous <code class="docutils literal notranslate"><span class="pre">pipe()</span></code> call would not work. Instead,
both processes use the name attached to the FIFO to set up the communication.</p>
<p>As a simple scenario, consider a server that prints hello whenever a client writes a non-zero value
to a file and shuts down when the client writes a zero. <a class="reference external" href="Pipes.html#cl3-4">Code Listing 3.4</a> shows the structure of the
server. The server starts by creating the FIFO with read and write permissions for the current user.
Then, the server opens the FIFO in read-only mode and enters the listening loop. Once the server
reads a value of 0 from the FIFO, it exits the loop, then closes and deletes the FIFO.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl3-4"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 3.4:</span>
<span class="cm"> The basic structure of a server process using a FIFO</span>
<span class="cm"> */</span>
<span class="cm">/* Create the FIFO or die trying */</span>
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">FIFO</span> <span class="o">=</span> <span class="s">&quot;/tmp/MY_FIFO&quot;</span><span class="p">;</span>
<span class="n">assert</span> <span class="p">(</span><span class="n">mkfifo</span> <span class="p">(</span><span class="n">FIFO</span><span class="p">,</span> <span class="n">S_IRUSR</span> <span class="o">|</span> <span class="n">S_IWUSR</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
<span class="cm">/* Try to open the FIFO. Delete FIFO if open() fails */</span>
<span class="kt">int</span> <span class="n">fifo</span> <span class="o">=</span> <span class="n">open</span> <span class="p">(</span><span class="n">FIFO</span><span class="p">,</span> <span class="n">O_RDONLY</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">fifo</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span> <span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Failed to open FIFO</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="n">unlink</span> <span class="p">(</span><span class="n">FIFO</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* Main server loop */</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="kt">int</span> <span class="n">req</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">read</span> <span class="p">(</span><span class="n">fifo</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">req</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="kt">int</span><span class="p">))</span> <span class="o">!=</span> <span class="k">sizeof</span> <span class="p">(</span><span class="kt">int</span><span class="p">))</span>
<span class="k">continue</span><span class="p">;</span>
<span class="cm">/* If we read a 0, quit; otherwise print hello */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">req</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">break</span><span class="p">;</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;hello</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Read a 0 from the FIFO, so close and delete the FIFO */</span>
<span class="n">close</span> <span class="p">(</span><span class="n">fifo</span><span class="p">);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Deleting FIFO</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="n">unlink</span> <span class="p">(</span><span class="n">FIFO</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p><a class="reference external" href="Pipes.html#cl3-5">Code Listing 3.5</a> shows a sample client. This client opens the FIFO, then writes a sequence of
integers (5 down to 0) into the FIFO. Note that anything the client writes after the 0 would be
thrown away, as the server would delete the FIFO at that point.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl3-5"><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 3.5:</span>
<span class="cm"> A client process that sends six messages to the server in Code Listing 3.4</span>
<span class="cm"> */</span>
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">FIFO</span> <span class="o">=</span> <span class="s">&quot;/tmp/MY_FIFO&quot;</span><span class="p">;</span>
<span class="cm">/* Use the file name to open the FIFO for writing */</span>
<span class="kt">int</span> <span class="n">fifo</span> <span class="o">=</span> <span class="n">open</span> <span class="p">(</span><span class="n">FIFO</span><span class="p">,</span> <span class="n">O_WRONLY</span><span class="p">);</span>
<span class="n">assert</span> <span class="p">(</span><span class="n">fifo</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>
<span class="cm">/* Open the FIFO 6 times, writing an int each time */</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">index</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span> <span class="n">index</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">index</span><span class="o">--</span><span class="p">)</span>
<span class="p">{</span>
<span class="cm">/* Write 5, 4, 3, 2, 1, 0 into the FIFO */</span>
<span class="kt">int</span> <span class="n">msg</span> <span class="o">=</span> <span class="n">index</span><span class="p">;</span>
<span class="n">write</span> <span class="p">(</span><span class="n">fifo</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">msg</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="kt">int</span><span class="p">));</span>
<span class="cm">/* Add a slight delay each time */</span>
<span class="n">sleep</span> <span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Close the FIFO */</span>
<span class="n">close</span> <span class="p">(</span><span class="n">fifo</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p>Although FIFOs use standard file I/O functions (e.g., <code class="docutils literal notranslate"><span class="pre">open()</span></code>, <code class="docutils literal notranslate"><span class="pre">read()</span></code>, and <code class="docutils literal notranslate"><span class="pre">write()</span></code>), it
is important to note that they are not regular files. Specifically, once data has been read from a
FIFO, the data is discarded and cannot be read again (just like an anonymous pipe). In contrast,
with a regular file, multiple processes can read the same data from the same file. That is, regular
files store data persistently, but FIFOs do not. Consequently, FIFOs cannot be used for broadcasting
a single message to multiple recipients; only one process can read the data. Similarly, FIFOs (like
pipes) are not suitable for bi-directional communication; if a process writes into the FIFO then
immediately tries to read a response, <strong>it may read its own message</strong>!</p>
<p>Also similar to anonymous pipes, FIFOs use <a class="reference internal" href="Glossary.html#term-blocking-i-o"><span class="xref std std-term">blocking I/O</span></a> until both ends are opened by at least
one process. As such, there is no concern about a process writing into the FIFO too soon; if no
process has opened the FIFO for reading, the writing process will block until a reader becomes
available. This behavior may be problematic if the writing process needs to perform some other task.
To resolve this problem, pass the <code class="docutils literal notranslate"><span class="pre">O_NONBLOCK</span></code> option during the call to <code class="docutils literal notranslate"><span class="pre">open()</span></code> to make the
FIFO access non-blocking.</p>
<div
id="IPCPipesSumm"
class="embedContainer"
data-exer-name="IPCPipesSumm"
data-long-name="Pipes and FIFOs questions"
data-short-name="IPCPipesSumm"
data-frame-src="../../../Exercises/IPC/IPCPipesSumm.html?selfLoggingEnabled=false&amp;localMode=true&amp;module=Pipes&amp;JXOP-debug=true&amp;JOP-lang=en&amp;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="5"
data-type="ka"
data-exer-id="">
<div class="center">
<div id="IPCPipesSumm_iframe"></div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="mt-4 container center">
«&#160;&#160;<a id="prevmod1" href="IPCModels.html">3.2. IPC Models</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod1" href="MMap.html">3.4. Shared Memory With Memory-mapped Files</a>&#160;&#160;»
</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>